issue #78 work in progress

pull/81/head
Dibyendu Majumdar 8 years ago
parent 402c4b2bc4
commit 754536b01d

@ -0,0 +1,3 @@
mkdir xcodellvm
cd xcodellvm
cmake -DCMAKE_BUILD_TYPE=Debug -G Xcode -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM/share/llvm/cmake ..

@ -435,7 +435,7 @@ typedef enum {
} ravi_jit_flag_t;
typedef struct RaviJITProto {
lu_byte jit_status; /* 0=not compiled, 1=can't compile, 2=compiled, 3=freed */
lu_byte jit_status; /* 0=not compiled, 1=can't compile, 2=IR generated, 3=compiled, 4=freed */
lu_byte jit_flags;
unsigned short execution_count; /* how many times has function been executed */
void *jit_data;

@ -343,7 +343,10 @@ public:
static std::unique_ptr<RaviJITState> newJITState();
};
// A wrapper for LLVM Module
// Maintains a dedicated ExecutionEngine for the module
class RAVI_API RaviJITModule {
// The Context that owns this module
RaviJITState *owner_;
// The execution engine responsible for compiling the
@ -368,10 +371,17 @@ class RAVI_API RaviJITModule {
void dump();
void dumpAssembly();
// Add the function to this module, the function will be
// saved in the functions_ array.
int addFunction(RaviJITFunction *f);
// Remove a function from the array
void removeFunction(RaviJITFunction *f);
// Rus optimzation passes
void runpasses(bool dumpAsm = false);
void compileFunctions(bool doDump = false);
// finalize the module, and assign each function
// its pointer
void finalize(bool doDump = false);
// Add declaration for an extern function that is not
// loaded dynamically - i.e., is part of the the executable
@ -422,9 +432,10 @@ class RAVI_API RaviJITFunction {
};
// Ravi's JIT State
// Ravi's LLVM JIT State
// All of the JIT information is held here
class RAVI_API RaviJITState {
// The LLVM Context
llvm::LLVMContext *context_;
// The triple represents the host target
@ -464,8 +475,8 @@ class RAVI_API RaviJITState {
void addGlobalSymbol(const std::string &name, void *address);
virtual void dump();
virtual llvm::LLVMContext &context() { return *context_; }
void dump();
llvm::LLVMContext &context() { return *context_; }
LuaLLVMTypes *types() const { return types_; }
const std::string &triple() const { return triple_; }
bool is_auto() const { return auto_; }

@ -1295,7 +1295,6 @@ RaviCodeGenerator::emit_gep_upval_value(RaviFunctionDef *def,
bool RaviCodeGenerator::compile(lua_State *L, Proto *p,
std::shared_ptr<RaviJITModule> module,
ravi_compile_options_t *options) {
bool doDump = options ? options->dump_level != 0 : 0;
bool doVerify = options ? options->verification_level != 0 : 0;
bool omitArrayGetRangeCheck =
options ? options->omit_array_get_range_check != 0 : 0;
@ -1306,9 +1305,6 @@ bool RaviCodeGenerator::compile(lua_State *L, Proto *p,
llvm::LLVMContext &context = jitState_->context();
llvm::IRBuilder<> builder(context);
// std::unique_ptr<RaviFunctionDef> definition =
// std::unique_ptr<RaviFunctionDef>(new RaviFunctionDef());
// RaviFunctionDef *def = definition.get();
RaviFunctionDef definition = {0};
RaviFunctionDef *def = &definition;

@ -27,6 +27,7 @@
* Implementation Notes:
* Each Lua function is compiled into an LLVM Module/Function
* This strategy allows functions to be garbage collected as normal by Lua
* See issue #78 for changes to this (wip)
*/
namespace ravi {
@ -45,9 +46,8 @@ RaviJITState::RaviJITState()
gc_step_(200), tracehook_enabled_(false) {
// LLVM needs to be initialized else
// ExecutionEngine cannot be created
// This should ideally be an atomic check but because LLVM docs
// say that it is okay to call these functions more than once we
// do not bother
// This needs to be an atomic check although LLVM docs
// say that it is okay to call these functions more than once
if (init == 0) {
llvm::InitializeNativeTarget();
llvm::InitializeNativeTargetAsmPrinter();
@ -81,7 +81,7 @@ void RaviJITState::dump() {
types_->dump();
}
static std::atomic_int module_id = 1;
static std::atomic_int module_id;
RaviJITModule::RaviJITModule(RaviJITState *owner) : owner_(owner), engine_(nullptr), module_(nullptr) {
int myid = module_id++;
@ -110,6 +110,7 @@ RaviJITModule::RaviJITModule(RaviJITState *owner) : owner_(owner), engine_(nullp
engine_ = builder.create();
if (!engine_) {
fprintf(stderr, "Could not create ExecutionEngine: %s\n", errStr.c_str());
// FIXME we need to handle this error somehow
return;
}
}
@ -132,13 +133,14 @@ RaviJITModule::addFunction(RaviJITFunction *f) {
void
RaviJITModule::removeFunction(RaviJITFunction *f) {
lua_assert(functions_[f->getId()] == f);
functions_[f->getId()] = nullptr;
}
RaviJITFunction::RaviJITFunction(
Proto *p, std::shared_ptr<RaviJITModule> module, llvm::FunctionType *type,
llvm::GlobalValue::LinkageTypes linkage, const std::string &name)
: proto_(p), module_(module), name_(name), function_(nullptr), ptr_(nullptr) {
: module_(module), name_(name), function_(nullptr), ptr_(nullptr), proto_(p) {
function_ = llvm::Function::Create(type, linkage, name, module_->module());
id_ = module_->addFunction(this);
}
@ -241,7 +243,7 @@ void RaviJITModule::runpasses(bool dumpAsm) {
llvm::errs() << codestr << "\n";
}
void RaviJITModule::compileFunctions(bool doDump) {
void RaviJITModule::finalize(bool doDump) {
// Following will generate very verbose dump when machine code is
// produced below
llvm::TargetMachine *TM = engine_->getTargetMachine();
@ -270,7 +272,7 @@ RaviJITFunction::setFunctionPtr() {
lua_assert(proto_ != nullptr);
ptr_ = engine()->getPointerToFunction(function_);
proto_->ravi_jit.jit_function = (lua_CFunction)ptr_;
lua_assert(proto->ravi_jit.jit_function);
lua_assert(proto_->ravi_jit.jit_function);
if (proto_->ravi_jit.jit_function == nullptr) {
proto_->ravi_jit.jit_status = RAVI_JIT_CANT_COMPILE; // can't compile
}
@ -371,9 +373,10 @@ int raviV_compile(struct lua_State *L, struct Proto *p,
}
if (doCompile) {
auto module = std::make_shared<ravi::RaviJITModule>(G->ravi_state->jit);
G->ravi_state->code_generator->compile(L, p, module, options);
module->runpasses();
module->compileFunctions();
if (G->ravi_state->code_generator->compile(L, p, module, options)) {
module->runpasses();
module->finalize(options ? options->dump_level != 0 : 0);
}
}
return p->ravi_jit.jit_status == RAVI_JIT_COMPILED;
}

Loading…
Cancel
Save