aboutsummaryrefslogtreecommitdiffstats
path: root/src/llvm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/llvm.cpp')
-rw-r--r--src/llvm.cpp70
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;
}