mirror of
https://github.com/corda/corda.git
synced 2025-01-07 13:38:47 +00:00
optimize multiple loads from the same local variable
This commit is contained in:
parent
56d8851764
commit
3c30e815ec
@ -849,51 +849,36 @@ class Frame {
|
|||||||
|
|
||||||
void loadInt(unsigned index) {
|
void loadInt(unsigned index) {
|
||||||
assert(t, index < localSize());
|
assert(t, index < localSize());
|
||||||
pushInt
|
pushInt(c->loadLocal(BytesPerWord, index));
|
||||||
(c->load
|
|
||||||
(4, c->memory(c->base(), localOffset(t, index, context->method))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadLong(unsigned index) {
|
void loadLong(unsigned index) {
|
||||||
assert(t, index < static_cast<unsigned>(localSize() - 1));
|
assert(t, index < static_cast<unsigned>(localSize() - 1));
|
||||||
pushLong
|
pushLong(c->loadLocal(8, index + 1));
|
||||||
(c->load
|
|
||||||
(8, c->memory(c->base(), localOffset(t, index + 1, context->method))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadObject(unsigned index) {
|
void loadObject(unsigned index) {
|
||||||
assert(t, index < localSize());
|
assert(t, index < localSize());
|
||||||
pushObject
|
pushObject(c->loadLocal(BytesPerWord, index));
|
||||||
(c->load
|
|
||||||
(BytesPerWord,
|
|
||||||
c->memory(c->base(), localOffset(t, index, context->method))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void storeInt(unsigned index) {
|
void storeInt(unsigned index) {
|
||||||
c->store
|
c->storeLocal(BytesPerWord, popInt(), index);
|
||||||
(4, popInt(), c->memory
|
|
||||||
(c->base(), localOffset(t, index, context->method)));
|
|
||||||
storedInt(index);
|
storedInt(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void storeLong(unsigned index) {
|
void storeLong(unsigned index) {
|
||||||
c->store
|
c->storeLocal(8, popLong(), index + 1);
|
||||||
(8, popLong(), c->memory
|
|
||||||
(c->base(), localOffset(t, index + 1, context->method)));
|
|
||||||
storedLong(index);
|
storedLong(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void storeObject(unsigned index) {
|
void storeObject(unsigned index) {
|
||||||
c->store
|
c->storeLocal(BytesPerWord, popObject(), index);
|
||||||
(BytesPerWord, popObject(), c->memory
|
|
||||||
(c->base(), localOffset(t, index, context->method)));
|
|
||||||
storedObject(index);
|
storedObject(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void storeObjectOrAddress(unsigned index) {
|
void storeObjectOrAddress(unsigned index) {
|
||||||
c->store
|
c->storeLocal(BytesPerWord, c->pop(BytesPerWord), index);
|
||||||
(BytesPerWord, c->pop(BytesPerWord), c->memory
|
|
||||||
(c->base(), localOffset(t, index, context->method)));
|
|
||||||
|
|
||||||
assert(t, sp >= 1);
|
assert(t, sp >= 1);
|
||||||
assert(t, sp - 1 >= localSize());
|
assert(t, sp - 1 >= localSize());
|
||||||
@ -2641,7 +2626,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
Compiler::Operand* a = c->memory
|
Compiler::Operand* a = c->memory
|
||||||
(c->base(), localOffset(t, index, context->method));
|
(c->base(), localOffset(t, index, context->method));
|
||||||
|
|
||||||
c->store(4, c->add(4, c->constant(count), a), a);
|
c->storeLocal(4, c->add(4, c->constant(count), a), index);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case iload:
|
case iload:
|
||||||
@ -3456,7 +3441,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
Compiler::Operand* a = c->memory
|
Compiler::Operand* a = c->memory
|
||||||
(c->base(), localOffset(t, index, context->method));
|
(c->base(), localOffset(t, index, context->method));
|
||||||
|
|
||||||
c->store(4, c->add(4, c->constant(count), a), a);
|
c->storeLocal(4, c->add(4, c->constant(count), a), index);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case iload: {
|
case iload: {
|
||||||
@ -3866,11 +3851,11 @@ finish(MyThread* t, Context* context)
|
|||||||
strcmp
|
strcmp
|
||||||
(reinterpret_cast<const char*>
|
(reinterpret_cast<const char*>
|
||||||
(&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)),
|
(&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)),
|
||||||
"org/eclipse/swt/widgets/CoolBar") == 0 and
|
"java/lang/String") == 0 and
|
||||||
strcmp
|
strcmp
|
||||||
(reinterpret_cast<const char*>
|
(reinterpret_cast<const char*>
|
||||||
(&byteArrayBody(t, methodName(t, context->method), 0)),
|
(&byteArrayBody(t, methodName(t, context->method), 0)),
|
||||||
"layoutItems") == 0)
|
"<init>") == 0)
|
||||||
{
|
{
|
||||||
asm("int3");
|
asm("int3");
|
||||||
}
|
}
|
||||||
@ -3890,7 +3875,7 @@ compile(MyThread* t, Context* context)
|
|||||||
|
|
||||||
unsigned footprint = methodParameterFootprint(t, context->method);
|
unsigned footprint = methodParameterFootprint(t, context->method);
|
||||||
unsigned locals = localSize(t, context->method);
|
unsigned locals = localSize(t, context->method);
|
||||||
c->init(codeLength(t, methodCode(t, context->method)), locals - footprint);
|
c->init(codeLength(t, methodCode(t, context->method)), footprint, locals);
|
||||||
|
|
||||||
uint8_t stackMap[codeMaxStack(t, methodCode(t, context->method))];
|
uint8_t stackMap[codeMaxStack(t, methodCode(t, context->method))];
|
||||||
Frame frame(context, stackMap);
|
Frame frame(context, stackMap);
|
||||||
|
236
src/compiler.cpp
236
src/compiler.cpp
@ -91,12 +91,26 @@ class State {
|
|||||||
State* next;
|
State* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Local {
|
||||||
|
public:
|
||||||
|
Local(unsigned size, unsigned index, Value* value, Site* site, Local* next):
|
||||||
|
size(size), index(index), value(value), site(site), next(next)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
unsigned size;
|
||||||
|
unsigned index;
|
||||||
|
Value* value;
|
||||||
|
Site* site;
|
||||||
|
Local* next;
|
||||||
|
};
|
||||||
|
|
||||||
class LogicalInstruction {
|
class LogicalInstruction {
|
||||||
public:
|
public:
|
||||||
Event* firstEvent;
|
Event* firstEvent;
|
||||||
Event* lastEvent;
|
Event* lastEvent;
|
||||||
LogicalInstruction* immediatePredecessor;
|
LogicalInstruction* immediatePredecessor;
|
||||||
Stack* stack;
|
Stack* stack;
|
||||||
|
Local* locals;
|
||||||
unsigned machineOffset;
|
unsigned machineOffset;
|
||||||
bool stackSaved;
|
bool stackSaved;
|
||||||
};
|
};
|
||||||
@ -177,7 +191,8 @@ class Context {
|
|||||||
state(new (zone->allocate(sizeof(State))) State(0, 0)),
|
state(new (zone->allocate(sizeof(State))) State(0, 0)),
|
||||||
logicalCode(0),
|
logicalCode(0),
|
||||||
logicalCodeLength(0),
|
logicalCodeLength(0),
|
||||||
stackOffset(0),
|
parameterFootprint(0),
|
||||||
|
localFootprint(0),
|
||||||
registers
|
registers
|
||||||
(static_cast<Register**>
|
(static_cast<Register**>
|
||||||
(zone->allocate(sizeof(Register*) * assembler->registerCount()))),
|
(zone->allocate(sizeof(Register*) * assembler->registerCount()))),
|
||||||
@ -187,6 +202,8 @@ class Context {
|
|||||||
nextSequence(0),
|
nextSequence(0),
|
||||||
junctions(0),
|
junctions(0),
|
||||||
machineCode(0),
|
machineCode(0),
|
||||||
|
locals(0),
|
||||||
|
localTable(0),
|
||||||
stackReset(false)
|
stackReset(false)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < assembler->registerCount(); ++i) {
|
for (unsigned i = 0; i < assembler->registerCount(); ++i) {
|
||||||
@ -206,7 +223,8 @@ class Context {
|
|||||||
State* state;
|
State* state;
|
||||||
LogicalInstruction* logicalCode;
|
LogicalInstruction* logicalCode;
|
||||||
unsigned logicalCodeLength;
|
unsigned logicalCodeLength;
|
||||||
unsigned stackOffset;
|
unsigned parameterFootprint;
|
||||||
|
unsigned localFootprint;
|
||||||
Register** registers;
|
Register** registers;
|
||||||
ConstantPoolNode* firstConstant;
|
ConstantPoolNode* firstConstant;
|
||||||
ConstantPoolNode* lastConstant;
|
ConstantPoolNode* lastConstant;
|
||||||
@ -214,6 +232,8 @@ class Context {
|
|||||||
unsigned nextSequence;
|
unsigned nextSequence;
|
||||||
Junction* junctions;
|
Junction* junctions;
|
||||||
uint8_t* machineCode;
|
uint8_t* machineCode;
|
||||||
|
Local* locals;
|
||||||
|
Local** localTable;
|
||||||
bool stackReset;
|
bool stackReset;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -308,8 +328,8 @@ expect(Context* c, bool v)
|
|||||||
class Event {
|
class Event {
|
||||||
public:
|
public:
|
||||||
Event(Context* c):
|
Event(Context* c):
|
||||||
next(0), stack(c->state->stack), promises(0), reads(0), readCount(0),
|
next(0), stack(c->state->stack), locals(c->locals), promises(0), reads(0),
|
||||||
sequence(c->nextSequence++), stackReset(c->stackReset)
|
readCount(0), sequence(c->nextSequence++), stackReset(c->stackReset)
|
||||||
{
|
{
|
||||||
assert(c, c->logicalIp >= 0);
|
assert(c, c->logicalIp >= 0);
|
||||||
|
|
||||||
@ -327,8 +347,8 @@ class Event {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Event(Context*, unsigned sequence, Stack* stack):
|
Event(Context*, unsigned sequence, Stack* stack, Local* locals):
|
||||||
next(0), stack(stack), promises(0), reads(0), readCount(0),
|
next(0), stack(stack), locals(locals), promises(0), reads(0), readCount(0),
|
||||||
sequence(sequence), stackReset(false)
|
sequence(sequence), stackReset(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
@ -340,6 +360,7 @@ class Event {
|
|||||||
|
|
||||||
Event* next;
|
Event* next;
|
||||||
Stack* stack;
|
Stack* stack;
|
||||||
|
Local* locals;
|
||||||
CodePromise* promises;
|
CodePromise* promises;
|
||||||
Read* reads;
|
Read* reads;
|
||||||
unsigned readCount;
|
unsigned readCount;
|
||||||
@ -347,6 +368,19 @@ class Event {
|
|||||||
bool stackReset;
|
bool stackReset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
localOffset(Context* c, int v)
|
||||||
|
{
|
||||||
|
int parameterFootprint = c->parameterFootprint * BytesPerWord;
|
||||||
|
|
||||||
|
v *= BytesPerWord;
|
||||||
|
if (v < parameterFootprint) {
|
||||||
|
return (parameterFootprint - v - BytesPerWord) + (BytesPerWord * 2);
|
||||||
|
} else {
|
||||||
|
return -(v + BytesPerWord - parameterFootprint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
findSite(Context*, Value* v, Site* site)
|
findSite(Context*, Value* v, Site* site)
|
||||||
{
|
{
|
||||||
@ -723,7 +757,8 @@ class MemorySite: public Site {
|
|||||||
};
|
};
|
||||||
|
|
||||||
MemorySite*
|
MemorySite*
|
||||||
memorySite(Context* c, int base, int offset, int index, unsigned scale)
|
memorySite(Context* c, int base, int offset = 0, int index = NoRegister,
|
||||||
|
unsigned scale = 1)
|
||||||
{
|
{
|
||||||
return new (c->zone->allocate(sizeof(MemorySite)))
|
return new (c->zone->allocate(sizeof(MemorySite)))
|
||||||
MemorySite(base, offset, index, scale);
|
MemorySite(base, offset, index, scale);
|
||||||
@ -874,12 +909,18 @@ pick(Context* c, Site* sites, Site* target = 0, unsigned* cost = 0)
|
|||||||
return site;
|
return site;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
stackOffset(Context* c)
|
||||||
|
{
|
||||||
|
return c->localFootprint - c->parameterFootprint;
|
||||||
|
}
|
||||||
|
|
||||||
Site*
|
Site*
|
||||||
pushSite(Context* c, unsigned index)
|
pushSite(Context* c, unsigned index)
|
||||||
{
|
{
|
||||||
return memorySite
|
return memorySite
|
||||||
(c, c->assembler->base(),
|
(c, c->assembler->base(),
|
||||||
- (c->stackOffset + index + 1) * BytesPerWord, NoRegister, 1);
|
- (stackOffset(c) + index + 1) * BytesPerWord, NoRegister, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1259,6 +1300,41 @@ ignore(Context* c, unsigned count)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cleanStack(Context* c, Stack* stack, Local* locals, Read* reads)
|
||||||
|
{
|
||||||
|
for (Local* l = locals; l; l = l->next) {
|
||||||
|
clearSites(c, l->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Local* l = locals; l; l = l->next) {
|
||||||
|
addSite(c, 0, l->size * BytesPerWord, l->value, l->site);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Stack* s = stack; s; s = s->next) {
|
||||||
|
clearSites(c, s->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Stack* s = stack; s; s = s->next) {
|
||||||
|
if (s->pushSite) {
|
||||||
|
addSite(c, 0, s->size * BytesPerWord, s->value, s->pushSite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Read* r = reads; r; r = r->eventNext) {
|
||||||
|
nextRead(c, r->value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
resetLocals(Context* c)
|
||||||
|
{
|
||||||
|
for (Local* l = c->locals; l; l = l->next) {
|
||||||
|
c->localTable[l->index] = 0;
|
||||||
|
}
|
||||||
|
c->locals = 0;
|
||||||
|
}
|
||||||
|
|
||||||
class CallEvent: public Event {
|
class CallEvent: public Event {
|
||||||
public:
|
public:
|
||||||
CallEvent(Context* c, Value* address, unsigned flags,
|
CallEvent(Context* c, Value* address, unsigned flags,
|
||||||
@ -1305,6 +1381,8 @@ class CallEvent: public Event {
|
|||||||
addRead(c, s->value, s->size * BytesPerWord, virtualSite
|
addRead(c, s->value, s->size * BytesPerWord, virtualSite
|
||||||
(c, 0, ~0, (static_cast<uint64_t>(mask) << 32) | mask));
|
(c, 0, ~0, (static_cast<uint64_t>(mask) << 32) | mask));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetLocals(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
@ -1328,19 +1406,7 @@ class CallEvent: public Event {
|
|||||||
CodePromise(c, c->assembler->length()));
|
CodePromise(c, c->assembler->length()));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Stack* s = stack; s; s = s->next) {
|
cleanStack(c, stack, locals, reads);
|
||||||
clearSites(c, s->value);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Stack* s = stack; s; s = s->next) {
|
|
||||||
if (s->pushSite) {
|
|
||||||
addSite(c, 0, s->size * BytesPerWord, s->value, s->pushSite);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Read* r = reads; r; r = r->eventNext) {
|
|
||||||
nextRead(c, r->value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resultSize and result->reads) {
|
if (resultSize and result->reads) {
|
||||||
addSite(c, 0, resultSize, result, registerSite
|
addSite(c, 0, resultSize, result, registerSite
|
||||||
@ -1455,7 +1521,11 @@ class MoveEvent: public Event {
|
|||||||
nextRead(c, src);
|
nextRead(c, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dst->reads) {
|
bool isStore = dst->reads == 0;
|
||||||
|
|
||||||
|
assert(c, isStore or target != src->source or src->reads == 0);
|
||||||
|
|
||||||
|
if (not isStore) {
|
||||||
addSite(c, stack, size, dst, target);
|
addSite(c, stack, size, dst, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1471,7 +1541,7 @@ class MoveEvent: public Event {
|
|||||||
|
|
||||||
apply(c, type, size, src->source, tmpTarget);
|
apply(c, type, size, src->source, tmpTarget);
|
||||||
|
|
||||||
if (dst->reads == 0) {
|
if (isStore) {
|
||||||
removeSite(c, dst, tmpTarget);
|
removeSite(c, dst, tmpTarget);
|
||||||
|
|
||||||
apply(c, Move, size, tmpTarget, target);
|
apply(c, Move, size, tmpTarget, target);
|
||||||
@ -1481,7 +1551,7 @@ class MoveEvent: public Event {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dst->reads == 0) {
|
if (isStore) {
|
||||||
removeSite(c, dst, target);
|
removeSite(c, dst, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1661,6 +1731,9 @@ appendCombine(Context* c, BinaryOperation type, unsigned size, Value* first,
|
|||||||
fprintf(stderr, "appendCombine\n");
|
fprintf(stderr, "appendCombine\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
firstTarget->typeMask &= ~(1 << MemoryOperand);
|
||||||
|
secondTarget->typeMask &= ~(1 << MemoryOperand);
|
||||||
|
|
||||||
new (c->zone->allocate(sizeof(CombineEvent)))
|
new (c->zone->allocate(sizeof(CombineEvent)))
|
||||||
CombineEvent(c, type, size, first, second, result, firstTarget,
|
CombineEvent(c, type, size, first, second, result, firstTarget,
|
||||||
secondTarget);
|
secondTarget);
|
||||||
@ -1715,6 +1788,8 @@ appendTranslate(Context* c, UnaryOperation type, unsigned size, Value* value,
|
|||||||
|
|
||||||
assert(c, procedure == 0); // todo
|
assert(c, procedure == 0); // todo
|
||||||
|
|
||||||
|
target->typeMask &= ~(1 << MemoryOperand);
|
||||||
|
|
||||||
new (c->zone->allocate(sizeof(TranslateEvent)))
|
new (c->zone->allocate(sizeof(TranslateEvent)))
|
||||||
TranslateEvent(c, type, size, value, result, target);
|
TranslateEvent(c, type, size, value, result, target);
|
||||||
}
|
}
|
||||||
@ -1805,6 +1880,8 @@ resetStack(Context* c)
|
|||||||
i += s->size;
|
i += s->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetLocals(c);
|
||||||
|
|
||||||
c->stackReset = true;
|
c->stackReset = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1863,8 +1940,8 @@ class StackSyncEvent: public Event {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StackSyncEvent(Context* c, unsigned sequence, Stack* stack):
|
StackSyncEvent(Context* c, unsigned sequence, Stack* stack, Local* locals):
|
||||||
Event(c, sequence, stack)
|
Event(c, sequence, stack, locals)
|
||||||
{
|
{
|
||||||
for (Stack* s = stack; s; s = s->next) {
|
for (Stack* s = stack; s; s = s->next) {
|
||||||
if (s->pushEvent) s->pushEvent->active = true;
|
if (s->pushEvent) s->pushEvent->active = true;
|
||||||
@ -1877,19 +1954,7 @@ class StackSyncEvent: public Event {
|
|||||||
fprintf(stderr, "StackSyncEvent.compile\n");
|
fprintf(stderr, "StackSyncEvent.compile\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Stack* s = stack; s; s = s->next) {
|
cleanStack(c, stack, locals, reads);
|
||||||
clearSites(c, s->value);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Stack* s = stack; s; s = s->next) {
|
|
||||||
if (s->pushSite) {
|
|
||||||
addSite(c, 0, s->size * BytesPerWord, s->value, s->pushSite);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Read* r = reads; r; r = r->eventNext) {
|
|
||||||
nextRead(c, r->value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2004,6 +2069,45 @@ 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 LocalEvent: public Event {
|
||||||
|
public:
|
||||||
|
LocalEvent(Context* c, unsigned size, Value* newValue, Value* oldValue,
|
||||||
|
Site* site):
|
||||||
|
Event(c), size(size), newValue(newValue), oldValue(oldValue), site(site)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual void compile(Context* c) {
|
||||||
|
if (DebugCompile) {
|
||||||
|
fprintf(stderr, "LocalEvent.compile\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldValue) {
|
||||||
|
removeSite(c, oldValue, site);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newValue->reads) {
|
||||||
|
addSite(c, 0, size, newValue, site);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned size;
|
||||||
|
Value* newValue;
|
||||||
|
Value* oldValue;
|
||||||
|
Site* site;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
appendLocal(Context* c, unsigned size, Value* newValue, Value* oldValue,
|
||||||
|
Site* site)
|
||||||
|
{
|
||||||
|
if (DebugAppend) {
|
||||||
|
fprintf(stderr, "appendLocal\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
new (c->zone->allocate(sizeof(LocalEvent)))
|
||||||
|
LocalEvent(c, size, newValue, oldValue, site);
|
||||||
|
}
|
||||||
|
|
||||||
Site*
|
Site*
|
||||||
readSource(Context* c, Stack* stack, Read* r)
|
readSource(Context* c, Stack* stack, Read* r)
|
||||||
{
|
{
|
||||||
@ -2037,8 +2141,8 @@ compile(Context* c)
|
|||||||
a->apply(Move, BytesPerWord, RegisterOperand, &stack,
|
a->apply(Move, BytesPerWord, RegisterOperand, &stack,
|
||||||
RegisterOperand, &base);
|
RegisterOperand, &base);
|
||||||
|
|
||||||
if (c->stackOffset) {
|
if (stackOffset(c)) {
|
||||||
Assembler::Constant offset(resolved(c, c->stackOffset * BytesPerWord));
|
Assembler::Constant offset(resolved(c, stackOffset(c) * BytesPerWord));
|
||||||
a->apply(Subtract, BytesPerWord, ConstantOperand, &offset,
|
a->apply(Subtract, BytesPerWord, ConstantOperand, &offset,
|
||||||
RegisterOperand, &stack);
|
RegisterOperand, &stack);
|
||||||
}
|
}
|
||||||
@ -2120,6 +2224,7 @@ saveStack(Context* c)
|
|||||||
if (c->logicalIp >= 0 and not c->logicalCode[c->logicalIp].stackSaved) {
|
if (c->logicalIp >= 0 and not c->logicalCode[c->logicalIp].stackSaved) {
|
||||||
c->logicalCode[c->logicalIp].stackSaved = true;
|
c->logicalCode[c->logicalIp].stackSaved = true;
|
||||||
c->logicalCode[c->logicalIp].stack = c->state->stack;
|
c->logicalCode[c->logicalIp].stack = c->state->stack;
|
||||||
|
c->logicalCode[c->logicalIp].locals = c->locals;
|
||||||
|
|
||||||
if (DebugAppend) {
|
if (DebugAppend) {
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
@ -2159,6 +2264,27 @@ push(Context* c, unsigned size, Value* v)
|
|||||||
appendPush(c);
|
appendPush(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
addLocal(Context* c, unsigned size, unsigned index, Value* newValue)
|
||||||
|
{
|
||||||
|
Value* oldValue;
|
||||||
|
unsigned s = ceiling(size, BytesPerWord);
|
||||||
|
Local* local = c->localTable[index];
|
||||||
|
if (local) {
|
||||||
|
oldValue = local->value;
|
||||||
|
c->localTable[index] = c->locals = new (c->zone->allocate(sizeof(Local)))
|
||||||
|
Local(s, index, newValue, local->site, c->locals);
|
||||||
|
} else {
|
||||||
|
oldValue = 0;
|
||||||
|
c->localTable[index] = c->locals = new (c->zone->allocate(sizeof(Local)))
|
||||||
|
Local(s, index, newValue, memorySite
|
||||||
|
(c, c->assembler->base(), localOffset(c, index)),
|
||||||
|
c->locals);
|
||||||
|
}
|
||||||
|
|
||||||
|
appendLocal(c, s, newValue, oldValue, c->localTable[index]->site);
|
||||||
|
}
|
||||||
|
|
||||||
Value*
|
Value*
|
||||||
pop(Context* c, unsigned size UNUSED)
|
pop(Context* c, unsigned size UNUSED)
|
||||||
{
|
{
|
||||||
@ -2180,7 +2306,7 @@ updateJunctions(Context* c)
|
|||||||
|
|
||||||
p->lastEvent = p->lastEvent->next
|
p->lastEvent = p->lastEvent->next
|
||||||
= new (c->zone->allocate(sizeof(StackSyncEvent)))
|
= new (c->zone->allocate(sizeof(StackSyncEvent)))
|
||||||
StackSyncEvent(c, p->lastEvent->sequence, p->stack);
|
StackSyncEvent(c, p->lastEvent->sequence, p->stack, p->locals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2255,12 +2381,20 @@ class MyCompiler: public Compiler {
|
|||||||
::resetStack(&c);
|
::resetStack(&c);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void init(unsigned logicalCodeLength, unsigned stackOffset) {
|
virtual void init(unsigned logicalCodeLength, unsigned parameterFootprint,
|
||||||
|
unsigned localFootprint)
|
||||||
|
{
|
||||||
c.logicalCodeLength = logicalCodeLength;
|
c.logicalCodeLength = logicalCodeLength;
|
||||||
c.stackOffset = stackOffset;
|
c.parameterFootprint = parameterFootprint;
|
||||||
|
c.localFootprint = localFootprint;
|
||||||
|
|
||||||
c.logicalCode = static_cast<LogicalInstruction*>
|
c.logicalCode = static_cast<LogicalInstruction*>
|
||||||
(c.zone->allocate(sizeof(LogicalInstruction) * logicalCodeLength));
|
(c.zone->allocate(sizeof(LogicalInstruction) * logicalCodeLength));
|
||||||
memset(c.logicalCode, 0, sizeof(LogicalInstruction) * logicalCodeLength);
|
memset(c.logicalCode, 0, sizeof(LogicalInstruction) * logicalCodeLength);
|
||||||
|
|
||||||
|
c.localTable = static_cast<Local**>
|
||||||
|
(c.zone->allocate(sizeof(Local*) * localFootprint));
|
||||||
|
memset(c.localTable, 0, sizeof(Local*) * localFootprint);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void visitLogicalIp(unsigned logicalIp) {
|
virtual void visitLogicalIp(unsigned logicalIp) {
|
||||||
@ -2493,6 +2627,20 @@ class MyCompiler: public Compiler {
|
|||||||
appendReturn(&c, size, static_cast<Value*>(value));
|
appendReturn(&c, size, static_cast<Value*>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void storeLocal(unsigned size, Operand* src, unsigned index) {
|
||||||
|
assert(&c, index < c.localFootprint);
|
||||||
|
store(size, src, memory(base(), localOffset(&c, index)));
|
||||||
|
addLocal(&c, size, index, value(&c));
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Operand* loadLocal(unsigned size, unsigned index) {
|
||||||
|
assert(&c, index < c.localFootprint);
|
||||||
|
if (c.localTable[index] == 0) {
|
||||||
|
addLocal(&c, size, index, value(&c));
|
||||||
|
}
|
||||||
|
return c.localTable[index]->value;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void store(unsigned size, Operand* src, Operand* dst) {
|
virtual void store(unsigned size, Operand* src, Operand* dst) {
|
||||||
appendMove(&c, Move, size, static_cast<Value*>(src),
|
appendMove(&c, Move, size, static_cast<Value*>(src),
|
||||||
static_cast<Value*>(dst));
|
static_cast<Value*>(dst));
|
||||||
|
@ -32,7 +32,8 @@ class Compiler {
|
|||||||
virtual void saveStack() = 0;
|
virtual void saveStack() = 0;
|
||||||
virtual void resetStack() = 0;
|
virtual void resetStack() = 0;
|
||||||
|
|
||||||
virtual void init(unsigned logicalCodeSize, unsigned localFootprint) = 0;
|
virtual void init(unsigned logicalCodeSize, unsigned parameterFootprint,
|
||||||
|
unsigned localFootprint) = 0;
|
||||||
|
|
||||||
virtual void visitLogicalIp(unsigned logicalIp) = 0;
|
virtual void visitLogicalIp(unsigned logicalIp) = 0;
|
||||||
virtual void startLogicalIp(unsigned logicalIp) = 0;
|
virtual void startLogicalIp(unsigned logicalIp) = 0;
|
||||||
@ -76,6 +77,9 @@ class Compiler {
|
|||||||
|
|
||||||
virtual void return_(unsigned size, Operand* value) = 0;
|
virtual void return_(unsigned size, Operand* value) = 0;
|
||||||
|
|
||||||
|
virtual void storeLocal(unsigned size, Operand* src, unsigned index) = 0;
|
||||||
|
virtual Operand* loadLocal(unsigned size, unsigned index) = 0;
|
||||||
|
|
||||||
virtual void store(unsigned size, Operand* src, Operand* dst) = 0;
|
virtual void store(unsigned size, Operand* src, Operand* dst) = 0;
|
||||||
virtual Operand* load(unsigned size, Operand* src) = 0;
|
virtual Operand* load(unsigned size, Operand* src) = 0;
|
||||||
virtual Operand* loadz(unsigned size, Operand* src) = 0;
|
virtual Operand* loadz(unsigned size, Operand* src) = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user