From 4860060bf8309280c4c0ffff7323de602abefde2 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Thu, 7 Feb 2008 16:47:48 -0700 Subject: [PATCH] refine sketch of new compiler a bit --- src/compiler2.cpp | 471 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 371 insertions(+), 100 deletions(-) diff --git a/src/compiler2.cpp b/src/compiler2.cpp index fd845f42a5..4c90734a00 100644 --- a/src/compiler2.cpp +++ b/src/compiler2.cpp @@ -37,17 +37,30 @@ enum OperationType { Negate }; +class Context; +class MyOperand; +class ConstantValue; +class RegisterValue; +class MemoryValue; +class Event; + class Value { public: - virtual void preserve(Context*) = 0; - virtual void acquire(Context*, MyOperand*) = 0; - virtual void release(Context*, MyOperand*) = 0; + virtual bool equals(Value* o); + virtual bool equals(ConstantValue* o) { return false; } + virtual bool equals(RegisterValue* o) { return false; } + virtual bool equals(ConstantValue* o) { return false; } + + virtual void preserve(Context*) { ] + virtual void acquire(Context*, MyOperand*) { } + virtual void release(Context*, MyOperand*) { } + virtual void apply(Context*, OperationType op) = 0; virtual void apply(Context*, OperationType op, unsigned size, Value* b) = 0; - virtual void accept(Context*, OperationType op, unsigned size, - RegisterValue* a) = 0; virtual void accept(Context*, OperationType op, unsigned size, ConstantValue* a) = 0; + virtual void accept(Context*, OperationType op, unsigned size, + RegisterValue* a) = 0; virtual void accept(Context*, OperationType op, unsigned size, MemoryValue* a) = 0; }; @@ -68,7 +81,7 @@ class MyOperand: public Operand { class State { public: State(State* s): - stack(s->stack), + stack(s ? s->stack : 0), next(s) { } @@ -83,15 +96,200 @@ class LogicalInstruction { Event* lastEvent; }; +class Register { + public: + bool reserved; + MyOperand* operand; +}; + class Context { public: - unsigned logicalIp; + Context(NativeMachine* machine, Zone* zone): + machine(machine), + zone(zone), + logicalIp(-1), + state(new (c->zone->allocate(sizeof(State))) State(0)), + event(0), + logicalCode(0), + registers(static_cast + (zone->allocate(sizeof(Register) * machine->registerCount()))) + { + memset(registers, 0, sizeof(Register) * machine->registerCount()); + + registers[machine->base()].reserved = true; + registers[machine->stack()].reserved = true; + registers[machine->thread()].reserved = true; + } + + NativeMachine* machine; Zone* zone; + unsigned logicalIp; State* state; Event* event; LogicalInstruction* logicalCode; + Register* registers; }; +class ConstantValue: public Value { + public: + ConstantValue(Promise* value): value(value) { } + + virtual bool equals(Value* o) { return o->equals(this); } + + virtual bool equals(ConstantValue* o) { return o->value == value; } + + virtual void apply(Context* c, OperationType op, unsigned size) { + c->machine->appendC(op, size, value); + } + + virtual void apply(Context* c, OperationType op, unsigned size, Value* b) { + b->accept(c, op, size, this); + } + + virtual void accept(Context* c, OperationType, unsigned, ConstantValue*) { + abort(c); + } + + virtual void accept(Context* c, OperationType, unsigned, RegisterValue*) { + abort(c); + } + + virtual void accept(Context* c, OperationType, unsigned, MemoryValue*) { + abort(c); + } + + Promise* value; +}; + +ConstantValue* +constant(Context* c, Promise* value) +{ + return new (c->zone->allocate(sizeof(ConstantValue))) ConstantValue(value); +} + +void preserve(Context* c, int reg); + +class RegisterValue: public Value { + public: + RegisterValue(int low, int high): low(low), high(high) { } + + virtual bool equals(Value* o) { return o->equals(this); } + + virtual bool equals(RegisterValue* o) { + return o->low == low and o->high == high; + } + + virtual void preserve(Context* c) { + ::preserve(c, low); + if (high >= 0) ::preserve(c, high); + } + + virtual void acquire(Context* c, MyOperand* a) { + preserve(c); + c->registers[low].operand = a; + if (high >= 0) c->registers[high].operand = a; + } + + virtual void release(Context* c, MyOperand* a) { + c->registers[low].operand = 0; + if (high >= 0) c->registers[high].operand = 0; + } + + virtual void apply(Context* c, OperationType op, unsigned size) { + c->machine->appendR(op, size, low, high); + } + + virtual void apply(Context* c, OperationType op, unsigned size, Value* b) { + b->accept(c, op, size, this); + } + + virtual void accept(Context* c, OperationType op, unsigned size, + ConstantValue* a) + { + c->machine->appendCR(op, size, a->value, low, high); + } + + virtual void accept(Context* c, OperationType op, unsigned size, + RegisterValue* a) + { + c->machine->appendRR(op, size, a->low, a->high, low, high); + } + + virtual void accept(Context* c, OperationType op, unsigned size, + MemoryValue* a); + + unsigned low; +}; + +RegisterValue* +register_(Context* c, int low, int high) +{ + return new (c->zone->allocate(sizeof(RegisterValue))) + RegisterValue(low, high); +} + +class MemoryValue: public Value { + public: + MemoryValue(int base, int offset, int index, unsigned scale, + TraceHandler* traceHandler): + base(base), offset(offset), index(index), scale(scale), + traceHandler(traceHandler) + { } + + virtual bool equals(Value* o) { return o->equals(this); } + + virtual bool equals(MemoryValue* o) { + return o->base == base + and o->offset == offset + and o->index == index + and o->scale == scale; + } + + virtual void apply(Context* c, OperationType op, unsigned size) { + c->machine->appendM(op, size, base, offset, index, scale, traceHandler); + } + + virtual void apply(Context* c, OperationType op, unsigned size, Value* b) { + b->accept(c, op, size, this); + } + + virtual void accept(Context* c, OperationType op, unsigned size, + RegisterValue* a) + { + c->machine->appendRM(op, size, a->low, a->high, + base, offset, index, scale, traceHandler); + } + + virtual void accept(Context* c, OperationType op, unsigned size, + ConstantValue* a) + { + c->machine->appendCM(op, size, a->value, + base, offset, index, scale, traceHandler); + } + + virtual void accept(Context* c, OperationType op, unsigned size, + MemoryValue* a) + { + c->machine->appendMM + (op, size, a->base, a->offset, a->index, a->scale, a->traceHandler, + base, offset, index, scale, traceHandler); + } + + int base; + int offset; + int index; + unsigned scale; + TraceHandler* traceHandler; +}; + +MemoryValue* +memory(Context* c, int base, int offset, int index, unsigned scale, + TraceHandler* traceHandler) +{ + return new (c->zone->allocate(sizeof(MemoryValue))) + MemoryValue(base, offset, index, scale, traceHandler); +} + class Event { public: Event(Context* c): next(0) { @@ -106,6 +304,8 @@ class Event { c->event = this; } + Event(Event* next): next(next) { } + virtual void target(Context* c, MyOperand* value) = 0; virtual void replace(Context* c, MyOperand* old, MyOperand* new_) = 0; virtual void compile(Context* c) = 0; @@ -122,11 +322,12 @@ class ArgumentEvent: public Event { virtual Value* target(Context* c, MyOperand* v) { assert(c, v == a); - if (index < GprParameterCount) { - return register_(c, gpRegister(c, index)); + if (index < c->machine->argumentRegisterCount()) { + return register_(c, c->machine->argumentRegister(index)); } else { - return memory(c, register_(c, BaseRegister), - (v->index + c->stackOffset) * BytesPerWord, 0, 0, 0); + return memory(c, c->machine->base(), + (v->index + c->stackOffset) * BytesPerWord, + NoRegister, 0, 0); } } @@ -140,7 +341,7 @@ class ArgumentEvent: public Event { a->value->release(c, a); a->target->preserve(c); - if (not equal(c, a->target, a->value)) { + if (not a->target->equals(a->value)) { a->value->apply(c, Move, a->size, a->target); } } @@ -149,6 +350,13 @@ class ArgumentEvent: public Event { unsigned index; }; +void +appendArgument(Context* c, MyOperand* value, unsigned index) +{ + new (c->zone->allocate(sizeof(ArgumentEvent))) + ArgumentEvent(c, value, index); +} + class ReturnEvent: public Event { public: ReturnEvent(Context* c, MyOperand* a): @@ -158,11 +366,7 @@ class ReturnEvent: public Event { virtual Value* target(Context* c, MyOperand* v) { assert(c, v == a); - if (BytesPerWord == 4 and v->size == 8) { - return register_(c, ReturnLowRegister, ReturnHighRegister); - } else { - return register_(c, ReturnLowRegister); - } + return register_(c, c->machine->returnLow(), c->machine->returnHigh()); } virtual void replace(Context* c, MyOperand* old, MyOperand* new_) { @@ -174,7 +378,7 @@ class ReturnEvent: public Event { virtual void compile(Context* c) { a->value->release(c, a); - if (not equal(c, a->target, a->value)) { + if (not a->target->equals(a->value)) { a->value->apply(c, Move, a->size, a->target); } } @@ -182,6 +386,12 @@ class ReturnEvent: public Event { MyOperand* a; }; +void +appendReturn(Context* c, MyOperand* value) +{ + new (c->zone->allocate(sizeof(ReturnEvent))) ReturnEvent(c, value); +} + class SyncForCallEvent: public Event { public: SyncForCallEvent(Context* c, MyOperand* src, MyOperand* dst): @@ -204,7 +414,7 @@ class SyncForCallEvent: public Event { virtual void compile(Context* c) { src->value->release(c, src); - if (not equal(c, src->target, src->value)) { + if (not src->target->equals(src->value)) { src->value->apply(c, Move, src->size, src->target); } } @@ -213,20 +423,31 @@ class SyncForCallEvent: public Event { MyOperand* dst; }; +void +appendSyncForCall(Context* c, MyOperand* src, MyOperand* dst) +{ + new (c->zone->allocate(sizeof(SyncForCallEvent))) + SyncForCallEvent(c, src, dst); +} + class SyncForJumpEvent: public Event { public: SyncForJumpEvent(Context* c, MyOperand* src, MyOperand* dst): Event(c), src(src), dst(dst) { } + SyncForJumpEvent(Event* next, MyOperand* src, MyOperand* dst): + Event(next), src(src), dst(dst) + { } + virtual Value* target(Context* c, MyOperand* v) { assert(c, v == src); if (BytesPerWord == 4 and v->size == 8) { - return register_(c, stackSyncRegister(c, v->index), - stackSyncRegister(c, v->index + 4)); + return register_(c, c->machine->stackSyncRegister(c, v->index), + c->machine->stackSyncRegister(c, v->index + 4)); } else { - return register_(c, stackSyncRegister(c, v->index)); + return register_(c, c->machine->stackSyncRegister(c, v->index)); } } @@ -240,7 +461,7 @@ class SyncForJumpEvent: public Event { src->value->release(c, src); src->target->acquire(c, dst); - if (not equal(c, src->target, src->value)) { + if (not src->target->equals(src->value)) { src->value->apply(c, Move, src->size, src->target); } @@ -251,6 +472,13 @@ class SyncForJumpEvent: public Event { MyOperand* dst; }; +void +appendSyncForJump(Context* c, MyOperand* src, MyOperand* dst) +{ + new (c->zone->allocate(sizeof(SyncForJumpEvent))) + SyncForJumpEvent(c, src, dst); +} + class CallEvent: public Event { public: CallEvent(Context* c, MyOperand* address, MyOperand* result, @@ -279,17 +507,15 @@ class CallEvent: public Event { address->value->release(c, address); if (result->event) { - if (BytesPerWord == 4 and result->size == 8) { - result->value = register_(c, ReturnLowRegister, ReturnHighRegister); - } else { - result->value = register_(c, ReturnLowRegister); - } + result->value = register_ + (c, c->machine->returnLow(), c->machine->returnHigh()); result->value->acquire(c, result); } register_(c, StackRegister)->accept (c, LoadAddress, BytesPerWord, - memory(c, rbp, stackOffset * BytesPerWord, 0, 0, 0)); + memory(c, c->machine->base(), stackOffset * BytesPerWord, + NoRegister, 0, 0)); address->value->apply(c, Call); } @@ -301,6 +527,33 @@ class CallEvent: public Event { TraceHandler* traceHandler; }; +void +appendCall(Context* c, MyOperand* address, MyOperand* result, + unsigned stackOffset, bool alignCall, + TraceHandler* traceHandler) +{ + new (c->zone->allocate(sizeof(CallEvent))) + CallEvent(c, address, result, alignCall, traceHandler); +} + +int +freeRegister(Context* c) +{ + for (unsigned i = 0; i < c->machine->registerCount(); ++i) { + if ((not c->registers[i].reserved) + and c->registers[i].operand == 0) + { + return i; + } + } + + for (unsigned i = 0; i < c->machine->registerCount(); ++i) { + if (not c->registers[i].reserved) { + return i; + } + } +} + class MoveEvent: public Event { public: MoveEvent(Context* c, OperationType type, MyOperand* src, MyOperand* dst): @@ -321,7 +574,11 @@ class MoveEvent: public Event { virtual void compile(Context* c) { if (src->target == 0) { - src->target = freeRegister(c); + if (BytesPerWord == 4 and src->size == 8) { + src->target = register_(c, freeRegister(c), freeRegister(c)); + } else { + src->target = register_(c, freeRegister(c)); + } } src->value->release(c, src); @@ -337,6 +594,12 @@ class MoveEvent: public Event { MyOperand* dst; }; +void +appendMove(Context* c, OperationType type, MyOperand* src, MyOperand* dst) +{ + new (c->zone->allocate(sizeof(MoveEvent))) MoveEvent(c, type, src, dst); +} + class BranchEvent: public Event { public: BranchEvent(Context* c, OperationType type, MyOperand* a, MyOperand* b, @@ -367,7 +630,7 @@ class BranchEvent: public Event { address->value->release(c, address); a->value->apply(c, Compare, a->size, b->value); - address->value->apply(c, type); + address->value->apply(c, type, address->size); } OperationType type; @@ -376,6 +639,14 @@ class BranchEvent: public Event { MyOperand* address; }; +void +appendBranch(Context* c, MoveType type, MyOperand* a, MyOperand* b, + MyOperand* address) +{ + new (c->zone->allocate(sizeof(BranchEvent))) + BranchEvent(c, type, a, b, address); +} + class JumpEvent: public Event { public: Jumpvent(Context* c, MyOperand* address): @@ -397,7 +668,7 @@ class JumpEvent: public Event { virtual void compile(Context* c) { address->value->release(c, address); - address->value->apply(c, Jump); + address->value->apply(c, Jump, address->size); } MyOperand* address; @@ -406,6 +677,12 @@ class JumpEvent: public Event { TraceHandler* traceHandler; }; +void +appendJump(Context* c, MyOperand* address) +{ + new (c->zone->allocate(sizeof(BranchEvent))) JumpEvent(c, address); +} + class CombineEvent: public Event { public: CombineEvent(Context* c, OperationType type, MyOperand* a, MyOperand* b, @@ -414,20 +691,23 @@ class CombineEvent: public Event { { } virtual Value* target(Context* c, MyOperand* v) { - if (v == a) { - switch (type) { - case ShiftLeft: - case ShiftRight: - case UnsignedShiftLeft: - return register_(c, rcx); + int aLow, aHigh, bLow, bHigh; + c->machine->getTargets(c, v->size, &aLow, &aHigh, &bLow, &bHigh); - default: + if (v == a) { + if (aLow == NoRegister) { return 0; + } else { + return register_(c, aLow, aHigh); } } else { assert(c, v == b); - return result->event->target(c, result); + if (bLow == NoRegister) { + return result->event->target(c, result); + } else { + return register_(c, aLow, aHigh); + } } } @@ -447,7 +727,7 @@ class CombineEvent: public Event { b->value->release(c, b); b->value->acquire(c, result); - if (a->target and a->target != a->value) { + if (a->target and not a->target->equals(a->value)) { a->value->apply(c, Move, a->size, a->target); } a->value->apply(c, type, a->size, b->value); @@ -461,6 +741,14 @@ class CombineEvent: public Event { MyOperand* result; }; +void +appendCombine(Context* c, MoveType type, MyOperand* a, MyOperand* b, + MyOperand* result) +{ + new (c->zone->allocate(sizeof(CombineEvent))) + CombineEvent(c, type, a, b, result); +} + class TranslateEvent: public Event { public: TranslateEvent(Context* c, OperationType type, MyOperand* a, @@ -493,6 +781,13 @@ class TranslateEvent: public Event { MyOperand* result; }; +void +appendTranslate(Context* c, MoveType type, MyOperand* a, MyOperand* result) +{ + new (c->zone->allocate(sizeof(TranslateEvent))) + TranslateEvent(c, type, a, result); +} + class Junction { public: Junction(unsigned logicalIp, MyOperand* stack, Junction* next): @@ -506,6 +801,34 @@ class Junction { Junction* next; }; +void +RegisterValue::accept(Context* c, OperationType op, unsigned size, + MemoryValue* a) +{ + c->machine->appendMR(op, size, a->base, a->offset, a->index, a->scale, + a->traceHandler, low, high); +} + +void +preserve(Context* c, int reg) +{ + MyOperand* a = c->registers[reg].operand; + if (a) { + MemoryValue* dst = memory + (c, machine->base(), (a->index + c->stackOffset) * BytesPerWord, + -1, 0, 0); + + c->machine->appendRM + (Move, a->size, + static_cast(a->value)->low, + static_cast(a->value)->high, + dst->base, dst->offset, dst->index, dst->scale, dst->traceHandler); + + a->value = dst; + c->registers[reg].operand = 0; + } +} + MyOperand* operand(Context* c) { @@ -541,62 +864,6 @@ pop(Context* c) return o; } -void -appendArgument(Context* c, MyOperand* value, unsigned index) -{ - new (c->zone->allocate(sizeof(ArgumentEvent))) - ArgumentEvent(c, value, index); -} - -void -appendReturn(Context* c, MyOperand* value) -{ - new (c->zone->allocate(sizeof(ReturnEvent))) ReturnEvent(c, value); -} - -void -appendMove(Context* c, MoveType type, MyOperand* src, MyOperand* dst) -{ - new (c->zone->allocate(sizeof(MoveEvent))) MoveEvent(c, type, src, dst); -} - -void -appendBranch(Context* c, MoveType type, MyOperand* a, MyOperand* b, - MyOperand* address) -{ - new (c->zone->allocate(sizeof(BranchEvent))) - BranchEvent(c, type, a, b, address); -} - -void -appendJump(Context* c, MyOperand* address) -{ - new (c->zone->allocate(sizeof(BranchEvent))) JumpEvent(c, address); -} - -void -appendCombine(Context* c, MoveType type, MyOperand* a, MyOperand* b, - MyOperand* result) -{ - new (c->zone->allocate(sizeof(CombineEvent))) - CombineEvent(c, type, a, b, result); -} - -void -appendTranslate(Context* c, MoveType type, MyOperand* a, MyOperand* result) -{ - new (c->zone->allocate(sizeof(TranslateEvent))) - TranslateEvent(c, type, a, result); -} - -void -appendCall(Context* c, MyOperand* address, MyOperand* result, bool alignCall, - TraceHandler* traceHandler) -{ - new (c->zone->allocate(sizeof(CallEvent))) - CallEvent(c, address, result, alignCall, traceHandler); -} - void syncStack(Context* c, MoveType type) { @@ -612,7 +879,11 @@ syncStack(Context* c, MoveType type) new_ = n; new_->index = old->index; - appendMove(&c, SyncForCall, old, new_); + if (type == SyncForCall) { + appendSyncForCall(&c, old, new_); + } else { + appendSyncForJump(&c, old, new_); + } } c->state->stack = top; @@ -639,8 +910,8 @@ updateJunctions(Context* c) } p->lastEvent = p->lastEvent->next = new - (c->zone->allocate(sizeof(MoveEvent))) - MoveEvent(p->lastEvent->next, SyncForJump, old, new_); + (c->zone->allocate(sizeof(SyncForJumpEvent))) + SyncForJumpEvent(p->lastEvent->next, old, new_); } } }