explode Subroutines in compile.cpp rather than handling them in Compiler

This commit is contained in:
Joshua Warner 2014-05-03 19:09:55 -06:00 committed by Joshua Warner
parent 14c960ac6a
commit 5ad1a14a73
7 changed files with 391 additions and 724 deletions

View File

@ -42,19 +42,15 @@ class Compiler {
static const unsigned LongJumpOrCall = 1 << 3;
class State { };
class Subroutine { };
virtual State* saveState() = 0;
virtual void restoreState(State* state) = 0;
virtual Subroutine* startSubroutine() = 0;
virtual void returnFromSubroutine(Subroutine* subroutine, ir::Value* address)
= 0;
virtual void linkSubroutine(Subroutine* subroutine) = 0;
virtual void init(unsigned logicalCodeSize, unsigned parameterFootprint,
unsigned localFootprint, unsigned alignedFrameSize) = 0;
virtual void extendLogicalCode(unsigned more) = 0;
virtual void visitLogicalIp(unsigned logicalIp) = 0;
virtual void startLogicalIp(unsigned logicalIp) = 0;
@ -76,7 +72,7 @@ class Compiler {
virtual void push(ir::Type type, ir::Value* value) = 0;
virtual void save(ir::Type type, ir::Value* value) = 0;
virtual ir::Value* pop(ir::Type type) = 0;
virtual void pushed() = 0;
virtual void pushed(ir::Type type) = 0;
virtual void popped(unsigned footprint) = 0;
virtual unsigned topOfStack() = 0;
virtual ir::Value* peek(unsigned footprint, unsigned index) = 0;

View File

@ -2141,27 +2141,9 @@ class MyCompiler: public Compiler {
compiler::restoreState(&c, static_cast<ForkState*>(state));
}
virtual Subroutine* startSubroutine() {
return c.subroutine = new(c.zone) MySubroutine;
}
virtual void returnFromSubroutine(Subroutine* subroutine, ir::Value* address)
{
appendSaveLocals(&c);
appendJump(&c, lir::Jump, static_cast<Value*>(address), false, true);
static_cast<MySubroutine*>(subroutine)->forkState = compiler::saveState(&c);
}
virtual void linkSubroutine(Subroutine* subroutine) {
Local* oldLocals = c.locals;
restoreState(static_cast<MySubroutine*>(subroutine)->forkState);
linkLocals(&c, oldLocals, c.locals);
}
virtual void init(unsigned logicalCodeLength, unsigned parameterFootprint,
unsigned localFootprint, unsigned alignedFrameSize)
{
c.logicalCodeLength = logicalCodeLength;
c.parameterFootprint = parameterFootprint;
c.localFootprint = localFootprint;
c.alignedFrameSize = alignedFrameSize;
@ -2180,23 +2162,23 @@ class MyCompiler: public Compiler {
c.frameResources[base + c.arch->framePointerOffset()].reserved
= UseFramePointer;
// leave room for logical instruction -1
unsigned codeSize = sizeof(LogicalInstruction*) * (logicalCodeLength + 1);
c.logicalCode = static_cast<LogicalInstruction**>
(c.zone->allocate(codeSize));
memset(c.logicalCode, 0, codeSize);
c.logicalCode++;
c.logicalCode.init(c.zone, logicalCodeLength);
c.logicalCode[-1] = new (c.zone) LogicalInstruction(-1, c.stack, c.locals);
c.locals = static_cast<Local*>
(c.zone->allocate(sizeof(Local) * localFootprint));
memset(c.locals, 0, sizeof(Local) * localFootprint);
}
c.logicalCode[-1] = new(c.zone) LogicalInstruction(-1, c.stack, c.locals);
virtual void extendLogicalCode(unsigned more)
{
c.logicalCode.extend(c.zone, more);
}
virtual void visitLogicalIp(unsigned logicalIp) {
assert(&c, logicalIp < c.logicalCodeLength);
assert(&c, logicalIp < c.logicalCode.count());
if (c.logicalCode[c.logicalIp]->lastEvent == 0) {
appendDummy(&c);
@ -2228,17 +2210,11 @@ class MyCompiler: public Compiler {
populateJunctionReads(&c, link);
}
if (c.subroutine) {
c.subroutine->forkState
= c.logicalCode[logicalIp]->subroutine->forkState;
c.subroutine = 0;
}
c.forkState = 0;
}
virtual void startLogicalIp(unsigned logicalIp) {
assert(&c, logicalIp < c.logicalCodeLength);
assert(&c, logicalIp < c.logicalCode.count());
assert(&c, c.logicalCode[logicalIp] == 0);
if (c.logicalCode[c.logicalIp]->lastEvent == 0) {
@ -2253,30 +2229,7 @@ class MyCompiler: public Compiler {
c.logicalCode[logicalIp] = new(c.zone) LogicalInstruction(logicalIp, c.stack, c.locals);
bool startSubroutine = c.subroutine != 0;
if (startSubroutine) {
c.logicalCode[logicalIp]->subroutine = c.subroutine;
c.subroutine = 0;
}
c.logicalIp = logicalIp;
if (startSubroutine) {
// assume all local variables are initialized on entry to a
// subroutine, since other calls to the subroutine may
// initialize them:
unsigned sizeInBytes = sizeof(Local) * c.localFootprint;
Local* newLocals = static_cast<Local*>(c.zone->allocate(sizeInBytes));
memcpy(newLocals, c.locals, sizeInBytes);
c.locals = newLocals;
for (unsigned li = 0; li < c.localFootprint; ++li) {
Local* local = c.locals + li;
if (local->value == 0) {
initLocal(1, li, ir::Type(ir::Type::Invalid, TargetBytesPerWord));
}
}
}
}
virtual Promise* machineIp(unsigned logicalIp) {
@ -2377,8 +2330,9 @@ class MyCompiler: public Compiler {
return value;
}
virtual void pushed() {
Value* v = value(&c, ir::Type(ir::Type::Object, TargetBytesPerWord));
virtual void pushed(ir::Type type)
{
Value* v = value(&c, type);
appendFrameSite
(&c, v, frameIndex
(&c, (c.stack ? c.stack->index : 0) + c.localFootprint));
@ -2570,7 +2524,7 @@ class MyCompiler: public Compiler {
}
virtual void initLocalsFromLogicalIp(unsigned logicalIp) {
assert(&c, logicalIp < c.logicalCodeLength);
assert(&c, logicalIp < c.logicalCode.count());
unsigned footprint = sizeof(Local) * c.localFootprint;
Local* newLocals = static_cast<Local*>(c.zone->allocate(footprint));
@ -2599,7 +2553,9 @@ class MyCompiler: public Compiler {
}
virtual void saveLocals() {
int oldIp UNUSED = c.logicalIp;
appendSaveLocals(&c);
assert(&c, oldIp == c.logicalIp);
}
virtual void checkBounds(ir::Value* object,

View File

@ -28,7 +28,6 @@ Context::Context(vm::System* system, Assembler* assembler, vm::Zone* zone,
locals(0),
saved(0),
predecessor(0),
logicalCode(0),
regFile(arch->registerFile()),
regAlloc(system, arch->registerFile()),
registerResources
@ -42,11 +41,9 @@ Context::Context(vm::System* system, Assembler* assembler, vm::Zone* zone,
firstEvent(0),
lastEvent(0),
forkState(0),
subroutine(0),
firstBlock(0),
logicalIp(-1),
constantCount(0),
logicalCodeLength(0),
parameterFootprint(0),
localFootprint(0),
machineCodeSize(0),

View File

@ -35,7 +35,6 @@ class FrameResource;
class ConstantPoolNode;
class ForkState;
class MySubroutine;
class Block;
template<class T>
@ -50,6 +49,48 @@ List<T>* reverseDestroy(List<T>* cell) {
return previous;
}
class LogicalCode {
private:
util::Slice<LogicalInstruction*> logicalCode;
public:
LogicalCode() : logicalCode(0, 0)
{
}
void init(vm::Zone* zone, size_t count)
{
// leave room for logical instruction -1
size_t realCount = count + 1;
logicalCode
= util::Slice<LogicalInstruction*>::allocAndSet(zone, realCount, 0);
}
void extend(vm::Zone* zone, size_t more)
{
util::Slice<LogicalInstruction*> newCode
= logicalCode.cloneAndSet(zone, logicalCode.count + more, 0);
for (size_t i = 0; i < logicalCode.count; i++) {
assert((vm::System*)0, logicalCode[i] == newCode[i]);
}
logicalCode = newCode;
}
size_t count()
{
return logicalCode.count - 1;
}
LogicalInstruction*& operator[](int index)
{
// leave room for logical instruction -1
return logicalCode[index + 1];
}
};
class Context {
public:
Context(vm::System* system, Assembler* assembler, vm::Zone* zone,
@ -64,7 +105,7 @@ class Context {
Local* locals;
List<Value*>* saved;
Event* predecessor;
LogicalInstruction** logicalCode;
LogicalCode logicalCode;
const RegisterFile* regFile;
RegisterAllocator regAlloc;
RegisterResource* registerResources;
@ -76,11 +117,9 @@ class Context {
Event* firstEvent;
Event* lastEvent;
ForkState* forkState;
MySubroutine* subroutine;
Block* firstBlock;
int logicalIp;
unsigned constantCount;
unsigned logicalCodeLength;
unsigned parameterFootprint;
unsigned localFootprint;
unsigned machineCodeSize;

View File

@ -15,14 +15,19 @@ namespace avian {
namespace codegen {
namespace compiler {
LogicalInstruction::LogicalInstruction(int index, Stack* stack, Local* locals):
firstEvent(0), lastEvent(0), immediatePredecessor(0), stack(stack),
locals(locals), machineOffset(0), subroutine(0), index(index)
LogicalInstruction::LogicalInstruction(int index, Stack* stack, Local* locals)
: firstEvent(0),
lastEvent(0),
immediatePredecessor(0),
stack(stack),
locals(locals),
machineOffset(0),
/*subroutine(0), */ index(index)
{ }
LogicalInstruction* LogicalInstruction::next(Context* c) {
LogicalInstruction* i = this;
for (unsigned n = i->index + 1; n < c->logicalCodeLength; ++n) {
for (size_t n = i->index + 1; n < c->logicalCode.count(); ++n) {
i = c->logicalCode[n];
if (i) return i;
}

View File

@ -57,17 +57,9 @@ class LogicalInstruction {
Stack* stack;
Local* locals;
Promise* machineOffset;
MySubroutine* subroutine;
int index;
};
class MySubroutine: public Compiler::Subroutine {
public:
MySubroutine(): forkState(0) { }
ForkState* forkState;
};
class Block {
public:
Block(Event* head);

File diff suppressed because it is too large Load Diff