aboutsummaryrefslogtreecommitdiffstats
path: root/src/llvm.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-10-06 17:02:44 +0000
committerDavid Robillard <d@drobilla.net>2009-10-06 17:02:44 +0000
commit165fc3638f9666e94c5cfc4fe719697b0ce72774 (patch)
tree00976bf8aae033f04b94875a983f6762e2a5c235 /src/llvm.cpp
parentce95207bc617e6152efe068c1e045b64121803cc (diff)
downloadresp-165fc3638f9666e94c5cfc4fe719697b0ce72774.tar.gz
resp-165fc3638f9666e94c5cfc4fe719697b0ce72774.tar.bz2
resp-165fc3638f9666e94c5cfc4fe719697b0ce72774.zip
Split backend specific compilation functions from generic ones.
git-svn-id: http://svn.drobilla.net/resp/tuplr@191 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'src/llvm.cpp')
-rw-r--r--src/llvm.cpp123
1 files changed, 14 insertions, 109 deletions
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 <map>
@@ -155,6 +159,11 @@ struct LLVMEngine : public Engine {
llFunc(f)->eraseFromParent();
}
+ CValue compileCall(CEnv& cenv, CFunction f, const vector<CValue>& args) {
+ const vector<Value*>& llArgs = *reinterpret_cast<const vector<Value*>*>(&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<CT>::compile(CEnv& cenv) { return (COMPILED); } \
-template<> void \
-ALiteral<CT>::constrain(TEnv& tenv, Constraints& c) const { \
- c.constrain(tenv, this, tenv.named(NAME)); \
-}
+#define COMPILE_LITERAL(CT, COMPILED) \
+template<> CValue ALiteral<CT>::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<ASymbol*>(), *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<AType*>();
- 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<AFn*>();
- 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<AFn*>();
-
- if (!c) return NULL; // Primitive
-
- AType protT(loc);
- vector<const Type*> 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<Value*> 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<AFn*>();
- 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)
{