diff options
| author | Zack Corr <zack@z0w0.me> | 2012-08-29 15:49:35 +1000 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2012-08-31 16:20:36 -0700 |
| commit | efb576a60dbd12cdd9c732cb5d8b202283b9864a (patch) | |
| tree | 0edac79bfc3b3c8931c5d2d14a71174590513aed | |
| parent | e27b8f7f02a6d9f963aae5823bbe07a962c04e33 (diff) | |
jit: Clean rustllvm code, let rustc expose __morestack instead of linking in libmorestack and return _rust_main and call it from rustc
| -rw-r--r-- | mk/rustllvm.mk | 3 | ||||
| -rw-r--r-- | src/rustc/back/link.rs | 60 | ||||
| -rw-r--r-- | src/rustc/lib/llvm.rs | 5 | ||||
| -rw-r--r-- | src/rustllvm/RustWrapper.cpp | 50 |
4 files changed, 80 insertions, 38 deletions
diff --git a/mk/rustllvm.mk b/mk/rustllvm.mk index 804a2cec5f2..622f7d4fa09 100644 --- a/mk/rustllvm.mk +++ b/mk/rustllvm.mk @@ -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)) diff --git a/src/rustc/back/link.rs b/src/rustc/back/link.rs index 82b1a52c37c..9632da761cb 100644 --- a/src/rustc/back/link.rs +++ b/src/rustc/back/link.rs @@ -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(); diff --git a/src/rustc/lib/llvm.rs b/src/rustc/lib/llvm.rs index f325b3a3d03..ddce3c9640e 100644 --- a/src/rustc/lib/llvm.rs +++ b/src/rustc/lib/llvm.rs @@ -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; diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 0d19ccfeb36..6ea433e6f1f 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -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; |
