diff options
-rw-r--r-- | llvm.cpp | 95 | ||||
-rw-r--r-- | tuplr.cpp | 6 | ||||
-rw-r--r-- | tuplr.hpp | 21 |
3 files changed, 47 insertions, 75 deletions
@@ -56,19 +56,33 @@ llType(const AType* t) ***************************************************************************/ struct LLVMEngine { - LLVMEngine() : module(new Module("tuplr")), engine(ExecutionEngine::create(module)) + LLVMEngine() + : module(new Module("tuplr")) + , engine(ExecutionEngine::create(module)) + , emp(module) + , opt(&emp) { - // Host provided allocation primitive prototype + // Set up optimiser pipeline + const TargetData* target = engine->getTargetData(); + opt.add(new TargetData(*target)); // Register target arch + opt.add(createInstructionCombiningPass()); // Simple optimizations + opt.add(createReassociatePass()); // Reassociate expressions + opt.add(createGVNPass()); // Eliminate Common Subexpressions + opt.add(createCFGSimplificationPass()); // Simplify control flow + + // Declare host provided allocation primitive std::vector<const Type*> argsT(1, Type::Int32Ty); // unsigned size argsT.push_back(Type::Int8Ty); // char tag FunctionType* funcT = FunctionType::get(PointerType::get(Type::Int8Ty, 0), argsT, false); alloc = Function::Create(funcT, Function::ExternalLinkage, "tuplr_gc_allocate", module); } - Module* module; - ExecutionEngine* engine; - IRBuilder<> builder; - CFunction alloc; + Module* module; + ExecutionEngine* engine; + IRBuilder<> builder; + CFunction alloc; + ExistingModuleProvider emp; + FunctionPassManager opt; }; static LLVMEngine* @@ -77,63 +91,6 @@ llEngine(CEnv& cenv) return reinterpret_cast<LLVMEngine*>(cenv.engine()); } -struct CEnv::PImpl { - PImpl(LLVMEngine* e) : engine(e), emp(e->module), opt(&emp) - { - // Set up the optimizer pipeline: - const TargetData* target = engine->engine->getTargetData(); - opt.add(new TargetData(*target)); // Register target arch - opt.add(createInstructionCombiningPass()); // Simple optimizations - opt.add(createReassociatePass()); // Reassociate expressions - opt.add(createGVNPass()); // Eliminate Common Subexpressions - opt.add(createCFGSimplificationPass()); // Simplify control flow - } - - LLVMEngine* engine; - ExistingModuleProvider emp; - FunctionPassManager opt; -}; - -CEnv::CEnv(PEnv& p, TEnv& t, CEngine e, ostream& os, ostream& es) - : out(os), err(es), penv(p), tenv(t), symID(0), _pimpl(new PImpl((LLVMEngine*)e)) -{ -} - -CEnv::~CEnv() -{ - Object::pool.collect(GC::Roots()); - delete _pimpl; -} - -CEngine -CEnv::engine() -{ - return _pimpl->engine; -} - -CValue -CEnv::compile(AST* obj) -{ - CValue* v = vals.ref(obj); - return (v && *v) ? *v : vals.def(obj, obj->compile(*this)); -} - -void -CEnv::optimise(CFunction f) -{ - if (args.find("-g") != args.end()) - return; - verifyFunction(*static_cast<Function*>(f)); - _pimpl->opt.run(*static_cast<Function*>(f)); -} - -void -CEnv::write(std::ostream& os) -{ - AssemblyAnnotationWriter writer; - _pimpl->engine->module->print(os, &writer); -} - #define LITERAL(CT, NAME, COMPILED) \ template<> CValue \ ALiteral<CT>::compile(CEnv& cenv) { return (COMPILED); } \ @@ -185,7 +142,10 @@ finishFunction(CEnv& cenv, CFunction f, CValue ret) { Value* retVal = llVal(ret); llEngine(cenv)->builder.CreateRet(retVal); - cenv.optimise(llFunc(f)); + + verifyFunction(*static_cast<Function*>(f)); + if (cenv.args.find("-g") == cenv.args.end()) + llEngine(cenv)->opt.run(*static_cast<Function*>(f)); } void @@ -195,6 +155,13 @@ eraseFunction(CEnv& cenv, CFunction f) llFunc(f)->eraseFromParent(); } +void +writeModule(CEnv& cenv, std::ostream& os) +{ + AssemblyAnnotationWriter writer; + llEngine(cenv)->module->print(os, &writer); +} + const string call(CEnv& cenv, CFunction f, AType* retT) { @@ -278,7 +278,7 @@ eval(CEnv& cenv, const string& name, istream& is) Object::pool.collect(Object::pool.roots()); if (cenv.args.find("-d") != cenv.args.end()) - cenv.write(cenv.out); + writeModule(cenv, cenv.out); } catch (Error& e) { cenv.err << e.what() << endl; @@ -337,7 +337,7 @@ repl(CEnv& cenv) cenv.tsubst = oldSubst; if (cenv.args.find("-d") != cenv.args.end()) - cenv.write(cenv.out); + writeModule(cenv, cenv.out); } catch (Error& e) { cenv.err << e.what() << endl; @@ -445,7 +445,7 @@ main(int argc, char** argv) if (output != "") { ofstream os(output.c_str()); if (os.good()) { - cenv->write(os); + writeModule(*cenv, os); } else { cerr << argv[0] << ": " << a->second << ": " << strerror(errno) << endl; ++ret; @@ -565,24 +565,30 @@ void tuplr_free_engine(CEngine engine); void finishFunction(CEnv& cenv, CFunction f, CValue ret); void eraseFunction(CEnv& cenv, CFunction f); +void writeModule(CEnv& cenv, std::ostream& os); + const string call(CEnv& cenv, CFunction f, AType* retT); /// Compile-Time Environment struct CEnv { - CEnv(PEnv& p, TEnv& t, CEngine e, ostream& os=std::cout, ostream& es=std::cerr); - ~CEnv(); + CEnv(PEnv& p, TEnv& t, CEngine e, ostream& os=std::cout, ostream& es=std::cerr) + : out(os), err(es), penv(p), tenv(t), symID(0), _engine(e) + {} + + ~CEnv() { Object::pool.collect(GC::Roots()); } typedef Env<const ASymbol*, AST*> Code; typedef Env<const AST*, CValue> Vals; - CEngine engine(); + CEngine engine() { return _engine; } string gensym(const char* s="_") { return (format("%s%d") % s % symID++).str(); } void push() { tenv.push(); vals.push(); } void pop() { tenv.pop(); vals.pop(); } void precompile(AST* obj, CValue value) { vals.def(obj, value); } - CValue compile(AST* obj); - void optimise(CFunction f); - void write(std::ostream& os); + CValue compile(AST* obj) { + CValue* v = vals.ref(obj); + return (v && *v) ? *v : vals.def(obj, obj->compile(*this)); + } void lock(AST* ast) { Object::pool.addRoot(ast); Object::pool.addRoot(type(ast)); } AType* type(AST* ast, const Subst& subst = Subst()) const { ASymbol* sym = ast->to<ASymbol*>(); @@ -607,8 +613,7 @@ struct CEnv { map<string,string> args; private: - struct PImpl; ///< Private Implementation - PImpl* _pimpl; + CEngine _engine; }; |