mirror of
https://github.com/corda/corda.git
synced 2025-04-12 21:53:17 +00:00
move MoveEvent out of compiler.cpp
This commit is contained in:
parent
165c77d772
commit
5ad0eb86d3
@ -36,7 +36,6 @@ const bool DebugCompile = false;
|
||||
const bool DebugResources = false;
|
||||
const bool DebugFrame = false;
|
||||
const bool DebugControl = false;
|
||||
const bool DebugMoves = false;
|
||||
const bool DebugBuddies = false;
|
||||
|
||||
const unsigned StealRegisterReserveCount = 2;
|
||||
@ -333,13 +332,6 @@ frameIndex(Context* c, FrameIterator::Element* element)
|
||||
return frameIndex(c, element->localIndex);
|
||||
}
|
||||
|
||||
bool
|
||||
hasSite(Context* c, Value* v)
|
||||
{
|
||||
SiteIterator it(c, v);
|
||||
return it.hasMore();
|
||||
}
|
||||
|
||||
bool
|
||||
uniqueSite(Context* c, Value* v, Site* s)
|
||||
{
|
||||
@ -365,25 +357,6 @@ uniqueSite(Context* c, Value* v, Site* s)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
removeSite(Context* c, Value* v, Site* s)
|
||||
{
|
||||
for (SiteIterator it(c, v); it.hasMore();) {
|
||||
if (s == it.next()) {
|
||||
if (DebugSites) {
|
||||
char buffer[256]; s->toString(c, buffer, 256);
|
||||
fprintf(stderr, "remove site %s from %p\n", buffer, v);
|
||||
}
|
||||
it.remove(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (DebugSites) {
|
||||
fprintf(stderr, "%p has more: %d\n", v, hasSite(c, v));
|
||||
}
|
||||
assert(c, not v->findSite(s));
|
||||
}
|
||||
|
||||
void
|
||||
clearSites(Context* c, Value* v)
|
||||
{
|
||||
@ -873,7 +846,7 @@ steal(Context* c, Resource* r, Value* thief)
|
||||
r->site->thaw(c, r->value);
|
||||
}
|
||||
|
||||
removeSite(c, r->value, r->site);
|
||||
r->value->removeSite(c, r->site);
|
||||
}
|
||||
|
||||
SiteMask
|
||||
@ -1238,7 +1211,7 @@ maybeMove(Context* c, lir::BinaryOperation type, unsigned srcSize,
|
||||
// pick a temporary register which is valid as both a
|
||||
// destination and a source for the moves we need to perform:
|
||||
|
||||
removeSite(c, dst, target);
|
||||
dst->removeSite(c, target);
|
||||
|
||||
bool thunk;
|
||||
uint8_t srcTypeMask;
|
||||
@ -1294,7 +1267,7 @@ maybeMove(Context* c, lir::BinaryOperation type, unsigned srcSize,
|
||||
tmpTarget->thaw(c, dst);
|
||||
|
||||
if (isStore) {
|
||||
removeSite(c, dst, tmpTarget);
|
||||
dst->removeSite(c, tmpTarget);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1315,7 +1288,7 @@ maybeMove(Context* c, lir::BinaryOperation type, unsigned srcSize,
|
||||
}
|
||||
|
||||
if (isStore) {
|
||||
removeSite(c, dst, target);
|
||||
dst->removeSite(c, target);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1358,7 +1331,7 @@ pickSiteOrMove(Context* c, Value* src, Value* dst, Site* nextWord,
|
||||
addBuddy(src, dst);
|
||||
|
||||
if (src->source->isVolatile(c)) {
|
||||
removeSite(c, src, src->source);
|
||||
src->removeSite(c, src->source);
|
||||
}
|
||||
|
||||
return s;
|
||||
@ -1367,222 +1340,6 @@ pickSiteOrMove(Context* c, Value* src, Value* dst, Site* nextWord,
|
||||
}
|
||||
}
|
||||
|
||||
Value*
|
||||
value(Context* c, lir::ValueType type, Site* site = 0, Site* target = 0)
|
||||
{
|
||||
return new(c->zone) Value(site, target, type);
|
||||
}
|
||||
|
||||
void
|
||||
grow(Context* c, Value* v)
|
||||
{
|
||||
assert(c, v->nextWord == v);
|
||||
|
||||
Value* next = value(c, v->type);
|
||||
v->nextWord = next;
|
||||
next->nextWord = v;
|
||||
next->wordIndex = 1;
|
||||
}
|
||||
|
||||
void
|
||||
split(Context* c, Value* v)
|
||||
{
|
||||
grow(c, v);
|
||||
for (SiteIterator it(c, v); it.hasMore();) {
|
||||
Site* s = it.next();
|
||||
removeSite(c, v, s);
|
||||
|
||||
v->addSite(c, s->copyLow(c));
|
||||
v->nextWord->addSite(c, s->copyHigh(c));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
maybeSplit(Context* c, Value* v)
|
||||
{
|
||||
if (v->nextWord == v) {
|
||||
split(c, v);
|
||||
}
|
||||
}
|
||||
|
||||
class MoveEvent: public Event {
|
||||
public:
|
||||
MoveEvent(Context* c, lir::BinaryOperation type, unsigned srcSize,
|
||||
unsigned srcSelectSize, Value* src, unsigned dstSize, Value* dst,
|
||||
const SiteMask& srcLowMask, const SiteMask& srcHighMask):
|
||||
Event(c), type(type), srcSize(srcSize), srcSelectSize(srcSelectSize),
|
||||
src(src), dstSize(dstSize), dst(dst)
|
||||
{
|
||||
assert(c, srcSelectSize <= srcSize);
|
||||
|
||||
bool noop = srcSelectSize >= dstSize;
|
||||
|
||||
if (dstSize > TargetBytesPerWord) {
|
||||
grow(c, dst);
|
||||
}
|
||||
|
||||
if (srcSelectSize > TargetBytesPerWord) {
|
||||
maybeSplit(c, src);
|
||||
}
|
||||
|
||||
this->addReads(c, src, srcSelectSize, srcLowMask, noop ? dst : 0,
|
||||
srcHighMask,
|
||||
noop and dstSize > TargetBytesPerWord ? dst->nextWord : 0);
|
||||
}
|
||||
|
||||
virtual const char* name() {
|
||||
return "MoveEvent";
|
||||
}
|
||||
|
||||
virtual void compile(Context* c) {
|
||||
uint8_t dstTypeMask;
|
||||
uint64_t dstRegisterMask;
|
||||
|
||||
c->arch->planDestination
|
||||
(type,
|
||||
srcSelectSize,
|
||||
1 << src->source->type(c),
|
||||
(static_cast<uint64_t>(src->nextWord->source->registerMask(c)) << 32)
|
||||
| static_cast<uint64_t>(src->source->registerMask(c)),
|
||||
dstSize,
|
||||
&dstTypeMask,
|
||||
&dstRegisterMask);
|
||||
|
||||
SiteMask dstLowMask(dstTypeMask, dstRegisterMask, AnyFrameIndex);
|
||||
SiteMask dstHighMask(dstTypeMask, dstRegisterMask >> 32, AnyFrameIndex);
|
||||
|
||||
if (srcSelectSize >= TargetBytesPerWord
|
||||
and dstSize >= TargetBytesPerWord
|
||||
and srcSelectSize >= dstSize)
|
||||
{
|
||||
if (dst->target) {
|
||||
if (dstSize > TargetBytesPerWord) {
|
||||
if (src->source->registerSize(c) > TargetBytesPerWord) {
|
||||
apply(c, lir::Move, srcSelectSize, src->source, src->source,
|
||||
dstSize, dst->target, dst->target);
|
||||
|
||||
if (live(c, dst) == 0) {
|
||||
removeSite(c, dst, dst->target);
|
||||
if (dstSize > TargetBytesPerWord) {
|
||||
removeSite(c, dst->nextWord, dst->nextWord->target);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
src->nextWord->source->freeze(c, src->nextWord);
|
||||
|
||||
maybeMove(c, lir::Move, TargetBytesPerWord, TargetBytesPerWord, src,
|
||||
TargetBytesPerWord, dst, dstLowMask);
|
||||
|
||||
src->nextWord->source->thaw(c, src->nextWord);
|
||||
|
||||
maybeMove
|
||||
(c, lir::Move, TargetBytesPerWord, TargetBytesPerWord, src->nextWord,
|
||||
TargetBytesPerWord, dst->nextWord, dstHighMask);
|
||||
}
|
||||
} else {
|
||||
maybeMove(c, lir::Move, TargetBytesPerWord, TargetBytesPerWord, src,
|
||||
TargetBytesPerWord, dst, dstLowMask);
|
||||
}
|
||||
} else {
|
||||
Site* low = pickSiteOrMove(c, src, dst, 0, 0);
|
||||
if (dstSize > TargetBytesPerWord) {
|
||||
pickSiteOrMove(c, src->nextWord, dst->nextWord, low, 1);
|
||||
}
|
||||
}
|
||||
} else if (srcSelectSize <= TargetBytesPerWord
|
||||
and dstSize <= TargetBytesPerWord)
|
||||
{
|
||||
maybeMove(c, type, srcSize, srcSelectSize, src, dstSize, dst,
|
||||
dstLowMask);
|
||||
} else {
|
||||
assert(c, srcSize == TargetBytesPerWord);
|
||||
assert(c, srcSelectSize == TargetBytesPerWord);
|
||||
|
||||
if (dst->nextWord->target or live(c, dst->nextWord)) {
|
||||
assert(c, dstLowMask.typeMask & (1 << lir::RegisterOperand));
|
||||
|
||||
Site* low = freeRegisterSite(c, dstLowMask.registerMask);
|
||||
|
||||
src->source->freeze(c, src);
|
||||
|
||||
dst->addSite(c, low);
|
||||
|
||||
low->freeze(c, dst);
|
||||
|
||||
if (DebugMoves) {
|
||||
char srcb[256]; src->source->toString(c, srcb, 256);
|
||||
char dstb[256]; low->toString(c, dstb, 256);
|
||||
fprintf(stderr, "move %s to %s for %p\n",
|
||||
srcb, dstb, src);
|
||||
}
|
||||
|
||||
apply(c, lir::Move, TargetBytesPerWord, src->source, src->source,
|
||||
TargetBytesPerWord, low, low);
|
||||
|
||||
low->thaw(c, dst);
|
||||
|
||||
src->source->thaw(c, src);
|
||||
|
||||
assert(c, dstHighMask.typeMask & (1 << lir::RegisterOperand));
|
||||
|
||||
Site* high = freeRegisterSite(c, dstHighMask.registerMask);
|
||||
|
||||
low->freeze(c, dst);
|
||||
|
||||
dst->nextWord->addSite(c, high);
|
||||
|
||||
high->freeze(c, dst->nextWord);
|
||||
|
||||
if (DebugMoves) {
|
||||
char srcb[256]; low->toString(c, srcb, 256);
|
||||
char dstb[256]; high->toString(c, dstb, 256);
|
||||
fprintf(stderr, "extend %s to %s for %p %p\n",
|
||||
srcb, dstb, dst, dst->nextWord);
|
||||
}
|
||||
|
||||
apply(c, lir::Move, TargetBytesPerWord, low, low, dstSize, low, high);
|
||||
|
||||
high->thaw(c, dst->nextWord);
|
||||
|
||||
low->thaw(c, dst);
|
||||
} else {
|
||||
pickSiteOrMove(c, src, dst, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
for (Read* r = reads; r; r = r->eventNext) {
|
||||
popRead(c, this, r->value);
|
||||
}
|
||||
}
|
||||
|
||||
lir::BinaryOperation type;
|
||||
unsigned srcSize;
|
||||
unsigned srcSelectSize;
|
||||
Value* src;
|
||||
unsigned dstSize;
|
||||
Value* dst;
|
||||
};
|
||||
|
||||
void
|
||||
appendMove(Context* c, lir::BinaryOperation type, unsigned srcSize,
|
||||
unsigned srcSelectSize, Value* src, unsigned dstSize, Value* dst)
|
||||
{
|
||||
bool thunk;
|
||||
uint8_t srcTypeMask;
|
||||
uint64_t srcRegisterMask;
|
||||
|
||||
c->arch->planSource
|
||||
(type, srcSelectSize, &srcTypeMask, &srcRegisterMask, dstSize, &thunk);
|
||||
|
||||
assert(c, not thunk);
|
||||
|
||||
append(c, new(c->zone)
|
||||
MoveEvent
|
||||
(c, type, srcSize, srcSelectSize, src, dstSize, dst,
|
||||
SiteMask(srcTypeMask, srcRegisterMask, AnyFrameIndex),
|
||||
SiteMask(srcTypeMask, srcRegisterMask >> 32, AnyFrameIndex)));
|
||||
}
|
||||
|
||||
ConstantSite*
|
||||
findConstantSite(Context* c, Value* v)
|
||||
{
|
||||
@ -1630,7 +1387,7 @@ getTarget(Context* c, Value* value, Value* result, const SiteMask& resultMask)
|
||||
result->addSite(c, s);
|
||||
}
|
||||
|
||||
removeSite(c, v, s);
|
||||
v->removeSite(c, s);
|
||||
|
||||
s->freeze(c, v);
|
||||
|
||||
@ -1672,7 +1429,7 @@ class CombineEvent: public Event {
|
||||
this->addReads(c, first, firstSize, firstLowMask, firstHighMask);
|
||||
|
||||
if (resultSize > TargetBytesPerWord) {
|
||||
grow(c, result);
|
||||
result->grow(c);
|
||||
}
|
||||
|
||||
bool condensed = c->arch->alwaysCondensed(type);
|
||||
@ -1896,7 +1653,7 @@ push(Context* c, unsigned footprint, Value* v)
|
||||
assert(c, footprint == 2);
|
||||
|
||||
if (TargetBytesPerWord == 4) {
|
||||
maybeSplit(c, low);
|
||||
low->maybeSplit(c);
|
||||
high = pushWord(c, low->nextWord);
|
||||
} else {
|
||||
high = pushWord(c, 0);
|
||||
@ -2136,7 +1893,7 @@ class TranslateEvent: public Event {
|
||||
bool condensed = c->arch->alwaysCondensed(type);
|
||||
|
||||
if (resultSize > TargetBytesPerWord) {
|
||||
grow(c, result);
|
||||
result->grow(c);
|
||||
}
|
||||
|
||||
this->addReads(c, value, valueSize, valueLowMask, condensed ? result : 0,
|
||||
@ -2268,7 +2025,7 @@ moveIfConflict(Context* c, Value* v, MemorySite* s)
|
||||
v->reads->intersect(&mask);
|
||||
if (s->conflicts(mask)) {
|
||||
maybeMove(c, v->reads, true, false);
|
||||
removeSite(c, v, s);
|
||||
v->removeSite(c, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2818,7 +2575,7 @@ class BuddyEvent: public Event {
|
||||
fprintf(stderr, "original %p buddy %p\n", original, buddy);
|
||||
}
|
||||
|
||||
assert(c, hasSite(c, original));
|
||||
assert(c, original->hasSite(c));
|
||||
|
||||
assert(c, original);
|
||||
assert(c, buddy);
|
||||
@ -2952,7 +2709,7 @@ readSource(Context* c, Read* r)
|
||||
fprintf(stderr, "read source for %p from %s\n", v, buffer);
|
||||
}
|
||||
|
||||
if (not hasSite(c, v)) {
|
||||
if (not v->hasSite(c)) {
|
||||
if (DebugReads) {
|
||||
fprintf(stderr, "no sites found for %p\n", v);
|
||||
}
|
||||
@ -3080,7 +2837,7 @@ resolveOriginalSites(Context* c, Event* e, SiteRecordList* frozen,
|
||||
|
||||
Value dummy(0, 0, lir::ValueGeneral);
|
||||
dummy.addSite(c, s);
|
||||
removeSite(c, &dummy, s);
|
||||
dummy.removeSite(c, s);
|
||||
freeze(c, frozen, s, 0);
|
||||
}
|
||||
}
|
||||
|
@ -61,6 +61,14 @@ Read* live(Context* c UNUSED, Value* v);
|
||||
|
||||
void popRead(Context* c, Event* e UNUSED, Value* v);
|
||||
|
||||
void
|
||||
maybeMove(Context* c, lir::BinaryOperation type, unsigned srcSize,
|
||||
unsigned srcSelectSize, Value* src, unsigned dstSize, Value* dst,
|
||||
const SiteMask& dstMask);
|
||||
Site*
|
||||
pickSiteOrMove(Context* c, Value* src, Value* dst, Site* nextWord,
|
||||
unsigned index);
|
||||
|
||||
Event::Event(Context* c):
|
||||
next(0), stackBefore(c->stack), localsBefore(c->locals),
|
||||
stackAfter(0), localsAfter(0), promises(0), reads(0),
|
||||
@ -493,6 +501,184 @@ void appendReturn(Context* c, unsigned size, Value* value) {
|
||||
append(c, new(c->zone) ReturnEvent(c, size, value));
|
||||
}
|
||||
|
||||
class MoveEvent: public Event {
|
||||
public:
|
||||
MoveEvent(Context* c, lir::BinaryOperation type, unsigned srcSize,
|
||||
unsigned srcSelectSize, Value* src, unsigned dstSize, Value* dst,
|
||||
const SiteMask& srcLowMask, const SiteMask& srcHighMask):
|
||||
Event(c), type(type), srcSize(srcSize), srcSelectSize(srcSelectSize),
|
||||
src(src), dstSize(dstSize), dst(dst)
|
||||
{
|
||||
assert(c, srcSelectSize <= srcSize);
|
||||
|
||||
bool noop = srcSelectSize >= dstSize;
|
||||
|
||||
if (dstSize > vm::TargetBytesPerWord) {
|
||||
dst->grow(c);
|
||||
}
|
||||
|
||||
if (srcSelectSize > vm::TargetBytesPerWord) {
|
||||
src->maybeSplit(c);
|
||||
}
|
||||
|
||||
this->addReads(c, src, srcSelectSize, srcLowMask, noop ? dst : 0,
|
||||
srcHighMask,
|
||||
noop and dstSize > vm::TargetBytesPerWord ? dst->nextWord : 0);
|
||||
}
|
||||
|
||||
virtual const char* name() {
|
||||
return "MoveEvent";
|
||||
}
|
||||
|
||||
virtual void compile(Context* c) {
|
||||
uint8_t dstTypeMask;
|
||||
uint64_t dstRegisterMask;
|
||||
|
||||
c->arch->planDestination
|
||||
(type,
|
||||
srcSelectSize,
|
||||
1 << src->source->type(c),
|
||||
(static_cast<uint64_t>(src->nextWord->source->registerMask(c)) << 32)
|
||||
| static_cast<uint64_t>(src->source->registerMask(c)),
|
||||
dstSize,
|
||||
&dstTypeMask,
|
||||
&dstRegisterMask);
|
||||
|
||||
SiteMask dstLowMask(dstTypeMask, dstRegisterMask, AnyFrameIndex);
|
||||
SiteMask dstHighMask(dstTypeMask, dstRegisterMask >> 32, AnyFrameIndex);
|
||||
|
||||
if (srcSelectSize >= vm::TargetBytesPerWord
|
||||
and dstSize >= vm::TargetBytesPerWord
|
||||
and srcSelectSize >= dstSize)
|
||||
{
|
||||
if (dst->target) {
|
||||
if (dstSize > vm::TargetBytesPerWord) {
|
||||
if (src->source->registerSize(c) > vm::TargetBytesPerWord) {
|
||||
apply(c, lir::Move, srcSelectSize, src->source, src->source,
|
||||
dstSize, dst->target, dst->target);
|
||||
|
||||
if (live(c, dst) == 0) {
|
||||
dst->removeSite(c, dst->target);
|
||||
if (dstSize > vm::TargetBytesPerWord) {
|
||||
dst->nextWord->removeSite(c, dst->nextWord->target);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
src->nextWord->source->freeze(c, src->nextWord);
|
||||
|
||||
maybeMove(c, lir::Move, vm::TargetBytesPerWord, vm::TargetBytesPerWord, src,
|
||||
vm::TargetBytesPerWord, dst, dstLowMask);
|
||||
|
||||
src->nextWord->source->thaw(c, src->nextWord);
|
||||
|
||||
maybeMove
|
||||
(c, lir::Move, vm::TargetBytesPerWord, vm::TargetBytesPerWord, src->nextWord,
|
||||
vm::TargetBytesPerWord, dst->nextWord, dstHighMask);
|
||||
}
|
||||
} else {
|
||||
maybeMove(c, lir::Move, vm::TargetBytesPerWord, vm::TargetBytesPerWord, src,
|
||||
vm::TargetBytesPerWord, dst, dstLowMask);
|
||||
}
|
||||
} else {
|
||||
Site* low = pickSiteOrMove(c, src, dst, 0, 0);
|
||||
if (dstSize > vm::TargetBytesPerWord) {
|
||||
pickSiteOrMove(c, src->nextWord, dst->nextWord, low, 1);
|
||||
}
|
||||
}
|
||||
} else if (srcSelectSize <= vm::TargetBytesPerWord
|
||||
and dstSize <= vm::TargetBytesPerWord)
|
||||
{
|
||||
maybeMove(c, type, srcSize, srcSelectSize, src, dstSize, dst,
|
||||
dstLowMask);
|
||||
} else {
|
||||
assert(c, srcSize == vm::TargetBytesPerWord);
|
||||
assert(c, srcSelectSize == vm::TargetBytesPerWord);
|
||||
|
||||
if (dst->nextWord->target or live(c, dst->nextWord)) {
|
||||
assert(c, dstLowMask.typeMask & (1 << lir::RegisterOperand));
|
||||
|
||||
Site* low = freeRegisterSite(c, dstLowMask.registerMask);
|
||||
|
||||
src->source->freeze(c, src);
|
||||
|
||||
dst->addSite(c, low);
|
||||
|
||||
low->freeze(c, dst);
|
||||
|
||||
if (DebugMoves) {
|
||||
char srcb[256]; src->source->toString(c, srcb, 256);
|
||||
char dstb[256]; low->toString(c, dstb, 256);
|
||||
fprintf(stderr, "move %s to %s for %p\n",
|
||||
srcb, dstb, src);
|
||||
}
|
||||
|
||||
apply(c, lir::Move, vm::TargetBytesPerWord, src->source, src->source,
|
||||
vm::TargetBytesPerWord, low, low);
|
||||
|
||||
low->thaw(c, dst);
|
||||
|
||||
src->source->thaw(c, src);
|
||||
|
||||
assert(c, dstHighMask.typeMask & (1 << lir::RegisterOperand));
|
||||
|
||||
Site* high = freeRegisterSite(c, dstHighMask.registerMask);
|
||||
|
||||
low->freeze(c, dst);
|
||||
|
||||
dst->nextWord->addSite(c, high);
|
||||
|
||||
high->freeze(c, dst->nextWord);
|
||||
|
||||
if (DebugMoves) {
|
||||
char srcb[256]; low->toString(c, srcb, 256);
|
||||
char dstb[256]; high->toString(c, dstb, 256);
|
||||
fprintf(stderr, "extend %s to %s for %p %p\n",
|
||||
srcb, dstb, dst, dst->nextWord);
|
||||
}
|
||||
|
||||
apply(c, lir::Move, vm::TargetBytesPerWord, low, low, dstSize, low, high);
|
||||
|
||||
high->thaw(c, dst->nextWord);
|
||||
|
||||
low->thaw(c, dst);
|
||||
} else {
|
||||
pickSiteOrMove(c, src, dst, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
for (Read* r = reads; r; r = r->eventNext) {
|
||||
popRead(c, this, r->value);
|
||||
}
|
||||
}
|
||||
|
||||
lir::BinaryOperation type;
|
||||
unsigned srcSize;
|
||||
unsigned srcSelectSize;
|
||||
Value* src;
|
||||
unsigned dstSize;
|
||||
Value* dst;
|
||||
};
|
||||
|
||||
void
|
||||
appendMove(Context* c, lir::BinaryOperation type, unsigned srcSize,
|
||||
unsigned srcSelectSize, Value* src, unsigned dstSize, Value* dst)
|
||||
{
|
||||
bool thunk;
|
||||
uint8_t srcTypeMask;
|
||||
uint64_t srcRegisterMask;
|
||||
|
||||
c->arch->planSource
|
||||
(type, srcSelectSize, &srcTypeMask, &srcRegisterMask, dstSize, &thunk);
|
||||
|
||||
assert(c, not thunk);
|
||||
|
||||
append(c, new(c->zone)
|
||||
MoveEvent
|
||||
(c, type, srcSize, srcSelectSize, src, dstSize, dst,
|
||||
SiteMask(srcTypeMask, srcRegisterMask, AnyFrameIndex),
|
||||
SiteMask(srcTypeMask, srcRegisterMask >> 32, AnyFrameIndex)));
|
||||
}
|
||||
|
||||
} // namespace compiler
|
||||
} // namespace codegen
|
||||
} // namespace avian
|
||||
|
@ -23,6 +23,7 @@ class Site;
|
||||
class StubRead;
|
||||
|
||||
const bool DebugReads = false;
|
||||
const bool DebugMoves = false;
|
||||
|
||||
class Event {
|
||||
public:
|
||||
@ -117,6 +118,10 @@ appendCall(Context* c, Value* address, unsigned flags,
|
||||
void
|
||||
appendReturn(Context* c, unsigned size, Value* value);
|
||||
|
||||
void
|
||||
appendMove(Context* c, lir::BinaryOperation type, unsigned srcSize,
|
||||
unsigned srcSelectSize, Value* src, unsigned dstSize, Value* dst);
|
||||
|
||||
} // namespace compiler
|
||||
} // namespace codegen
|
||||
} // namespace avian
|
||||
|
@ -50,6 +50,61 @@ void Value::addSite(Context* c, Site* s) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Value::grow(Context* c) {
|
||||
assert(c, this->nextWord == this);
|
||||
|
||||
Value* next = value(c, this->type);
|
||||
this->nextWord = next;
|
||||
next->nextWord = this;
|
||||
next->wordIndex = 1;
|
||||
}
|
||||
|
||||
|
||||
void Value::maybeSplit(Context* c) {
|
||||
if (this->nextWord == this) {
|
||||
this->split(c);
|
||||
}
|
||||
}
|
||||
|
||||
void Value::split(Context* c) {
|
||||
this->grow(c);
|
||||
for (SiteIterator it(c, this); it.hasMore();) {
|
||||
Site* s = it.next();
|
||||
this->removeSite(c, s);
|
||||
|
||||
this->addSite(c, s->copyLow(c));
|
||||
this->nextWord->addSite(c, s->copyHigh(c));
|
||||
}
|
||||
}
|
||||
|
||||
void Value::removeSite(Context* c, Site* s) {
|
||||
for (SiteIterator it(c, this); it.hasMore();) {
|
||||
if (s == it.next()) {
|
||||
if (DebugSites) {
|
||||
char buffer[256]; s->toString(c, buffer, 256);
|
||||
fprintf(stderr, "remove site %s from %p\n", buffer, this);
|
||||
}
|
||||
it.remove(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (DebugSites) {
|
||||
fprintf(stderr, "%p has more: %d\n", this, this->hasSite(c));
|
||||
}
|
||||
assert(c, not this->findSite(s));
|
||||
}
|
||||
|
||||
bool Value::hasSite(Context* c) {
|
||||
SiteIterator it(c, this);
|
||||
return it.hasMore();
|
||||
}
|
||||
|
||||
|
||||
Value* value(Context* c, lir::ValueType type, Site* site, Site* target) {
|
||||
return new(c->zone) Value(site, target, type);
|
||||
}
|
||||
|
||||
} // namespace regalloc
|
||||
} // namespace codegen
|
||||
} // namespace avian
|
||||
|
@ -47,8 +47,21 @@ class Value: public Compiler::Operand {
|
||||
bool isBuddyOf(Value* b);
|
||||
|
||||
void addSite(Context* c, Site* s);
|
||||
|
||||
void grow(Context* c);
|
||||
|
||||
void maybeSplit(Context* c);
|
||||
|
||||
void split(Context* c);
|
||||
|
||||
void removeSite(Context* c, Site* s);
|
||||
|
||||
bool hasSite(Context* c);
|
||||
};
|
||||
|
||||
|
||||
Value* value(Context* c, lir::ValueType type, Site* site = 0, Site* target = 0);
|
||||
|
||||
} // namespace compiler
|
||||
} // namespace codegen
|
||||
} // namespace avian
|
||||
|
Loading…
x
Reference in New Issue
Block a user