From c10b039113a618b6b0851260430985a64da4d826 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 20 Jun 2009 19:15:30 +0000 Subject: More sanification of front/back end separation. git-svn-id: http://svn.drobilla.net/resp/tuplr@138 ad02d1e2-f140-0410-9f75-f8b11f17cedd --- llvm.cpp | 130 ++++++++++++++++++++++++++++++-------------------------------- tuplr.cpp | 8 +++- tuplr.hpp | 3 ++ 3 files changed, 72 insertions(+), 69 deletions(-) diff --git a/llvm.cpp b/llvm.cpp index b40f953..efbd454 100644 --- a/llvm.cpp +++ b/llvm.cpp @@ -35,8 +35,8 @@ using namespace llvm; using namespace std; using boost::format; -inline Value* llVal(CValue v) { return static_cast(v); } -inline Function* llFunc(CFunction f) { return static_cast(f); } +static inline Value* llVal(CValue v) { return static_cast(v); } +static inline Function* llFunc(CFunction f) { return static_cast(f); } static const Type* llType(const AType* t) @@ -50,9 +50,13 @@ llType(const AType* t) return NULL; // non-primitive type } + +/*************************************************************************** + * Engine * + ***************************************************************************/ + struct LLVMEngine { - LLVMEngine() - : module(new Module("tuplr")), engine(ExecutionEngine::create(module)) + LLVMEngine() : module(new Module("tuplr")), engine(ExecutionEngine::create(module)) { // Host provided allocation primitive prototype std::vector argsT(1, Type::Int32Ty); // unsigned size @@ -68,7 +72,7 @@ struct LLVMEngine { }; static LLVMEngine* -llengine(CEnv& cenv) +llEngine(CEnv& cenv) { return reinterpret_cast(cenv.engine()); } @@ -98,6 +102,7 @@ CEnv::CEnv(PEnv& p, TEnv& t, CEngine e, ostream& os, ostream& es) CEnv::~CEnv() { + Object::pool.collect(GC::Roots()); delete _pimpl; } @@ -156,7 +161,7 @@ startFunction(CEnv& cenv, const std::string& name, const AType* retT, const ATup THROW_IF(!llType(retT), Cursor(), "function return is untyped"); FunctionType* fT = FunctionType::get(llType(retT), cprot, false); - Function* f = Function::Create(fT, linkage, name, llengine(cenv)->module); + Function* f = Function::Create(fT, linkage, name, llEngine(cenv)->module); if (f->getName() != name) { cenv.out << "DIFFERENT NAME: " << f->getName() << endl; @@ -171,7 +176,7 @@ startFunction(CEnv& cenv, const std::string& name, const AType* retT, const ATup a->setName(argNames.at(i)); BasicBlock* bb = BasicBlock::Create("entry", f); - llengine(cenv)->builder.SetInsertPoint(bb); + llEngine(cenv)->builder.SetInsertPoint(bb); return f; } @@ -180,7 +185,7 @@ void finishFunction(CEnv& cenv, CFunction f, CValue ret) { Value* retVal = llVal(ret); - llengine(cenv)->builder.CreateRet(retVal); + llEngine(cenv)->builder.CreateRet(retVal); cenv.optimise(llFunc(f)); } @@ -191,6 +196,39 @@ eraseFunction(CEnv& cenv, CFunction f) llFunc(f)->eraseFromParent(); } +const string +call(CEnv& cenv, CFunction f, AType* retT) +{ + void* fp = llEngine(cenv)->engine->getPointerToFunction(llFunc(f)); + const Type* t = llType(retT); + THROW_IF(!fp, Cursor(), "unable to get function pointer"); + THROW_IF(!t, Cursor(), "function with non-primitive return type called"); + + std::stringstream ss; + if (t == Type::Int32Ty) + ss << ((int32_t (*)())fp)(); + else if (t == Type::FloatTy) + ss << showpoint << ((float (*)())fp)(); + else if (t == Type::Int1Ty) + ss << (((bool (*)())fp)() ? "#t" : "#f"); + else + ss << ((void* (*)())fp)(); + return ss.str(); +} + +CEngine +tuplr_new_engine() +{ + return new LLVMEngine(); +} + +void +tuplr_free_engine(CEngine engine) +{ + delete (LLVMEngine*)engine; +} + + /*************************************************************************** * Code Generation * @@ -290,7 +328,7 @@ AFn::liftCall(CEnv& cenv, const AType& argsT) #ifdef EXPLICIT_STACK_FRAMES - IRBuilder<> builder = llengine(cenv)->builder; + IRBuilder<> builder = llEngine(cenv)->builder; // Scan out definitions for (size_t i = 0; i < size(); ++i) { @@ -388,7 +426,7 @@ ACall::compile(CEnv& cenv) for (size_t i = 0; i < types.size(); ++i) params[i] = llVal(cenv.compile(at(i+1))); - return llengine(cenv)->builder.CreateCall(f, params.begin(), params.end()); + return llEngine(cenv)->builder.CreateCall(f, params.begin(), params.end()); } void @@ -416,7 +454,7 @@ CValue AIf::compile(CEnv& cenv) { typedef vector< pair > Branches; - Function* parent = llengine(cenv)->builder.GetInsertBlock()->getParent(); + Function* parent = llEngine(cenv)->builder.GetInsertBlock()->getParent(); BasicBlock* mergeBB = BasicBlock::Create("endif"); BasicBlock* nextBB = NULL; Branches branches; @@ -426,29 +464,29 @@ AIf::compile(CEnv& cenv) nextBB = BasicBlock::Create((format("else%1%") % ((i+1)/2)).str()); - llengine(cenv)->builder.CreateCondBr(condV, thenBB, nextBB); + llEngine(cenv)->builder.CreateCondBr(condV, thenBB, nextBB); // Emit then block for this condition parent->getBasicBlockList().push_back(thenBB); - llengine(cenv)->builder.SetInsertPoint(thenBB); + llEngine(cenv)->builder.SetInsertPoint(thenBB); Value* thenV = llVal(cenv.compile(at(i+1))); - llengine(cenv)->builder.CreateBr(mergeBB); - branches.push_back(make_pair(thenV, llengine(cenv)->builder.GetInsertBlock())); + llEngine(cenv)->builder.CreateBr(mergeBB); + branches.push_back(make_pair(thenV, llEngine(cenv)->builder.GetInsertBlock())); parent->getBasicBlockList().push_back(nextBB); - llengine(cenv)->builder.SetInsertPoint(nextBB); + llEngine(cenv)->builder.SetInsertPoint(nextBB); } // Emit final else block - llengine(cenv)->builder.SetInsertPoint(nextBB); + llEngine(cenv)->builder.SetInsertPoint(nextBB); Value* elseV = llVal(cenv.compile(at(size() - 1))); - llengine(cenv)->builder.CreateBr(mergeBB); - branches.push_back(make_pair(elseV, llengine(cenv)->builder.GetInsertBlock())); + llEngine(cenv)->builder.CreateBr(mergeBB); + branches.push_back(make_pair(elseV, llEngine(cenv)->builder.GetInsertBlock())); // Emit merge block (Phi node) parent->getBasicBlockList().push_back(mergeBB); - llengine(cenv)->builder.SetInsertPoint(mergeBB); - PHINode* pn = llengine(cenv)->builder.CreatePHI(llType(cenv.type(this)), "ifval"); + llEngine(cenv)->builder.SetInsertPoint(mergeBB); + PHINode* pn = llEngine(cenv)->builder.CreatePHI(llType(cenv.type(this)), "ifval"); FOREACH(Branches::iterator, i, branches) pn->addIncoming(i->first, i->second); @@ -475,9 +513,9 @@ APrimitive::compile(CEnv& cenv) if (n == "/") op = isFloat ? Instruction::FDiv : Instruction::SDiv; if (n == "%") op = isFloat ? Instruction::FRem : Instruction::SRem; if (op != 0) { - Value* val = llengine(cenv)->builder.CreateBinOp(op, a, b); + Value* val = llEngine(cenv)->builder.CreateBinOp(op, a, b); for (size_t i = 3; i < size(); ++i) - val = llengine(cenv)->builder.CreateBinOp(op, val, llVal(cenv.compile(at(i)))); + val = llEngine(cenv)->builder.CreateBinOp(op, val, llVal(cenv.compile(at(i)))); return val; } @@ -491,53 +529,11 @@ APrimitive::compile(CEnv& cenv) if (n == "<=") pred = isFloat ? CmpInst::FCMP_OLE : CmpInst::ICMP_SLE; if (pred != 0) { if (isFloat) - return llengine(cenv)->builder.CreateFCmp(pred, a, b); + return llEngine(cenv)->builder.CreateFCmp(pred, a, b); else - return llengine(cenv)->builder.CreateICmp(pred, a, b); + return llEngine(cenv)->builder.CreateICmp(pred, a, b); } throw Error(loc, "unknown primitive"); } - -/*************************************************************************** - * EVAL/REPL * - ***************************************************************************/ - -const string -call(CEnv& cenv, CFunction f, AType* retT) -{ - void* fp = llengine(cenv)->engine->getPointerToFunction(llFunc(f)); - const Type* t = llType(retT); - THROW_IF(!fp, Cursor(), "unable to get function pointer"); - THROW_IF(!t, Cursor(), "function with non-primitive return type called"); - - std::stringstream ss; - if (t == Type::Int32Ty) - ss << ((int32_t (*)())fp)(); - else if (t == Type::FloatTy) - ss << showpoint << ((float (*)())fp)(); - else if (t == Type::Int1Ty) - ss << (((bool (*)())fp)() ? "#t" : "#f"); - else - ss << ((void* (*)())fp)(); - return ss.str(); -} - -CEnv* -newCenv(PEnv& penv, TEnv& tenv) -{ - LLVMEngine* engine = new LLVMEngine(); - CEnv* cenv = new CEnv(penv, tenv, engine); - - return cenv; -} - -void -freeCenv(CEnv* cenv) -{ - Object::pool.collect(GC::Roots()); - delete (LLVMEngine*)cenv->engine(); - delete cenv; -} - diff --git a/tuplr.cpp b/tuplr.cpp index af7dae1..bc5ea0b 100644 --- a/tuplr.cpp +++ b/tuplr.cpp @@ -374,7 +374,9 @@ main(int argc, char** argv) TEnv tenv(penv); initLang(penv, tenv); - CEnv* cenv = newCenv(penv, tenv); + CEngine engine = tuplr_new_engine(); + CEnv* cenv = new CEnv(penv, tenv, engine); + cenv->push(); Object::pool.lock(); @@ -450,7 +452,9 @@ main(int argc, char** argv) os.close(); } - freeCenv(cenv); + delete cenv; + tuplr_free_engine(engine); + return ret; } diff --git a/tuplr.hpp b/tuplr.hpp index 96a1556..b60d21e 100644 --- a/tuplr.hpp +++ b/tuplr.hpp @@ -560,6 +560,9 @@ CFunction startFunction(CEnv& cenv, const std::string& name, const AType* retT, const ATuple& argsT, const vector argNames=vector()); +CEngine tuplr_new_engine(); +void tuplr_free_engine(CEngine engine); + void finishFunction(CEnv& cenv, CFunction f, CValue ret); void eraseFunction(CEnv& cenv, CFunction f); const string call(CEnv& cenv, CFunction f, AType* retT); -- cgit v1.2.1