From 60cb2bb1a12a1393abdc0d82b40ea0feabe3a74d Mon Sep 17 00:00:00 2001 From: David Robillard Date: Mon, 15 Oct 2012 20:08:52 +0000 Subject: Update for LLVM 3.1 git-svn-id: http://svn.drobilla.net/resp/trunk@433 ad02d1e2-f140-0410-9f75-f8b11f17cedd --- src/c.cpp | 4 +- src/compile.cpp | 3 +- src/llvm.cpp | 131 +++++++++++++++++++++++++++++-------------------------- src/repl.cpp | 2 +- src/resp.hpp | 2 +- src/simplify.cpp | 2 +- 6 files changed, 76 insertions(+), 68 deletions(-) (limited to 'src') diff --git a/src/c.cpp b/src/c.cpp index f172b65..0f56b5a 100644 --- a/src/c.cpp +++ b/src/c.cpp @@ -47,7 +47,7 @@ struct CEngine : public Engine { CVal compileCall(CEnv& cenv, CFunc f, const ATuple* funcT, const vector& args); CVal compileCast(CEnv& cenv, CVal v, const AST* t); - CVal compileCons(CEnv& cenv, const ATuple* type, CVal rtti, const vector& fields); + CVal compileCons(CEnv& cenv, const char* tname, const ATuple* type, CVal rtti, const vector& fields); CVal compileDot(CEnv& cenv, CVal tup, int32_t index); CVal compileGlobalSet(CEnv& cenv, const string& s, CVal v, const AST* t); CVal compileGlobalGet(CEnv& cenv, const string& s, CVal v); @@ -145,7 +145,7 @@ CEngine::compileCast(CEnv& cenv, CVal v, const AST* t) } CVal -CEngine::compileCons(CEnv& cenv, const ATuple* type, CVal rtti, const vector& fields) +CEngine::compileCons(CEnv& cenv, const char* tname, const ATuple* type, CVal rtti, const vector& fields) { return NULL; } diff --git a/src/compile.cpp b/src/compile.cpp index fd5baff..ecd0807 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -64,8 +64,9 @@ compile_cons(CEnv& cenv, const ATuple* cons) throw() tlist.push_back(cenv.type(*i)); fields.push_back(resp_compile(cenv, *i)); } + const std::string tstr = cenv.type(cons, Subst(), false)->as_symbol()->str(); return cenv.engine()->compileCons( - cenv, type, compile_literal_symbol(cenv, tname), fields); + cenv, tstr.c_str(), type, compile_literal_symbol(cenv, tname), fields); } static CVal diff --git a/src/llvm.cpp b/src/llvm.cpp index c4744c3..7f521b7 100644 --- a/src/llvm.cpp +++ b/src/llvm.cpp @@ -30,22 +30,24 @@ #include -#include "llvm/Value.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Assembly/AssemblyAnnotationWriter.h" +#include "llvm/DefaultPasses.h" #include "llvm/DerivedTypes.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/ExecutionEngine/JIT.h" +#include "llvm/ExecutionEngine/JITMemoryManager.h" #include "llvm/Instructions.h" #include "llvm/LLVMContext.h" #include "llvm/Module.h" #include "llvm/PassManager.h" -#include "llvm/Support/raw_os_ostream.h" #include "llvm/Support/IRBuilder.h" -#include "llvm/Support/StandardPasses.h" +#include "llvm/Support/TargetSelect.h" +#include "llvm/Support/raw_os_ostream.h" #include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetSelect.h" +#include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/Scalar.h" +#include "llvm/Value.h" #include "resp.hpp" @@ -54,22 +56,25 @@ using namespace std; using boost::format; struct IfRecord { - IfRecord(LLVMContext& context, unsigned labelIndex, const Type* t) + IfRecord(LLVMContext& context, unsigned labelIndex, Type* t) : type(t) , mergeBB(BasicBlock::Create(context, "endif")) , thenBB(BasicBlock::Create(context, (format("then%1%") % labelIndex).str())) , elseBB(BasicBlock::Create(context, (format("else%1%") % labelIndex).str())) , thenV(NULL) , elseV(NULL) + , nMergeBranches(0) {} - const Type* type; + Type* type; BasicBlock* mergeBB; BasicBlock* thenBB; BasicBlock* elseBB; Value* thenV; Value* elseV; + + unsigned nMergeBranches; }; /** LLVM Engine (Compiler and JIT) */ @@ -84,7 +89,7 @@ struct LLVMEngine : public Engine { CVal compileCall(CEnv& cenv, CFunc f, const ATuple* funcT, const vector& args); CVal compileCast(CEnv& cenv, CVal v, const AST* t); - CVal compileCons(CEnv& cenv, const ATuple* type, CVal rtti, const vector& fields); + CVal compileCons(CEnv& cenv, const char* tname, const ATuple* type, CVal rtti, const vector& fields); CVal compileDot(CEnv& cenv, CVal tup, int32_t index); CVal compileGlobalSet(CEnv& cenv, const string& s, CVal v, const AST* t); CVal compileGlobalGet(CEnv& cenv, const string& s, CVal v); @@ -111,7 +116,7 @@ private: inline Value* llVal(CVal v) { return static_cast(v); } inline Function* llFunc(CFunc f) { return static_cast(f); } - const Type* llType(const AST* t, const char* name=NULL); + Type* llType(const AST* t, const char* name=NULL); LLVMContext context; Module* module; @@ -122,10 +127,10 @@ private: PassManager* modOpt; CType objectT; - PATypeHolder* opaqueT; - std::string opaqueName; + StructType* opaqueT; + std::string opaqueName; - typedef std::map CTypes; + typedef std::map CTypes; CTypes compiledTypes; typedef std::stack IfStack; @@ -149,22 +154,22 @@ LLVMEngine::LLVMEngine() modOpt = new PassManager(); // Set up optimisers - unsigned optLevel = 3; - createStandardFunctionPasses(fnOpt, optLevel); - createStandardModulePasses(modOpt, optLevel, false, true, true, true, false, NULL); + PassManagerBuilder pmb; + pmb.OptLevel = 3; + pmb.populateFunctionPassManager(*fnOpt); + pmb.populateModulePassManager(*modOpt); // Declare host provided allocation primitive - std::vector argsT(1, Type::getInt32Ty(context)); // unsigned size + 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, "__resp_alloc", module); // Build Object type (tag only, binary compatible with any constructed thing) - vector ctypes; + vector ctypes; ctypes.push_back(PointerType::get(Type::getInt8Ty(context), 0)); // RTTI - StructType* cObjectT = StructType::get(context, ctypes, false); - module->addTypeName("Object", cObjectT); + StructType* cObjectT = StructType::create(context, ctypes, "Object", false); objectT = cObjectT; } @@ -175,7 +180,7 @@ LLVMEngine::~LLVMEngine() delete modOpt; } -const Type* +Type* LLVMEngine::llType(const AST* t, const char* name) { if (t == NULL) { @@ -191,7 +196,7 @@ LLVMEngine::llType(const AST* t, const char* name) if (sym == "Expr") return PointerType::get(Type::getInt8Ty(context), 0); if (sym == opaqueName) { THROW_IF(!opaqueT, t->loc, "Broken recursive type"); - return *opaqueT; + return PointerType::getUnqual(opaqueT); } CTypes::const_iterator i = compiledTypes.find(sym); @@ -205,15 +210,7 @@ LLVMEngine::llType(const AST* t, const char* name) THROW_IF(!isupper(t->as_tuple()->fst()->str()[0]), t->loc, "Lower-case type expression"); - // Define opaque type to stand for name in recursive type body - if (name) { - THROW_IF(opaqueT, t->loc, "Nested recursive types"); - opaqueT = new PATypeHolder(OpaqueType::get(context)); - opaqueName = name; - } - - const Type* ret; - + // Function type if (is_form(t, "Fn")) { ATuple::const_iterator i = t->as_tuple()->begin(); const ATuple* protT = (*++i)->to_tuple(); @@ -221,47 +218,48 @@ LLVMEngine::llType(const AST* t, const char* name) if (!llType(retT)) return NULL; - vector cprot; + vector cprot; FOREACHP(ATuple::const_iterator, i, protT) { - const Type* lt = llType(*i); + Type* lt = llType(*i); if (!lt) return NULL; cprot.push_back(lt); } - ret = FunctionType::get(llType(retT), cprot, false); + return PointerType::getUnqual(FunctionType::get(llType(retT), cprot, false)); + } - } else { - vector ctypes; - ctypes.push_back(PointerType::get(Type::getInt8Ty(context), 0)); // RTTI - for (ATuple::const_iterator i = t->as_tuple()->iter_at(1); i != t->as_tuple()->end(); ++i) { - const Type* lt = llType(*i); - if (!lt) - return NULL; - ctypes.push_back(lt); - } + // Struct type + Type* ret = NULL; + vector ctypes; - ret = StructType::get(context, ctypes, false); + // Define opaque type to stand for name in recursive type body + if (name) { + THROW_IF(opaqueT, t->loc, "Nested recursive types"); + opaqueT = StructType::create(context, name); + opaqueName = name; } - if (!ret) { - cerr << "WARNING: No low-level type for " << t << endl; - return NULL; + // Get member types + ctypes.push_back(PointerType::get(Type::getInt8Ty(context), 0)); // RTTI + for (ATuple::const_iterator i = t->as_tuple()->iter_at(1); i != t->as_tuple()->end(); ++i) { + Type* lt = llType(*i); + if (!lt) + return NULL; + ctypes.push_back(lt); } - // Tell LLVM opaqueT is actually ret* (for recursive types) - const PointerType* ptrT(PointerType::get(ret, 0)); - if (name) { - PATypeHolder retT(ret); - ((OpaqueType*)opaqueT->get())->refineAbstractTypeTo(ptrT); - ptrT = cast(opaqueT->get()); // update potentially invalidated type + // Resolve recursive type + opaqueT->setBody(ctypes); + ret = opaqueT; opaqueT = NULL; opaqueName = ""; - module->addTypeName(name, retT.get()); + } else { + ret = StructType::get(context, ctypes, false); } - return ptrT; + return PointerType::getUnqual(ret); } /** Convert a size in bits to bytes, rounding up as necessary */ @@ -275,17 +273,17 @@ CVal LLVMEngine::compileCall(CEnv& cenv, CFunc f, const ATuple* funcT, const vector& args) { vector llArgs(*reinterpret_cast*>(&args)); - return builder.CreateCall(llFunc(f), llArgs.begin(), llArgs.end()); + return builder.CreateCall(llFunc(f), llArgs); } CVal LLVMEngine::compileCast(CEnv& cenv, CVal v, const AST* t) { - return builder.CreateBitCast(llVal(v), (const Type*)compileType(cenv, NULL, t), "cast"); + return builder.CreateBitCast(llVal(v), (Type*)compileType(cenv, NULL, t), "cast"); } CVal -LLVMEngine::compileCons(CEnv& cenv, const ATuple* type, CVal rtti, const vector& fields) +LLVMEngine::compileCons(CEnv& cenv, const char* tname, const ATuple* type, CVal rtti, const vector& fields) { // Find size of memory required size_t s = engine->getTargetData()->getTypeSizeInBits( @@ -293,13 +291,20 @@ LLVMEngine::compileCons(CEnv& cenv, const ATuple* type, CVal rtti, const vector< assert(type->begin() != type->end()); for (ATuple::const_iterator i = type->iter_at(1); i != type->end(); ++i) s += engine->getTargetData()->getTypeSizeInBits( - (const Type*)compileType(cenv, NULL, *i)); + (Type*)compileType(cenv, NULL, *i)); // Allocate struct const std::string name = type->fst()->str(); Value* structSize = ConstantInt::get(Type::getInt32Ty(context), bitsToBytes(s)); Value* mem = builder.CreateCall(alloc, structSize, name + "_mem"); - Value* structPtr = builder.CreateBitCast(mem, llType(type), name); + + StructType* consT = module->getTypeByName(tname); + Value* structPtr = NULL; + if (consT) { // Named type + structPtr = builder.CreateBitCast(mem, PointerType::getUnqual(consT), name); + } else { // Anonymous type + structPtr = builder.CreateBitCast(mem, llType(type), name); + } // Set struct fields if (rtti) @@ -357,7 +362,7 @@ LLVMEngine::compileType(CEnv& cenv, const char* name, const AST* expr) return i->second; } - const Type* const type = llType(expr, name); + Type* const type = llType(expr, name); if (name) compiledTypes.insert(make_pair(name, type)); @@ -374,12 +379,12 @@ LLVMEngine::startFn( Function::LinkageTypes linkage = Function::ExternalLinkage; - vector cprot; + vector cprot; FOREACHP(ATuple::const_iterator, i, argsT) { const char* name = (*i)->to_symbol() ? (*i)->as_symbol()->sym() : NULL; CType iT = compileType(cenv, name, cenv.resolveType(*i)); THROW_IF(!iT, Cursor(), string("non-concrete parameter :: ") + (*i)->str()); - cprot.push_back((const Type*)iT); + cprot.push_back((Type*)iT); } THROW_IF(!llType(retT), Cursor(), @@ -511,6 +516,7 @@ LLVMEngine::compileIfElse(CEnv& cenv, CVal elseV) if (elseV) { engine->builder.CreateBr(rec->mergeBB); + ++rec->nMergeBranches; } else { engine->builder.CreateUnreachable(); } @@ -528,7 +534,8 @@ LLVMEngine::compileIfEnd(CEnv& cenv) // Emit merge block (Phi node) appendBlock(engine, parent, rec->mergeBB); - PHINode* pn = engine->builder.CreatePHI(rec->type, "ifval"); + ++rec->nMergeBranches; + PHINode* pn = engine->builder.CreatePHI(rec->type, rec->nMergeBranches, "ifval"); pn->addIncoming(rec->thenV, rec->thenBB); if (rec->elseV) pn->addIncoming(rec->elseV, rec->elseBB); diff --git a/src/repl.cpp b/src/repl.cpp index b457e06..4e9c44c 100644 --- a/src/repl.cpp +++ b/src/repl.cpp @@ -166,7 +166,7 @@ eval(CEnv& cenv, Cursor& cursor, istream& is, bool execute) } Code defs; - bool hasMain; + bool hasMain = false; const AST* retT = compile(cenv, parsed, defs, hasMain, "main"); if (cenv.args.find("-F") != cenv.args.end()) { dump(cenv, defs); diff --git a/src/resp.hpp b/src/resp.hpp index f952c40..d6a46ab 100644 --- a/src/resp.hpp +++ b/src/resp.hpp @@ -677,7 +677,7 @@ struct Engine { virtual CVal compileCall(CEnv& cenv, CFunc f, const ATuple* fT, CVals& args) = 0; virtual CVal compileCast(CEnv& cenv, CVal v, const AST* t) = 0; - virtual CVal compileCons(CEnv& cenv, const ATuple* t, CVal rtti, CVals& f) = 0; + virtual CVal compileCons(CEnv& cenv, const char* tname, const ATuple* t, CVal rtti, CVals& f) = 0; virtual CVal compileDot(CEnv& cenv, CVal tup, int32_t index) = 0; virtual CVal compileGlobalSet(CEnv& cenv, const string& s, CVal v, const AST* t) = 0; virtual CVal compileGlobalGet(CEnv& cenv, const string& s, CVal v) = 0; diff --git a/src/simplify.cpp b/src/simplify.cpp index ea83cff..2085ad9 100644 --- a/src/simplify.cpp +++ b/src/simplify.cpp @@ -103,7 +103,7 @@ simplify_match(CEnv& cenv, const ATuple* match) throw() for (ATuple::const_iterator j = pat->iter_at(1); j != pat->end(); ++j, ++ti, ++idx) { const AST* index = new ALiteral(T_INT32, idx, Cursor()); const AST* dot = tup(Cursor(), cenv.penv.sym("."), osym, index, 0); - const AST* def = tup(Cursor(), cenv.penv.sym("def"), *j, dot); + const AST* def = tup(Cursor(), cenv.penv.sym("def"), *j, dot, 0); fn.push_back(def); } -- cgit v1.2.1