diff --git a/mk/llvm.mk b/mk/llvm.mk index efaa109c29e91..42b1a551805af 100644 --- a/mk/llvm.mk +++ b/mk/llvm.mk @@ -37,7 +37,9 @@ endif # dependencies. In these cases, commit a change that touches # the stamp in the source dir. $$(LLVM_STAMP_$(1)): $(S)src/rustllvm/llvm-auto-clean-trigger + @$$(call E, make: cleaning llvm) $(Q)$(MAKE) clean-llvm + @$$(call E, make: done cleaning llvm) touch $$@ endef diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 1c4b15f42e986..1cb10d59e59c9 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -82,111 +82,8 @@ pub fn WriteOutputFile( } } -pub mod jit { - - use back::link::llvm_err; - use driver::session::Session; - use lib::llvm::llvm; - use lib::llvm::{ModuleRef, ContextRef, ExecutionEngineRef}; - - use std::c_str::ToCStr; - use std::cast; - use std::local_data; - use std::unstable::intrinsics; - - struct LLVMJITData { - ee: ExecutionEngineRef, - llcx: ContextRef - } - - pub trait Engine {} - impl Engine for LLVMJITData {} - - impl Drop for LLVMJITData { - fn drop(&mut self) { - unsafe { - llvm::LLVMDisposeExecutionEngine(self.ee); - llvm::LLVMContextDispose(self.llcx); - } - } - } - - pub fn exec(sess: Session, - c: ContextRef, - m: ModuleRef, - stacks: bool) { - unsafe { - 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. - // By default the JIT will resolve symbols from the extra and - // core linked into rustc. We don't want that, - // incase the user wants to use an older extra library. - - // 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"); - } - - // 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 = "_rust_main".with_c_str(|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 func: extern "Rust" fn() = cast::transmute(code); - func(); - - // Currently there is no method of re-using the executing engine - // from LLVM in another call to the JIT. While this kinda defeats - // the purpose of having a JIT in the first place, there isn't - // actually much code currently which would re-use data between - // different invocations of this. Additionally, the compilation - // model currently isn't designed to support this scenario. - // - // We can't destroy the engine/context immediately here, however, - // because of annihilation. The JIT code contains drop glue for any - // types defined in the crate we just ran, and if any of those boxes - // are going to be dropped during annihilation, the drop glue must - // be run. Hence, we need to transfer ownership of this jit engine - // to the caller of this function. To be convenient for now, we - // shove it into TLS and have someone else remove it later on. - let data = ~LLVMJITData { ee: ee, llcx: c }; - set_engine(data as ~Engine); - } - } - - // The stage1 compiler won't work, but that doesn't really matter. TLS - // changed only very recently to allow storage of owned values. - local_data_key!(engine_key: ~Engine) - - fn set_engine(engine: ~Engine) { - local_data::set(engine_key, engine) - } - - pub fn consume_engine() -> Option<~Engine> { - local_data::pop(engine_key) - } -} - pub mod write { - use back::link::jit; use back::link::{WriteOutputFile, output_type}; use back::link::{output_type_assembly, output_type_bitcode}; use back::link::{output_type_exe, output_type_llvm_assembly}; @@ -307,48 +204,38 @@ pub mod write { }) } - if sess.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 - jit::exec(sess, llcx, llmod, true); - } else { - // Create a codegen-specific pass manager to emit the actual - // assembly or object files. This may not end up getting used, - // but we make it anyway for good measure. - let cpm = llvm::LLVMCreatePassManager(); - llvm::LLVMRustAddAnalysisPasses(tm, cpm, llmod); - llvm::LLVMRustAddLibraryInfo(cpm, llmod); - - match output_type { - output_type_none => {} - output_type_bitcode => { - output.with_c_str(|buf| { - llvm::LLVMWriteBitcodeToFile(llmod, buf); - }) - } - output_type_llvm_assembly => { - output.with_c_str(|output| { - llvm::LLVMRustPrintModule(cpm, llmod, output) - }) - } - output_type_assembly => { - WriteOutputFile(sess, tm, cpm, llmod, output, lib::llvm::AssemblyFile); - } - output_type_exe | output_type_object => { - WriteOutputFile(sess, tm, cpm, llmod, output, lib::llvm::ObjectFile); - } + // Create a codegen-specific pass manager to emit the actual + // assembly or object files. This may not end up getting used, + // but we make it anyway for good measure. + let cpm = llvm::LLVMCreatePassManager(); + llvm::LLVMRustAddAnalysisPasses(tm, cpm, llmod); + llvm::LLVMRustAddLibraryInfo(cpm, llmod); + + match output_type { + output_type_none => {} + output_type_bitcode => { + output.with_c_str(|buf| { + llvm::LLVMWriteBitcodeToFile(llmod, buf); + }) + } + output_type_llvm_assembly => { + output.with_c_str(|output| { + llvm::LLVMRustPrintModule(cpm, llmod, output) + }) + } + output_type_assembly => { + WriteOutputFile(sess, tm, cpm, llmod, output, lib::llvm::AssemblyFile); + } + output_type_exe | output_type_object => { + WriteOutputFile(sess, tm, cpm, llmod, output, lib::llvm::ObjectFile); } - - llvm::LLVMDisposePassManager(cpm); } + llvm::LLVMDisposePassManager(cpm); + llvm::LLVMRustDisposeTargetMachine(tm); - // the jit takes ownership of these two items - if !sess.opts.jit { - llvm::LLVMDisposeModule(llmod); - llvm::LLVMContextDispose(llcx); - } + llvm::LLVMDisposeModule(llmod); + llvm::LLVMContextDispose(llcx); if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); } } } @@ -711,8 +598,8 @@ pub fn sanitize(s: &str) -> ~str { ',' => result.push_str("$C$"), // '.' doesn't occur in types and functions, so reuse it - // for ':' - ':' => result.push_char('.'), + // for ':' and '-' + '-' | ':' => result.push_char('.'), // These are legal symbols 'a' .. 'z' diff --git a/src/librustc/back/upcall.rs b/src/librustc/back/upcall.rs index 0ad53c4d49c1a..730ceba12c786 100644 --- a/src/librustc/back/upcall.rs +++ b/src/librustc/back/upcall.rs @@ -15,22 +15,10 @@ use middle::trans::type_::Type; use lib::llvm::{ModuleRef, ValueRef}; pub struct Upcalls { - trace: ValueRef, rust_personality: ValueRef, - reset_stack_limit: ValueRef } macro_rules! upcall ( - (fn $name:ident($($arg:expr),+) -> $ret:expr) => ({ - let fn_ty = Type::func([ $($arg),* ], &$ret); - base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty) - }); - (nothrow fn $name:ident($($arg:expr),+) -> $ret:expr) => ({ - let fn_ty = Type::func([ $($arg),* ], &$ret); - let decl = base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty); - base::set_no_unwind(decl); - decl - }); (nothrow fn $name:ident -> $ret:expr) => ({ let fn_ty = Type::func([], &$ret); let decl = base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty); @@ -39,13 +27,9 @@ macro_rules! upcall ( }) ) -pub fn declare_upcalls(targ_cfg: @session::config, llmod: ModuleRef) -> @Upcalls { - let opaque_ptr = Type::i8().ptr_to(); - let int_ty = Type::int(targ_cfg.arch); - +pub fn declare_upcalls(_targ_cfg: @session::config, + llmod: ModuleRef) -> @Upcalls { @Upcalls { - trace: upcall!(fn trace(opaque_ptr, opaque_ptr, int_ty) -> Type::void()), rust_personality: upcall!(nothrow fn rust_personality -> Type::i32()), - reset_stack_limit: upcall!(nothrow fn reset_stack_limit -> Type::void()) } } diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 4559a1230bd14..63d6c60d2698d 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -419,11 +419,6 @@ pub fn stop_after_phase_5(sess: Session) -> bool { debug!("not building executable, returning early from compile_input"); return true; } - - if sess.opts.jit { - debug!("running JIT, returning early from compile_input"); - return true; - } return false; } @@ -751,7 +746,6 @@ pub fn build_session_options(binary: @str, } else { No } }; let gc = debugging_opts & session::gc != 0; - let jit = debugging_opts & session::jit != 0; let extra_debuginfo = debugging_opts & session::extra_debug_info != 0; let debuginfo = debugging_opts & session::debug_info != 0 || extra_debuginfo; @@ -802,7 +796,6 @@ pub fn build_session_options(binary: @str, extra_debuginfo: extra_debuginfo, lint_opts: lint_opts, save_temps: save_temps, - jit: jit, output_type: output_type, addl_lib_search_paths: @mut addl_lib_search_paths, ar: ar, diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index e45ea533f7937..6a4755344eff4 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -44,30 +44,28 @@ pub static time_llvm_passes: uint = 1 << 3; pub static trans_stats: uint = 1 << 4; pub static asm_comments: uint = 1 << 5; pub static no_verify: uint = 1 << 6; -pub static trace: uint = 1 << 7; -pub static coherence: uint = 1 << 8; -pub static borrowck_stats: uint = 1 << 9; -pub static borrowck_note_pure: uint = 1 << 10; -pub static borrowck_note_loan: uint = 1 << 11; -pub static no_landing_pads: uint = 1 << 12; -pub static debug_llvm: uint = 1 << 13; -pub static count_type_sizes: uint = 1 << 14; -pub static meta_stats: uint = 1 << 15; -pub static no_opt: uint = 1 << 16; -pub static gc: uint = 1 << 17; -pub static jit: uint = 1 << 18; -pub static debug_info: uint = 1 << 19; -pub static extra_debug_info: uint = 1 << 20; -pub static print_link_args: uint = 1 << 21; -pub static no_debug_borrows: uint = 1 << 22; -pub static lint_llvm: uint = 1 << 23; -pub static print_llvm_passes: uint = 1 << 24; -pub static no_vectorize_loops: uint = 1 << 25; -pub static no_vectorize_slp: uint = 1 << 26; -pub static no_prepopulate_passes: uint = 1 << 27; -pub static use_softfp: uint = 1 << 28; -pub static gen_crate_map: uint = 1 << 29; -pub static prefer_dynamic: uint = 1 << 30; +pub static coherence: uint = 1 << 7; +pub static borrowck_stats: uint = 1 << 8; +pub static borrowck_note_pure: uint = 1 << 9; +pub static borrowck_note_loan: uint = 1 << 10; +pub static no_landing_pads: uint = 1 << 11; +pub static debug_llvm: uint = 1 << 12; +pub static count_type_sizes: uint = 1 << 13; +pub static meta_stats: uint = 1 << 14; +pub static no_opt: uint = 1 << 15; +pub static gc: uint = 1 << 16; +pub static debug_info: uint = 1 << 17; +pub static extra_debug_info: uint = 1 << 18; +pub static print_link_args: uint = 1 << 19; +pub static no_debug_borrows: uint = 1 << 20; +pub static lint_llvm: uint = 1 << 21; +pub static print_llvm_passes: uint = 1 << 22; +pub static no_vectorize_loops: uint = 1 << 23; +pub static no_vectorize_slp: uint = 1 << 24; +pub static no_prepopulate_passes: uint = 1 << 25; +pub static use_softfp: uint = 1 << 26; +pub static gen_crate_map: uint = 1 << 27; +pub static prefer_dynamic: uint = 1 << 28; pub fn debugging_opts_map() -> ~[(&'static str, &'static str, uint)] { ~[("verbose", "in general, enable more debug printouts", verbose), @@ -79,7 +77,6 @@ pub fn debugging_opts_map() -> ~[(&'static str, &'static str, uint)] { ("trans-stats", "gather trans statistics", trans_stats), ("asm-comments", "generate comments into the assembly (may change behavior)", asm_comments), ("no-verify", "skip LLVM verification", no_verify), - ("trace", "emit trace logs", trace), ("coherence", "perform coherence checking", coherence), ("borrowck-stats", "gather borrowck statistics", borrowck_stats), ("borrowck-note-pure", "note where purity is req'd", @@ -95,7 +92,6 @@ pub fn debugging_opts_map() -> ~[(&'static str, &'static str, uint)] { ("no-opt", "do not optimize, even if -O is passed", no_opt), ("print-link-args", "Print the arguments passed to the linker", print_link_args), ("gc", "Garbage collect shared data (experimental)", gc), - ("jit", "Execute using JIT (experimental)", jit), ("extra-debug-info", "Extra debugging info (experimental)", extra_debug_info), ("debug-info", "Produce debug info (experimental)", debug_info), @@ -146,7 +142,6 @@ pub struct options { extra_debuginfo: bool, lint_opts: ~[(lint::lint, lint::level)], save_temps: bool, - jit: bool, output_type: back::link::output_type, addl_lib_search_paths: @mut HashSet, // This is mutable for rustpkg, which // updates search paths based on the @@ -311,7 +306,6 @@ impl Session_ { pub fn asm_comments(&self) -> bool { self.debugging_opt(asm_comments) } pub fn no_verify(&self) -> bool { self.debugging_opt(no_verify) } pub fn lint_llvm(&self) -> bool { self.debugging_opt(lint_llvm) } - pub fn trace(&self) -> bool { self.debugging_opt(trace) } pub fn coherence(&self) -> bool { self.debugging_opt(coherence) } pub fn borrowck_stats(&self) -> bool { self.debugging_opt(borrowck_stats) } pub fn borrowck_note_pure(&self) -> bool { @@ -370,7 +364,6 @@ pub fn basic_options() -> @options { extra_debuginfo: false, lint_opts: ~[], save_temps: false, - jit: false, output_type: link::output_type_exe, addl_lib_search_paths: @mut HashSet::new(), ar: None, diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 438dc03b76621..166e1414f6ea2 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -363,10 +363,6 @@ pub fn monitor(f: proc(@diagnostic::Emitter)) { let _finally = finally { ch: ch }; f(demitter); - - // Due reasons explain in #7732, if there was a jit execution context it - // must be consumed and passed along to our parent task. - back::link::jit::consume_engine() }) { result::Ok(_) => { /* fallthrough */ } result::Err(_) => { diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index a856c06997169..1e1444babf232 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -1441,18 +1441,6 @@ pub mod llvm { call. */ pub fn LLVMRustGetLastError() -> *c_char; - /** Prepare the JIT. Returns a memory manager that can load crates. */ - pub fn LLVMRustPrepareJIT(__morestack: *()) -> *(); - - /** Load a crate into the memory manager. */ - pub fn LLVMRustLoadCrate(MM: *(), Filename: *c_char) -> bool; - - /** Execute the JIT engine. */ - pub fn LLVMRustBuildJIT(MM: *(), - M: ModuleRef, - EnableSegmentedStacks: bool) - -> ExecutionEngineRef; - /// Print the pass timings since static dtors aren't picking them up. pub fn LLVMRustPrintPassTimings(); diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index d4586fc59905b..72b9fc83c4ab8 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1018,11 +1018,6 @@ pub fn get_landing_pad(bcx: @mut Block) -> BasicBlockRef { // The landing pad block is a cleanup SetCleanup(pad_bcx, llretval); - // Because we may have unwound across a stack boundary, we must call into - // the runtime to figure out which stack segment we are on and place the - // stack limit back into the TLS. - Call(pad_bcx, bcx.ccx().upcalls.reset_stack_limit, [], []); - // We store the retval in a function-central alloca, so that calls to // Resume can find it. match bcx.fcx.personality { @@ -1097,28 +1092,6 @@ pub fn load_if_immediate(cx: @mut Block, v: ValueRef, t: ty::t) -> ValueRef { return v; } -pub fn trans_trace(bcx: @mut Block, sp_opt: Option, trace_str: @str) { - if !bcx.sess().trace() { return; } - let _icx = push_ctxt("trans_trace"); - add_comment(bcx, trace_str); - let V_trace_str = C_cstr(bcx.ccx(), trace_str); - let (V_filename, V_line) = match sp_opt { - Some(sp) => { - let sess = bcx.sess(); - let loc = sess.parse_sess.cm.lookup_char_pos(sp.lo); - (C_cstr(bcx.ccx(), loc.file.name), loc.line as int) - } - None => { - (C_cstr(bcx.ccx(), @""), 0) - } - }; - let ccx = bcx.ccx(); - let V_trace_str = PointerCast(bcx, V_trace_str, Type::i8p()); - let V_filename = PointerCast(bcx, V_filename, Type::i8p()); - let args = ~[V_trace_str, V_filename, C_int(ccx, V_line)]; - Call(bcx, ccx.upcalls.trace, args, []); -} - pub fn ignore_lhs(_bcx: @mut Block, local: &ast::Local) -> bool { match local.pat.node { ast::PatWild => true, _ => false @@ -1313,12 +1286,6 @@ pub fn cleanup_and_leave(bcx: @mut Block, loop { debug!("cleanup_and_leave: leaving {}", cur.to_str()); - if bcx.sess().trace() { - trans_trace( - bcx, None, - (format!("cleanup_and_leave({})", cur.to_str())).to_managed()); - } - let mut cur_scope = cur.scope; loop { cur_scope = match cur_scope { @@ -1387,12 +1354,6 @@ pub fn cleanup_block(bcx: @mut Block, upto: Option) -> @mut Block loop { debug!("cleanup_block: {}", cur.to_str()); - if bcx.sess().trace() { - trans_trace( - bcx, None, - (format!("cleanup_block({})", cur.to_str())).to_managed()); - } - let mut cur_scope = cur.scope; loop { cur_scope = match cur_scope { @@ -2961,6 +2922,11 @@ pub fn create_module_map(ccx: &mut CrateContext) -> (ValueRef, uint) { return (map, keys.len()) } +pub fn symname(sess: session::Session, name: &str, + hash: &str, vers: &str) -> ~str { + let elt = path_name(sess.ident_of(name)); + link::exported_name(sess, ~[elt], hash, vers) +} pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta, llmod: ModuleRef) -> ValueRef { @@ -2969,13 +2935,14 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta, let mut n_subcrates = 1; let cstore = sess.cstore; while cstore::have_crate_data(cstore, n_subcrates) { n_subcrates += 1; } - let mapname = if *sess.building_library && !sess.gen_crate_map() { - format!("{}_{}_{}", mapmeta.name, mapmeta.vers, mapmeta.extras_hash) + let is_top = !*sess.building_library || sess.gen_crate_map(); + let sym_name = if is_top { + ~"_rust_crate_map_toplevel" } else { - ~"toplevel" + symname(sess, "_rust_crate_map_" + mapmeta.name, mapmeta.extras_hash, + mapmeta.vers) }; - let sym_name = ~"_rust_crate_map_" + mapname; let slicetype = Type::struct_([int_type, int_type], false); let maptype = Type::struct_([ Type::i32(), // version @@ -2990,7 +2957,7 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta, }); // On windows we'd like to export the toplevel cratemap // such that we can find it from libstd. - if targ_cfg.os == OsWin32 && "toplevel" == mapname { + if targ_cfg.os == OsWin32 && is_top { lib::llvm::SetLinkage(map, lib::llvm::DLLExportLinkage); } else { lib::llvm::SetLinkage(map, lib::llvm::ExternalLinkage); @@ -3005,10 +2972,9 @@ pub fn fill_crate_map(ccx: @mut CrateContext, map: ValueRef) { let cstore = ccx.sess.cstore; while cstore::have_crate_data(cstore, i) { let cdata = cstore::get_crate_data(cstore, i); - let nm = format!("_rust_crate_map_{}_{}_{}", - cdata.name, - cstore::get_crate_vers(cstore, i), - cstore::get_crate_hash(cstore, i)); + let nm = symname(ccx.sess, format!("_rust_crate_map_{}", cdata.name), + cstore::get_crate_hash(cstore, i), + cstore::get_crate_vers(cstore, i)); let cr = nm.with_c_str(|buf| { unsafe { llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type.to_ref(), buf) diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 09218b5342493..2c3a9e040c959 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -567,8 +567,6 @@ fn trans_to_datum_unadjusted(bcx: @mut Block, expr: &ast::Expr) -> DatumBlock { fn trans_rvalue_datum_unadjusted(bcx: @mut Block, expr: &ast::Expr) -> DatumBlock { let _icx = push_ctxt("trans_rvalue_datum_unadjusted"); - trace_span!(bcx, expr.span, shorten(bcx.expr_to_str(expr))); - match expr.node { ast::ExprPath(_) | ast::ExprSelf => { return trans_def_datum_unadjusted(bcx, expr, bcx.def(expr.id)); @@ -625,8 +623,6 @@ fn trans_rvalue_stmt_unadjusted(bcx: @mut Block, expr: &ast::Expr) -> @mut Block return bcx; } - trace_span!(bcx, expr.span, shorten(bcx.expr_to_str(expr))); - match expr.node { ast::ExprBreak(label_opt) => { return controlflow::trans_break(bcx, label_opt); @@ -676,8 +672,6 @@ fn trans_rvalue_dps_unadjusted(bcx: @mut Block, expr: &ast::Expr, let _icx = push_ctxt("trans_rvalue_dps_unadjusted"); let tcx = bcx.tcx(); - trace_span!(bcx, expr.span, shorten(bcx.expr_to_str(expr))); - match expr.node { ast::ExprParen(e) => { return trans_rvalue_dps_unadjusted(bcx, e, dest); @@ -895,8 +889,6 @@ fn trans_lvalue_unadjusted(bcx: @mut Block, expr: &ast::Expr) -> DatumBlock { debug!("trans_lvalue(expr={})", bcx.expr_to_str(expr)); let _indenter = indenter(); - trace_span!(bcx, expr.span, shorten(bcx.expr_to_str(expr))); - return match expr.node { ast::ExprParen(e) => { trans_lvalue_unadjusted(bcx, e) diff --git a/src/librustc/middle/trans/macros.rs b/src/librustc/middle/trans/macros.rs index 43cc66c556867..938484fd44ceb 100644 --- a/src/librustc/middle/trans/macros.rs +++ b/src/librustc/middle/trans/macros.rs @@ -29,25 +29,3 @@ macro_rules! unpack_result( } ) ) - -macro_rules! trace_span( - ($bcx: ident, $sp: expr, $str: expr) => ( - { - let bcx = $bcx; - if bcx.sess().trace() { - trans_trace(bcx, Some($sp), $str); - } - } - ) -) - -macro_rules! trace( - ($bcx: ident, $str: expr) => ( - { - let bcx = $bcx; - if bcx.sess().trace() { - trans_trace(bcx, None, $str); - } - } - ) -) diff --git a/src/librustc/middle/trans/write_guard.rs b/src/librustc/middle/trans/write_guard.rs index 577e0a28105f2..2da2da80fdd6a 100644 --- a/src/librustc/middle/trans/write_guard.rs +++ b/src/librustc/middle/trans/write_guard.rs @@ -114,13 +114,6 @@ fn root(datum: &Datum, debug!("write_guard::root(root_key={:?}, root_info={:?}, datum={:?})", root_key, root_info, datum.to_str(bcx.ccx())); - if bcx.sess().trace() { - trans_trace( - bcx, None, - (format!("preserving until end of scope {}", - root_info.scope)).to_managed()); - } - // First, root the datum. Note that we must zero this value, // because sometimes we root on one path but not another. // See e.g. #4904. diff --git a/src/llvm b/src/llvm index c9ffab392a39e..eac6ff795c407 160000 --- a/src/llvm +++ b/src/llvm @@ -1 +1 @@ -Subproject commit c9ffab392a39eb85f2f15ffc8d41e8c4f4397b8e +Subproject commit eac6ff795c40778683e42b0c6ab6f6adaceb391d diff --git a/src/rt/rust_upcall.c b/src/rt/rust_upcall.c index 9740fdea82c96..18b71fbb17908 100644 --- a/src/rt/rust_upcall.c +++ b/src/rt/rust_upcall.c @@ -51,7 +51,7 @@ struct s_rust_personality_args { struct _Unwind_Context *context; }; -void +static void upcall_s_rust_personality(struct s_rust_personality_args *args) { args->retval = PERSONALITY_FUNC(args->version, args->actions, @@ -78,6 +78,7 @@ upcall_rust_personality(int version, return args.retval; } +// NOTE: remove after stage0 // Landing pads need to call this to insert the // correct limit into TLS. // NB: This must run on the Rust stack because it diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 8d0b447fa4a1e..0ae8991b2e740 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -81,7 +81,6 @@ LLVMRustCreateTargetMachine(const char *triple, TargetOptions Options; Options.NoFramePointerElim = true; Options.EnableSegmentedStacks = EnableSegmentedStacks; - Options.FixedStackSegmentSize = 2 * 1024 * 1024; // XXX: This is too big. Options.FloatABIType = (Trip.getEnvironment() == Triple::GNUEABIHF) ? FloatABI::Hard : FloatABI::Default; diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 0a148d334ab61..484cded314710 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -34,282 +34,6 @@ extern "C" const char *LLVMRustGetLastError(void) { return LLVMRustError; } -// 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. -class RustMCJITMemoryManager : public JITMemoryManager { -public: - SmallVector AllocatedDataMem; - SmallVector AllocatedCodeMem; - SmallVector FreeCodeMem; - void* __morestack; - DenseSet crates; - - RustMCJITMemoryManager(void* sym) : __morestack(sym) { } - ~RustMCJITMemoryManager(); - - bool loadCrate(const char*, std::string*); - - virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID); - - virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID, bool isReadOnly); - bool finalizeMemory(std::string *ErrMsg) { return false; } - - virtual bool applyPermissions(std::string *Str); - - virtual void *getPointerToNamedFunction(const std::string &Name, - bool AbortOnFailure = true); - - // Invalidate instruction cache for code sections. Some platforms with - // separate data cache and instruction cache require explicit cache flush, - // otherwise JIT code manipulations (like resolved relocations) will get to - // the data cache but not to the instruction cache. - virtual void invalidateInstructionCache(); - - // The MCJITMemoryManager doesn't use the following functions, so we don't - // need implement them. - virtual void setMemoryWritable() { - llvm_unreachable("Unimplemented call"); - } - virtual void setMemoryExecutable() { - llvm_unreachable("Unimplemented call"); - } - virtual void setPoisonMemory(bool poison) { - llvm_unreachable("Unimplemented call"); - } - virtual void AllocateGOT() { - llvm_unreachable("Unimplemented call"); - } - virtual uint8_t *getGOTBase() const { - llvm_unreachable("Unimplemented call"); - return 0; - } - virtual uint8_t *startFunctionBody(const Function *F, - uintptr_t &ActualSize){ - llvm_unreachable("Unimplemented call"); - return 0; - } - virtual uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize, - unsigned Alignment) { - llvm_unreachable("Unimplemented call"); - return 0; - } - virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart, - uint8_t *FunctionEnd) { - llvm_unreachable("Unimplemented call"); - } - virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) { - llvm_unreachable("Unimplemented call"); - return 0; - } - virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) { - llvm_unreachable("Unimplemented call"); - return 0; - } - virtual void deallocateFunctionBody(void *Body) { - llvm_unreachable("Unimplemented call"); - } - virtual uint8_t* startExceptionTable(const Function* F, - uintptr_t &ActualSize) { - llvm_unreachable("Unimplemented call"); - return 0; - } - virtual void endExceptionTable(const Function *F, uint8_t *TableStart, - uint8_t *TableEnd, uint8_t* FrameRegister) { - llvm_unreachable("Unimplemented call"); - } - virtual void deallocateExceptionTable(void *ET) { - llvm_unreachable("Unimplemented call"); - } -}; - -bool RustMCJITMemoryManager::loadCrate(const char* file, std::string* err) { - DynamicLibrary crate = DynamicLibrary::getPermanentLibrary(file, - err); - - if(crate.isValid()) { - crates.insert(&crate); - - return true; - } - - return false; -} - -uint8_t *RustMCJITMemoryManager::allocateDataSection(uintptr_t Size, - unsigned Alignment, - unsigned SectionID, - bool isReadOnly) { - if (!Alignment) - Alignment = 16; - uint8_t *Addr = (uint8_t*)calloc((Size + Alignment - 1)/Alignment, Alignment); - AllocatedDataMem.push_back(sys::MemoryBlock(Addr, Size)); - return Addr; -} - -bool RustMCJITMemoryManager::applyPermissions(std::string *Str) { - // Empty. - return true; -} - -uint8_t *RustMCJITMemoryManager::allocateCodeSection(uintptr_t Size, - unsigned Alignment, - unsigned SectionID) { - if (!Alignment) - Alignment = 16; - unsigned NeedAllocate = Alignment * ((Size + Alignment - 1)/Alignment + 1); - uintptr_t Addr = 0; - // Look in the list of free code memory regions and use a block there if one - // is available. - for (int i = 0, e = FreeCodeMem.size(); i != e; ++i) { - sys::MemoryBlock &MB = FreeCodeMem[i]; - if (MB.size() >= NeedAllocate) { - Addr = (uintptr_t)MB.base(); - uintptr_t EndOfBlock = Addr + MB.size(); - // Align the address. - Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1); - // Store cutted free memory block. - FreeCodeMem[i] = sys::MemoryBlock((void*)(Addr + Size), - EndOfBlock - Addr - Size); - return (uint8_t*)Addr; - } - } - - // No pre-allocated free block was large enough. Allocate a new memory region. - sys::MemoryBlock MB = sys::Memory::AllocateRWX(NeedAllocate, 0, 0); - - AllocatedCodeMem.push_back(MB); - Addr = (uintptr_t)MB.base(); - uintptr_t EndOfBlock = Addr + MB.size(); - // Align the address. - Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1); - // The AllocateRWX may allocate much more memory than we need. In this case, - // we store the unused memory as a free memory block. - unsigned FreeSize = EndOfBlock-Addr-Size; - if (FreeSize > 16) - FreeCodeMem.push_back(sys::MemoryBlock((void*)(Addr + Size), FreeSize)); - - // Return aligned address - return (uint8_t*)Addr; -} - -void RustMCJITMemoryManager::invalidateInstructionCache() { - for (int i = 0, e = AllocatedCodeMem.size(); i != e; ++i) - sys::Memory::InvalidateInstructionCache(AllocatedCodeMem[i].base(), - AllocatedCodeMem[i].size()); -} - -void *RustMCJITMemoryManager::getPointerToNamedFunction(const std::string &Name, - bool AbortOnFailure) { -#ifdef __linux__ - // Force the following functions to be linked in to anything that uses the - // JIT. This is a hack designed to work around the all-too-clever Glibc - // strategy of making these functions work differently when inlined vs. when - // not inlined, and hiding their real definitions in a separate archive file - // that the dynamic linker can't see. For more info, search for - // 'libc_nonshared.a' on Google, or read http://llvm.org/PR274. - if (Name == "stat") return (void*)(intptr_t)&stat; - if (Name == "fstat") return (void*)(intptr_t)&fstat; - if (Name == "lstat") return (void*)(intptr_t)&lstat; - if (Name == "stat64") return (void*)(intptr_t)&stat64; - if (Name == "fstat64") return (void*)(intptr_t)&fstat64; - if (Name == "lstat64") return (void*)(intptr_t)&lstat64; - if (Name == "atexit") return (void*)(intptr_t)&atexit; - if (Name == "mknod") return (void*)(intptr_t)&mknod; -#endif - - if (Name == "__morestack" || Name == "___morestack") return &__morestack; - - const char *NameStr = Name.c_str(); - - // Look through loaded crates and main for symbols. - - void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr); - if (Ptr) return Ptr; - - // If it wasn't found and if it starts with an underscore ('_') character, - // try again without the underscore. - if (NameStr[0] == '_') { - Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr+1); - if (Ptr) return Ptr; - } - - if (AbortOnFailure) - report_fatal_error("Program used external function '" + Name + - "' which could not be resolved!"); - return 0; -} - -RustMCJITMemoryManager::~RustMCJITMemoryManager() { - for (unsigned i = 0, e = AllocatedCodeMem.size(); i != e; ++i) - sys::Memory::ReleaseRWX(AllocatedCodeMem[i]); - for (unsigned i = 0, e = AllocatedDataMem.size(); i != e; ++i) - free(AllocatedDataMem[i].base()); -} - -extern "C" void* -LLVMRustPrepareJIT(void* __morestack) { - // An execution engine will take ownership of this later - // and clean it up for us. - - return (void*) new RustMCJITMemoryManager(__morestack); -} - -extern "C" bool -LLVMRustLoadCrate(void* mem, const char* crate) { - RustMCJITMemoryManager* manager = (RustMCJITMemoryManager*) mem; - std::string Err; - - assert(manager); - - if(!manager->loadCrate(crate, &Err)) { - LLVMRustError = Err.c_str(); - return false; - } - - return true; -} - -extern "C" LLVMExecutionEngineRef -LLVMRustBuildJIT(void* mem, - LLVMModuleRef M, - bool EnableSegmentedStacks) { - - InitializeNativeTarget(); - InitializeNativeTargetAsmPrinter(); - InitializeNativeTargetAsmParser(); - - std::string Err; - TargetOptions Options; - Options.JITEmitDebugInfo = true; - Options.NoFramePointerElim = true; - Options.EnableSegmentedStacks = EnableSegmentedStacks; - RustMCJITMemoryManager* MM = (RustMCJITMemoryManager*) mem; - assert(MM); - - ExecutionEngine* EE = EngineBuilder(unwrap(M)) - .setErrorStr(&Err) - .setTargetOptions(Options) - .setJITMemoryManager(MM) - .setUseMCJIT(true) - .setAllocateGVsWithCode(false) - .create(); - - if(!EE || Err != "") { - LLVMRustError = Err.c_str(); - // The EngineBuilder only takes ownership of these two structures if the - // create() call is successful, but here it wasn't successful. - LLVMDisposeModule(M); - delete MM; - return NULL; - } - - MM->invalidateInstructionCache(); - return wrap(EE); -} - extern "C" void LLVMRustSetNormalizedTarget(LLVMModuleRef M, const char *triple) { unwrap(M)->setTargetTriple(Triple::normalize(triple)); @@ -566,7 +290,7 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateStructType( unwrapDI(DerivedFrom), unwrapDI(Elements), RunTimeLang, - unwrapDI(VTableHolder), + unwrapDI(VTableHolder), UniqueId)); } diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-auto-clean-trigger index 01a5eaefa89b5..bae0ad8fbc6c1 100644 --- a/src/rustllvm/llvm-auto-clean-trigger +++ b/src/rustllvm/llvm-auto-clean-trigger @@ -1,4 +1,4 @@ # If this file is modified, then llvm will be forcibly cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. -2013-09-23 +2013-12-05 diff --git a/src/rustllvm/rustllvm.def.in b/src/rustllvm/rustllvm.def.in index 069f29e909d4b..d8ec1c868408d 100644 --- a/src/rustllvm/rustllvm.def.in +++ b/src/rustllvm/rustllvm.def.in @@ -3,9 +3,6 @@ LLVMRustWriteOutputFile LLVMRustGetLastError LLVMRustConstSmallInt LLVMRustConstInt -LLVMRustLoadCrate -LLVMRustPrepareJIT -LLVMRustBuildJIT LLVMRustPrintPassTimings LLVMRustStartMultithreading LLVMCreateObjectFile