aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2012-10-15 20:08:52 +0000
committerDavid Robillard <d@drobilla.net>2012-10-15 20:08:52 +0000
commit60cb2bb1a12a1393abdc0d82b40ea0feabe3a74d (patch)
tree42ab3460523da85011a448f74c6f430888942df9
parent7bdf853545a3d1bcaf7ae028a0409007862c3382 (diff)
downloadresp-60cb2bb1a12a1393abdc0d82b40ea0feabe3a74d.tar.gz
resp-60cb2bb1a12a1393abdc0d82b40ea0feabe3a74d.tar.bz2
resp-60cb2bb1a12a1393abdc0d82b40ea0feabe3a74d.zip
Update for LLVM 3.1
git-svn-id: http://svn.drobilla.net/resp/trunk@433 ad02d1e2-f140-0410-9f75-f8b11f17cedd
-rw-r--r--src/c.cpp4
-rw-r--r--src/compile.cpp3
-rw-r--r--src/llvm.cpp131
-rw-r--r--src/repl.cpp2
-rw-r--r--src/resp.hpp2
-rw-r--r--src/simplify.cpp2
-rw-r--r--wscript23
7 files changed, 89 insertions, 78 deletions
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<CVal>& args);
CVal compileCast(CEnv& cenv, CVal v, const AST* t);
- CVal compileCons(CEnv& cenv, const ATuple* type, CVal rtti, const vector<CVal>& fields);
+ CVal compileCons(CEnv& cenv, const char* tname, const ATuple* type, CVal rtti, const vector<CVal>& 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<CVal>& fields)
+CEngine::compileCons(CEnv& cenv, const char* tname, const ATuple* type, CVal rtti, const vector<CVal>& 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 <boost/format.hpp>
-#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<CVal>& args);
CVal compileCast(CEnv& cenv, CVal v, const AST* t);
- CVal compileCons(CEnv& cenv, const ATuple* type, CVal rtti, const vector<CVal>& fields);
+ CVal compileCons(CEnv& cenv, const char* tname, const ATuple* type, CVal rtti, const vector<CVal>& 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<Value*>(v); }
inline Function* llFunc(CFunc f) { return static_cast<Function*>(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<const std::string, const Type*> CTypes;
+ typedef std::map<const std::string, Type*> CTypes;
CTypes compiledTypes;
typedef std::stack<IfRecord*> 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<const Type*> argsT(1, Type::getInt32Ty(context)); // unsigned size
+ std::vector<Type*> 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<const Type*> ctypes;
+ vector<Type*> 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<const Type*> cprot;
+ vector<Type*> 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<const Type*> 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<Type*> 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<PointerType>(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<CVal>& args)
{
vector<Value*> llArgs(*reinterpret_cast<const vector<Value*>*>(&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<CVal>& fields)
+LLVMEngine::compileCons(CEnv& cenv, const char* tname, const ATuple* type, CVal rtti, const vector<CVal>& 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<const Type*> cprot;
+ vector<Type*> 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<int32_t>(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);
}
diff --git a/wscript b/wscript
index f7054a2..3a50203 100644
--- a/wscript
+++ b/wscript
@@ -42,7 +42,7 @@ def configure(conf):
conf.env.append_unique('CFLAGS', '-std=c99')
conf.check_cfg(
- path = 'llvm-config-2.9',
+ path = 'llvm-config-3.1',
args = '--cppflags --ldflags --libs core jit native codegen ipo',
package = '',
uselib_store = 'LLVM',
@@ -50,11 +50,11 @@ def configure(conf):
if not conf.is_defined('HAVE_LLVM'):
conf.check_cfg(
- path = 'llvm-config-2.8',
+ path = 'llvm-config-3.0',
args = '--cppflags --ldflags --libs core jit native codegen ipo',
package = '',
uselib_store = 'LLVM',
- mandatory = True)
+ mandatory = False)
def build(bld):
source = '''
@@ -83,13 +83,16 @@ def build(bld):
def test(ctx):
def run_test(prog, correct_out):
- out = subprocess.check_output(['./build/resp', prog]).strip()
- if out == correct_out:
- Logs.info("PASS: %s" % prog)
- else:
- Logs.error("FAIL: %s" % prog)
- Logs.error("Expected: %s" % correct_out)
- Logs.error("Got: %s" % out)
+ try:
+ out = subprocess.check_output(['./build/resp', prog]).strip()
+ if out == correct_out:
+ Logs.info("PASS: %s" % prog)
+ else:
+ Logs.error("FAIL: %s" % prog)
+ Logs.error("Expected: %s" % correct_out)
+ Logs.error("Got: %s" % out)
+ except:
+ Logs.error("ERROR: %s" % prog)
# Basic lexical sanity
run_test('./test/def.resp', '4 : Int')