diff options
author | David Robillard <d@drobilla.net> | 2009-10-06 20:29:06 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2009-10-06 20:29:06 +0000 |
commit | 31586bbff8588f8eab127bf57bc311d38ad8e1e0 (patch) | |
tree | fd2b38c0bc57a17559a78a98b8e9c3e8cda8bddb | |
parent | f55fa30ac2169357ca089a6a4c73c14480841e6e (diff) | |
download | resp-31586bbff8588f8eab127bf57bc311d38ad8e1e0.tar.gz resp-31586bbff8588f8eab127bf57bc311d38ad8e1e0.tar.bz2 resp-31586bbff8588f8eab127bf57bc311d38ad8e1e0.zip |
Fully abstract backend interface.
git-svn-id: http://svn.drobilla.net/resp/tuplr@197 ad02d1e2-f140-0410-9f75-f8b11f17cedd
-rw-r--r-- | Makefile | 22 | ||||
-rw-r--r-- | src/compile.cpp | 8 | ||||
-rw-r--r-- | src/tuplr.cpp | 43 | ||||
-rw-r--r-- | src/tuplr.hpp | 8 | ||||
-rw-r--r-- | src/tuplr_llvm.cpp | 45 |
5 files changed, 70 insertions, 56 deletions
@@ -1,13 +1,14 @@ LLVM_CXXFLAGS=`llvm-config --cppflags core jit native` LLVM_LDFLAGS=`llvm-config --ldflags --libs core jit native` -COMMON_FLAGS=-Wextra -Wno-unused-parameter +COMMON_FLAGS=-fPIC +COMMON_FLAGS+=-Wextra -Wno-unused-parameter COMMON_FLAGS+=-O0 -g #COMMON_FLAGS+=-O2 -march=nocona -fomit-frame-pointer CFLAGS=$(COMMON_FLAGS) -std=c99 -CXXFLAGS=$(COMMON_FLAGS) $(LLVM_CXXFLAGS) -LDFLAGS=$(LLVM_LDFLAGS) -lm +CXXFLAGS=$(COMMON_FLAGS) -ansi +LDFLAGS=-rdynamic -lm -ldl all: builddir build/tuplr mkdir -p build @@ -20,18 +21,20 @@ OBJECTS = \ build/constrain.o \ build/cps.o \ build/gc.o \ - build/tuplr_gc.so \ build/lex.o \ - build/tuplr_llvm.so \ build/parse.o \ build/pprint.o \ build/repl.o \ build/tlsf.o \ build/tuplr.o \ + build/tuplr_llvm.o \ build/unify.o -build/tuplr: $(OBJECTS) - g++ -o $@ $^ $(LDFLAGS) +LIBS = \ + build/tuplr_gc.so + +build/tuplr: $(OBJECTS) $(LIBS) + g++ -o $@ $(OBJECTS) $(LDFLAGS) $(LLVM_LDFLAGS) build/%.o: src/%.cpp src/tuplr.hpp g++ $(CXXFLAGS) -o $@ -c $< @@ -39,8 +42,11 @@ build/%.o: src/%.cpp src/tuplr.hpp build/tlsf.o: src/tlsf.c src/tlsf.h gcc $(CFLAGS) -o $@ -c $< +build/tuplr_llvm.o: src/tuplr_llvm.cpp src/tuplr.hpp + g++ -c $(CXXFLAGS) $(LLVM_CXXFLAGS) -o $@ src/tuplr_llvm.cpp + build/%.so: src/%.cpp src/tuplr.hpp - g++ -fPIC -dPIC -shared $(CXXFLAGS) -o $@ $< + g++ -shared $(CXXFLAGS) -o $@ $^ clean: rm -rf build diff --git a/src/compile.cpp b/src/compile.cpp index 8c83e15..addad2b 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -27,6 +27,14 @@ using namespace std; +#define COMPILE_LITERAL(CT) \ +template<> CValue ALiteral<CT>::compile(CEnv& cenv) { \ + return cenv.engine()->compileLiteral(cenv, this); \ +} +COMPILE_LITERAL(int32_t); +COMPILE_LITERAL(float); +COMPILE_LITERAL(bool); + CValue ASymbol::compile(CEnv& cenv) { diff --git a/src/tuplr.cpp b/src/tuplr.cpp index f8cc246..481885c 100644 --- a/src/tuplr.cpp +++ b/src/tuplr.cpp @@ -48,16 +48,7 @@ print_usage(char* name, bool error) int main(int argc, char** argv) { - PEnv penv; - TEnv tenv(penv); - initLang(penv, tenv); - - Engine* engine = tuplr_new_engine(); - CEnv* cenv = new CEnv(penv, tenv, engine); - - cenv->push(); - Object::pool.lock(); - + // Read command line arguments map<string,string> args; list<string> files; for (int i = 1; i < argc; ++i) { @@ -78,17 +69,35 @@ main(int argc, char** argv) } } + PEnv penv; + TEnv tenv(penv); + initLang(penv, tenv); + + Engine* engine = NULL; + + map<string,string>::const_iterator a = args.find("-b"); + const string backend_name = (a != args.end() ? a->second : "llvm"); + + if (backend_name == "llvm") + engine = tuplr_new_llvm_engine(); + + if (!engine) { + std::cerr << "Unable to open backend " << backend_name << std::endl; + return 1; + } + + CEnv* cenv = new CEnv(penv, tenv, engine); cenv->args = args; + cenv->push(); + + Object::pool.lock(); int ret = 0; - string output; - map<string,string>::const_iterator a = args.find("-o"); - if (a != args.end()) - output = a->second; + a = args.find("-o"); + const string output = (a != args.end()) ? a->second : ""; - a = args.find("-p"); - if (a != args.end()) { + if (args.find("-p") != args.end()) { ifstream is(files.front().c_str()); if (is.good()) { Cursor loc; @@ -131,7 +140,7 @@ main(int argc, char** argv) } delete cenv; - tuplr_free_engine(engine); + delete engine; return ret; } diff --git a/src/tuplr.hpp b/src/tuplr.hpp index 925deec..c3c30c4 100644 --- a/src/tuplr.hpp +++ b/src/tuplr.hpp @@ -621,7 +621,7 @@ Subst unify(const Constraints& c); * Code Generation * ***************************************************************************/ -/// Compiler back-end +/// Compiler backend struct Engine { virtual CFunction startFunction(CEnv& cenv, const std::string& name, const AType* retT, const ATuple& argsT, @@ -630,6 +630,7 @@ struct Engine { virtual void finishFunction(CEnv& cenv, CFunction f, const AType* retT, CValue ret) = 0; virtual void eraseFunction(CEnv& cenv, CFunction f) = 0; virtual void liftCall(CEnv& cenv, AFn* fn, const AType& argsT) = 0; + virtual CValue compileLiteral(CEnv& cenv, AST* lit) = 0; virtual CValue compileCall(CEnv& cenv, CFunction f, const vector<CValue>& args) = 0; virtual CValue compilePrimitive(CEnv& cenv, APrimitive* prim) = 0; virtual CValue compileIf(CEnv& cenv, AIf* aif) = 0; @@ -638,10 +639,7 @@ struct Engine { virtual const string call(CEnv& cenv, CFunction f, AType* retT) = 0; }; -extern "C" { - Engine* tuplr_new_engine(); - void tuplr_free_engine(Engine* engine); -} +Engine* tuplr_new_llvm_engine(); /// Compile-Time Environment struct CEnv { diff --git a/src/tuplr_llvm.cpp b/src/tuplr_llvm.cpp index dfd4c9d..e2f7f1a 100644 --- a/src/tuplr_llvm.cpp +++ b/src/tuplr_llvm.cpp @@ -43,12 +43,6 @@ using namespace llvm; using namespace std; using boost::format; -// Backend shared library interface -extern "C" { - Engine* tuplr_new_engine(); - void tuplr_free_engine(Engine* engine); -} - static inline Value* llVal(CValue v) { return static_cast<Value*>(v); } static inline Function* llFunc(CFunction f) { return static_cast<Function*>(f); } @@ -166,6 +160,8 @@ struct LLVMEngine : public Engine { } void liftCall(CEnv& cenv, AFn* fn, const AType& argsT); + + CValue compileLiteral(CEnv& cenv, AST* lit); CValue compilePrimitive(CEnv& cenv, APrimitive* prim); CValue compileIf(CEnv& cenv, AIf* aif); @@ -200,36 +196,33 @@ struct LLVMEngine : public Engine { FunctionPassManager opt; }; -extern "C" { - -/// Create a new Engine (shared library entry point) Engine* -tuplr_new_engine() +tuplr_new_llvm_engine() { return new LLVMEngine(); } -/// Free an Engine (shared library entry point) -void -tuplr_free_engine(Engine* engine) -{ - delete (LLVMEngine*)engine; -} - -} - - /*************************************************************************** * Code Generation * ***************************************************************************/ -#define COMPILE_LITERAL(CT, COMPILED) \ -template<> CValue ALiteral<CT>::compile(CEnv& cenv) { return (COMPILED); } +CValue +LLVMEngine::compileLiteral(CEnv& cenv, AST* lit) +{ + ALiteral<int32_t>* ilit = dynamic_cast<ALiteral<int32_t>*>(lit); + if (ilit) + return ConstantInt::get(Type::Int32Ty, ilit->val, true); + + ALiteral<float>* flit = dynamic_cast<ALiteral<float>*>(lit); + if (flit) + return ConstantFP::get(Type::FloatTy, flit->val); -// Literal template instantiations -COMPILE_LITERAL(int32_t, ConstantInt::get(Type::Int32Ty, val, true)) -COMPILE_LITERAL(float, ConstantFP::get(Type::FloatTy, val)) -COMPILE_LITERAL(bool, ConstantInt::get(Type::Int1Ty, val, false)) + ALiteral<bool>* blit = dynamic_cast<ALiteral<bool>*>(lit); + if (blit) + return ConstantFP::get(Type::FloatTy, blit->val); + + throw Error(lit->loc, "Unknown literal type"); +} void LLVMEngine::liftCall(CEnv& cenv, AFn* fn, const AType& argsT) |