]> git.lizzy.rs Git - rust.git/commitdiff
jit: Clean rustllvm code, let rustc expose __morestack instead of linking in libmores...
authorZack Corr <zack@z0w0.me>
Wed, 29 Aug 2012 05:49:35 +0000 (15:49 +1000)
committerBrian Anderson <banderson@mozilla.com>
Fri, 31 Aug 2012 23:20:36 +0000 (16:20 -0700)
mk/rustllvm.mk
src/rustc/back/link.rs
src/rustc/lib/llvm.rs
src/rustllvm/RustWrapper.cpp

index 804a2cec5f2b150f50c355c7fd92a8e3f322b298..622f7d4fa090a757820ba1ebb12a9f02334f9afb 100644 (file)
@@ -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))
 
index 82b1a52c37ca593d83b966d745a281bd68d2bde8..9632da761cbef595764ebe53a36c35e7bed9f792 100644 (file)
@@ -12,7 +12,7 @@
 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 @@ fn run_passes(sess: session, llmod: ModuleRef, output: &Path) {
                         });
                 }*/
 
-                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();
index f325b3a3d03511e4bcbc3aa840ee9aad3ae2ff47..ddce3c9640ef3cb177340c88c87aa50538bd4803 100644 (file)
@@ -990,10 +990,11 @@ fn LLVMRustWriteOutputFile(PM: PassManagerRef, M: ModuleRef,
     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;
index 0d19ccfeb36b77acfd4f93f7712603231bad407a..6ea433e6f1f053da5f16b43df92cc5fccceea027 100644 (file)
@@ -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;