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
|
@ -23,11 +23,10 @@ RUSTLLVM_OBJS_OBJS_$(1) := $$(RUSTLLVM_OBJS_CS_$(1):rustllvm/%.cpp=rustllvm/$(1)
|
|||
ALL_OBJ_FILES += $$(RUSTLLVM_OBJS_OBJS_$(1))
|
||||
|
||||
rustllvm/$(1)/$(CFG_RUSTLLVM): $$(RUSTLLVM_OBJS_OBJS_$(1)) \
|
||||
rt/$(1)/arch/$$(HOST_$(1))/libmorestack.a \
|
||||
$$(MKFILE_DEPS) $$(RUSTLLVM_DEF_$(1))
|
||||
@$$(call E, link: $$@)
|
||||
$$(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) \
|
||||
$$(LLVM_LDFLAGS_$(1)),$$(RUSTLLVM_DEF_$(1)),$$(CFG_RUSTLLVM))
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ import std::sha1::sha1;
|
|||
import syntax::ast;
|
||||
import syntax::print::pprust;
|
||||
import lib::llvm::{ModuleRef, mk_pass_manager, mk_target_data, True, False,
|
||||
FileType};
|
||||
PassManagerRef, FileType};
|
||||
import metadata::filesearch;
|
||||
import syntax::ast_map::{path, path_mod, path_name};
|
||||
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 {
|
||||
fn is_object_or_assembly_or_exe(ot: output_type) -> bool {
|
||||
if ot == output_type_assembly || ot == output_type_object ||
|
||||
|
@ -174,12 +225,7 @@ mod write {
|
|||
});
|
||||
}*/
|
||||
|
||||
if !llvm::LLVMRustJIT(pm.llpm,
|
||||
llmod,
|
||||
CodeGenOptLevel,
|
||||
true) {
|
||||
llvm_err(sess, ~"Could not JIT");
|
||||
}
|
||||
jit::exec(sess, pm.llpm, llmod, CodeGenOptLevel, true);
|
||||
|
||||
if sess.time_llvm_passes() {
|
||||
llvm::LLVMRustPrintPassTimings();
|
||||
|
|
|
@ -990,10 +990,11 @@ extern mod llvm {
|
|||
fn LLVMRustLoadLibrary(Filename: *c_char) -> bool;
|
||||
|
||||
/** Create and execute the JIT engine. */
|
||||
fn LLVMRustJIT(PM: PassManagerRef,
|
||||
fn LLVMRustJIT(__morestack: *(),
|
||||
PM: PassManagerRef,
|
||||
M: ModuleRef,
|
||||
OptLevel: c_int,
|
||||
EnableSegmentedStacks: bool) -> bool;
|
||||
EnableSegmentedStacks: bool) -> *();
|
||||
|
||||
/** Parses the bitcode in the given memory buffer. */
|
||||
fn LLVMRustParseBitcode(MemBuf: MemoryBufferRef) -> ModuleRef;
|
||||
|
|
|
@ -52,9 +52,6 @@
|
|||
#include <unistd.h>
|
||||
#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;
|
||||
|
||||
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
|
||||
// into the registry that Rust can not generate machine code for.
|
||||
|
||||
#define INITIALIZE_TARGETS() LLVMInitializeX86TargetInfo(); \
|
||||
LLVMInitializeX86Target(); \
|
||||
LLVMInitializeX86TargetMC(); \
|
||||
LLVMInitializeX86AsmPrinter(); \
|
||||
LLVMInitializeX86AsmParser();
|
||||
void LLVMRustInitializeTargets() {
|
||||
LLVMInitializeX86TargetInfo();
|
||||
LLVMInitializeX86Target();
|
||||
LLVMInitializeX86TargetMC();
|
||||
LLVMInitializeX86AsmPrinter();
|
||||
LLVMInitializeX86AsmParser();
|
||||
}
|
||||
|
||||
extern "C" bool
|
||||
LLVMRustLoadLibrary(const char* file) {
|
||||
|
@ -113,8 +112,6 @@ LLVMRustLoadLibrary(const char* file) {
|
|||
return true;
|
||||
}
|
||||
|
||||
ExecutionEngine* EE;
|
||||
|
||||
// Custom memory manager for MCJITting. It needs special features
|
||||
// that the generic JIT memory manager doesn't entail. Based on
|
||||
// code from LLI, change where needed for Rust.
|
||||
|
@ -123,8 +120,9 @@ public:
|
|||
SmallVector<sys::MemoryBlock, 16> AllocatedDataMem;
|
||||
SmallVector<sys::MemoryBlock, 16> AllocatedCodeMem;
|
||||
SmallVector<sys::MemoryBlock, 16> FreeCodeMem;
|
||||
void* __morestack;
|
||||
|
||||
RustMCJITMemoryManager() { }
|
||||
RustMCJITMemoryManager(void* sym) : __morestack(sym) { }
|
||||
~RustMCJITMemoryManager();
|
||||
|
||||
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;
|
||||
#endif
|
||||
|
||||
if (Name == "__morestack") return (void*)(intptr_t)&__morestack;
|
||||
if (Name == "__morestack") return &__morestack;
|
||||
|
||||
const char *NameStr = Name.c_str();
|
||||
void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr);
|
||||
|
@ -294,13 +292,13 @@ RustMCJITMemoryManager::~RustMCJITMemoryManager() {
|
|||
free(AllocatedDataMem[i].base());
|
||||
}
|
||||
|
||||
extern "C" bool
|
||||
LLVMRustJIT(LLVMPassManagerRef PMR,
|
||||
extern "C" void*
|
||||
LLVMRustJIT(void* __morestack,
|
||||
LLVMPassManagerRef PMR,
|
||||
LLVMModuleRef M,
|
||||
CodeGenOpt::Level OptLevel,
|
||||
bool EnableSegmentedStacks) {
|
||||
|
||||
INITIALIZE_TARGETS();
|
||||
InitializeNativeTarget();
|
||||
InitializeNativeTargetAsmPrinter();
|
||||
|
||||
|
@ -315,39 +313,37 @@ LLVMRustJIT(LLVMPassManagerRef PMR,
|
|||
PM->add(createInstructionCombiningPass());
|
||||
PM->add(createReassociatePass());
|
||||
PM->add(createGVNPass());
|
||||
PM->add(createPromoteMemoryToRegisterPass());
|
||||
PM->add(createCFGSimplificationPass());
|
||||
PM->add(createFunctionInliningPass());
|
||||
PM->add(createPromoteMemoryToRegisterPass());
|
||||
PM->run(*unwrap(M));
|
||||
|
||||
RustMCJITMemoryManager* MM = new RustMCJITMemoryManager();
|
||||
EE = EngineBuilder(unwrap(M))
|
||||
RustMCJITMemoryManager* MM = new RustMCJITMemoryManager(__morestack);
|
||||
ExecutionEngine* EE = EngineBuilder(unwrap(M))
|
||||
.setTargetOptions(Options)
|
||||
.setJITMemoryManager(MM)
|
||||
.setOptLevel(OptLevel)
|
||||
.setUseMCJIT(true)
|
||||
.setAllocateGVsWithCode(false)
|
||||
.create();
|
||||
|
||||
if(!EE || Err != "") {
|
||||
LLVMRustError = Err.c_str();
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
MM->invalidateInstructionCache();
|
||||
Function* func = EE->FindFunctionNamed("main");
|
||||
Function* func = EE->FindFunctionNamed("_rust_main");
|
||||
|
||||
if(!func || Err != "") {
|
||||
LLVMRustError = Err.c_str();
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef int (*Entry)(int, int);
|
||||
Entry entry = (Entry) EE->getPointerToFunction(func);
|
||||
|
||||
void* entry = EE->getPointerToFunction(func);
|
||||
assert(entry);
|
||||
entry(0, 0);
|
||||
|
||||
return true;
|
||||
return entry;
|
||||
}
|
||||
|
||||
extern "C" bool
|
||||
|
@ -359,7 +355,7 @@ LLVMRustWriteOutputFile(LLVMPassManagerRef PMR,
|
|||
CodeGenOpt::Level OptLevel,
|
||||
bool EnableSegmentedStacks) {
|
||||
|
||||
INITIALIZE_TARGETS();
|
||||
LLVMRustInitializeTargets();
|
||||
|
||||
TargetOptions Options;
|
||||
Options.NoFramePointerElim = true;
|
||||
|
|
Loading…
Reference in New Issue