1
Fork 0

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:
Zack Corr 2012-08-29 15:49:35 +10:00 committed by Brian Anderson
parent e27b8f7f02
commit efb576a60d
4 changed files with 80 additions and 38 deletions

View file

@ -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))

View file

@ -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();

View file

@ -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;

View file

@ -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;