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

View File

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

View File

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

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