diff options
Diffstat (limited to 'src/llvm.cpp')
-rw-r--r-- | src/llvm.cpp | 70 |
1 files changed, 24 insertions, 46 deletions
diff --git a/src/llvm.cpp b/src/llvm.cpp index de53baa..69d421a 100644 --- a/src/llvm.cpp +++ b/src/llvm.cpp @@ -66,9 +66,7 @@ struct LLVMEngine : public Engine { CVal compileDot(CEnv& cenv, CVal tup, int32_t index); CVal compileGlobalSet(CEnv& cenv, const string& s, CVal v, const AType* t); CVal compileGlobalGet(CEnv& cenv, const string& s, CVal v); - IfState compileIfStart(CEnv& cenv); - void compileIfBranch(CEnv& cenv, IfState state, CVal condV, const AST* then); - CVal compileIfEnd(CEnv& cenv, IfState state, CVal elseV, const AType* type); + CVal compileIf(CEnv& cenv, const AST* cond, const AST* then, const AST* aelse); CVal compileIsA(CEnv& cenv, CVal rtti, const ASymbol* tag); CVal compileLiteral(CEnv& cenv, const AST* lit); CVal compilePrimitive(CEnv& cenv, const ATuple* prim); @@ -79,16 +77,6 @@ struct LLVMEngine : public Engine { const string call(CEnv& cenv, CFunc f, const AType* retT); private: - typedef pair<Value*, BasicBlock*> IfBranch; - typedef vector<IfBranch> IfBranches; - - struct LLVMIfState { - LLVMIfState(BasicBlock* m, Function* p) : mergeBB(m), parent(p) {} - BasicBlock* mergeBB; - Function* parent; - IfBranches branches; - }; - void appendBlock(LLVMEngine* engine, Function* function, BasicBlock* block) { function->getBasicBlockList().push_back(block); engine->builder.SetInsertPoint(block); @@ -336,53 +324,43 @@ LLVMEngine::eraseFn(CEnv& cenv, CFunc f) llFunc(f)->eraseFromParent(); } -IfState -LLVMEngine::compileIfStart(CEnv& cenv) -{ - LLVMEngine* engine = reinterpret_cast<LLVMEngine*>(cenv.engine()); - return new LLVMIfState(BasicBlock::Create(context, "endif"), - engine->builder.GetInsertBlock()->getParent()); -} - -void -LLVMEngine::compileIfBranch(CEnv& cenv, IfState s, CVal condV, const AST* then) +CVal +LLVMEngine::compileIf(CEnv& cenv, const AST* cond, const AST* then, const AST* aelse) { - LLVMIfState* state = (LLVMIfState*)s; - LLVMEngine* engine = reinterpret_cast<LLVMEngine*>(cenv.engine()); - BasicBlock* thenBB = BasicBlock::Create(context, (format("then%1%") % labelIndex).str()); - BasicBlock* nextBB = BasicBlock::Create(context, (format("else%1%") % labelIndex).str()); - + LLVMEngine* engine = reinterpret_cast<LLVMEngine*>(cenv.engine()); + BasicBlock* mergeBB = BasicBlock::Create(context, "endif"); + Function* parent = engine->builder.GetInsertBlock()->getParent(); + BasicBlock* thenBB = BasicBlock::Create(context, (format("then%1%") % labelIndex).str()); + BasicBlock* nextBB = BasicBlock::Create(context, (format("else%1%") % labelIndex).str()); + + const AType* type = cenv.type(then); + ++labelIndex; - engine->builder.CreateCondBr(llVal(condV), thenBB, nextBB); + engine->builder.CreateCondBr(llVal(resp_compile(cenv, cond)), thenBB, nextBB); // Emit then block for this condition - appendBlock(engine, state->parent, thenBB); + appendBlock(engine, parent, thenBB); Value* thenV = llVal(resp_compile(cenv, then)); - engine->builder.CreateBr(state->mergeBB); - state->branches.push_back(make_pair(thenV, thenBB)); - - appendBlock(engine, state->parent, nextBB); -} + engine->builder.CreateBr(mergeBB); -CVal -LLVMEngine::compileIfEnd(CEnv& cenv, IfState s, CVal elseV, const AType* type) -{ - LLVMIfState* state = (LLVMIfState*)s; - LLVMEngine* engine = reinterpret_cast<LLVMEngine*>(cenv.engine()); + appendBlock(engine, parent, nextBB); - if (!elseV) + Value* elseV = NULL; + if (aelse) + elseV = llVal(resp_compile(cenv, aelse)); + else elseV = Constant::getNullValue(llType(type)); // Emit end of final else block - engine->builder.CreateBr(state->mergeBB); - state->branches.push_back(make_pair(llVal(elseV), engine->builder.GetInsertBlock())); + engine->builder.CreateBr(mergeBB); + BasicBlock* elseBB = engine->builder.GetInsertBlock(); // Emit merge block (Phi node) - appendBlock(engine, state->parent, state->mergeBB); + appendBlock(engine, parent, mergeBB); PHINode* pn = engine->builder.CreatePHI(llType(type), "ifval"); - FOREACH(IfBranches::iterator, i, state->branches) - pn->addIncoming(i->first, i->second); + pn->addIncoming(thenV, thenBB); + pn->addIncoming(elseV, elseBB); return pn; } |