aboutsummaryrefslogtreecommitdiffstats
path: root/llvm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm.cpp')
-rw-r--r--llvm.cpp130
1 files changed, 63 insertions, 67 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<Value*>(v); }
-inline Function* llFunc(CFunction f) { return static_cast<Function*>(f); }
+static inline Value* llVal(CValue v) { return static_cast<Value*>(v); }
+static inline Function* llFunc(CFunction f) { return static_cast<Function*>(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<const Type*> argsT(1, Type::Int32Ty); // unsigned size
@@ -68,7 +72,7 @@ struct LLVMEngine {
};
static LLVMEngine*
-llengine(CEnv& cenv)
+llEngine(CEnv& cenv)
{
return reinterpret_cast<LLVMEngine*>(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<Value*, BasicBlock*> > 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;
-}
-