diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index d3005ff2ded2..dfde3ded46d1 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -30,13 +30,16 @@ use syntax::{ast, codemap}; use syntax::feature_gate::AttributeType; use rustc_back::target::Target; +use llvm; use std::path::{Path, PathBuf}; use std::cell::{Cell, RefCell}; use std::collections::{HashMap, HashSet}; use std::env; +use std::ffi::CString; use std::rc::Rc; use std::fmt; +use libc::c_int; pub mod config; pub mod filesearch; @@ -491,9 +494,63 @@ pub fn build_session_(sopts: config::Options, imported_macro_spans: RefCell::new(HashMap::new()), }; + init_llvm(&sess); + sess } +fn init_llvm(sess: &Session) { + unsafe { + // Before we touch LLVM, make sure that multithreading is enabled. + use std::sync::Once; + static INIT: Once = Once::new(); + static mut POISONED: bool = false; + INIT.call_once(|| { + if llvm::LLVMStartMultithreaded() != 1 { + // use an extra bool to make sure that all future usage of LLVM + // cannot proceed despite the Once not running more than once. + POISONED = true; + } + + configure_llvm(sess); + }); + + if POISONED { + bug!("couldn't enable multi-threaded LLVM"); + } + } +} + +unsafe fn configure_llvm(sess: &Session) { + let mut llvm_c_strs = Vec::new(); + let mut llvm_args = Vec::new(); + + { + let mut add = |arg: &str| { + let s = CString::new(arg).unwrap(); + llvm_args.push(s.as_ptr()); + llvm_c_strs.push(s); + }; + add("rustc"); // fake program name + if sess.time_llvm_passes() { add("-time-passes"); } + if sess.print_llvm_passes() { add("-debug-pass=Structure"); } + + // FIXME #21627 disable faulty FastISel on AArch64 (even for -O0) + if sess.target.target.arch == "aarch64" { add("-fast-isel=0"); } + + for arg in &sess.opts.cg.llvm_args { + add(&(*arg)); + } + } + + llvm::LLVMInitializePasses(); + + llvm::initialize_available_targets(); + + llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, + llvm_args.as_ptr()); +} + pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! { let mut emitter: Box = match output { config::ErrorOutputType::HumanReadable(color_config) => { diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index e6a51eb7c87e..8a915f044053 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -31,7 +31,7 @@ use std::str; use std::sync::{Arc, Mutex}; use std::sync::mpsc::channel; use std::thread; -use libc::{c_uint, c_int, c_void}; +use libc::{c_uint, c_void}; pub fn llvm_err(handler: &errors::Handler, msg: String) -> ! { match llvm::last_error() { @@ -984,36 +984,6 @@ pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) { } } -pub unsafe fn configure_llvm(sess: &Session) { - let mut llvm_c_strs = Vec::new(); - let mut llvm_args = Vec::new(); - - { - let mut add = |arg: &str| { - let s = CString::new(arg).unwrap(); - llvm_args.push(s.as_ptr()); - llvm_c_strs.push(s); - }; - add("rustc"); // fake program name - if sess.time_llvm_passes() { add("-time-passes"); } - if sess.print_llvm_passes() { add("-debug-pass=Structure"); } - - // FIXME #21627 disable faulty FastISel on AArch64 (even for -O0) - if sess.target.target.arch == "aarch64" { add("-fast-isel=0"); } - - for arg in &sess.opts.cg.llvm_args { - add(&(*arg)); - } - } - - llvm::LLVMInitializePasses(); - - llvm::initialize_available_targets(); - - llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, - llvm_args.as_ptr()); -} - pub unsafe fn with_llvm_pmb(llmod: ModuleRef, config: &ModuleConfig, f: &mut FnMut(llvm::PassManagerBuilderRef)) { diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 17230eff6e63..6304a0eacd3b 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -2709,26 +2709,6 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>, tcx.sess.opts.debug_assertions }; - // Before we touch LLVM, make sure that multithreading is enabled. - unsafe { - use std::sync::Once; - static INIT: Once = Once::new(); - static mut POISONED: bool = false; - INIT.call_once(|| { - if llvm::LLVMStartMultithreaded() != 1 { - // use an extra bool to make sure that all future usage of LLVM - // cannot proceed despite the Once not running more than once. - POISONED = true; - } - - ::back::write::configure_llvm(&tcx.sess); - }); - - if POISONED { - bug!("couldn't enable multi-threaded LLVM"); - } - } - let link_meta = link::build_link_meta(&tcx, name); let codegen_units = tcx.sess.opts.cg.codegen_units;