fix stack frame offset calculations for 64-bit values; insert dummy events for instructions which start with stack activity

This commit is contained in:
Joel Dice
2008-10-24 20:12:02 -06:00
parent 7d6ca28b2f
commit d20ee74d79

View File

@ -566,50 +566,35 @@ class Event {
}; };
int int
frameIndexToLocalOffset(Context* c, int frameIndex) frameIndex(Context* c, int index, unsigned size)
{ {
int parameterFootprint = c->parameterFootprint; return c->alignedFrameSize + c->parameterFootprint - index - size;
int frameSize = c->alignedFrameSize;
int offset = ((frameIndex < parameterFootprint) ?
(frameSize
+ parameterFootprint
+ (c->arch->frameFooterSize() * 2)
+ c->arch->frameHeaderSize()
- frameIndex - 1) :
(frameSize
+ parameterFootprint
+ c->arch->frameFooterSize()
- frameIndex - 1)) * BytesPerWord;
assert(c, offset >= 0);
return offset;
} }
int unsigned
localOffsetToFrameIndex(Context* c, int offset) frameIndexToOffset(Context* c, unsigned frameIndex)
{ {
int parameterFootprint = c->parameterFootprint; return ((frameIndex >= c->alignedFrameSize) ?
int frameSize = c->alignedFrameSize; (frameIndex
+ (c->arch->frameFooterSize() * 2)
+ c->arch->frameHeaderSize()) :
(frameIndex
+ c->arch->frameFooterSize())) * BytesPerWord;
}
int normalizedOffset = offset / BytesPerWord; unsigned
offsetToFrameIndex(Context* c, unsigned offset)
{
unsigned normalizedOffset = offset / BytesPerWord;
int frameIndex = ((normalizedOffset > frameSize) ? return ((normalizedOffset
(frameSize >= c->alignedFrameSize
+ parameterFootprint + c->arch->frameFooterSize()) ?
+ (c->arch->frameFooterSize() * 2) (normalizedOffset
+ c->arch->frameHeaderSize() - (c->arch->frameFooterSize() * 2)
- normalizedOffset - 1) : - c->arch->frameHeaderSize()) :
(frameSize (normalizedOffset
+ parameterFootprint - c->arch->frameFooterSize()));
+ c->arch->frameFooterSize()
- normalizedOffset - 1));
assert(c, frameIndex >= 0);
assert(c, frameIndexToLocalOffset(c, frameIndex) == offset);
return frameIndex;
} }
bool bool
@ -666,7 +651,7 @@ removeMemorySites(Context* c, Value* v)
void void
clearSites(Context* c, Value* v) clearSites(Context* c, Value* v)
{ {
//fprintf(stderr, "clear sites for %p\n", v); // fprintf(stderr, "clear sites for %p\n", v);
for (Site* s = v->sites; s; s = s->next) { for (Site* s = v->sites; s; s = s->next) {
s->release(c); s->release(c);
} }
@ -1080,7 +1065,8 @@ class MemorySite: public Site {
assert(c, value.index == NoRegister); assert(c, value.index == NoRegister);
return frameIndex == AnyFrameIndex return frameIndex == AnyFrameIndex
|| (frameIndex != NoFrameIndex || (frameIndex != NoFrameIndex
&& frameIndexToLocalOffset(c, frameIndex) == value.offset); && static_cast<int>(frameIndexToOffset(c, frameIndex))
== value.offset);
} else { } else {
return true; return true;
} }
@ -1100,7 +1086,7 @@ class MemorySite: public Site {
if (value.base == c->arch->stack()) { if (value.base == c->arch->stack()) {
assert(c, value.index == NoRegister); assert(c, value.index == NoRegister);
acquireFrameIndex acquireFrameIndex
(c, localOffsetToFrameIndex(c, value.offset), stack, locals, size, v, (c, offsetToFrameIndex(c, value.offset), stack, locals, size, v,
this); this);
} }
} }
@ -1108,7 +1094,7 @@ class MemorySite: public Site {
virtual void release(Context* c) { virtual void release(Context* c) {
if (value.base == c->arch->stack()) { if (value.base == c->arch->stack()) {
assert(c, value.index == NoRegister); assert(c, value.index == NoRegister);
releaseFrameIndex(c, localOffsetToFrameIndex(c, value.offset)); releaseFrameIndex(c, offsetToFrameIndex(c, value.offset));
} }
decrement(c, base); decrement(c, base);
@ -1152,7 +1138,7 @@ frameSite(Context* c, int frameIndex)
{ {
assert(c, frameIndex >= 0); assert(c, frameIndex >= 0);
return memorySite return memorySite
(c, c->arch->stack(), frameIndexToLocalOffset(c, frameIndex)); (c, c->arch->stack(), frameIndexToOffset(c, frameIndex));
} }
Site* Site*
@ -1537,14 +1523,14 @@ toString(Context* c, Site* sites, char* buffer, unsigned size)
} }
void void
releaseRegister(Context* c, Value* v, unsigned index, unsigned size, int r) releaseRegister(Context* c, Value* v, unsigned frameIndex, unsigned size, int r)
{ {
if (v) { if (v) {
Site* source = 0; Site* source = 0;
for (Site** s = &(v->sites); *s;) { for (Site** s = &(v->sites); *s;) {
if ((*s)->usesRegister(c, r)) { if ((*s)->usesRegister(c, r)) {
char buffer[256]; (*s)->toString(c, buffer, 256); char buffer[256]; (*s)->toString(c, buffer, 256);
fprintf(stderr, "%p (%s) in %p at %d uses %d\n", *s, buffer, v, index, r); fprintf(stderr, "%p (%s) in %p at %d uses %d\n", *s, buffer, v, frameIndex, r);
source = *s; source = *s;
*s = (*s)->next; *s = (*s)->next;
@ -1552,13 +1538,13 @@ releaseRegister(Context* c, Value* v, unsigned index, unsigned size, int r)
source->release(c); source->release(c);
} else { } else {
char buffer[256]; (*s)->toString(c, buffer, 256); char buffer[256]; (*s)->toString(c, buffer, 256);
fprintf(stderr, "%p (%s) in %p at %d does not use %d\n", *s, buffer, v, index, r); fprintf(stderr, "%p (%s) in %p at %d does not use %d\n", *s, buffer, v, frameIndex, r);
s = &((*s)->next); s = &((*s)->next);
} }
} }
if (v->sites == 0) { if (v->sites == 0) {
move(c, c->stack, c->locals, size, v, source, frameSite(c, index)); move(c, c->stack, c->locals, size, v, source, frameSite(c, frameIndex));
} }
char buffer[256]; toString(c, v->sites, buffer, 256); char buffer[256]; toString(c, v->sites, buffer, 256);
@ -1569,13 +1555,17 @@ releaseRegister(Context* c, Value* v, unsigned index, unsigned size, int r)
void void
releaseRegister(Context* c, int r) releaseRegister(Context* c, int r)
{ {
for (unsigned i = 0; i < c->localFootprint; ++i) { for (unsigned li = 0; li < c->localFootprint; ++li) {
releaseRegister(c, c->locals[i].value, i, c->locals[i].size, r); releaseRegister
(c, c->locals[li].value,
frameIndex(c, li, ceiling(c->locals[li].size, BytesPerWord)),
c->locals[li].size, r);
} }
for (Stack* s = c->stack; s; s = s->next) { for (Stack* s = c->stack; s; s = s->next) {
releaseRegister(c, s->value, s->index + c->localFootprint, releaseRegister
s->size * BytesPerWord, r); (c, s->value, frameIndex(c, s->index + c->localFootprint, s->size),
s->size * BytesPerWord, r);
} }
} }
@ -1585,9 +1575,10 @@ trySteal(Context* c, Site* site, Value* v, unsigned size, Stack* stack,
{ {
if (v->sites->next == 0) { if (v->sites->next == 0) {
Site* saveSite = 0; Site* saveSite = 0;
for (unsigned i = 0; i < c->localFootprint; ++i) { for (unsigned li = 0; li < c->localFootprint; ++li) {
if (locals[i].value == v) { if (locals[li].value == v) {
saveSite = frameSite(c, i); saveSite = frameSite
(c, frameIndex(c, li, ceiling(locals[li].size, BytesPerWord)));
break; break;
} }
} }
@ -1603,7 +1594,8 @@ trySteal(Context* c, Site* site, Value* v, unsigned size, Stack* stack,
if (frameIndex >= 0) { if (frameIndex >= 0) {
saveSite = frameSite(c, frameIndex); saveSite = frameSite(c, frameIndex);
} else { } else {
saveSite = frameSite(c, s->index + c->localFootprint); saveSite = frameSite
(c, ::frameIndex(c, s->index + c->localFootprint, s->size));
} }
break; break;
} }
@ -1837,32 +1829,32 @@ trySteal(Context* c, FrameResource* r, Stack* stack, Local* locals)
int index = r - c->frameResources; int index = r - c->frameResources;
fprintf(stderr, fprintf(stderr,
"try steal frame index %d offset 0x%x from value %p site %p\n", "try steal frame index %d offset 0x%x from value %p site %p\n",
index, frameIndexToLocalOffset(c, index), r->value, r->site); index, frameIndexToOffset(c, index), r->value, r->site);
} }
return trySteal(c, r->site, r->value, r->size, stack, locals); return trySteal(c, r->site, r->value, r->size, stack, locals);
} }
void void
acquireFrameIndex(Context* c, int index, Stack* stack, Local* locals, acquireFrameIndex(Context* c, int frameIndex, Stack* stack, Local* locals,
unsigned newSize, Value* newValue, MemorySite* newSite, unsigned newSize, Value* newValue, MemorySite* newSite,
bool recurse) bool recurse)
{ {
assert(c, index >= 0); assert(c, frameIndex >= 0);
assert(c, index < static_cast<int> assert(c, frameIndex < static_cast<int>
(c->alignedFrameSize + c->parameterFootprint)); (c->alignedFrameSize + c->parameterFootprint));
if (DebugFrameIndexes) { if (DebugFrameIndexes) {
fprintf(stderr, fprintf(stderr,
"acquire frame index %d offset 0x%x value %p site %p\n", "acquire frame index %d offset 0x%x value %p site %p\n",
index, frameIndexToLocalOffset(c, index), newValue, newSite); frameIndex, frameIndexToOffset(c, frameIndex), newValue, newSite);
} }
FrameResource* r = c->frameResources + index; FrameResource* r = c->frameResources + frameIndex;
if (recurse and newSize > BytesPerWord) { if (recurse and newSize > BytesPerWord) {
acquireFrameIndex acquireFrameIndex
(c, index + 1, stack, locals, newSize, newValue, newSite, false); (c, frameIndex + 1, stack, locals, newSize, newValue, newSite, false);
} }
Value* oldValue = r->value; Value* oldValue = r->value;
@ -1881,21 +1873,21 @@ acquireFrameIndex(Context* c, int index, Stack* stack, Local* locals,
} }
void void
releaseFrameIndex(Context* c, int index, bool recurse) releaseFrameIndex(Context* c, int frameIndex, bool recurse)
{ {
assert(c, index >= 0); assert(c, frameIndex >= 0);
assert(c, index < static_cast<int> assert(c, frameIndex < static_cast<int>
(c->alignedFrameSize + c->parameterFootprint)); (c->alignedFrameSize + c->parameterFootprint));
if (DebugFrameIndexes) { if (DebugFrameIndexes) {
fprintf(stderr, "release frame index %d offset 0x%x\n", fprintf(stderr, "release frame index %d offset 0x%x\n",
index, frameIndexToLocalOffset(c, index)); frameIndex, frameIndexToOffset(c, frameIndex));
} }
FrameResource* r = c->frameResources + index; FrameResource* r = c->frameResources + frameIndex;
if (recurse and r->size > BytesPerWord) { if (recurse and r->size > BytesPerWord) {
releaseFrameIndex(c, index + 1, false); releaseFrameIndex(c, frameIndex + 1, false);
} }
r->size = 0; r->size = 0;
@ -1975,12 +1967,14 @@ clean(Context* c, Value* v, unsigned popIndex)
{ {
for (Site** s = &(v->sites); *s;) { for (Site** s = &(v->sites); *s;) {
if ((*s)->match(c, 1 << MemoryOperand, 0, AnyFrameIndex) if ((*s)->match(c, 1 << MemoryOperand, 0, AnyFrameIndex)
and localOffsetToFrameIndex and offsetToFrameIndex
(c, static_cast<MemorySite*>(*s)->value.offset) (c, static_cast<MemorySite*>(*s)->value.offset)
< static_cast<int>(popIndex)) >= popIndex)
{ {
s = &((*s)->next); s = &((*s)->next);
} else { } else {
fprintf(stderr, "clean %p at %d pop index %d\n", v, offsetToFrameIndex
(c, static_cast<MemorySite*>(*s)->value.offset), popIndex);
(*s)->release(c); (*s)->release(c);
*s = (*s)->next; *s = (*s)->next;
} }
@ -1992,7 +1986,7 @@ clean(Context* c, Event* e, Stack* stack, Local* locals, Read* reads,
unsigned popIndex) unsigned popIndex)
{ {
for (unsigned i = 0; i < c->localFootprint; ++i) { for (unsigned i = 0; i < c->localFootprint; ++i) {
if (locals[i].value) clean(c, locals[i].value, c->localFootprint); if (locals[i].value) clean(c, locals[i].value, 0);
} }
for (Stack* s = stack; s; s = s->next) { for (Stack* s = stack; s; s = s->next) {
@ -2030,24 +2024,25 @@ class CallEvent: public Event {
address(address), address(address),
traceHandler(traceHandler), traceHandler(traceHandler),
result(result), result(result),
popIndex(c->localFootprint), popIndex(0),
flags(flags), flags(flags),
resultSize(resultSize) resultSize(resultSize)
{ {
uint32_t mask = ~0; uint32_t mask = ~0;
Stack* s = argumentStack; Stack* s = argumentStack;
unsigned index = 0; unsigned index = 0;
unsigned frameIndex = c->alignedFrameSize + c->parameterFootprint; unsigned frameIndex = 0;
for (unsigned i = 0; i < argumentCount; ++i) { for (unsigned i = 0; i < argumentCount; ++i) {
Read* target; Read* target;
if (index < c->arch->argumentRegisterCount()) { if (index < c->arch->argumentRegisterCount()) {
int r = c->arch->argumentRegister(index); int r = c->arch->argumentRegister(index);
fprintf(stderr, "reg %d arg read %p\n", r, s->value);
target = fixedRegisterRead(c, s->size * BytesPerWord, r); target = fixedRegisterRead(c, s->size * BytesPerWord, r);
mask &= ~(1 << r); mask &= ~(1 << r);
} else { } else {
frameIndex -= s->size;
target = read(c, s->size * BytesPerWord, 1 << MemoryOperand, 0, target = read(c, s->size * BytesPerWord, 1 << MemoryOperand, 0,
frameIndex); frameIndex);
frameIndex += s->size;
} }
addRead(c, this, s->value, target); addRead(c, this, s->value, target);
index += s->size; index += s->size;
@ -2060,30 +2055,33 @@ class CallEvent: public Event {
int footprint = stackArgumentFootprint; int footprint = stackArgumentFootprint;
for (Stack* s = stackBefore; s; s = s->next) { for (Stack* s = stackBefore; s; s = s->next) {
frameIndex -= s->size;
if (footprint > 0) { if (footprint > 0) {
fprintf(stderr, "stack arg of size %d at %d of %d\n", s->size, frameIndex, c->alignedFrameSize + c->parameterFootprint); fprintf(stderr, "stack arg of size %d at %d of %d\n", s->size, frameIndex, c->alignedFrameSize + c->parameterFootprint);
addRead(c, this, s->value, read addRead(c, this, s->value, read
(c, s->size * BytesPerWord, (c, s->size * BytesPerWord,
1 << MemoryOperand, 0, frameIndex)); 1 << MemoryOperand, 0, frameIndex));
} else { } else {
unsigned index = s->index + c->localFootprint; unsigned index = ::frameIndex
(c, s->index + c->localFootprint, s->size);
if (footprint == 0) { if (footprint == 0) {
assert(c, index <= frameIndex); assert(c, index >= frameIndex);
s->padding = frameIndex - index; s->padding = index - frameIndex;
popIndex = index + s->size; popIndex = index;
} }
fprintf(stderr, "stack save of size %d at %d of %d\n", s->size, index, c->alignedFrameSize + c->parameterFootprint);
addRead(c, this, s->value, read addRead(c, this, s->value, read
(c, s->size * BytesPerWord, 1 << MemoryOperand, 0, index)); (c, s->size * BytesPerWord, 1 << MemoryOperand, 0, index));
} }
frameIndex += s->size;
footprint -= s->size; footprint -= s->size;
} }
for (unsigned i = 0; i < c->localFootprint; ++i) { for (unsigned li = 0; li < c->localFootprint; ++li) {
Local* local = localsBefore + i; Local* local = localsBefore + li;
if (local->value) { if (local->value) {
addRead(c, this, local->value, read addRead(c, this, local->value, read
(c, local->size, 1 << MemoryOperand, 0, i)); (c, local->size, 1 << MemoryOperand, 0,
::frameIndex(c, li, ceiling(local->size, BytesPerWord))));
} }
} }
} }
@ -2166,6 +2164,25 @@ appendReturn(Context* c, unsigned size, Value* value)
ReturnEvent(c, size, value)); ReturnEvent(c, size, value));
} }
void
preserve(Context* c, Stack* stack, Local* locals, unsigned size, Value* v,
Site* s, Read* read)
{
assert(c, v->sites == s);
Site* r = targetOrNull(c, v, read);
if (r == 0 or r == s) r = freeRegisterSite(c);
move(c, stack, locals, size, v, s, r);
}
void
maybePreserve(Context* c, Stack* stack, Local* locals, unsigned size,
Value* v, Site* s)
{
if (valid(v->reads->next(c)) and v->sites->next == 0) {
preserve(c, stack, locals, size, v, s, v->reads->next(c));
}
}
class MoveEvent: public Event { class MoveEvent: public Event {
public: public:
MoveEvent(Context* c, BinaryOperation type, unsigned srcSize, Value* src, MoveEvent(Context* c, BinaryOperation type, unsigned srcSize, Value* src,
@ -2187,9 +2204,13 @@ class MoveEvent: public Event {
unsigned cost = src->source->copyCost(c, target); unsigned cost = src->source->copyCost(c, target);
if (cost == 0) { if (cost == 0) {
target = src->source; target = src->source;
char dstb[256]; target->toString(c, dstb, 256);
fprintf(stderr, "null move in %s for %p to %p\n", dstb, src, dst);
} }
if (target == src->source) { if (target == src->source) {
maybePreserve(c, stackBefore, localsBefore, srcSize, src, target);
removeSite(c, src, target); removeSite(c, src, target);
} }
@ -2358,25 +2379,6 @@ appendCompare(Context* c, unsigned size, Value* first, Value* second)
read(c, size, secondTypeMask, secondRegisterMask, AnyFrameIndex))); read(c, size, secondTypeMask, secondRegisterMask, AnyFrameIndex)));
} }
void
preserve(Context* c, Stack* stack, Local* locals, unsigned size, Value* v,
Site* s, Read* read)
{
assert(c, v->sites == s);
Site* r = targetOrNull(c, v, read);
if (r == 0 or r == s) r = freeRegisterSite(c);
move(c, stack, locals, size, v, s, r);
}
void
maybePreserve(Context* c, Stack* stack, Local* locals, unsigned size,
Value* v, Site* s)
{
if (valid(v->reads->next(c)) and v->sites->next == 0) {
preserve(c, stack, locals, size, v, s, v->reads->next(c));
}
}
class CombineEvent: public Event { class CombineEvent: public Event {
public: public:
CombineEvent(Context* c, TernaryOperation type, CombineEvent(Context* c, TernaryOperation type,
@ -2935,12 +2937,18 @@ appendDummy(Context* c)
void void
append(Context* c, Event* e) append(Context* c, Event* e)
{ {
if (DebugAppend) { assert(c, c->logicalIp >= 0);
fprintf(stderr, " -- append %s at %d\n",
e->name(), e->logicalInstruction->index); LogicalInstruction* i = c->logicalCode[c->logicalIp];
if (c->stack != i->stack or c->locals != i->locals) {
appendDummy(c);
} }
assert(c, c->logicalIp >= 0); if (DebugAppend) {
fprintf(stderr, " -- append %s at %d with %d stack before\n",
e->name(), e->logicalInstruction->index, c->stack ?
c->stack->index + c->stack->size : 0);
}
if (c->lastEvent) { if (c->lastEvent) {
c->lastEvent->next = e; c->lastEvent->next = e;
@ -2987,7 +2995,7 @@ readSource(Context* c, Stack* stack, Local* locals, Read* r)
} }
Site* Site*
pickJunctionSite(Context* c, Value* v, Read* r, unsigned index) pickJunctionSite(Context* c, Value* v, Read* r, unsigned frameIndex)
{ {
if (c->availableRegisterCount > 1) { if (c->availableRegisterCount > 1) {
if (not v->visited) { if (not v->visited) {
@ -3010,27 +3018,28 @@ pickJunctionSite(Context* c, Value* v, Read* r, unsigned index)
return freeRegisterSite(c); return freeRegisterSite(c);
} else { } else {
return frameSite(c, index); return frameSite(c, frameIndex);
} }
} }
unsigned unsigned
resolveJunctionSite(Context* c, Event* e, Value* v, unsigned index, resolveJunctionSite(Context* c, Event* e, Value* v,
unsigned siteIndex, unsigned frameIndex,
Site** frozenSites, unsigned frozenSiteIndex) Site** frozenSites, unsigned frozenSiteIndex)
{ {
assert(c, index < frameFootprint(c, e->stackAfter)); assert(c, siteIndex < frameFootprint(c, e->stackAfter));
if (live(v)) { if (live(v)) {
assert(c, v->sites); assert(c, v->sites);
Read* r = v->reads; Read* r = v->reads;
Site* original = e->junctionSites[index]; Site* original = e->junctionSites[siteIndex];
Site* target; Site* target;
if (original) { if (original) {
target = original; target = original;
} else { } else {
target = pickJunctionSite(c, v, r, index); target = pickJunctionSite(c, v, r, frameIndex);
} }
unsigned copyCost; unsigned copyCost;
@ -3048,11 +3057,11 @@ resolveJunctionSite(Context* c, Event* e, Value* v, unsigned index,
if (original == 0) { if (original == 0) {
frozenSites[frozenSiteIndex++] = target; frozenSites[frozenSiteIndex++] = target;
target->freeze(c); target->freeze(c);
e->junctionSites[index] = target->copy(c); e->junctionSites[siteIndex] = target->copy(c);
} }
char buffer[256]; target->toString(c, buffer, 256); char buffer[256]; target->toString(c, buffer, 256);
fprintf(stderr, "resolved junction site %d %s %p\n", index, buffer, v); fprintf(stderr, "resolved junction site %d %s %p\n", frameIndex, buffer, v);
} }
v->visited = true; v->visited = true;
@ -3102,21 +3111,26 @@ populateSiteTables(Context* c, Event* e)
if (e->junctionSites) { if (e->junctionSites) {
if (e->stackAfter) { if (e->stackAfter) {
unsigned i = e->stackAfter->index + c->localFootprint; unsigned fi = frameIndex
(c, e->stackAfter->index + c->localFootprint, e->stackAfter->size);
for (Stack* stack = e->stackAfter; stack; stack = stack->next) { for (Stack* stack = e->stackAfter; stack; stack = stack->next) {
if (e->junctionSites[i]) { unsigned si = stack->index + c->localFootprint;
if (e->junctionSites[si]) {
frozenSiteIndex = resolveJunctionSite frozenSiteIndex = resolveJunctionSite
(c, e, stack->value, i, frozenSites, frozenSiteIndex); (c, e, stack->value, si, fi, frozenSites, frozenSiteIndex);
i -= stack->size; fi += stack->size;
} }
} }
} }
for (int i = c->localFootprint - 1; i >= 0; --i) { for (int li = c->localFootprint - 1; li >= 0; --li) {
if (e->localsAfter[i].value and e->junctionSites[i]) { int fi = frameIndex
(c, li, ceiling(e->localsAfter[li].size, BytesPerWord));
if (e->localsAfter[li].value and e->junctionSites[li]) {
frozenSiteIndex = resolveJunctionSite frozenSiteIndex = resolveJunctionSite
(c, e, e->localsAfter[i].value, i, frozenSites, frozenSiteIndex); (c, e, e->localsAfter[li].value, li, fi, frozenSites,
frozenSiteIndex);
} }
} }
} else { } else {
@ -3136,21 +3150,26 @@ populateSiteTables(Context* c, Event* e)
if (e->junctionSites) { if (e->junctionSites) {
if (e->stackAfter) { if (e->stackAfter) {
unsigned i = e->stackAfter->index + c->localFootprint; int fi = frameIndex
(c, e->stackAfter->index + c->localFootprint, e->stackAfter->size);
for (Stack* stack = e->stackAfter; stack; stack = stack->next) { for (Stack* stack = e->stackAfter; stack; stack = stack->next) {
if (e->junctionSites[i] == 0) { unsigned si = stack->index + c->localFootprint;
if (e->junctionSites[si] == 0) {
frozenSiteIndex = resolveJunctionSite frozenSiteIndex = resolveJunctionSite
(c, e, stack->value, i, frozenSites, frozenSiteIndex); (c, e, stack->value, si, fi, frozenSites, frozenSiteIndex);
i -= stack->size; fi += stack->size;
} }
} }
} }
for (int i = c->localFootprint - 1; i >= 0; --i) { for (int li = c->localFootprint - 1; li >= 0; --li) {
if (e->localsAfter[i].value and e->junctionSites[i] == 0) { int fi = frameIndex
(c, li, ceiling(e->localsAfter[li].size, BytesPerWord));
if (e->localsAfter[li].value and e->junctionSites[li] == 0) {
frozenSiteIndex = resolveJunctionSite frozenSiteIndex = resolveJunctionSite
(c, e, e->localsAfter[i].value, i, frozenSites, frozenSiteIndex); (c, e, e->localsAfter[li].value, li, fi, frozenSites,
frozenSiteIndex);
} }
} }
@ -3160,12 +3179,15 @@ populateSiteTables(Context* c, Event* e)
} }
} }
for (int i = c->localFootprint - 1; i >= 0; --i) { for (int li = c->localFootprint - 1; li >= 0; --li) {
Value* v = e->localsAfter[i].value; Value* v = e->localsAfter[li].value;
if (v) { if (v) {
v->visited = false; v->visited = false;
} }
} }
fprintf(stderr, "resolved junction sites %p at %d\n",
e->junctionSites, e->logicalInstruction->index);
} }
while (frozenSiteIndex) { while (frozenSiteIndex) {
@ -3179,33 +3201,36 @@ populateSiteTables(Context* c, Event* e)
memset(savedSites, 0, size); memset(savedSites, 0, size);
if (e->stackAfter) { if (e->stackAfter) {
unsigned i = e->stackAfter->index + c->localFootprint; int fi = frameIndex
(c, e->stackAfter->index + c->localFootprint, e->stackAfter->size);
for (Stack* stack = e->stackAfter; stack; stack = stack->next) { for (Stack* stack = e->stackAfter; stack; stack = stack->next) {
Value* v = stack->value; Value* v = stack->value;
if (not v->visited) { if (not v->visited) {
v->visited = true; v->visited = true;
if (v->sites) { if (v->sites) {
char buffer[256]; toString(c, v->sites, buffer, 256); char buffer[256]; toString(c, v->sites, buffer, 256);
fprintf(stderr, "save %s for %p at %d\n", buffer, v, i); fprintf(stderr, "save %s for %p at %d\n", buffer, v, fi);
} }
savedSites[i] = copy(c, v->sites); savedSites[stack->index + c->localFootprint] = copy(c, v->sites);
i -= stack->size; fi += stack->size;
} }
} }
} }
for (int i = c->localFootprint - 1; i >= 0; --i) { for (int li = c->localFootprint - 1; li >= 0; --li) {
Value* v = e->localsAfter[i].value; Value* v = e->localsAfter[li].value;
if (v and not v->visited) { if (v and not v->visited) {
int fi = frameIndex
(c, li, ceiling(e->localsAfter[li].size, BytesPerWord));
v->visited = true; v->visited = true;
if (v->sites) { if (v->sites) {
char buffer[256]; toString(c, v->sites, buffer, 256); char buffer[256]; toString(c, v->sites, buffer, 256);
fprintf(stderr, "save %s for %p at %d\n", buffer, v, i); fprintf(stderr, "save %s for %p at %d\n", buffer, v, fi);
} }
savedSites[i] = copy(c, v->sites); savedSites[li] = copy(c, v->sites);
} }
} }
@ -3215,19 +3240,22 @@ populateSiteTables(Context* c, Event* e)
} }
} }
for (int i = c->localFootprint - 1; i >= 0; --i) { for (int li = c->localFootprint - 1; li >= 0; --li) {
Value* v = e->localsAfter[i].value; Value* v = e->localsAfter[li].value;
if (v) { if (v) {
v->visited = false; v->visited = false;
} }
} }
e->savedSites = savedSites; e->savedSites = savedSites;
fprintf(stderr, "captured saved sites %p at %d\n",
e->savedSites, e->logicalInstruction->index);
} }
} }
void void
setSites(Context* c, Event* e, Value* v, Site* s, unsigned i) setSites(Context* c, Event* e, Value* v, Site* s, unsigned frameIndex)
{ {
for (; s; s = s->next) { for (; s; s = s->next) {
addSite(c, e->stackBefore, e->localsBefore, v->reads->size, v, addSite(c, e->stackBefore, e->localsBefore, v->reads->size, v,
@ -3235,43 +3263,44 @@ setSites(Context* c, Event* e, Value* v, Site* s, unsigned i)
} }
char buffer[256]; toString(c, v->sites, buffer, 256); char buffer[256]; toString(c, v->sites, buffer, 256);
fprintf(stderr, "set sites %s for %p at %d\n", buffer, v, i); fprintf(stderr, "set sites %s for %p at %d\n", buffer, v, frameIndex);
} }
void void
setSites(Context* c, Event* e, Site** sites) setSites(Context* c, Event* e, Site** sites)
{ {
for (unsigned i = 0; i < c->localFootprint; ++i) { for (unsigned li = 0; li < c->localFootprint; ++li) {
Value* v = e->localsBefore[i].value; Value* v = e->localsBefore[li].value;
if (v) { if (v) {
clearSites(c, v); clearSites(c, v);
} }
} }
if (e->stackBefore) { if (e->stackBefore) {
unsigned i = e->stackBefore->index + c->localFootprint;
for (Stack* stack = e->stackBefore; stack; stack = stack->next) { for (Stack* stack = e->stackBefore; stack; stack = stack->next) {
Value* v = stack->value; Value* v = stack->value;
clearSites(c, v); clearSites(c, v);
i -= stack->size;
} }
} }
if (e->stackBefore) { if (e->stackBefore) {
unsigned i = e->stackBefore->index + c->localFootprint; int fi = frameIndex
(c, e->stackBefore->index + c->localFootprint, e->stackBefore->size);
for (Stack* stack = e->stackBefore; stack; stack = stack->next) { for (Stack* stack = e->stackBefore; stack; stack = stack->next) {
Value* v = stack->value; Value* v = stack->value;
if (live(v)) { if (live(v)) {
setSites(c, e, v, sites[i], i); setSites(c, e, v, sites[stack->index + c->localFootprint], fi);
} }
i -= stack->size; fi += stack->size;
} }
} }
for (int i = c->localFootprint - 1; i >= 0; --i) { for (int li = c->localFootprint - 1; li >= 0; --li) {
Value* v = e->localsBefore[i].value; Value* v = e->localsBefore[li].value;
if (v and live(v) and sites[i]) { int fi = frameIndex
setSites(c, e, v, sites[i], i); (c, li, ceiling(e->localsBefore[li].size, BytesPerWord));
if (v and live(v) and sites[li]) {
setSites(c, e, v, sites[li], fi);
} }
} }
} }
@ -3428,8 +3457,12 @@ compile(Context* c)
{ {
updateJunctionReads(c, pl->junctionState); updateJunctionReads(c, pl->junctionState);
} }
fprintf(stderr, "set sites to junction sites %p at %d\n",
first->junctionSites, first->logicalInstruction->index);
setSites(c, e, first->junctionSites); setSites(c, e, first->junctionSites);
} else if (first->successors->nextSuccessor) { } else if (first->successors->nextSuccessor) {
fprintf(stderr, "set sites to saved sites %p at %d\n",
first->savedSites, first->logicalInstruction->index);
setSites(c, e, first->savedSites); setSites(c, e, first->savedSites);
} }
} }
@ -3760,7 +3793,8 @@ class MyCompiler: public Compiler {
} }
virtual Operand* stackTop() { virtual Operand* stackTop() {
Site* s = frameSite(&c, c.stack->index); Site* s = frameSite
(&c, frameIndex(&c, c.stack->index + c.localFootprint, c.stack->size));
return value(&c, s, s); return value(&c, s, s);
} }
@ -3786,7 +3820,7 @@ class MyCompiler: public Compiler {
Value* v = value(&c); Value* v = value(&c);
appendFrameSite appendFrameSite
(&c, v, BytesPerWord, (&c, v, BytesPerWord,
(c.stack ? c.stack->index + c.stack->size : c.localFootprint)); frameIndex(&c, (c.stack ? c.stack->index : 0) + c.localFootprint, 1));
c.stack = ::stack(&c, v, 1, c.stack); c.stack = ::stack(&c, v, 1, c.stack);
} }
@ -3885,8 +3919,10 @@ class MyCompiler: public Compiler {
assert(&c, index < c.localFootprint); assert(&c, index < c.localFootprint);
Value* v = value(&c); Value* v = value(&c);
fprintf(stderr, "init local %p of size %d at %d\n", v, size, index); fprintf(stderr, "init local %p of size %d at %d (%d)\n", v, size, index,
appendFrameSite(&c, v, size, index); frameIndex(&c, index, ceiling(size, BytesPerWord)));
appendFrameSite
(&c, v, size, frameIndex(&c, index, ceiling(size, BytesPerWord)));
Local* local = c.locals + index; Local* local = c.locals + index;
local->value = v; local->value = v;