mirror of
https://github.com/corda/corda.git
synced 2025-06-11 20:01:46 +00:00
fix stack frame offset calculations for 64-bit values; insert dummy events for instructions which start with stack activity
This commit is contained in:
348
src/compiler.cpp
348
src/compiler.cpp
@ -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;
|
||||||
|
Reference in New Issue
Block a user