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.
This commit is contained in:
Andrea Canciani 2016-03-02 21:02:12 +01:00
parent 92e24b9516
commit 358e41cee4
3 changed files with 58 additions and 51 deletions

View file

@ -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<Emitter> = match output {
config::ErrorOutputType::HumanReadable(color_config) => {

View file

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

View file

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