move MoveEvent out of compiler.cpp

This commit is contained in:
Joshua Warner 2013-02-13 20:03:37 -07:00
parent 165c77d772
commit 5ad0eb86d3
5 changed files with 272 additions and 256 deletions

View File

@ -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);
}
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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