Skip to content

Commit

Permalink
auto merge of rust-lang#7125 : alexcrichton/rust/rusti-issues, r=brson
Browse files Browse the repository at this point in the history
This un-reverts the reverts of the rusti commits made awhile back. These were reverted for an LLVM failure in rustpkg. I believe that this is not a problem with these commits, but rather that rustc is being used in parallel for rustpkg tests (in-process). This is not working yet (almost! see rust-lang#7011), so I serialized all the tests to run one after another.

@brson, I'm mainly just guessing as to the cause of the LLVM failures in rustpkg tests. I'm confident that running tests in parallel is more likely to be the problem than those commits I made.

Additionally, this fixes two recently reported issues with rusti.
  • Loading branch information
bors committed Jun 15, 2013
2 parents 7d1065e + 9c3b1cb commit 83d44f8
Show file tree
Hide file tree
Showing 15 changed files with 241 additions and 214 deletions.
106 changes: 55 additions & 51 deletions src/librustc/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,34 +101,21 @@ pub mod jit {
use back::link::llvm_err;
use driver::session::Session;
use lib::llvm::llvm;
use lib::llvm::{ModuleRef, PassManagerRef};
use lib::llvm::{ModuleRef, ContextRef};
use metadata::cstore;

use core::cast;
use core::libc::c_int;
use core::ptr;
use core::str;

pub mod rusti {
#[nolink]
#[abi = "rust-intrinsic"]
pub extern "rust-intrinsic" {
pub fn morestack_addr() -> *();
}
}

pub struct Closure {
code: *(),
env: *(),
}
use core::sys;
use core::unstable::intrinsics;

pub fn exec(sess: Session,
pm: PassManagerRef,
c: ContextRef,
m: ModuleRef,
opt: c_int,
stacks: bool) {
unsafe {
let manager = llvm::LLVMRustPrepareJIT(rusti::morestack_addr());
let manager = llvm::LLVMRustPrepareJIT(intrinsics::morestack_addr());

// We need to tell JIT where to resolve all linked
// symbols from. The equivalent of -lstd, -lcore, etc.
Expand All @@ -152,26 +139,43 @@ pub mod jit {
});
}

// The execute function will return a void pointer
// to the _rust_main function. We can do closure
// magic here to turn it straight into a callable rust
// closure. It will also cleanup the memory manager
// for us.

let entry = llvm::LLVMRustExecuteJIT(manager,
pm, m, opt, stacks);

if ptr::is_null(entry) {
llvm_err(sess, ~"Could not JIT");
} else {
let closure = Closure {
code: entry,
env: ptr::null()
};
let func: &fn() = cast::transmute(closure);
// We custom-build a JIT execution engine via some rust wrappers
// first. This wrappers takes ownership of the module passed in.
let ee = llvm::LLVMRustBuildJIT(manager, m, stacks);
if ee.is_null() {
llvm::LLVMContextDispose(c);
llvm_err(sess, ~"Could not create the JIT");
}

func();
// Next, we need to get a handle on the _rust_main function by
// looking up it's corresponding ValueRef and then requesting that
// the execution engine compiles the function.
let fun = do str::as_c_str("_rust_main") |entry| {
llvm::LLVMGetNamedFunction(m, entry)
};
if fun.is_null() {
llvm::LLVMDisposeExecutionEngine(ee);
llvm::LLVMContextDispose(c);
llvm_err(sess, ~"Could not find _rust_main in the JIT");
}

// Finally, once we have the pointer to the code, we can do some
// closure magic here to turn it straight into a callable rust
// closure
let code = llvm::LLVMGetPointerToGlobal(ee, fun);
assert!(!code.is_null());
let closure = sys::Closure {
code: code,
env: ptr::null()
};
let func: &fn() = cast::transmute(closure);
func();

// Sadly, there currently is no interface to re-use this execution
// engine, so it's disposed of here along with the context to
// prevent leaks.
llvm::LLVMDisposeExecutionEngine(ee);
llvm::LLVMContextDispose(c);
}
}
}
Expand All @@ -188,6 +192,7 @@ pub mod write {
use driver::session;
use lib::llvm::llvm;
use lib::llvm::{ModuleRef, mk_pass_manager, mk_target_data};
use lib::llvm::{ContextRef};
use lib;

use back::passes;
Expand All @@ -206,6 +211,7 @@ pub mod write {
}

pub fn run_passes(sess: Session,
llcx: ContextRef,
llmod: ModuleRef,
output_type: output_type,
output: &Path) {
Expand Down Expand Up @@ -261,7 +267,17 @@ pub mod write {
debug!("Running Module Optimization Pass");
mpm.run(llmod);

if is_object_or_assembly_or_exe(output_type) || opts.jit {
if opts.jit {
// If we are using JIT, go ahead and create and execute the
// engine now. JIT execution takes ownership of the module and
// context, so don't dispose and return.
jit::exec(sess, llcx, llmod, true);

if sess.time_llvm_passes() {
llvm::LLVMRustPrintPassTimings();
}
return;
} else if is_object_or_assembly_or_exe(output_type) {
let LLVMOptNone = 0 as c_int; // -O0
let LLVMOptLess = 1 as c_int; // -O1
let LLVMOptDefault = 2 as c_int; // -O2, -Os
Expand All @@ -274,20 +290,6 @@ pub mod write {
session::Aggressive => LLVMOptAggressive
};

if opts.jit {
// If we are using JIT, go ahead and create and
// execute the engine now.
// JIT execution takes ownership of the module,
// so don't dispose and return.

jit::exec(sess, pm.llpm, llmod, CodeGenOptLevel, true);

if sess.time_llvm_passes() {
llvm::LLVMRustPrintPassTimings();
}
return;
}

let FileType;
if output_type == output_type_object ||
output_type == output_type_exe {
Expand Down Expand Up @@ -348,6 +350,7 @@ pub mod write {
// Clean up and return

llvm::LLVMDisposeModule(llmod);
llvm::LLVMContextDispose(llcx);
if sess.time_llvm_passes() {
llvm::LLVMRustPrintPassTimings();
}
Expand All @@ -366,6 +369,7 @@ pub mod write {
}

llvm::LLVMDisposeModule(llmod);
llvm::LLVMContextDispose(llcx);
if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); }
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/librustc/driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ pub fn compile_rest(sess: Session,

let mut crate = crate_opt.unwrap();

let (llmod, link_meta) = {
let (llcx, llmod, link_meta) = {
crate = time(time_passes, ~"intrinsic injection", ||
front::intrinsic_inject::inject_intrinsic(sess, crate));

Expand Down Expand Up @@ -338,14 +338,14 @@ pub fn compile_rest(sess: Session,
let obj_filename = outputs.obj_filename.with_filetype("s");

time(time_passes, ~"LLVM passes", ||
link::write::run_passes(sess, llmod, output_type,
&obj_filename));
link::write::run_passes(sess, llcx, llmod, output_type,
&obj_filename));

link::write::run_ndk(sess, &obj_filename, &outputs.obj_filename);
} else {
time(time_passes, ~"LLVM passes", ||
link::write::run_passes(sess, llmod, sess.opts.output_type,
&outputs.obj_filename));
link::write::run_passes(sess, llcx, llmod, sess.opts.output_type,
&outputs.obj_filename));
}

let stop_after_codegen =
Expand Down
Loading

0 comments on commit 83d44f8

Please sign in to comment.