jit: Clean rustllvm code, let rustc expose __morestack instead of linking in libmorestack and return _rust_main and call it from rustc
This commit is contained in:
parent
e27b8f7f02
commit
efb576a60d
4 changed files with 80 additions and 38 deletions
|
@ -23,11 +23,10 @@ RUSTLLVM_OBJS_OBJS_$(1) := $$(RUSTLLVM_OBJS_CS_$(1):rustllvm/%.cpp=rustllvm/$(1)
|
||||||
ALL_OBJ_FILES += $$(RUSTLLVM_OBJS_OBJS_$(1))
|
ALL_OBJ_FILES += $$(RUSTLLVM_OBJS_OBJS_$(1))
|
||||||
|
|
||||||
rustllvm/$(1)/$(CFG_RUSTLLVM): $$(RUSTLLVM_OBJS_OBJS_$(1)) \
|
rustllvm/$(1)/$(CFG_RUSTLLVM): $$(RUSTLLVM_OBJS_OBJS_$(1)) \
|
||||||
rt/$(1)/arch/$$(HOST_$(1))/libmorestack.a \
|
|
||||||
$$(MKFILE_DEPS) $$(RUSTLLVM_DEF_$(1))
|
$$(MKFILE_DEPS) $$(RUSTLLVM_DEF_$(1))
|
||||||
@$$(call E, link: $$@)
|
@$$(call E, link: $$@)
|
||||||
$$(Q)$$(call CFG_LINK_C_$(1),$$@,$$(RUSTLLVM_OBJS_OBJS_$(1)) \
|
$$(Q)$$(call CFG_LINK_C_$(1),$$@,$$(RUSTLLVM_OBJS_OBJS_$(1)) \
|
||||||
$$(CFG_GCCISH_PRE_LIB_FLAGS) $$(LLVM_LIBS_$(1)) rt/$(1)/arch/$$(HOST_$(1))/libmorestack.a \
|
$$(CFG_GCCISH_PRE_LIB_FLAGS) $$(LLVM_LIBS_$(1)) \
|
||||||
$$(CFG_GCCISH_POST_LIB_FLAGS) \
|
$$(CFG_GCCISH_POST_LIB_FLAGS) \
|
||||||
$$(LLVM_LDFLAGS_$(1)),$$(RUSTLLVM_DEF_$(1)),$$(CFG_RUSTLLVM))
|
$$(LLVM_LDFLAGS_$(1)),$$(RUSTLLVM_DEF_$(1)),$$(CFG_RUSTLLVM))
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ import std::sha1::sha1;
|
||||||
import syntax::ast;
|
import syntax::ast;
|
||||||
import syntax::print::pprust;
|
import syntax::print::pprust;
|
||||||
import lib::llvm::{ModuleRef, mk_pass_manager, mk_target_data, True, False,
|
import lib::llvm::{ModuleRef, mk_pass_manager, mk_target_data, True, False,
|
||||||
FileType};
|
PassManagerRef, FileType};
|
||||||
import metadata::filesearch;
|
import metadata::filesearch;
|
||||||
import syntax::ast_map::{path, path_mod, path_name};
|
import syntax::ast_map::{path, path_mod, path_name};
|
||||||
import io::{Writer, WriterUtil};
|
import io::{Writer, WriterUtil};
|
||||||
|
@ -54,6 +54,57 @@ fn WriteOutputFile(sess:session,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(stage0)]
|
||||||
|
mod jit {
|
||||||
|
fn exec(_sess: session,
|
||||||
|
_pm: PassManagerRef,
|
||||||
|
_m: ModuleRef,
|
||||||
|
_opt: c_int,
|
||||||
|
_stacks: bool) {
|
||||||
|
fail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(stage1)]
|
||||||
|
#[cfg(stage2)]
|
||||||
|
#[cfg(stage3)]
|
||||||
|
mod jit {
|
||||||
|
#[nolink]
|
||||||
|
#[abi = "rust-intrinsic"]
|
||||||
|
extern mod rusti {
|
||||||
|
fn morestack_addr() -> *();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Closure {
|
||||||
|
code: *();
|
||||||
|
env: *();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn exec(sess: session,
|
||||||
|
pm: PassManagerRef,
|
||||||
|
m: ModuleRef,
|
||||||
|
opt: c_int,
|
||||||
|
stacks: bool) unsafe {
|
||||||
|
let ptr = llvm::LLVMRustJIT(rusti::morestack_addr(), pm, m, opt, stacks);
|
||||||
|
|
||||||
|
if ptr::is_null(ptr) {
|
||||||
|
llvm_err(sess, ~"Could not JIT");
|
||||||
|
} else {
|
||||||
|
let bin = match os::self_exe_path() {
|
||||||
|
Some(path) => path.to_str(),
|
||||||
|
_ => ~"rustc"
|
||||||
|
};
|
||||||
|
let closure = Closure {
|
||||||
|
code: ptr,
|
||||||
|
env: ptr::null()
|
||||||
|
};
|
||||||
|
let func: fn(~[~str]) = unsafe::transmute(closure);
|
||||||
|
|
||||||
|
func(~[bin]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mod write {
|
mod write {
|
||||||
fn is_object_or_assembly_or_exe(ot: output_type) -> bool {
|
fn is_object_or_assembly_or_exe(ot: output_type) -> bool {
|
||||||
if ot == output_type_assembly || ot == output_type_object ||
|
if ot == output_type_assembly || ot == output_type_object ||
|
||||||
|
@ -174,12 +225,7 @@ mod write {
|
||||||
});
|
});
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
if !llvm::LLVMRustJIT(pm.llpm,
|
jit::exec(sess, pm.llpm, llmod, CodeGenOptLevel, true);
|
||||||
llmod,
|
|
||||||
CodeGenOptLevel,
|
|
||||||
true) {
|
|
||||||
llvm_err(sess, ~"Could not JIT");
|
|
||||||
}
|
|
||||||
|
|
||||||
if sess.time_llvm_passes() {
|
if sess.time_llvm_passes() {
|
||||||
llvm::LLVMRustPrintPassTimings();
|
llvm::LLVMRustPrintPassTimings();
|
||||||
|
|
|
@ -990,10 +990,11 @@ extern mod llvm {
|
||||||
fn LLVMRustLoadLibrary(Filename: *c_char) -> bool;
|
fn LLVMRustLoadLibrary(Filename: *c_char) -> bool;
|
||||||
|
|
||||||
/** Create and execute the JIT engine. */
|
/** Create and execute the JIT engine. */
|
||||||
fn LLVMRustJIT(PM: PassManagerRef,
|
fn LLVMRustJIT(__morestack: *(),
|
||||||
|
PM: PassManagerRef,
|
||||||
M: ModuleRef,
|
M: ModuleRef,
|
||||||
OptLevel: c_int,
|
OptLevel: c_int,
|
||||||
EnableSegmentedStacks: bool) -> bool;
|
EnableSegmentedStacks: 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;
|
||||||
|
|
|
@ -52,9 +52,6 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Does this need to be done, or can it be made to resolve from the main program?
|
|
||||||
extern "C" void __morestack(void *args, void *fn_ptr, uintptr_t stack_ptr);
|
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
static const char *LLVMRustError;
|
static const char *LLVMRustError;
|
||||||
|
@ -95,11 +92,13 @@ void LLVMInitializeX86AsmParser();
|
||||||
// that rustllvm doesn't actually link to and it's pointless to put target info
|
// that rustllvm doesn't actually link to and it's pointless to put target info
|
||||||
// into the registry that Rust can not generate machine code for.
|
// into the registry that Rust can not generate machine code for.
|
||||||
|
|
||||||
#define INITIALIZE_TARGETS() LLVMInitializeX86TargetInfo(); \
|
void LLVMRustInitializeTargets() {
|
||||||
LLVMInitializeX86Target(); \
|
LLVMInitializeX86TargetInfo();
|
||||||
LLVMInitializeX86TargetMC(); \
|
LLVMInitializeX86Target();
|
||||||
LLVMInitializeX86AsmPrinter(); \
|
LLVMInitializeX86TargetMC();
|
||||||
LLVMInitializeX86AsmParser();
|
LLVMInitializeX86AsmPrinter();
|
||||||
|
LLVMInitializeX86AsmParser();
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" bool
|
extern "C" bool
|
||||||
LLVMRustLoadLibrary(const char* file) {
|
LLVMRustLoadLibrary(const char* file) {
|
||||||
|
@ -113,8 +112,6 @@ LLVMRustLoadLibrary(const char* file) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExecutionEngine* EE;
|
|
||||||
|
|
||||||
// Custom memory manager for MCJITting. It needs special features
|
// Custom memory manager for MCJITting. It needs special features
|
||||||
// that the generic JIT memory manager doesn't entail. Based on
|
// that the generic JIT memory manager doesn't entail. Based on
|
||||||
// code from LLI, change where needed for Rust.
|
// code from LLI, change where needed for Rust.
|
||||||
|
@ -123,8 +120,9 @@ public:
|
||||||
SmallVector<sys::MemoryBlock, 16> AllocatedDataMem;
|
SmallVector<sys::MemoryBlock, 16> AllocatedDataMem;
|
||||||
SmallVector<sys::MemoryBlock, 16> AllocatedCodeMem;
|
SmallVector<sys::MemoryBlock, 16> AllocatedCodeMem;
|
||||||
SmallVector<sys::MemoryBlock, 16> FreeCodeMem;
|
SmallVector<sys::MemoryBlock, 16> FreeCodeMem;
|
||||||
|
void* __morestack;
|
||||||
|
|
||||||
RustMCJITMemoryManager() { }
|
RustMCJITMemoryManager(void* sym) : __morestack(sym) { }
|
||||||
~RustMCJITMemoryManager();
|
~RustMCJITMemoryManager();
|
||||||
|
|
||||||
virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
|
virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
|
||||||
|
@ -275,7 +273,7 @@ void *RustMCJITMemoryManager::getPointerToNamedFunction(const std::string &Name,
|
||||||
if (Name == "mknod") return (void*)(intptr_t)&mknod;
|
if (Name == "mknod") return (void*)(intptr_t)&mknod;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (Name == "__morestack") return (void*)(intptr_t)&__morestack;
|
if (Name == "__morestack") return &__morestack;
|
||||||
|
|
||||||
const char *NameStr = Name.c_str();
|
const char *NameStr = Name.c_str();
|
||||||
void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr);
|
void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr);
|
||||||
|
@ -294,13 +292,13 @@ RustMCJITMemoryManager::~RustMCJITMemoryManager() {
|
||||||
free(AllocatedDataMem[i].base());
|
free(AllocatedDataMem[i].base());
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" bool
|
extern "C" void*
|
||||||
LLVMRustJIT(LLVMPassManagerRef PMR,
|
LLVMRustJIT(void* __morestack,
|
||||||
|
LLVMPassManagerRef PMR,
|
||||||
LLVMModuleRef M,
|
LLVMModuleRef M,
|
||||||
CodeGenOpt::Level OptLevel,
|
CodeGenOpt::Level OptLevel,
|
||||||
bool EnableSegmentedStacks) {
|
bool EnableSegmentedStacks) {
|
||||||
|
|
||||||
INITIALIZE_TARGETS();
|
|
||||||
InitializeNativeTarget();
|
InitializeNativeTarget();
|
||||||
InitializeNativeTargetAsmPrinter();
|
InitializeNativeTargetAsmPrinter();
|
||||||
|
|
||||||
|
@ -315,39 +313,37 @@ LLVMRustJIT(LLVMPassManagerRef PMR,
|
||||||
PM->add(createInstructionCombiningPass());
|
PM->add(createInstructionCombiningPass());
|
||||||
PM->add(createReassociatePass());
|
PM->add(createReassociatePass());
|
||||||
PM->add(createGVNPass());
|
PM->add(createGVNPass());
|
||||||
PM->add(createPromoteMemoryToRegisterPass());
|
|
||||||
PM->add(createCFGSimplificationPass());
|
PM->add(createCFGSimplificationPass());
|
||||||
PM->add(createFunctionInliningPass());
|
PM->add(createFunctionInliningPass());
|
||||||
|
PM->add(createPromoteMemoryToRegisterPass());
|
||||||
PM->run(*unwrap(M));
|
PM->run(*unwrap(M));
|
||||||
|
|
||||||
RustMCJITMemoryManager* MM = new RustMCJITMemoryManager();
|
RustMCJITMemoryManager* MM = new RustMCJITMemoryManager(__morestack);
|
||||||
EE = EngineBuilder(unwrap(M))
|
ExecutionEngine* EE = EngineBuilder(unwrap(M))
|
||||||
.setTargetOptions(Options)
|
.setTargetOptions(Options)
|
||||||
.setJITMemoryManager(MM)
|
.setJITMemoryManager(MM)
|
||||||
.setOptLevel(OptLevel)
|
.setOptLevel(OptLevel)
|
||||||
.setUseMCJIT(true)
|
.setUseMCJIT(true)
|
||||||
|
.setAllocateGVsWithCode(false)
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
if(!EE || Err != "") {
|
if(!EE || Err != "") {
|
||||||
LLVMRustError = Err.c_str();
|
LLVMRustError = Err.c_str();
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
MM->invalidateInstructionCache();
|
MM->invalidateInstructionCache();
|
||||||
Function* func = EE->FindFunctionNamed("main");
|
Function* func = EE->FindFunctionNamed("_rust_main");
|
||||||
|
|
||||||
if(!func || Err != "") {
|
if(!func || Err != "") {
|
||||||
LLVMRustError = Err.c_str();
|
LLVMRustError = Err.c_str();
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef int (*Entry)(int, int);
|
void* entry = EE->getPointerToFunction(func);
|
||||||
Entry entry = (Entry) EE->getPointerToFunction(func);
|
|
||||||
|
|
||||||
assert(entry);
|
assert(entry);
|
||||||
entry(0, 0);
|
|
||||||
|
|
||||||
return true;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" bool
|
extern "C" bool
|
||||||
|
@ -359,7 +355,7 @@ LLVMRustWriteOutputFile(LLVMPassManagerRef PMR,
|
||||||
CodeGenOpt::Level OptLevel,
|
CodeGenOpt::Level OptLevel,
|
||||||
bool EnableSegmentedStacks) {
|
bool EnableSegmentedStacks) {
|
||||||
|
|
||||||
INITIALIZE_TARGETS();
|
LLVMRustInitializeTargets();
|
||||||
|
|
||||||
TargetOptions Options;
|
TargetOptions Options;
|
||||||
Options.NoFramePointerElim = true;
|
Options.NoFramePointerElim = true;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue