aboutsummaryrefslogtreecommitdiffstats
path: root/src/llvm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/llvm.cpp')
-rw-r--r--src/llvm.cpp88
1 files changed, 39 insertions, 49 deletions
diff --git a/src/llvm.cpp b/src/llvm.cpp
index 5b6d69f..6243919 100644
--- a/src/llvm.cpp
+++ b/src/llvm.cpp
@@ -123,7 +123,7 @@ struct LLVMEngine : public Engine {
return PointerType::get(StructType::get(context, ctypes, false), 0);
}
- return NULL; // non-primitive type
+ return PointerType::get(Type::getVoidTy(context), NULL);
}
CFunc startFunction(CEnv& cenv,
@@ -161,13 +161,12 @@ struct LLVMEngine : public Engine {
return f;
}
- void finishFunction(CEnv& cenv, CFunc f, const AType* retT, CVal ret) {
- if (retT->concrete())
- builder.CreateRet(llVal(ret));
- else
- builder.CreateRetVoid();
-
- verifyFunction(*static_cast<Function*>(f));
+ void finishFunction(CEnv& cenv, CFunc f, CVal ret) {
+ builder.CreateRet(llVal(ret));
+ if (verifyFunction(*static_cast<Function*>(f), llvm::PrintMessageAction)) {
+ module->dump();
+ throw Error(Cursor(), "Broken module");
+ }
if (cenv.args.find("-g") == cenv.args.end())
opt->run(*static_cast<Function*>(f));
}
@@ -177,19 +176,23 @@ struct LLVMEngine : public Engine {
llFunc(f)->eraseFromParent();
}
- CVal compileCall(CEnv& cenv, CFunc f, const vector<CVal>& args) {
- const vector<Value*>& llArgs = *reinterpret_cast<const vector<Value*>*>(&args);
+ CVal compileCall(CEnv& cenv, CFunc f, const AType* funcT, const vector<CVal>& args) {
+ vector<Value*> llArgs(*reinterpret_cast<const vector<Value*>*>(&args));
+ Value* closure = builder.CreateBitCast(llArgs[0],
+ llType(funcT->prot()->head()->as<const AType*>()),
+ cenv.penv.gensymstr("you"));
+ llArgs[0] = closure;
return builder.CreateCall(llFunc(f), llArgs.begin(), llArgs.end());
}
- CFunc compileFunction(CEnv& cenv, AFn* fn, const AType& argsT);
+ CFunc compileFunction(CEnv& cenv, AFn* fn, const AType* type);
CVal compileTup(CEnv& cenv, const AType* type, const vector<CVal>& fields);
CVal compileDot(CEnv& cenv, CVal tup, int32_t index);
CVal compileLiteral(CEnv& cenv, AST* lit);
CVal compilePrimitive(CEnv& cenv, APrimitive* prim);
CVal compileIf(CEnv& cenv, AIf* aif);
- CVal compileGlobal(CEnv& cenv, AType* type, const string& name, CVal val);
+ CVal compileGlobal(CEnv& cenv, const AType* type, const string& name, CVal val);
CVal getGlobal(CEnv& cenv, CVal val);
void writeModule(CEnv& cenv, std::ostream& os) {
@@ -197,7 +200,7 @@ struct LLVMEngine : public Engine {
module->print(os, &writer);
}
- const string call(CEnv& cenv, CFunc f, AType* retT) {
+ const string call(CEnv& cenv, CFunc f, const AType* retT) {
void* fp = engine->getPointerToFunction(llFunc(f));
const Type* t = llType(retT);
THROW_IF(!fp, Cursor(), "unable to get function pointer");
@@ -248,8 +251,9 @@ LLVMEngine::compileTup(CEnv& cenv, const AType* type, const vector<CVal>& fields
{
// Find size of memory required
size_t s = 0;
+ assert(type->begin() != type->end());
for (AType::const_iterator i = type->begin() + 1; i != type->end(); ++i)
- s += llType((*i)->as<AType*>())->getPrimitiveSizeInBits();
+ s += engine->getTargetData()->getTypeSizeInBits(llType((*i)->as<AType*>()));
// Allocate struct
Value* structSize = ConstantInt::get(Type::getInt32Ty(context), bitsToBytes(s));
@@ -259,8 +263,8 @@ LLVMEngine::compileTup(CEnv& cenv, const AType* type, const vector<CVal>& fields
// Set struct fields
size_t i = 0;
for (vector<CVal>::const_iterator f = fields.begin(); f != fields.end(); ++f, ++i) {
- Value* v = builder.CreateStructGEP(structPtr, i, (format("tup%1%") % i).str().c_str());
- builder.CreateStore(llVal(*f), v);
+ builder.CreateStore(llVal(*f),
+ builder.CreateStructGEP(structPtr, i, (format("tup%1%") % i).str().c_str()));
}
return structPtr;
@@ -292,28 +296,13 @@ LLVMEngine::compileLiteral(CEnv& cenv, AST* lit)
}
CFunc
-LLVMEngine::compileFunction(CEnv& cenv, AFn* fn, const AType& argsT)
+LLVMEngine::compileFunction(CEnv& cenv, AFn* fn, const AType* type)
{
- LLVMEngine* engine = reinterpret_cast<LLVMEngine*>(cenv.engine());
- AType* genericType = cenv.type(cenv.resolve(fn));
- AType* thisType = genericType;
- Subst argsSubst;
-
- // Build and apply substitution to get concrete type for this call
- if (!genericType->concrete()) {
- argsSubst = cenv.tenv.buildSubst(genericType, argsT);
- thisType = argsSubst.apply(genericType)->as<AType*>();
- }
+ assert(type->concrete());
- THROW_IF(!thisType->concrete(), fn->loc,
- string("call has non-concrete type %1%\n") + thisType->str());
-
- Object::pool.addRoot(thisType);
- Function* f = (Function*)fn->impls.find(thisType);
- if (f)
- return f;
-
- ATuple* protT = thisType->prot();
+ LLVMEngine* engine = reinterpret_cast<LLVMEngine*>(cenv.engine());
+ const AType* argsT = type->prot()->as<const AType*>();
+ const AType* retT = type->last()->as<const AType*>();
vector<string> argNames;
for (ATuple::const_iterator i = fn->prot()->begin(); i != fn->prot()->end(); ++i)
@@ -321,39 +310,40 @@ LLVMEngine::compileFunction(CEnv& cenv, AFn* fn, const AType& argsT)
// Write function declaration
const string name = (fn->name == "") ? cenv.penv.gensymstr("_fn") : fn->name;
- f = llFunc(cenv.engine()->startFunction(cenv, name,
- thisType->last()->to<AType*>(),
- *protT, argNames));
+ Function* f = llFunc(cenv.engine()->startFunction(cenv, name, retT, *argsT, argNames));
cenv.push();
- Subst oldSubst = cenv.tsubst;
- cenv.tsubst = Subst::compose(cenv.tsubst, argsSubst);
// Bind argument values in CEnv
vector<Value*> args;
AFn::const_iterator p = fn->prot()->begin();
- ATuple::const_iterator pT = protT->begin();
+ ATuple::const_iterator pT = argsT->begin();
+ assert(fn->prot()->size() == argsT->size());
+ assert(fn->prot()->size() == f->num_args());
for (Function::arg_iterator a = f->arg_begin(); a != f->arg_end(); ++a, ++p, ++pT) {
- AType* t = (*pT)->as<AType*>();
- const Type* lt = llType(t);
+ const AType* t = (*pT)->as<const AType*>();
+ const Type* lt = llType(t);
THROW_IF(!lt, fn->loc, "untyped parameter\n");
cenv.def((*p)->as<ASymbol*>(), *p, t, &*a);
}
+ assert(!cenv.currentFn);
+
// Write function body
try {
- fn->impls.push_back(make_pair(thisType, f));
+ cenv.currentFn = f;
CVal retVal = NULL;
for (AFn::iterator i = fn->begin() + 2; i != fn->end(); ++i)
retVal = (*i)->compile(cenv);
- cenv.engine()->finishFunction(cenv, f, cenv.type(fn->last()), retVal);
+ cenv.engine()->finishFunction(cenv, f, retVal);
} catch (Error& e) {
f->eraseFromParent(); // Error reading body, remove function
cenv.pop();
+ cenv.currentFn = NULL;
throw e;
}
- cenv.tsubst = oldSubst;
cenv.pop();
+ cenv.currentFn = NULL;
return f;
}
@@ -456,12 +446,12 @@ LLVMEngine::compilePrimitive(CEnv& cenv, APrimitive* prim)
}
CVal
-LLVMEngine::compileGlobal(CEnv& cenv, AType* type, const string& name, CVal val)
+LLVMEngine::compileGlobal(CEnv& cenv, const AType* type, const string& sym, CVal val)
{
LLVMEngine* engine = reinterpret_cast<LLVMEngine*>(cenv.engine());
Constant* init = Constant::getNullValue(llType(type));
GlobalVariable* global = new GlobalVariable(*module, llType(type), false,
- GlobalValue::ExternalLinkage, Constant::getNullValue(llType(type)), name);
+ GlobalValue::ExternalLinkage, Constant::getNullValue(llType(type)), sym);
engine->builder.CreateStore(llVal(val), global);
return global;