aboutsummaryrefslogtreecommitdiffstats
path: root/llvm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm.cpp')
-rw-r--r--llvm.cpp101
1 files changed, 82 insertions, 19 deletions
diff --git a/llvm.cpp b/llvm.cpp
index c5161a0..b07624d 100644
--- a/llvm.cpp
+++ b/llvm.cpp
@@ -124,6 +124,8 @@ CEnv::compile(AST* obj)
void
CEnv::optimise(CFunction f)
{
+ if (args.find("-g") != args.end())
+ return;
verifyFunction(*static_cast<Function*>(f));
_pimpl->opt.run(*static_cast<Function*>(f));
}
@@ -194,20 +196,26 @@ ASymbol::compile(CEnv& cenv)
void
AClosure::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 (funcs.find(type) || !type->concrete())
return;
- ATuple* protT = type->at(1)->as<ATuple*>();
- vector<AType*> argsT;
- for (size_t i = 0; i < protT->size(); ++i)
- argsT.push_back(protT->at(i)->as<AType*>());
-
- liftCall(cenv, argsT);
+ AType* protT = type->at(1)->as<AType*>();
+ liftCall(cenv, *protT);
}
void
-AClosure::liftCall(CEnv& cenv, const vector<AType*>& argsT)
+AClosure::liftCall(CEnv& cenv, const AType& argsT)
{
TEnv::GenericTypes::const_iterator gt = cenv.tenv.genericTypes.find(this);
assert(gt != cenv.tenv.genericTypes.end());
@@ -233,21 +241,67 @@ AClosure::liftCall(CEnv& cenv, const vector<AType*>& argsT)
ATuple* protT = thisType->at(1)->as<ATuple*>();
// Write function declaration
- string name = this->name == "" ? cenv.gensym("_fn") : this->name;
+ const string name = (this->name == "") ? cenv.gensym("_fn") : this->name;
Function* f = compileFunction(cenv, name,
lltype(thisType->at(thisType->size()-1)->to<AType*>()),
*protT, loc);
+ llvm::IRBuilder<>& builder = llengine(cenv)->builder;
+
cenv.push();
Subst oldSubst = cenv.tsubst;
cenv.tsubst = Subst::compose(cenv.tsubst, Subst::compose(argsSubst, subst));
+//#define EXPLICIT_STACK_FRAME 1
+
+#ifdef EXPLICIT_STACK_FRAMES
+ vector<const Type*> types;
+ types.push_back(PointerType::get(Type::VoidTy, 0));
+ size_t s = 0;
+#endif
+
// Bind argument values in CEnv
vector<Value*> args;
const_iterator p = prot()->begin();
size_t i = 0;
- for (Function::arg_iterator a = f->arg_begin(); a != f->arg_end(); ++a, ++p)
- cenv.def((*p)->as<ASymbol*>(), *p, protT->at(i++)->as<AType*>(), &*a);
+ for (Function::arg_iterator a = f->arg_begin(); a != f->arg_end(); ++a, ++p, ++i) {
+ AType* t = protT->at(i)->as<AType*>();
+ const Type* lt = lltype(t);
+ THROW_IF(!lt, loc, "untyped parameter\n");
+ cenv.def((*p)->as<ASymbol*>(), *p, t, &*a);
+#ifdef EXPLICIT_STACK_FRAMES
+ types.push_back(lt);
+ s += std::max(lt->getPrimitiveSizeInBits(), unsigned(8));
+#endif
+ }
+
+
+#ifdef EXPLICIT_STACK_FRAMES
+ // Scan out definitions
+ for (size_t i = 0; i < size(); ++i) {
+ ADefinition* def = at(i)->to<ADefinition*>();
+ if (def) {
+ const Type* lt = lltype(cenv.type(def->at(2)));
+ THROW_IF(!lt, loc, "untyped definition\n");
+ types.push_back(lt);
+ s += std::max(lt->getPrimitiveSizeInBits(), unsigned(8));
+ }
+ }
+
+ // Create stack frame
+ StructType* sT = StructType::get(types, false);
+ PointerType* pT = PointerType::get(sT, 0);
+ Value* frameSize = ConstantInt::get(Type::Int32Ty, (s + pT->getPrimitiveSizeInBits()) / 8);
+ Value* mem = builder.CreateCall(LLVal(cenv.alloc), frameSize, "mem");
+ Value* frame = builder.CreateBitCast(mem, pT, "frame");
+
+ // Bind parameter values in stack frame
+ i = 1;
+ for (Function::arg_iterator a = f->arg_begin(); a != f->arg_end(); ++a, ++i) {
+ Value* v = builder.CreateStructGEP(frame, i);
+ builder.CreateStore(&*a, v);
+ }
+#endif
// Write function body
try {
@@ -257,7 +311,7 @@ AClosure::liftCall(CEnv& cenv, const vector<AType*>& argsT)
CValue retVal = NULL;
for (size_t i = 2; i < size(); ++i)
retVal = cenv.compile(at(i));
- llengine(cenv)->builder.CreateRet(LLVal(retVal)); // Finish function
+ builder.CreateRet(LLVal(retVal)); // Finish function
cenv.optimise(LLFunc(f));
} catch (Error& e) {
f->eraseFromParent(); // Error reading body, remove function
@@ -277,8 +331,8 @@ AClosure::compile(CEnv& cenv)
void
ACall::lift(CEnv& cenv)
{
- AClosure* c = cenv.tenv.resolve(at(0))->to<AClosure*>();
- vector<AType*> argsT;
+ AClosure* c = cenv.tenv.resolve(at(0))->to<AClosure*>();
+ AType argsT(loc, NULL);
// Lift arguments
for (size_t i = 1; i < size(); ++i) {
@@ -304,18 +358,21 @@ ACall::compile(CEnv& cenv)
if (!c) return NULL; // Primitive
AType protT(loc, NULL);
- for (size_t i = 1; i < size(); ++i)
+ 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, cenv.penv.sym("Fn"), &protT, cenv.type(this), 0);
Function* f = (Function*)c->funcs.find(&fnT);
- THROW_IF(!f, loc, (format("callee failed to compile for type %1%") % fnT.str()).str())
+ THROW_IF(!f, loc, (format("callee failed to compile for type %1%") % fnT.str()).str());
vector<Value*> params(size() - 1);
- for (size_t i = 1; i < size(); ++i)
- params[i-1] = LLVal(cenv.compile(at(i)));
+ 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());
}
@@ -582,6 +639,9 @@ eval(CEnv& cenv, const string& name, istream& is)
Object::pool.collect(cenv, Object::pool.roots());
+ if (cenv.args.find("-d") != cenv.args.end())
+ cenv.write(cenv.out);
+
} catch (Error& e) {
cenv.err << e.what() << endl;
return 1;
@@ -638,6 +698,8 @@ repl(CEnv& cenv)
Object::pool.collect(cenv, Object::pool.roots());
cenv.tsubst = oldSubst;
+ if (cenv.args.find("-d") != cenv.args.end())
+ cenv.write(cenv.out);
} catch (Error& e) {
cenv.err << e.what() << endl;
@@ -655,7 +717,8 @@ newCenv(PEnv& penv, TEnv& tenv)
// Host provided allocation primitive prototypes
std::vector<const Type*> argsT(1, Type::Int32Ty);
FunctionType* funcT = FunctionType::get(PointerType::get(Type::Int8Ty, 0), argsT, false);
- cenv->alloc = Function::Create(funcT, Function::ExternalLinkage, "malloc", engine->module);
+ cenv->alloc = Function::Create(funcT, Function::ExternalLinkage,
+ "tuplr_gc_allocate", engine->module);
return cenv;
}
@@ -663,7 +726,7 @@ newCenv(PEnv& penv, TEnv& tenv)
void
freeCenv(CEnv* cenv)
{
- Object::pool.collect(*cenv, GC::Roots());
+ Object::pool.collect(*cenv, ::GC::Roots());
delete (LLVMEngine*)cenv->engine();
delete cenv;
}