Skip to content

Commit

Permalink
Add LLVM ExecutionEngine API
Browse files Browse the repository at this point in the history
  • Loading branch information
murarth committed Dec 11, 2014
1 parent c38e73f commit 2c02845
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 1 deletion.
3 changes: 2 additions & 1 deletion mk/rustllvm.mk
Expand Up @@ -22,7 +22,8 @@ LLVM_EXTRA_INCDIRS_$(1)= -iquote $(S)src/llvm/include \
-iquote $$(CFG_LLVM_BUILD_DIR_$(1))/include
endif

RUSTLLVM_OBJS_CS_$(1) := $$(addprefix rustllvm/, RustWrapper.cpp PassWrapper.cpp)
RUSTLLVM_OBJS_CS_$(1) := $$(addprefix rustllvm/, \
ExecutionEngineWrapper.cpp RustWrapper.cpp PassWrapper.cpp)

RUSTLLVM_DEF_$(1) := $(1)/rustllvm/rustllvm$(CFG_DEF_SUFFIX_$(1))

Expand Down
14 changes: 14 additions & 0 deletions src/librustc_llvm/lib.rs
Expand Up @@ -466,6 +466,9 @@ pub type BuilderRef = *mut Builder_opaque;
pub enum ExecutionEngine_opaque {}
pub type ExecutionEngineRef = *mut ExecutionEngine_opaque;
#[allow(missing_copy_implementations)]
pub enum RustJITMemoryManager_opaque {}
pub type RustJITMemoryManagerRef = *mut RustJITMemoryManager_opaque;
#[allow(missing_copy_implementations)]
pub enum MemoryBuffer_opaque {}
pub type MemoryBufferRef = *mut MemoryBuffer_opaque;
#[allow(missing_copy_implementations)]
Expand Down Expand Up @@ -1064,7 +1067,18 @@ extern {
Instr: ValueRef,
Name: *const c_char);
pub fn LLVMDisposeBuilder(Builder: BuilderRef);

/* Execution engine */
pub fn LLVMRustCreateJITMemoryManager(morestack: *const ())
-> RustJITMemoryManagerRef;
pub fn LLVMBuildExecutionEngine(Mod: ModuleRef,
MM: RustJITMemoryManagerRef) -> ExecutionEngineRef;
pub fn LLVMDisposeExecutionEngine(EE: ExecutionEngineRef);
pub fn LLVMExecutionEngineFinalizeObject(EE: ExecutionEngineRef);
pub fn LLVMRustLoadDynamicLibrary(path: *const c_char) -> Bool;
pub fn LLVMExecutionEngineAddModule(EE: ExecutionEngineRef, M: ModuleRef);
pub fn LLVMExecutionEngineRemoveModule(EE: ExecutionEngineRef, M: ModuleRef)
-> Bool;

/* Metadata */
pub fn LLVMSetCurrentDebugLocation(Builder: BuilderRef, L: ValueRef);
Expand Down
112 changes: 112 additions & 0 deletions src/rustllvm/ExecutionEngineWrapper.cpp
@@ -0,0 +1,112 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#include "rustllvm.h"

#include "llvm/ExecutionEngine/SectionMemoryManager.h"

using namespace llvm;
using namespace llvm::sys;
using namespace llvm::object;

class RustJITMemoryManager : public SectionMemoryManager
{
typedef SectionMemoryManager Base;

const void *morestack;

public:

RustJITMemoryManager(const void *morestack_ptr)
: morestack(morestack_ptr)
{}

uint64_t getSymbolAddress(const std::string &Name) override
{
if (Name == "__morestack" || Name == "___morestack")
return reinterpret_cast<uint64_t>(morestack);

return Base::getSymbolAddress(Name);
}
};

DEFINE_SIMPLE_CONVERSION_FUNCTIONS(RustJITMemoryManager, LLVMRustJITMemoryManagerRef)

extern "C" LLVMRustJITMemoryManagerRef LLVMRustCreateJITMemoryManager(void *morestack)
{
return wrap(new RustJITMemoryManager(morestack));
}

extern "C" LLVMBool LLVMRustLoadDynamicLibrary(const char *path)
{
std::string err;
DynamicLibrary lib = DynamicLibrary::getPermanentLibrary(path, &err);

if (!lib.isValid())
LLVMRustSetLastError(err.c_str());

return lib.isValid();
}

// Calls LLVMAddModule;
// exists for consistency with LLVMExecutionEngineRemoveModule
extern "C" void LLVMExecutionEngineAddModule(
LLVMExecutionEngineRef eeref, LLVMModuleRef mref)
{
LLVMAddModule(eeref, mref);
}

// LLVMRemoveModule exists in LLVM's C bindings,
// but it requires pointless parameters
extern "C" LLVMBool LLVMExecutionEngineRemoveModule(
LLVMExecutionEngineRef eeref, LLVMModuleRef mref)
{
ExecutionEngine *ee = unwrap(eeref);
Module *m = unwrap(mref);

return ee->removeModule(m);
}

extern "C" LLVMExecutionEngineRef LLVMBuildExecutionEngine(
LLVMModuleRef mod, LLVMRustJITMemoryManagerRef mref)
{
// These are necessary for code generation to work properly.
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
InitializeNativeTargetAsmParser();

std::unique_ptr<Module> m(unwrap(mod));
RustJITMemoryManager *mm = unwrap(mref);

std::string error_str;
TargetOptions options;

options.JITEmitDebugInfo = true;
options.NoFramePointerElim = true;

ExecutionEngine *ee = EngineBuilder(std::move(m))
.setEngineKind(EngineKind::JIT)
.setErrorStr(&error_str)
.setMCJITMemoryManager(mm)
.setTargetOptions(options)
.create();

if (!ee)
LLVMRustSetLastError(error_str.c_str());

return wrap(ee);
}

extern "C" void LLVMExecutionEngineFinalizeObject(LLVMExecutionEngineRef eeref)
{
ExecutionEngine *ee = unwrap(eeref);

ee->finalizeObject();
}
1 change: 1 addition & 0 deletions src/rustllvm/rustllvm.h
Expand Up @@ -72,6 +72,7 @@ typedef struct OpaqueRustString *RustStringRef;
typedef struct LLVMOpaqueTwine *LLVMTwineRef;
typedef struct LLVMOpaqueDebugLoc *LLVMDebugLocRef;
typedef struct LLVMOpaqueSMDiagnostic *LLVMSMDiagnosticRef;
typedef struct LLVMOpaqueRustJITMemoryManager *LLVMRustJITMemoryManagerRef;

extern "C" void
rust_llvm_string_write_impl(RustStringRef str, const char *ptr, size_t size);
Expand Down

0 comments on commit 2c02845

Please sign in to comment.