move use of SingleRead::successor; fix build errors

We now use SingleRead::successor in pickTarget, where we use it to
determine the prefered target site for the successor without requiring
the target to conform to that preference.  The previous code made the
preference a hard requirement, which is not desirable or even possible
in general.
This commit is contained in:
Joel Dice 2009-04-07 18:55:43 -06:00
parent 35d1c6e068
commit dba72409aa
5 changed files with 119 additions and 65 deletions

View File

@ -31,6 +31,7 @@ enum UnaryOperation {
AlignedCall, AlignedCall,
Jump, Jump,
LongJump, LongJump,
AlignedJump,
JumpIfLess, JumpIfLess,
JumpIfGreater, JumpIfGreater,
JumpIfLessOrEqual, JumpIfLessOrEqual,
@ -318,7 +319,9 @@ class Assembler {
virtual Architecture* arch() = 0; virtual Architecture* arch() = 0;
virtual void popReturnAddress(unsigned addressOffset) = 0;
virtual void saveFrame(unsigned stackOffset, unsigned baseOffset) = 0; virtual void saveFrame(unsigned stackOffset, unsigned baseOffset) = 0;
virtual void restoreFrame(unsigned stackOffset, unsigned baseOffset) = 0;
virtual void pushFrame(unsigned argumentCount, ...) = 0; virtual void pushFrame(unsigned argumentCount, ...) = 0;
virtual void allocateFrame(unsigned footprint) = 0; virtual void allocateFrame(unsigned footprint) = 0;
virtual void popFrame() = 0; virtual void popFrame() = 0;

View File

@ -1957,7 +1957,7 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target, bool tailCall,
rSize, rSize,
methodParameterFootprint(t, target)); methodParameterFootprint(t, target));
} else { } else {
unsigned flags = (tailCall ? Compiler::TailCall : 0); unsigned flags = (tailCall ? Compiler::TailJump : 0);
if (useThunk) { if (useThunk) {
if (tailCall) { if (tailCall) {
@ -6450,6 +6450,8 @@ compileVirtualThunk(MyThread* t, unsigned index)
(codeAllocator(t)->allocate(a->length())); (codeAllocator(t)->allocate(a->length()));
a->writeTo(start); a->writeTo(start);
return reinterpret_cast<uintptr_t>(start);
} }
uintptr_t uintptr_t

View File

@ -257,6 +257,8 @@ class Read {
{ } { }
virtual bool intersect(SiteMask* mask) = 0; virtual bool intersect(SiteMask* mask) = 0;
virtual Value* successor() = 0;
virtual bool valid() = 0; virtual bool valid() = 0;
@ -286,13 +288,6 @@ intersect(const SiteMask& a, const SiteMask& b)
intersectFrameIndexes(a.frameIndex, b.frameIndex)); intersectFrameIndexes(a.frameIndex, b.frameIndex));
} }
bool
valid(const SiteMask& a)
{
return a.typeMask
and ((a.typeMask & ~(1 << RegisterOperand)) or a.registerMask);
}
class Value: public Compiler::Operand { class Value: public Compiler::Operand {
public: public:
Value(Site* site, Site* target): Value(Site* site, Site* target):
@ -1191,18 +1186,11 @@ pickAnyFrameTarget(Context* c, Value* v)
} }
Target Target
pickTarget(Context* c, Read* read, bool intersectRead, pickTarget(Context* c, Value* value, const SiteMask& mask,
unsigned registerReserveCount) unsigned registerPenalty, Target best)
{ {
SiteMask mask;
read->intersect(&mask);
unsigned registerPenalty = (c->availableRegisterCount > registerReserveCount
? 0 : Target::Penalty);
Target best;
if (mask.typeMask & (1 << RegisterOperand)) { if (mask.typeMask & (1 << RegisterOperand)) {
Target mine = pickRegisterTarget(c, read->value, mask.registerMask); Target mine = pickRegisterTarget(c, value, mask.registerMask);
mine.cost += registerPenalty; mine.cost += registerPenalty;
@ -1215,7 +1203,7 @@ pickTarget(Context* c, Read* read, bool intersectRead,
if ((mask.typeMask & (1 << MemoryOperand)) && mask.frameIndex >= 0) { if ((mask.typeMask & (1 << MemoryOperand)) && mask.frameIndex >= 0) {
Target mine(mask.frameIndex, MemoryOperand, Target mine(mask.frameIndex, MemoryOperand,
frameCost(c, read->value, mask.frameIndex)); frameCost(c, value, mask.frameIndex));
if (mine.cost == 0) { if (mine.cost == 0) {
return mine; return mine;
} else if (mine.cost < best.cost) { } else if (mine.cost < best.cost) {
@ -1223,6 +1211,40 @@ pickTarget(Context* c, Read* read, bool intersectRead,
} }
} }
return best;
}
Target
pickTarget(Context* c, Read* read, bool intersectRead,
unsigned registerReserveCount)
{
unsigned registerPenalty = (c->availableRegisterCount > registerReserveCount
? 0 : Target::Penalty);
SiteMask mask;
read->intersect(&mask);
Target best;
Value* successor = read->successor();
if (successor) {
Read* r = live(successor);
if (r) {
SiteMask intersection = mask;
if (r->intersect(&intersection)) {
best = pickTarget(c, read->value, mask, registerPenalty, best);
if (best.cost == 0) {
return best;
}
}
}
}
best = pickTarget(c, read->value, mask, registerPenalty, best);
if (best.cost == 0) {
return best;
}
if (intersectRead) { if (intersectRead) {
return best; return best;
} }
@ -1887,27 +1909,18 @@ release(Context* c, Resource* resource, Value* value UNUSED, Site* site UNUSED)
class SingleRead: public Read { class SingleRead: public Read {
public: public:
SingleRead(const SiteMask& mask, Value* successor): SingleRead(const SiteMask& mask, Value* successor):
next_(0), mask(mask), successor(successor) next_(0), mask(mask), successor_(successor)
{ } { }
virtual bool intersect(SiteMask* mask) { virtual bool intersect(SiteMask* mask) {
SiteMask result = ::intersect(*mask, this->mask); *mask = ::intersect(*mask, this->mask);
if (successor) {
Read* r = live(successor);
if (r) {
SiteMask intersection = result;
bool valid = r->intersect(&intersection);
if (valid and ::valid(intersection)) {
result = intersection;
}
}
}
*mask = result;
return true; return true;
} }
virtual Value* successor() {
return successor_;
}
virtual bool valid() { virtual bool valid() {
return true; return true;
@ -1924,7 +1937,7 @@ class SingleRead: public Read {
Read* next_; Read* next_;
SiteMask mask; SiteMask mask;
Value* successor; Value* successor_;
}; };
Read* Read*
@ -1981,6 +1994,10 @@ class MultiRead: public Read {
return result; return result;
} }
virtual Value* successor() {
return 0;
}
virtual bool valid() { virtual bool valid() {
bool result = false; bool result = false;
if (not visited) { if (not visited) {
@ -2008,7 +2025,7 @@ class MultiRead: public Read {
} }
lastRead = cell; lastRead = cell;
// fprintf(stderr, "append %p to %p for %p\n", r, lastTarget, this); // fprintf(stderr, "append %p to %p for %p\n", r, lastTarget, this);
lastTarget->value = r; lastTarget->value = r;
} }
@ -2020,7 +2037,7 @@ class MultiRead: public Read {
void allocateTarget(Context* c) { void allocateTarget(Context* c) {
Cell* cell = cons(c, 0, 0); Cell* cell = cons(c, 0, 0);
// fprintf(stderr, "allocate target for %p: %p\n", this, cell); // fprintf(stderr, "allocate target for %p: %p\n", this, cell);
if (lastTarget) { if (lastTarget) {
lastTarget->next = cell; lastTarget->next = cell;
@ -2031,7 +2048,7 @@ class MultiRead: public Read {
} }
Read* nextTarget() { Read* nextTarget() {
// fprintf(stderr, "next target for %p: %p\n", this, firstTarget); // fprintf(stderr, "next target for %p: %p\n", this, firstTarget);
Read* r = static_cast<Read*>(firstTarget->value); Read* r = static_cast<Read*>(firstTarget->value);
firstTarget = firstTarget->next; firstTarget = firstTarget->next;
@ -2071,6 +2088,10 @@ class StubRead: public Read {
return valid_; return valid_;
} }
virtual Value* successor() {
return 0;
}
virtual bool valid() { virtual bool valid() {
return valid_; return valid_;
} }
@ -2180,9 +2201,9 @@ addRead(Context* c, Event* e, Value* v, Read* r)
} }
if (v->lastRead) { if (v->lastRead) {
// if (DebugReads) { // if (DebugReads) {
// fprintf(stderr, "append %p to %p for %p\n", r, v->lastRead, v); // fprintf(stderr, "append %p to %p for %p\n", r, v->lastRead, v);
// } // }
v->lastRead->append(c, r); v->lastRead->append(c, r);
} else { } else {
@ -2334,7 +2355,7 @@ class CallEvent: public Event {
(typeMask, registerMask & planRegisterMask, AnyFrameIndex))); (typeMask, registerMask & planRegisterMask, AnyFrameIndex)));
} }
if ((flags & (Compiler::TailJump | Compiler::TailCall)_ == 0) { if ((flags & (Compiler::TailJump | Compiler::TailCall)) == 0) {
int footprint = stackArgumentFootprint; int footprint = stackArgumentFootprint;
for (Stack* s = stackBefore; s; s = s->next) { for (Stack* s = stackBefore; s; s = s->next) {
if (s->value) { if (s->value) {
@ -2932,7 +2953,7 @@ getTarget(Context* c, Value* value, Value* result, const SiteMask& resultMask)
preserve(c, v, s, r); preserve(c, v, s, r);
} }
} else { } else {
SingleRead r(resultMask); SingleRead r(resultMask, 0);
s = pickTargetSite(c, &r, true); s = pickTargetSite(c, &r, true);
v = result; v = result;
addSite(c, result, s); addSite(c, result, s);
@ -3017,7 +3038,7 @@ class CombineEvent: public Event {
? getTarget(c, second->high, result->high, resultHighMask) ? getTarget(c, second->high, result->high, resultHighMask)
: 0); : 0);
// fprintf(stderr, "combine %p and %p into %p\n", first, second, result); // fprintf(stderr, "combine %p and %p into %p\n", first, second, result);
apply(c, type, firstSize, first->source, source(first->high), apply(c, type, firstSize, first->source, source(first->high),
secondSize, second->source, source(second->high), secondSize, second->source, source(second->high),
resultSize, low, high); resultSize, low, high);
@ -3783,11 +3804,11 @@ frameFootprint(Context* c, Stack* s)
void void
visit(Context* c, Link* link) visit(Context* c, Link* link)
{ {
// fprintf(stderr, "visit link from %d to %d fork %p junction %p\n", // fprintf(stderr, "visit link from %d to %d fork %p junction %p\n",
// link->predecessor->logicalInstruction->index, // link->predecessor->logicalInstruction->index,
// link->successor->logicalInstruction->index, // link->successor->logicalInstruction->index,
// link->forkState, // link->forkState,
// link->junctionState); // link->junctionState);
ForkState* forkState = link->forkState; ForkState* forkState = link->forkState;
if (forkState) { if (forkState) {
@ -3795,7 +3816,7 @@ visit(Context* c, Link* link)
ForkElement* p = forkState->elements + i; ForkElement* p = forkState->elements + i;
Value* v = p->value; Value* v = p->value;
v->reads = p->read->nextTarget(); v->reads = p->read->nextTarget();
// fprintf(stderr, "next read %p for %p from %p\n", v->reads, v, p->read); // fprintf(stderr, "next read %p for %p from %p\n", v->reads, v, p->read);
if (not live(v)) { if (not live(v)) {
clearSites(c, v); clearSites(c, v);
} }
@ -3828,7 +3849,7 @@ class BuddyEvent: public Event {
} }
virtual void compile(Context* c) { virtual void compile(Context* c) {
// fprintf(stderr, "original %p buddy %p\n", original, buddy); // fprintf(stderr, "original %p buddy %p\n", original, buddy);
assert(c, hasSite(original)); assert(c, hasSite(original));
addBuddy(original, buddy); addBuddy(original, buddy);
@ -3886,7 +3907,7 @@ class FreezeRegisterEvent: public Event {
} }
virtual void compile(Context* c) { virtual void compile(Context* c) {
c->registers[number].freeze(c, value); c->registerResources[number].freeze(c, value);
for (Read* r = reads; r; r = r->eventNext) { for (Read* r = reads; r; r = r->eventNext) {
popRead(c, this, r->value); popRead(c, this, r->value);
@ -3915,17 +3936,17 @@ class ThawRegisterEvent: public Event {
} }
virtual void compile(Context* c) { virtual void compile(Context* c) {
c->registers[number].thaw(c, value); c->registerResources[number].thaw(c, 0);
} }
int number; int number;
}; };
void void
appendThawRegister(Context* c, int number, Value* value) appendThawRegister(Context* c, int number)
{ {
append(c, new (c->zone->allocate(sizeof(ThawRegisterEvent))) append(c, new (c->zone->allocate(sizeof(ThawRegisterEvent)))
ThawRegisterEvent(c, number, value)); ThawRegisterEvent(c, number));
} }
class DummyEvent: public Event { class DummyEvent: public Event {
@ -4418,9 +4439,9 @@ void
restore(Context* c, Event* e, Snapshot* snapshots) restore(Context* c, Event* e, Snapshot* snapshots)
{ {
for (Snapshot* s = snapshots; s; s = s->next) { for (Snapshot* s = snapshots; s; s = s->next) {
// char buffer[256]; sitesToString(c, s->sites, buffer, 256); // char buffer[256]; sitesToString(c, s->sites, buffer, 256);
// fprintf(stderr, "restore %p buddy %p sites %s live %p\n", // fprintf(stderr, "restore %p buddy %p sites %s live %p\n",
// s->value, s->value->buddy, buffer, live(s->value)); // s->value, s->value->buddy, buffer, live(s->value));
s->value->buddy = s->buddy; s->value->buddy = s->buddy;
} }
@ -5001,13 +5022,8 @@ class MyCompiler: public Compiler {
return result; return result;
} }
virtual Operand* stack() { virtual Operand* register_(int number) {
Site* s = registerSite(&c, c.arch->stack()); Site* s = registerSite(&c, number);
return value(&c, s, s);
}
virtual Operand* thread() {
Site* s = registerSite(&c, c.arch->thread());
return value(&c, s, s); return value(&c, s, s);
} }

View File

@ -28,6 +28,7 @@ class Compiler {
static const unsigned Aligned = 1 << 0; static const unsigned Aligned = 1 << 0;
static const unsigned NoReturn = 1 << 1; static const unsigned NoReturn = 1 << 1;
static const unsigned TailCall = 1 << 2; static const unsigned TailCall = 1 << 2;
static const unsigned TailJump = 1 << 3;
class Operand { }; class Operand { };
class StackElement { }; class StackElement { };

View File

@ -703,6 +703,21 @@ popR(Context* c, unsigned size, Assembler::Register* a)
} }
} }
void
popM(Context* c, unsigned size, Assembler::Memory* a)
{
if (BytesPerWord == 4 and size == 8) {
Assembler::Memory ah(a->base, a->offset + 4, a->index, a->scale);
popM(c, 4, a);
popM(c, 4, &ah);
} else {
assert(c, BytesPerWord == 4 or size == 8);
encode(c, 0x8f, 0, a, false);
}
}
void void
addCarryCR(Context* c, unsigned size, Assembler::Constant* a, addCarryCR(Context* c, unsigned size, Assembler::Constant* a,
Assembler::Register* b); Assembler::Register* b);
@ -2290,6 +2305,11 @@ class MyAssembler: public Assembler {
return arch_; return arch_;
} }
virtual void popReturnAddress(unsigned addressOffset) {
Memory addressDst(rbx, addressOffset);
popM(&c, BytesPerWord, &addressDst);
}
virtual void saveFrame(unsigned stackOffset, unsigned baseOffset) { virtual void saveFrame(unsigned stackOffset, unsigned baseOffset) {
Register stack(rsp); Register stack(rsp);
Memory stackDst(rbx, stackOffset); Memory stackDst(rbx, stackOffset);
@ -2302,6 +2322,18 @@ class MyAssembler: public Assembler {
BytesPerWord, MemoryOperand, &baseDst); BytesPerWord, MemoryOperand, &baseDst);
} }
virtual void restoreFrame(unsigned stackOffset, unsigned baseOffset) {
Register stack(rsp);
Memory stackDst(rbx, stackOffset);
apply(Move, BytesPerWord, MemoryOperand, &stackDst,
BytesPerWord, RegisterOperand, &stack);
Register base(rbp);
Memory baseDst(rbx, baseOffset);
apply(Move, BytesPerWord, MemoryOperand, &baseDst,
BytesPerWord, RegisterOperand, &base);
}
virtual void pushFrame(unsigned argumentCount, ...) { virtual void pushFrame(unsigned argumentCount, ...) {
struct { struct {
unsigned size; unsigned size;