diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 79a01f5c4b0b..499c45e28fe8 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -92,7 +92,7 @@ pub struct Session { pub one_time_diagnostics: RefCell, String)>>, pub plugin_llvm_passes: OneThread>>, pub plugin_attributes: OneThread>>, - pub crate_types: RefCell>, + pub crate_types: Once>, pub dependency_formats: RefCell, /// The crate_disambiguator is constructed out of all the `-C metadata` /// arguments passed to the compiler. Its value together with the crate-name @@ -1096,7 +1096,7 @@ pub fn build_session_( one_time_diagnostics: RefCell::new(FxHashSet()), plugin_llvm_passes: OneThread::new(RefCell::new(Vec::new())), plugin_attributes: OneThread::new(RefCell::new(Vec::new())), - crate_types: RefCell::new(Vec::new()), + crate_types: Once::new(), dependency_formats: RefCell::new(FxHashMap()), crate_disambiguator: Once::new(), features: Once::new(), diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 4776f516eac4..4071b804def6 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -652,7 +652,8 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session, // these need to be set "early" so that expansion sees `quote` if enabled. sess.init_features(features); - *sess.crate_types.borrow_mut() = collect_crate_types(sess, &krate.attrs); + let crate_types = collect_crate_types(sess, &krate.attrs); + sess.crate_types.set(crate_types); let disambiguator = compute_crate_disambiguator(sess); sess.crate_disambiguator.set(disambiguator); diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 6c7565764119..f501b1739eb9 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -154,13 +154,16 @@ fn get_llvm_opt_size(optimize: config::OptLevel) -> llvm::CodeGenOptSize { } } -pub fn create_target_machine(sess: &Session) -> TargetMachineRef { - target_machine_factory(sess)().unwrap_or_else(|err| { +pub fn create_target_machine(sess: &Session, find_features: bool) -> TargetMachineRef { + target_machine_factory(sess, find_features)().unwrap_or_else(|err| { llvm_err(sess.diagnostic(), err).raise() }) } -pub fn target_machine_factory(sess: &Session) +// If find_features is true this won't access `sess.crate_types` by assuming +// that `is_pie_binary` is false. When we discover LLVM target features +// `sess.crate_types` is uninitialized so we cannot access it. +pub fn target_machine_factory(sess: &Session, find_features: bool) -> Arc Result + Send + Sync> { let reloc_model = get_reloc_model(sess); @@ -201,7 +204,7 @@ pub fn target_machine_factory(sess: &Session) }; let cpu = CString::new(cpu.as_bytes()).unwrap(); let features = CString::new(target_feature(sess).as_bytes()).unwrap(); - let is_pie_binary = is_pie_binary(sess); + let is_pie_binary = !find_features && is_pie_binary(sess); let trap_unreachable = sess.target.target.options.trap_unreachable; Arc::new(move || { @@ -1510,7 +1513,7 @@ fn start_executing_work(tcx: TyCtxt, regular_module_config: modules_config, metadata_module_config: metadata_config, allocator_module_config: allocator_config, - tm_factory: target_machine_factory(tcx.sess), + tm_factory: target_machine_factory(tcx.sess, false), total_cgus, msvc_imps_needed: msvc_imps_needed(tcx), target_pointer_width: tcx.sess.target.target.target_pointer_width.clone(), diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index dd51ffcf3136..c2d94a17f03d 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -737,7 +737,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, source: ModuleSource::Translated(ModuleLlvm { llcx: metadata_llcx, llmod: metadata_llmod, - tm: create_target_machine(tcx.sess), + tm: create_target_machine(tcx.sess, false), }), kind: ModuleKind::Metadata, }; @@ -803,7 +803,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let modules = ModuleLlvm { llmod, llcx, - tm: create_target_machine(tcx.sess), + tm: create_target_machine(tcx.sess, false), }; time(tcx.sess, "write allocator module", || { allocator::trans(tcx, &modules, kind) @@ -1260,7 +1260,7 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let llvm_module = ModuleLlvm { llcx: cx.llcx, llmod: cx.llmod, - tm: create_target_machine(cx.sess()), + tm: create_target_machine(cx.sess(), false), }; ModuleTranslation { diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 1f2c3cc883c6..fe8a7052bdff 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -162,7 +162,7 @@ pub unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (Cont // Ensure the data-layout values hardcoded remain the defaults. if sess.target.target.options.is_builtin { - let tm = ::back::write::create_target_machine(sess); + let tm = ::back::write::create_target_machine(sess, false); llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, tm); llvm::LLVMRustDisposeTargetMachine(tm); diff --git a/src/librustc_trans/llvm_util.rs b/src/librustc_trans/llvm_util.rs index 1c8f09ce7b3f..85952ea77969 100644 --- a/src/librustc_trans/llvm_util.rs +++ b/src/librustc_trans/llvm_util.rs @@ -140,7 +140,7 @@ pub fn to_llvm_feature<'a>(sess: &Session, s: &'a str) -> &'a str { } pub fn target_features(sess: &Session) -> Vec { - let target_machine = create_target_machine(sess); + let target_machine = create_target_machine(sess, true); target_feature_whitelist(sess) .iter() .filter(|feature| { @@ -178,7 +178,7 @@ pub fn print_passes() { pub(crate) fn print(req: PrintRequest, sess: &Session) { require_inited(); - let tm = create_target_machine(sess); + let tm = create_target_machine(sess, true); unsafe { match req { PrintRequest::TargetCPUs => llvm::LLVMRustPrintTargetCPUs(tm),