aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile11
-rw-r--r--src/lex.cpp1
-rw-r--r--src/llvm.cpp139
-rw-r--r--src/tuplr.hpp1
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 <stdio.h>
#include <stack>
#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 <map>
#include <sstream>
#include <boost/format.hpp>
@@ -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<Value*>(v); }
-static inline Function* llFunc(CFunc f) { return static_cast<Function*>(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 ATuple*>();
- const AType* retT = (*++i)->as<const AType*>();
- if (!llType(retT))
- return NULL;
-
- vector<const Type*> cprot;
- FOREACHP(ATuple::const_iterator, i, protT) {
- const Type* lt = llType((*i)->to<const AType*>());
- 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<const Type*> ctypes;
- for (AType::const_iterator i = t->begin() + 1; i != t->end(); ++i) {
- const Type* lt = llType((*i)->to<const AType*>());
- 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<const Type*> argsT(1, Type::Int32Ty); // unsigned size
- FunctionType* funcT = FunctionType::get(PointerType::get(Type::Int8Ty, 0), argsT, false);
+ std::vector<const 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,
"tuplr_gc_allocate", module);
}
@@ -118,6 +82,50 @@ struct LLVMEngine : public Engine {
delete emp;
}
+ inline Value* llVal(CVal v) { return static_cast<Value*>(v); }
+ inline Function* llFunc(CFunc f) { return static_cast<Function*>(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 ATuple*>();
+ const AType* retT = (*++i)->as<const AType*>();
+ if (!llType(retT))
+ return NULL;
+
+ vector<const Type*> cprot;
+ FOREACHP(ATuple::const_iterator, i, protT) {
+ const Type* lt = llType((*i)->to<const AType*>());
+ 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<const Type*> ctypes;
+ for (AType::const_iterator i = t->begin() + 1; i != t->end(); ++i) {
+ const Type* lt = llType((*i)->to<const AType*>());
+ 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<string> argNames)
@@ -147,7 +155,7 @@ struct LLVMEngine : public Engine {
for (vector<string>::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<CVal>& fields
s += llType((*i)->as<AType*>())->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<int32_t>* ilit = dynamic_cast<ALiteral<int32_t>*>(lit);
if (ilit)
- return ConstantInt::get(Type::Int32Ty, ilit->val, true);
+ return ConstantInt::get(Type::getInt32Ty(context), ilit->val, true);
ALiteral<float>* flit = dynamic_cast<ALiteral<float>*>(lit);
if (flit)
- return ConstantFP::get(Type::FloatTy, flit->val);
+ return ConstantFP::get(Type::getFloatTy(context), flit->val);
ALiteral<bool>* blit = dynamic_cast<ALiteral<bool>*>(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<Value*, BasicBlock*> > Branches;
LLVMEngine* engine = reinterpret_cast<LLVMEngine*>(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<LLVMEngine*>(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 <stdarg.h>
+#include <stdint.h>
#include <string.h>
#include <iostream>
#include <list>