aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm.cpp95
-rw-r--r--tuplr.cpp6
-rw-r--r--tuplr.hpp21
3 files changed, 47 insertions, 75 deletions
diff --git a/llvm.cpp b/llvm.cpp
index d3782f9..13b6eaa 100644
--- a/llvm.cpp
+++ b/llvm.cpp
@@ -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)
{
diff --git a/tuplr.cpp b/tuplr.cpp
index da5a31a..eaf351c 100644
--- a/tuplr.cpp
+++ b/tuplr.cpp
@@ -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;
diff --git a/tuplr.hpp b/tuplr.hpp
index b60d21e..2da326a 100644
--- a/tuplr.hpp
+++ b/tuplr.hpp
@@ -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;
};