From 358e41cee4c31a739b6a45723e8917b19e7f7db9 Mon Sep 17 00:00:00 2001 From: Andrea Canciani Date: Wed, 2 Mar 2016 21:02:12 +0100 Subject: [PATCH] Introduce the `init_llvm` function Extract the code that performs the initialization of the LLVM backend and invoke it before computing the available features. The initialization is required to happen before the features are added to the configuration, because they are computed by LLVM, therefore is is now performed when creating the `Session` object. --- src/librustc/session/mod.rs | 57 ++++++++++++++++++++++++++++++++ src/librustc_trans/back/write.rs | 32 +----------------- src/librustc_trans/base.rs | 20 ----------- 3 files changed, 58 insertions(+), 51 deletions(-) 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;