aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/llvm.cpp72
1 files changed, 23 insertions, 49 deletions
diff --git a/src/llvm.cpp b/src/llvm.cpp
index 73935bb..e7c8524 100644
--- a/src/llvm.cpp
+++ b/src/llvm.cpp
@@ -224,10 +224,10 @@ struct LLVMEngine : public Engine {
compileIfStart(CEnv& cenv);
void
- compileIfBranch(CEnv& cenv, IfState* state, const AST* cond, const AST* then);
+ compileIfBranch(CEnv& cenv, IfState* state, CVal condV, const AST* then);
CVal
- compileIfEnd(CEnv& cenv, IfState* state, const AST* aelse, const AType* type);
+ compileIfEnd(CEnv& cenv, IfState* state, CVal elseV, const AType* type);
void writeModule(CEnv& cenv, std::ostream& os) {
AssemblyAnnotationWriter writer;
@@ -380,17 +380,15 @@ LLVMEngine::compileIfStart(CEnv& cenv)
}
void
-LLVMEngine::compileIfBranch(CEnv& cenv, IfState* state, const AST* cond, const AST* then)
+LLVMEngine::compileIfBranch(CEnv& cenv, IfState* state, CVal condV, const AST* then)
{
LLVMEngine* engine = reinterpret_cast<LLVMEngine*>(cenv.engine());
- Value* condV = llVal(resp_compile(cenv, cond));
-
- ++labelIndex;
-
BasicBlock* thenBB = BasicBlock::Create(context, (format("then%1%") % labelIndex).str());
BasicBlock* nextBB = BasicBlock::Create(context, (format("else%1%") % labelIndex).str());
- engine->builder.CreateCondBr(condV, thenBB, nextBB);
+ ++labelIndex;
+
+ engine->builder.CreateCondBr(llVal(condV), thenBB, nextBB);
// Emit then block for this condition
appendBlock(engine, state->parent, thenBB);
@@ -402,14 +400,13 @@ LLVMEngine::compileIfBranch(CEnv& cenv, IfState* state, const AST* cond, const A
}
CVal
-LLVMEngine::compileIfEnd(CEnv& cenv, IfState* state, const AST* aelse, const AType* type)
+LLVMEngine::compileIfEnd(CEnv& cenv, IfState* state, CVal elseV, const AType* type)
{
LLVMEngine* engine = reinterpret_cast<LLVMEngine*>(cenv.engine());
- // Emit final else block
- Value* elseV = llVal(resp_compile(cenv, aelse));
+ // Emit end of final else block
engine->builder.CreateBr(state->mergeBB);
- state->branches.push_back(make_pair(elseV, engine->builder.GetInsertBlock()));
+ state->branches.push_back(make_pair(llVal(elseV), engine->builder.GetInsertBlock()));
// Emit merge block (Phi node)
appendBlock(engine, state->parent, state->mergeBB);
@@ -429,63 +426,40 @@ LLVMEngine::compileIf(CEnv& cenv, const ATuple* aif)
if (++next == aif->end())
break;
- compileIfBranch(cenv, state, *i, *next);
+ compileIfBranch(cenv, state, resp_compile(cenv, *i), *next);
i = next; // jump 2 each iteration (to the next predicate)
}
- return compileIfEnd(cenv, state, aif->list_last(), cenv.type(aif));
+ CVal elseV = resp_compile(cenv, aif->list_last());
+ return compileIfEnd(cenv, state, elseV, cenv.type(aif));
}
CVal
LLVMEngine::compileMatch(CEnv& cenv, const ATuple* match)
{
- typedef vector< pair<Value*, BasicBlock*> > Branches;
- Value* matchee = llVal(resp_compile(cenv, match->list_ref(1)));
- Value* rttiPtr = builder.CreateStructGEP(matchee, 0, "matchRTTIPtr");
- Value* rtti = builder.CreateLoad(rttiPtr, 0, "matchRTTI");
-
LLVMEngine* engine = reinterpret_cast<LLVMEngine*>(cenv.engine());
- Function* parent = engine->builder.GetInsertBlock()->getParent();
- BasicBlock* mergeBB = BasicBlock::Create(context, "endmatch");
- BasicBlock* nextBB = NULL;
- Branches branches;
+ IfState* state = compileIfStart(cenv);
+ Value* matchee = llVal(resp_compile(cenv, match->list_ref(1)));
+ Value* rttiPtr = builder.CreateStructGEP(matchee, 0, "matchRTTIPtr");
+ Value* rtti = builder.CreateLoad(rttiPtr, 0, "matchRTTI");
size_t idx = 1;
for (ATuple::const_iterator i = match->iter_at(2); i != match->end(); ++idx) {
const AST* pat = *i++;
const AST* body = *i++;
- const ASymbol* sym = pat->to_tuple()->head()->as_symbol();
+ const ASymbol* sym = pat->as_tuple()->head()->as_symbol();
const AType* patT = new AType(sym, 0, Cursor());
- Value* typeV = llVal(resp_compile(cenv, patT));
- Value* condV = engine->builder.CreateICmp(CmpInst::ICMP_EQ, rtti, typeV);
- BasicBlock* thenBB = BasicBlock::Create(context, (format("case%1%") % ((idx+1)/2)).str());
-
- nextBB = BasicBlock::Create(context, (format("otherwise%1%") % ((idx+1)/2)).str());
+ Value* typeV = llVal(resp_compile(cenv, patT));
+ Value* condV = engine->builder.CreateICmp(CmpInst::ICMP_EQ, rtti, typeV);
- engine->builder.CreateCondBr(condV, thenBB, nextBB);
-
- // Emit then block for this condition
- appendBlock(engine, parent, thenBB);
- Value* thenV = llVal(resp_compile(cenv, body));
- engine->builder.CreateBr(mergeBB);
- branches.push_back(make_pair(thenV, engine->builder.GetInsertBlock()));
-
- appendBlock(engine, parent, nextBB);
+ compileIfBranch(cenv, state, condV, body);
}
- // Emit final else block (FIXME: n/a, what to do here?)
- engine->builder.CreateBr(mergeBB);
- branches.push_back(make_pair(Constant::getNullValue(llType(cenv.type(match))), engine->builder.GetInsertBlock()));
-
- // Emit merge block (Phi node)
- appendBlock(engine, parent, mergeBB);
- PHINode* pn = engine->builder.CreatePHI(llType(cenv.type(match)), "mergeval");
- FOREACH(Branches::iterator, i, branches)
- pn->addIncoming(i->first, i->second);
-
- return pn;
+ const AType* type = cenv.type(match);
+ CVal elseV = Constant::getNullValue(llType(type));
+ return compileIfEnd(cenv, state, elseV, type);
}
CVal