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,
Jump,
LongJump,
AlignedJump,
JumpIfLess,
JumpIfGreater,
JumpIfLessOrEqual,
@ -318,7 +319,9 @@ class Assembler {
virtual Architecture* arch() = 0;
virtual void popReturnAddress(unsigned addressOffset) = 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 allocateFrame(unsigned footprint) = 0;
virtual void popFrame() = 0;

View File

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

View File

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

View File

@ -28,6 +28,7 @@ class Compiler {
static const unsigned Aligned = 1 << 0;
static const unsigned NoReturn = 1 << 1;
static const unsigned TailCall = 1 << 2;
static const unsigned TailJump = 1 << 3;
class Operand { };
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
addCarryCR(Context* c, unsigned size, Assembler::Constant* a,
Assembler::Register* b);
@ -2290,6 +2305,11 @@ class MyAssembler: public Assembler {
return arch_;
}
virtual void popReturnAddress(unsigned addressOffset) {
Memory addressDst(rbx, addressOffset);
popM(&c, BytesPerWord, &addressDst);
}
virtual void saveFrame(unsigned stackOffset, unsigned baseOffset) {
Register stack(rsp);
Memory stackDst(rbx, stackOffset);
@ -2302,6 +2322,18 @@ class MyAssembler: public Assembler {
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, ...) {
struct {
unsigned size;