This commit is contained in:
Joel Dice 2008-07-17 17:34:38 -06:00
parent 2343483d8e
commit f0c9deaa06

View File

@ -54,7 +54,7 @@ class Site {
virtual unsigned copyCost(Context*, Site*) = 0; virtual unsigned copyCost(Context*, Site*) = 0;
virtual void acquire(Context*, Stack*, unsigned, Value*) { } virtual void acquire(Context*, Stack*, Value**, unsigned, Value*) { }
virtual void release(Context*) { } virtual void release(Context*) { }
@ -390,11 +390,12 @@ findSite(Context*, Value* v, Site* site)
} }
void void
addSite(Context* c, Stack* stack, unsigned size, Value* v, Site* s) addSite(Context* c, Stack* stack, Value** locals, unsigned size, Value* v,
Site* s)
{ {
if (not findSite(c, v, s)) { if (not findSite(c, v, s)) {
// fprintf(stderr, "add site %p (%d) to %p\n", s, s->type(c), v); // fprintf(stderr, "add site %p (%d) to %p\n", s, s->type(c), v);
s->acquire(c, stack, size, v); s->acquire(c, stack, locals, size, v);
s->next = v->sites; s->next = v->sites;
v->sites = s; v->sites = s;
} }
@ -546,8 +547,8 @@ thaw(Register* r)
} }
Register* Register*
acquire(Context* c, uint32_t mask, Stack* stack, unsigned newSize, acquire(Context* c, uint32_t mask, Stack* stack, Value** locals,
Value* newValue, RegisterSite* newSite); unsigned newSize, Value* newValue, RegisterSite* newSite);
void void
release(Context* c, Register* r); release(Context* c, Register* r);
@ -587,11 +588,13 @@ class RegisterSite: public Site {
} }
} }
virtual void acquire(Context* c, Stack* stack, unsigned size, Value* v) { virtual void acquire(Context* c, Stack* stack, Value** locals, unsigned size,
low = ::validate(c, mask, stack, size, v, this, low); Value* v)
{
low = ::validate(c, mask, stack, locals, size, v, this, low);
if (size > BytesPerWord) { if (size > BytesPerWord) {
::freeze(low); ::freeze(low);
high = ::validate(c, mask >> 32, stack, size, v, this, high); high = ::validate(c, mask >> 32, stack, locals, size, v, this, high);
::thaw(low); ::thaw(low);
} }
} }
@ -735,7 +738,7 @@ class MemorySite: public Site {
} }
} }
virtual void acquire(Context* c, Stack*, unsigned, Value*) { virtual void acquire(Context* c, Stack*, Value**, unsigned, Value*) {
base = increment(c, value.base); base = increment(c, value.base);
if (value.index != NoRegister) { if (value.index != NoRegister) {
index = increment(c, value.index); index = increment(c, value.index);
@ -983,6 +986,7 @@ trySteal(Context* c, Register* r, Stack* stack, Value** locals)
assert(c, r->refCount == 0); assert(c, r->refCount == 0);
Value* v = r->value; Value* v = r->value;
assert(c, v->reads);
if (DebugRegisters) { if (DebugRegisters) {
fprintf(stderr, "try steal %d from %p: next: %p\n", fprintf(stderr, "try steal %d from %p: next: %p\n",
@ -990,22 +994,35 @@ trySteal(Context* c, Register* r, Stack* stack, Value** locals)
} }
if (v->sites->next == 0) { if (v->sites->next == 0) {
unsigned count = 0; Site* saveSite = 0;
Stack* start = 0; for (unsigned i = 0; i < localFootprint; ++i) {
for (Stack* s = stack; s and (not s->pushed); s = s->next) { if (locals[i] == v) {
if (start == 0 and s->value == v) { saveSite = frameSite(c, i);
start = s; break;
}
if (start) {
++ count;
} }
} }
if (start) { if (saveSite == 0) {
if (DebugRegisters) { for (Stack* s = stack; s and (not s->pushed); s = s->next) {
fprintf(stderr, "push %p\n", v); if (s->value == v) {
uint8_t typeMask;
uint64_t registerMask;
int frameIndex = AnyFrameIndex;
v->reads->intersect(&typeMask, &registerMask, &frameIndex);
if (frameIndex >= 0) {
saveSite = frameSite(c, frameIndex);
} else {
saveSite = stackSite(c, s);
}
break;
}
} }
pushNow(c, start, count); }
if (saveSite) {
apply(c, Move, r->size, r->site, saveSite);
addSite(c, 0, 0, r->size, v, saveSite);
} else { } else {
if (DebugRegisters) { if (DebugRegisters) {
fprintf(stderr, "unable to steal %d from %p\n", r->number, v); fprintf(stderr, "unable to steal %d from %p\n", r->number, v);
@ -1100,12 +1117,12 @@ swap(Context* c, Register* a, Register* b)
} }
Register* Register*
replace(Context* c, Stack* stack, Register* r) replace(Context* c, Stack* stack, Value** locals, Register* r)
{ {
uint32_t mask = (r->freezeCount? r->site->mask : ~0); uint32_t mask = (r->freezeCount? r->site->mask : ~0);
freeze(r); freeze(r);
Register* s = acquire(c, mask, stack, r->size, r->value, r->site); Register* s = acquire(c, mask, stack, locals, r->size, r->value, r->site);
thaw(r); thaw(r);
if (DebugRegisters) { if (DebugRegisters) {
@ -1118,16 +1135,18 @@ replace(Context* c, Stack* stack, Register* r)
} }
Register* Register*
acquire(Context* c, uint32_t mask, Stack* stack, unsigned newSize, acquire(Context* c, uint32_t mask, Stack* stack, Value** locals,
Value* newValue, RegisterSite* newSite) unsigned newSize, Value* newValue, RegisterSite* newSite)
{ {
Register* r = pickRegister(c, mask); Register* r = pickRegister(c, mask);
if (r->reserved) return r; if (r->reserved) return r;
if (DebugRegisters) { if (DebugRegisters) {
fprintf(stderr, "acquire %d, value %p, site %p freeze count %d ref count %d used %d used exclusively %d\n", fprintf(stderr, "acquire %d, value %p, site %p freeze count %d "
r->number, newValue, newSite, r->freezeCount, r->refCount, used(c, r), usedExclusively(c, r)); "ref count %d used %d used exclusively %d\n",
r->number, newValue, newSite, r->freezeCount, r->refCount,
used(c, r), usedExclusively(c, r));
} }
if (r->refCount) { if (r->refCount) {
@ -1138,7 +1157,7 @@ acquire(Context* c, uint32_t mask, Stack* stack, unsigned newSize,
and oldValue != newValue and oldValue != newValue
and findSite(c, oldValue, r->site)) and findSite(c, oldValue, r->site))
{ {
if (not trySteal(c, r, stack)) { if (not trySteal(c, r, stack, locals)) {
r = replace(c, stack, r); r = replace(c, stack, r);
} }
} }
@ -1164,8 +1183,8 @@ release(Context*, Register* r)
} }
Register* Register*
validate(Context* c, uint32_t mask, Stack* stack, unsigned size, validate(Context* c, uint32_t mask, Stack* stack, Value** locals,
Value* value, RegisterSite* site, Register* current) unsigned size, Value* value, RegisterSite* site, Register* current)
{ {
if (current and (mask & (1 << current->number))) { if (current and (mask & (1 << current->number))) {
if (current->reserved or current->value == value) { if (current->reserved or current->value == value) {
@ -1182,7 +1201,7 @@ validate(Context* c, uint32_t mask, Stack* stack, unsigned size,
} }
} }
Register* r = acquire(c, mask, stack, size, value, site); Register* r = acquire(c, mask, stack, locals, size, value, site);
if (current and current != r) { if (current and current != r) {
release(c, current); release(c, current);
@ -1360,7 +1379,8 @@ cleanStack(Context* c, Stack* stack, Local* locals, Read* reads)
for (Stack* s = stack; s; s = s->next) { for (Stack* s = stack; s; s = s->next) {
if (s->pushSite) { if (s->pushSite) {
addSite(c, 0, s->geometry->size * BytesPerWord, s->value, s->pushSite); addSite(c, 0, 0, s->geometry->size * BytesPerWord, s->value,
s->pushSite);
} }
} }
@ -1455,7 +1475,7 @@ class CallEvent: public Event {
cleanStack(c, stack, locals, reads); cleanStack(c, stack, locals, reads);
if (resultSize and live(result)) { if (resultSize and live(result)) {
addSite(c, 0, resultSize, result, registerSite addSite(c, 0, 0, resultSize, result, registerSite
(c, c->assembler->returnLow(), (c, c->assembler->returnLow(),
resultSize > BytesPerWord ? resultSize > BytesPerWord ?
c->assembler->returnHigh() : NoRegister)); c->assembler->returnHigh() : NoRegister));
@ -1563,7 +1583,7 @@ class MoveEvent: public Event {
} }
if (not isStore) { if (not isStore) {
addSite(c, stack, size, dst, target); addSite(c, stack, locals, size, dst, target);
} }
if (cost or type != Move) { if (cost or type != Move) {
@ -1574,7 +1594,7 @@ class MoveEvent: public Event {
Site* tmpTarget = freeRegisterSite(c, dstTarget->registerMask); Site* tmpTarget = freeRegisterSite(c, dstTarget->registerMask);
addSite(c, stack, size, dst, tmpTarget); addSite(c, stack, locals, size, dst, tmpTarget);
apply(c, type, size, src->source, tmpTarget); apply(c, type, size, src->source, tmpTarget);
@ -1709,7 +1729,7 @@ preserve(Context* c, Stack* stack, unsigned size, Value* v, Site* s,
assert(c, v->sites == s); assert(c, v->sites == s);
Site* r = targetOrNull(c, read); Site* r = targetOrNull(c, read);
if (r == 0 or r == s) r = freeRegisterSite(c); if (r == 0 or r == s) r = freeRegisterSite(c);
addSite(c, stack, size, v, r); addSite(c, stack, locals, size, v, r);
apply(c, Move, size, s, r); apply(c, Move, size, s, r);
} }
@ -1763,7 +1783,7 @@ class CombineEvent: public Event {
removeSite(c, second, second->source); removeSite(c, second, second->source);
if (live(result)) { if (live(result)) {
addSite(c, 0, size, result, second->source); addSite(c, 0, 0, size, result, second->source);
} }
} }
@ -1845,7 +1865,7 @@ class TranslateEvent: public Event {
removeSite(c, value, value->source); removeSite(c, value, value->source);
if (live(result)) { if (live(result)) {
addSite(c, 0, size, result, value->source); addSite(c, 0, 0, size, result, value->source);
} }
} }
@ -1925,7 +1945,7 @@ class MemoryEvent: public Event {
result->target = memorySite result->target = memorySite
(c, baseRegister, displacement, indexRegister, scale); (c, baseRegister, displacement, indexRegister, scale);
addSite(c, 0, 0, result, result->target); addSite(c, 0, 0, 0, result, result->target);
} }
Value* base; Value* base;
@ -1985,53 +2005,6 @@ resetStack(Context* c)
c->stackReset = true; c->stackReset = true;
} }
void
popNow(Context* c, Stack* stack, unsigned count, bool ignore)
{
Stack* s = stack;
unsigned ignored = 0;
for (unsigned i = count; i and s;) {
if (s->pushed) {
removeSite(c, s->value, s->pushSite);
s->pushSite = 0;
s->pushed = false;
Value* v = s->value;
if (live(v) and v->sites == 0 and (not ignore)) {
::ignore(c, ignored);
Site* target = targetOrRegister(c, v);
if (DebugStack) {
fprintf(stderr, "pop %p value: %p target: %p\n",
s, s->value, target);
}
addSite(c, stack, s->geometry->size * BytesPerWord, v, target);
apply(c, Pop, BytesPerWord * s->geometry->size, target);
} else {
if (DebugStack) {
fprintf(stderr, "ignore %p value: %p\n", s, v);
}
ignored += s->geometry->size;
}
} else {
if (DebugStack) {
fprintf(stderr, "%p not pushed\n", s);
}
}
c->stackPadding -= s->geometry->padding;
ignored += s->geometry->padding;
i -= s->geometry->size;
s = s->next;
}
::ignore(c, ignored);
}
class StackSyncEvent: public Event { class StackSyncEvent: public Event {
public: public:
StackSyncEvent(Context* c): StackSyncEvent(Context* c):
@ -2215,98 +2188,6 @@ appendPop(Context* c, unsigned count, bool ignore)
new (c->zone->allocate(sizeof(PopEvent))) PopEvent(c, count, ignore); new (c->zone->allocate(sizeof(PopEvent))) PopEvent(c, count, ignore);
} }
class ClobberLocalEvent: public Event {
public:
ClobberLocalEvent(Context* c, unsigned size, Local* local):
Event(c), size(size), local(local)
{ }
virtual void compile(Context* c) {
if (DebugCompile) {
fprintf(stderr, "ClobberLocalEvent.compile\n");
}
for (Local* l = local; l; l = l->old) {
Value* v = l->value;
Site* s = l->site;
if (live(v)
and v->sites->next == 0
and v->sites == s)
{
preserve(c, stack, size, v, s, v->reads);
}
removeSite(c, v, s);
}
}
unsigned size;
Local* local;
};
void
appendClobberLocal(Context* c, unsigned size, Local* local)
{
if (DebugAppend) {
fprintf(stderr, "appendClobberLocal\n");
}
new (c->zone->allocate(sizeof(ClobberLocalEvent)))
ClobberLocalEvent(c, size, local);
}
class LocalEvent: public Event {
public:
LocalEvent(Context* c, unsigned size, Local* local):
Event(c), size(size), local(local)
{
if (local->old) {
addRead(c, local->old->value, size, 0);
}
}
virtual void compile(Context* c) {
if (DebugCompile) {
fprintf(stderr, "LocalEvent.compile\n");
}
Site* sites = 0;
if (local->old) {
Value* v = local->old->value;
if (local->old->reuse and valid(v->reads->next) == 0) {
sites = v->sites;
}
nextRead(c, v);
}
Value* v = local->value;
if (live(v)) {
for (Site* s = sites; s;) {
Site* t = s->next;
if (s->type(c) != MemoryOperand) {
addSite(c, 0, size, v, s);
}
s = t;
}
addSite(c, 0, size, v, local->site);
}
}
unsigned size;
Local* local;
};
void
appendLocal(Context* c, unsigned size, Local* local)
{
if (DebugAppend) {
fprintf(stderr, "appendLocal\n");
}
new (c->zone->allocate(sizeof(LocalEvent))) LocalEvent(c, size, local);
}
class BoundsCheckEvent: public Event { class BoundsCheckEvent: public Event {
public: public:
BoundsCheckEvent(Context* c, Value* object, unsigned lengthOffset, BoundsCheckEvent(Context* c, Value* object, unsigned lengthOffset,
@ -2386,7 +2267,7 @@ appendBoundsCheck(Context* c, Value* object, unsigned lengthOffset,
} }
Site* Site*
readSource(Context* c, Stack* stack, Read* r) readSource(Context* c, Stack* stack, Value** locals, Read* r)
{ {
if (r->value->sites == 0) { if (r->value->sites == 0) {
return 0; return 0;
@ -2398,7 +2279,7 @@ readSource(Context* c, Stack* stack, Read* r)
Site* site = pick(c, r->value->sites, target, &copyCost); Site* site = pick(c, r->value->sites, target, &copyCost);
if (target and copyCost) { if (target and copyCost) {
addSite(c, stack, r->size, r->value, target); addSite(c, stack, locals, r->size, r->value, target);
apply(c, Move, r->size, site, target); apply(c, Move, r->size, site, target);
return target; return target;
} else { } else {
@ -2449,7 +2330,7 @@ compile(Context* c)
Site* sites[e->readCount]; Site* sites[e->readCount];
unsigned si = 0; unsigned si = 0;
for (Read* r = e->reads; r; r = r->eventNext) { for (Read* r = e->reads; r; r = r->eventNext) {
r->value->source = readSource(c, e->stack, r); r->value->source = readSource(c, e->stack, e->locals, r);
if (r->value->source) { if (r->value->source) {
assert(c, si < e->readCount); assert(c, si < e->readCount);
@ -2545,19 +2426,6 @@ push(Context* c, unsigned size, Value* v)
appendPush(c); appendPush(c);
} }
void
addLocal(Context* c, unsigned size, unsigned index, Value* newValue)
{
unsigned sizeInWords = ceiling(size, BytesPerWord);
c->localTable[index] = c->locals = new (c->zone->allocate(sizeof(Local)))
Local(sizeInWords, index, newValue, memorySite
(c, c->assembler->base(), localOffset(c, index)),
c->localTable[index], c->locals);
appendLocal(c, sizeInWords * BytesPerWord, c->locals);
}
Value* Value*
pop(Context* c, unsigned size UNUSED) pop(Context* c, unsigned size UNUSED)
{ {
@ -2930,23 +2798,21 @@ class MyCompiler: public Compiler {
virtual void storeLocal(unsigned size, Operand* src, unsigned index) { virtual void storeLocal(unsigned size, Operand* src, unsigned index) {
assert(&c, index < c.localFootprint); assert(&c, index < c.localFootprint);
if (c.localTable[index]) { if (c.state->locals[index]) {
appendClobberLocal(&c, size, c.localTable[index]); appendClobberLocal(&c, size, c.state->locals[index]);
c.localTable[index] = 0;
} }
store(size, src, memory(base(), localOffset(&c, index))); Value* v = static_cast<Value*>(memory(base(), localOffset(&c, index)));
store(size, src, v);
// todo: find out why this doesn't work and fix it: c.state->locals[index] = v;
// addLocal(&c, size, index, static_cast<Value*>(src));
} }
virtual Operand* loadLocal(unsigned size, unsigned index) { virtual Operand* loadLocal(unsigned size, unsigned index) {
assert(&c, index < c.localFootprint); assert(&c, index < c.localFootprint);
assert(&c, c.state->locals[index]);
Value* v = value(&c); return c.state->locals[index];
addLocal(&c, size, index, v);
return v;
} }
virtual void checkBounds(Operand* object, unsigned lengthOffset, virtual void checkBounds(Operand* object, unsigned lengthOffset,