From 9d9fa6162295f3813d20f7a3ad4e07ccd6087c3c Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 13 Dec 2009 03:55:24 +0000 Subject: Update for LLVM 2.6. git-svn-id: http://svn.drobilla.net/resp/tuplr@248 ad02d1e2-f140-0410-9f75-f8b11f17cedd --- Makefile | 11 +++-- src/lex.cpp | 1 + src/llvm.cpp | 139 +++++++++++++++++++++++++++++++--------------------------- src/tuplr.hpp | 1 + 4 files changed, 83 insertions(+), 69 deletions(-) diff --git a/Makefile b/Makefile index 8e12678..0279d41 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,7 @@ LLVM_CXXFLAGS=`llvm-config --cppflags core jit native` LLVM_LDFLAGS=`llvm-config --ldflags --libs core jit native` +#LLVM_CXXFLAGS=`llvm-config --cppflags all` +#LLVM_LDFLAGS=`llvm-config --ldflags --libs all` COMMON_FLAGS=-fPIC COMMON_FLAGS+=-Wextra -Wno-unused-parameter @@ -15,7 +17,6 @@ LDFLAGS=-rdynamic -lm -ldl #LDFLAGS+=-lgcov all: builddir build/tuplr - mkdir -p build builddir: mkdir -p build @@ -28,7 +29,6 @@ OBJECTS = \ build/gc.o \ build/lex.o \ build/lift.o \ - build/llvm.o \ build/parse.o \ build/pprint.o \ build/repl.o \ @@ -37,8 +37,11 @@ OBJECTS = \ build/unify.o \ build/tuplr_gc.o -build/tuplr: $(OBJECTS) - g++ -o $@ $(OBJECTS) $(LDFLAGS) $(LLVM_LDFLAGS) +LLVM_OBJECTS = build/llvm.o +#LLVM_OBJECTS = + +build/tuplr: $(OBJECTS) $(LLVM_OBJECTS) + g++ -o $@ $(OBJECTS) $(LLVM_OBJECTS) $(LDFLAGS) $(LLVM_LDFLAGS) build/%.o: src/%.cpp src/tuplr.hpp g++ $(CXXFLAGS) -o $@ -c $< diff --git a/src/lex.cpp b/src/lex.cpp index b5c89e9..597ca34 100644 --- a/src/lex.cpp +++ b/src/lex.cpp @@ -19,6 +19,7 @@ * @brief Lexing (build an unparsed textual AST from a string) */ +#include #include #include "tuplr.hpp" diff --git a/src/llvm.cpp b/src/llvm.cpp index 5010775..fdb9783 100644 --- a/src/llvm.cpp +++ b/src/llvm.cpp @@ -19,6 +19,9 @@ * @brief Compile to LLVM IR */ +#define __STDC_LIMIT_MACROS 1 +#define __STDC_CONSTANT_MACROS 1 + #include #include #include @@ -26,12 +29,15 @@ #include "llvm/Assembly/AsmAnnotationWriter.h" #include "llvm/DerivedTypes.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" +#include "llvm/ExecutionEngine/JIT.h" #include "llvm/Instructions.h" +#include "llvm/LLVMContext.h" #include "llvm/Module.h" #include "llvm/ModuleProvider.h" #include "llvm/PassManager.h" #include "llvm/Support/IRBuilder.h" #include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetSelect.h" #include "llvm/Transforms/Scalar.h" #include "tuplr.hpp" @@ -39,62 +45,20 @@ using namespace llvm; using namespace std; using boost::format; -static inline Value* llVal(CVal v) { return static_cast(v); } -static inline Function* llFunc(CFunc f) { return static_cast(f); } - -static const Type* -llType(const AType* t) -{ - if (t == NULL) { - return NULL; - } else if (t->kind == AType::PRIM) { - if (t->head()->str() == "Nothing") return Type::VoidTy; - if (t->head()->str() == "Bool") return Type::Int1Ty; - if (t->head()->str() == "Int") return Type::Int32Ty; - if (t->head()->str() == "Float") return Type::FloatTy; - throw Error(t->loc, string("Unknown primitive type `") + t->str() + "'"); - } else if (t->kind == AType::EXPR && t->head()->str() == "Fn") { - AType::const_iterator i = t->begin(); - const ATuple* protT = (*++i)->to(); - const AType* retT = (*++i)->as(); - if (!llType(retT)) - return NULL; - - vector cprot; - FOREACHP(ATuple::const_iterator, i, protT) { - const Type* lt = llType((*i)->to()); - if (!lt) - return NULL; - cprot.push_back(lt); - } - - return PointerType::get(FunctionType::get(llType(retT), cprot, false), 0); - } else if (t->kind == AType::EXPR && t->head()->str() == "Tup") { - vector ctypes; - for (AType::const_iterator i = t->begin() + 1; i != t->end(); ++i) { - const Type* lt = llType((*i)->to()); - if (!lt) - return NULL; - ctypes.push_back(lt); - } - - return PointerType::get(StructType::get(ctypes, false), 0); - } - return NULL; // non-primitive type -} - - /*************************************************************************** * LLVM Engine * ***************************************************************************/ struct LLVMEngine : public Engine { LLVMEngine() - : module(new Module("tuplr")) - , engine(ExecutionEngine::create(module)) - , emp(new ExistingModuleProvider(module)) - , opt(new FunctionPassManager(emp)) + : builder(context) { + InitializeNativeTarget(); + module = new Module("tuplr", context); + emp = new ExistingModuleProvider(module); + engine = EngineBuilder(module).create(); + opt = new FunctionPassManager(emp); + // Set up optimiser pipeline const TargetData* target = engine->getTargetData(); opt->add(new TargetData(*target)); // Register target arch @@ -104,8 +68,8 @@ struct LLVMEngine : public Engine { opt->add(createCFGSimplificationPass()); // Simplify control flow // Declare host provided allocation primitive - std::vector argsT(1, Type::Int32Ty); // unsigned size - FunctionType* funcT = FunctionType::get(PointerType::get(Type::Int8Ty, 0), argsT, false); + std::vector argsT(1, Type::getInt32Ty(context)); // unsigned size + FunctionType* funcT = FunctionType::get(PointerType::get(Type::getInt8Ty(context), 0), argsT, false); alloc = Function::Create(funcT, Function::ExternalLinkage, "tuplr_gc_allocate", module); } @@ -118,6 +82,50 @@ struct LLVMEngine : public Engine { delete emp; } + inline Value* llVal(CVal v) { return static_cast(v); } + inline Function* llFunc(CFunc f) { return static_cast(f); } + + const Type* + llType(const AType* t) + { + if (t == NULL) { + return NULL; + } else if (t->kind == AType::PRIM) { + if (t->head()->str() == "Nothing") return Type::getVoidTy(context); + if (t->head()->str() == "Bool") return Type::getInt1Ty(context); + if (t->head()->str() == "Int") return Type::getInt32Ty(context); + if (t->head()->str() == "Float") return Type::getFloatTy(context); + throw Error(t->loc, string("Unknown primitive type `") + t->str() + "'"); + } else if (t->kind == AType::EXPR && t->head()->str() == "Fn") { + AType::const_iterator i = t->begin(); + const ATuple* protT = (*++i)->to(); + const AType* retT = (*++i)->as(); + if (!llType(retT)) + return NULL; + + vector cprot; + FOREACHP(ATuple::const_iterator, i, protT) { + const Type* lt = llType((*i)->to()); + if (!lt) + return NULL; + cprot.push_back(lt); + } + + return PointerType::get(FunctionType::get(llType(retT), cprot, false), 0); + } else if (t->kind == AType::EXPR && t->head()->str() == "Tup") { + vector ctypes; + for (AType::const_iterator i = t->begin() + 1; i != t->end(); ++i) { + const Type* lt = llType((*i)->to()); + if (!lt) + return NULL; + ctypes.push_back(lt); + } + + return PointerType::get(StructType::get(context, ctypes, false), 0); + } + return NULL; // non-primitive type + } + CFunc startFunction(CEnv& cenv, const std::string& name, const AType* retT, const ATuple& argsT, const vector argNames) @@ -147,7 +155,7 @@ struct LLVMEngine : public Engine { for (vector::const_iterator i = argNames.begin(); i != argNames.end(); ++a, ++i) a->setName(*i); - BasicBlock* bb = BasicBlock::Create("entry", f); + BasicBlock* bb = BasicBlock::Create(context, "entry", f); builder.SetInsertPoint(bb); return f; @@ -196,19 +204,20 @@ struct LLVMEngine : public Engine { THROW_IF(!t, Cursor(), "function with non-concrete return type called"); std::stringstream ss; - if (t == Type::Int32Ty) + if (t == Type::getInt32Ty(context)) ss << ((int32_t (*)())fp)(); - else if (t == Type::FloatTy) + else if (t == Type::getFloatTy(context)) ss << showpoint << ((float (*)())fp)(); - else if (t == Type::Int1Ty) + else if (t == Type::getInt1Ty(context)) ss << (((bool (*)())fp)() ? "#t" : "#f"); - else if (t != Type::VoidTy) + else if (t != Type::getVoidTy(context)) ss << ((void* (*)())fp)(); else ((void (*)())fp)(); return ss.str(); } + LLVMContext context; Module* module; ExecutionEngine* engine; IRBuilder<> builder; @@ -243,7 +252,7 @@ LLVMEngine::compileTup(CEnv& cenv, const AType* type, const vector& fields s += llType((*i)->as())->getPrimitiveSizeInBits(); // Allocate struct - Value* structSize = ConstantInt::get(Type::Int32Ty, bitsToBytes(s)); + Value* structSize = ConstantInt::get(Type::getInt32Ty(context), bitsToBytes(s)); Value* mem = builder.CreateCall(alloc, structSize, "tupMem"); Value* structPtr = builder.CreateBitCast(mem, llType(type), "tup"); @@ -269,15 +278,15 @@ LLVMEngine::compileLiteral(CEnv& cenv, AST* lit) { ALiteral* ilit = dynamic_cast*>(lit); if (ilit) - return ConstantInt::get(Type::Int32Ty, ilit->val, true); + return ConstantInt::get(Type::getInt32Ty(context), ilit->val, true); ALiteral* flit = dynamic_cast*>(lit); if (flit) - return ConstantFP::get(Type::FloatTy, flit->val); + return ConstantFP::get(Type::getFloatTy(context), flit->val); ALiteral* blit = dynamic_cast*>(lit); if (blit) - return ConstantFP::get(Type::FloatTy, blit->val); + return ConstantFP::get(Type::getFloatTy(context), blit->val); throw Error(lit->loc, "Unknown literal type"); } @@ -354,7 +363,7 @@ LLVMEngine::compileIf(CEnv& cenv, AIf* aif) typedef vector< pair > Branches; LLVMEngine* engine = reinterpret_cast(cenv.engine()); Function* parent = engine->builder.GetInsertBlock()->getParent(); - BasicBlock* mergeBB = BasicBlock::Create("endif"); + BasicBlock* mergeBB = BasicBlock::Create(context, "endif"); BasicBlock* nextBB = NULL; Branches branches; size_t idx = 1; @@ -364,9 +373,9 @@ LLVMEngine::compileIf(CEnv& cenv, AIf* aif) break; Value* condV = llVal((*i)->compile(cenv)); - BasicBlock* thenBB = BasicBlock::Create((format("then%1%") % ((idx+1)/2)).str()); + BasicBlock* thenBB = BasicBlock::Create(context, (format("then%1%") % ((idx+1)/2)).str()); - nextBB = BasicBlock::Create((format("else%1%") % ((idx+1)/2)).str()); + nextBB = BasicBlock::Create(context, (format("else%1%") % ((idx+1)/2)).str()); engine->builder.CreateCondBr(condV, thenBB, nextBB); @@ -451,8 +460,8 @@ LLVMEngine::compileGlobal(CEnv& cenv, AType* type, const string& name, CVal val) { LLVMEngine* engine = reinterpret_cast(cenv.engine()); Constant* init = Constant::getNullValue(llType(type)); - GlobalVariable* global = new GlobalVariable(llType(type), false, - GlobalValue::ExternalLinkage, Constant::getNullValue(llType(type)), name, module); + GlobalVariable* global = new GlobalVariable(*module, llType(type), false, + GlobalValue::ExternalLinkage, Constant::getNullValue(llType(type)), name); engine->builder.CreateStore(llVal(val), global); return global; diff --git a/src/tuplr.hpp b/src/tuplr.hpp index 7d0bb6a..7cebaf4 100644 --- a/src/tuplr.hpp +++ b/src/tuplr.hpp @@ -23,6 +23,7 @@ #define TUPLR_HPP #include +#include #include #include #include -- cgit v1.2.1