jit: Add passes and cleanup code
This commit is contained in:
parent
795acb7395
commit
19ea3ab480
4 changed files with 26 additions and 44 deletions
|
@ -152,27 +152,14 @@ mod write {
|
||||||
if opts.jit {
|
if opts.jit {
|
||||||
// If we are using JIT, go ahead and create and
|
// If we are using JIT, go ahead and create and
|
||||||
// execute the engine now.
|
// execute the engine now.
|
||||||
|
|
||||||
/*llvm::LLVMAddBasicAliasAnalysisPass(pm.llpm);
|
|
||||||
llvm::LLVMAddInstructionCombiningPass(pm.llpm);
|
|
||||||
llvm::LLVMAddReassociatePass(pm.llpm);
|
|
||||||
llvm::LLVMAddGVNPass(pm.llpm);
|
|
||||||
llvm::LLVMAddCFGSimplificationPass(pm.llpm);*/
|
|
||||||
|
|
||||||
// JIT execution takes ownership of the module,
|
// JIT execution takes ownership of the module,
|
||||||
// so don't dispose and return. Due to a weird bug
|
// so don't dispose and return.
|
||||||
// with dynamic libraries, we need to separate jitting
|
|
||||||
// into two functions and load crates inbetween.
|
|
||||||
|
|
||||||
if !llvm::LLVMRustPrepareJIT(pm.llpm,
|
|
||||||
llmod,
|
|
||||||
CodeGenOptLevel,
|
|
||||||
true) {
|
|
||||||
llvm_err(sess, ~"Could not JIT");
|
|
||||||
}
|
|
||||||
|
|
||||||
// We need to tell LLVM where to resolve all linked
|
// We need to tell LLVM where to resolve all linked
|
||||||
// symbols from. The equivalent of -lstd, -lcore, etc.
|
// symbols from. The equivalent of -lstd, -lcore, etc.
|
||||||
|
// By default the JIT will resolve symbols from the std and
|
||||||
|
// core linked into rustc. We don't want that,
|
||||||
|
// incase the user wants to use an older std library.
|
||||||
/*let cstore = sess.cstore;
|
/*let cstore = sess.cstore;
|
||||||
for cstore::get_used_crate_files(cstore).each |cratepath| {
|
for cstore::get_used_crate_files(cstore).each |cratepath| {
|
||||||
debug!{"linking: %s", cratepath};
|
debug!{"linking: %s", cratepath};
|
||||||
|
@ -187,7 +174,10 @@ mod write {
|
||||||
});
|
});
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
if !llvm::LLVMRustExecuteJIT() {
|
if !llvm::LLVMRustJIT(pm.llpm,
|
||||||
|
llmod,
|
||||||
|
CodeGenOptLevel,
|
||||||
|
true) {
|
||||||
llvm_err(sess, ~"Could not JIT");
|
llvm_err(sess, ~"Could not JIT");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -989,15 +989,12 @@ extern mod llvm {
|
||||||
/** Load a shared library to resolve symbols against. */
|
/** Load a shared library to resolve symbols against. */
|
||||||
fn LLVMRustLoadLibrary(Filename: *c_char) -> bool;
|
fn LLVMRustLoadLibrary(Filename: *c_char) -> bool;
|
||||||
|
|
||||||
/** Create the JIT engine. */
|
/** Create and execute the JIT engine. */
|
||||||
fn LLVMRustPrepareJIT(PM: PassManagerRef,
|
fn LLVMRustJIT(PM: PassManagerRef,
|
||||||
M: ModuleRef,
|
M: ModuleRef,
|
||||||
OptLevel: c_int,
|
OptLevel: c_int,
|
||||||
EnableSegmentedStacks: bool) -> bool;
|
EnableSegmentedStacks: bool) -> bool;
|
||||||
|
|
||||||
/** Execute the JIT engine. */
|
|
||||||
fn LLVMRustExecuteJIT() -> bool;
|
|
||||||
|
|
||||||
/** Parses the bitcode in the given memory buffer. */
|
/** Parses the bitcode in the given memory buffer. */
|
||||||
fn LLVMRustParseBitcode(MemBuf: MemoryBufferRef) -> ModuleRef;
|
fn LLVMRustParseBitcode(MemBuf: MemoryBufferRef) -> ModuleRef;
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,9 @@
|
||||||
#include "llvm/LLVMContext.h"
|
#include "llvm/LLVMContext.h"
|
||||||
#include "llvm/Linker.h"
|
#include "llvm/Linker.h"
|
||||||
#include "llvm/PassManager.h"
|
#include "llvm/PassManager.h"
|
||||||
|
#include "llvm/Analysis/Verifier.h"
|
||||||
|
#include "llvm/Analysis/Passes.h"
|
||||||
|
#include "llvm/Transforms/Scalar.h"
|
||||||
#include "llvm/ADT/Triple.h"
|
#include "llvm/ADT/Triple.h"
|
||||||
#include "llvm/Assembly/Parser.h"
|
#include "llvm/Assembly/Parser.h"
|
||||||
#include "llvm/Assembly/PrintModulePass.h"
|
#include "llvm/Assembly/PrintModulePass.h"
|
||||||
|
@ -35,7 +38,6 @@
|
||||||
#include "llvm/ExecutionEngine/JITMemoryManager.h"
|
#include "llvm/ExecutionEngine/JITMemoryManager.h"
|
||||||
#include "llvm/ExecutionEngine/MCJIT.h"
|
#include "llvm/ExecutionEngine/MCJIT.h"
|
||||||
#include "llvm/ExecutionEngine/Interpreter.h"
|
#include "llvm/ExecutionEngine/Interpreter.h"
|
||||||
#include "llvm/ExecutionEngine/GenericValue.h"
|
|
||||||
#include "llvm-c/Core.h"
|
#include "llvm-c/Core.h"
|
||||||
#include "llvm-c/BitReader.h"
|
#include "llvm-c/BitReader.h"
|
||||||
#include "llvm-c/Object.h"
|
#include "llvm-c/Object.h"
|
||||||
|
@ -291,11 +293,8 @@ RustMCJITMemoryManager::~RustMCJITMemoryManager() {
|
||||||
free(AllocatedDataMem[i].base());
|
free(AllocatedDataMem[i].base());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Separated functions because loading libraries before creating
|
|
||||||
// an execution engine seems to break stuff.
|
|
||||||
|
|
||||||
extern "C" bool
|
extern "C" bool
|
||||||
LLVMRustPrepareJIT(LLVMPassManagerRef PMR,
|
LLVMRustJIT(LLVMPassManagerRef PMR,
|
||||||
LLVMModuleRef M,
|
LLVMModuleRef M,
|
||||||
CodeGenOpt::Level OptLevel,
|
CodeGenOpt::Level OptLevel,
|
||||||
bool EnableSegmentedStacks) {
|
bool EnableSegmentedStacks) {
|
||||||
|
@ -309,8 +308,16 @@ LLVMRustPrepareJIT(LLVMPassManagerRef PMR,
|
||||||
Options.JITEmitDebugInfo = true;
|
Options.JITEmitDebugInfo = true;
|
||||||
Options.NoFramePointerElim = true;
|
Options.NoFramePointerElim = true;
|
||||||
Options.EnableSegmentedStacks = EnableSegmentedStacks;
|
Options.EnableSegmentedStacks = EnableSegmentedStacks;
|
||||||
|
PassManager *PM = unwrap<PassManager>(PMR);
|
||||||
|
|
||||||
unwrap<PassManager>(PMR)->run(*unwrap(M));
|
PM->add(createBasicAliasAnalysisPass());
|
||||||
|
PM->add(createInstructionCombiningPass());
|
||||||
|
PM->add(createReassociatePass());
|
||||||
|
PM->add(createGVNPass());
|
||||||
|
PM->add(createPromoteMemoryToRegisterPass());
|
||||||
|
PM->add(createCFGSimplificationPass());
|
||||||
|
PM->add(createFunctionInliningPass());
|
||||||
|
PM->run(*unwrap(M));
|
||||||
|
|
||||||
RustMCJITMemoryManager* MM = new RustMCJITMemoryManager();
|
RustMCJITMemoryManager* MM = new RustMCJITMemoryManager();
|
||||||
EE = EngineBuilder(unwrap(M))
|
EE = EngineBuilder(unwrap(M))
|
||||||
|
@ -326,15 +333,6 @@ LLVMRustPrepareJIT(LLVMPassManagerRef PMR,
|
||||||
}
|
}
|
||||||
|
|
||||||
MM->invalidateInstructionCache();
|
MM->invalidateInstructionCache();
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" bool
|
|
||||||
LLVMRustExecuteJIT() {
|
|
||||||
assert(EE);
|
|
||||||
|
|
||||||
std::string Err;
|
|
||||||
Function* func = EE->FindFunctionNamed("main");
|
Function* func = EE->FindFunctionNamed("main");
|
||||||
|
|
||||||
if(!func || Err != "") {
|
if(!func || Err != "") {
|
||||||
|
@ -342,13 +340,11 @@ LLVMRustExecuteJIT() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//std::vector<GenericValue> args;
|
typedef int (*Entry)(int, int);
|
||||||
typedef int (*entry_t)(int, int);
|
Entry entry = (Entry) EE->getPointerToFunction(func);
|
||||||
entry_t entry = (entry_t) EE->getPointerToFunction(func);
|
|
||||||
|
|
||||||
assert(entry);
|
assert(entry);
|
||||||
entry(0, 0);
|
entry(0, 0);
|
||||||
//EE->runFunction(func, args);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,7 @@ LLVMRustGetLastError
|
||||||
LLVMRustConstSmallInt
|
LLVMRustConstSmallInt
|
||||||
LLVMRustConstInt
|
LLVMRustConstInt
|
||||||
LLVMRustLoadLibrary
|
LLVMRustLoadLibrary
|
||||||
LLVMRustPrepareJIT
|
LLVMRustJIT
|
||||||
LLVMRustExecuteJIT
|
|
||||||
LLVMRustParseBitcode
|
LLVMRustParseBitcode
|
||||||
LLVMRustParseAssemblyFile
|
LLVMRustParseAssemblyFile
|
||||||
LLVMRustPrintPassTimings
|
LLVMRustPrintPassTimings
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue