From 165fc3638f9666e94c5cfc4fe719697b0ce72774 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Tue, 6 Oct 2009 17:02:44 +0000 Subject: Split backend specific compilation functions from generic ones. git-svn-id: http://svn.drobilla.net/resp/tuplr@191 ad02d1e2-f140-0410-9f75-f8b11f17cedd --- src/llvm.cpp | 123 +++++++---------------------------------------------------- 1 file changed, 14 insertions(+), 109 deletions(-) (limited to 'src/llvm.cpp') diff --git a/src/llvm.cpp b/src/llvm.cpp index ec2c2a4..36f639f 100644 --- a/src/llvm.cpp +++ b/src/llvm.cpp @@ -17,6 +17,10 @@ /** @file * @brief Compile AST to LLVM IR + * + * Compilation pass functions (lift/compile) that require direct use of LLVM + * specific things are implemented here. Generic compilation pass functions + * are implemented in compile.cpp. */ #include @@ -155,6 +159,11 @@ struct LLVMEngine : public Engine { llFunc(f)->eraseFromParent(); } + CValue compileCall(CEnv& cenv, CFunction f, const vector& args) { + const vector& llArgs = *reinterpret_cast*>(&args); + return builder.CreateCall(llFunc(f), llArgs.begin(), llArgs.end()); + } + void writeModule(CEnv& cenv, std::ostream& os) { AssemblyAnnotationWriter writer; module->print(os, &writer); @@ -211,44 +220,13 @@ tuplr_free_engine(Engine* engine) * Code Generation * ***************************************************************************/ -#define LITERAL(CT, NAME, COMPILED) \ -template<> CValue ALiteral::compile(CEnv& cenv) { return (COMPILED); } \ -template<> void \ -ALiteral::constrain(TEnv& tenv, Constraints& c) const { \ - c.constrain(tenv, this, tenv.named(NAME)); \ -} +#define COMPILE_LITERAL(CT, COMPILED) \ +template<> CValue ALiteral::compile(CEnv& cenv) { return (COMPILED); } // Literal template instantiations -LITERAL(int32_t, "Int", ConstantInt::get(Type::Int32Ty, val, true)) -LITERAL(float, "Float", ConstantFP::get(Type::FloatTy, val)) -LITERAL(bool, "Bool", ConstantInt::get(Type::Int1Ty, val, false)) - -CValue -ASymbol::compile(CEnv& cenv) -{ - return cenv.vals.ref(this); -} - -void -AFn::lift(CEnv& cenv) -{ - cenv.push(); - for (const_iterator p = prot()->begin(); p != prot()->end(); ++p) - cenv.def((*p)->as(), *p, NULL, NULL); - - // Lift body - for (size_t i = 2; i < size(); ++i) - at(i)->lift(cenv); - - cenv.pop(); - - AType* type = cenv.type(this); - if (impls.find(type) || !type->concrete()) - return; - - AType* protT = type->at(1)->as(); - liftCall(cenv, *protT); -} +COMPILE_LITERAL(int32_t, ConstantInt::get(Type::Int32Ty, val, true)) +COMPILE_LITERAL(float, ConstantFP::get(Type::FloatTy, val)) +COMPILE_LITERAL(bool, ConstantInt::get(Type::Int1Ty, val, false)) void AFn::liftCall(CEnv& cenv, const AType& argsT) @@ -404,79 +382,6 @@ AFn::compile(CEnv& cenv) return tupPtr;*/ } -void -ACall::lift(CEnv& cenv) -{ - AFn* c = cenv.tenv.resolve(at(0))->to(); - AType argsT(loc); - - // Lift arguments - for (size_t i = 1; i < size(); ++i) { - at(i)->lift(cenv); - argsT.push_back(cenv.type(at(i))); - } - - if (!c) return; // Primitive - - if (c->prot()->size() < size() - 1) - throw Error(loc, (format("too many arguments to function `%1%'") % at(0)->str()).str()); - if (c->prot()->size() > size() - 1) - throw Error(loc, (format("too few arguments to function `%1%'") % at(0)->str()).str()); - - c->liftCall(cenv, argsT); // Lift called closure -} - -CValue -ACall::compile(CEnv& cenv) -{ - AFn* c = cenv.tenv.resolve(at(0))->to(); - - if (!c) return NULL; // Primitive - - AType protT(loc); - vector types; - for (size_t i = 1; i < size(); ++i) { - protT.push_back(cenv.type(at(i))); - types.push_back(llType(cenv.type(at(i)))); - } - - TEnv::GenericTypes::const_iterator gt = cenv.tenv.genericTypes.find(c); - assert(gt != cenv.tenv.genericTypes.end()); - AType fnT(loc); - fnT.push_back(cenv.penv.sym("Fn")); - fnT.push_back(&protT); - fnT.push_back(cenv.type(this)); - Function* f = (Function*)c->impls.find(&fnT); - THROW_IF(!f, loc, (format("callee failed to compile for type %1%") % fnT.str()).str()); - - vector params(size() - 1); - 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()); -} - -void -ADef::lift(CEnv& cenv) -{ - // Define stub first for recursion - cenv.def(sym(), at(2), cenv.type(at(2)), NULL); - AFn* c = at(2)->to(); - if (c) - c->name = sym()->str(); - at(2)->lift(cenv); -} - -CValue -ADef::compile(CEnv& cenv) -{ - // Define stub first for recursion - cenv.def(sym(), at(2), cenv.type(at(2)), NULL); - CValue val = cenv.compile(at(size() - 1)); - cenv.vals.def(sym(), val); - return val; -} - CValue AIf::compile(CEnv& cenv) { -- cgit v1.2.1