diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/llvm.cpp | 72 |
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 |