diff options
Diffstat (limited to 'llvm.cpp')
-rw-r--r-- | llvm.cpp | 101 |
1 files changed, 82 insertions, 19 deletions
@@ -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; } |