From e349452f5213080f948d45b63ee28539c900df40 Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Fri, 5 May 2017 00:59:28 -0700 Subject: [PATCH 1/2] Queryify more metadata --- src/librustc/middle/cstore.rs | 6 ---- src/librustc/ty/maps.rs | 24 +++++++++++--- src/librustc_const_eval/eval.rs | 2 +- src/librustc_metadata/cstore_impl.rs | 33 +++++++------------- src/librustc_metadata/decoder.rs | 11 ------- src/librustc_mir/transform/qualify_consts.rs | 2 +- src/librustc_passes/consts.rs | 2 +- src/librustc_trans/callee.rs | 2 +- src/librustc_trans/consts.rs | 2 +- src/librustdoc/clean/inline.rs | 6 ++-- 10 files changed, 40 insertions(+), 50 deletions(-) diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 303c5059e7cf3..13ed7408e4472 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -197,10 +197,7 @@ pub trait CrateStore { fn associated_item_cloned(&self, def: DefId) -> ty::AssociatedItem; // flags - fn is_const_fn(&self, did: DefId) -> bool; - fn is_default_impl(&self, impl_did: DefId) -> bool; fn is_foreign_item(&self, did: DefId) -> bool; - fn is_dllimport_foreign_item(&self, def: DefId) -> bool; fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool; fn is_exported_symbol(&self, def_id: DefId) -> bool; @@ -325,10 +322,7 @@ impl CrateStore for DummyCrateStore { { bug!("associated_item_cloned") } // flags - fn is_const_fn(&self, did: DefId) -> bool { bug!("is_const_fn") } - fn is_default_impl(&self, impl_did: DefId) -> bool { bug!("is_default_impl") } fn is_foreign_item(&self, did: DefId) -> bool { bug!("is_foreign_item") } - fn is_dllimport_foreign_item(&self, id: DefId) -> bool { false } fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool { false } fn is_exported_symbol(&self, def_id: DefId) -> bool { false } diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 66df8dc050a24..6887387227f11 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -347,13 +347,25 @@ impl<'tcx> QueryDescription for queries::const_is_rvalue_promotable_to_static<'t } } -impl<'tcx> QueryDescription for queries::is_mir_available<'tcx> { - fn describe(tcx: TyCtxt, def_id: DefId) -> String { - format!("checking if item is mir available: `{}`", - tcx.item_path_str(def_id)) +macro_rules! simple_query_description { + ($($fn_name:ident, $desc:expr),*,) => { + $( + impl<'tcx> QueryDescription for queries::$fn_name<'tcx> { + fn describe(tcx: TyCtxt, def_id: DefId) -> String { + format!(concat!($desc, "`: {}`"), + tcx.item_path_str(def_id)) + } + } + )* } } +simple_query_description! { + is_mir_available, "checking if item is mir available", + is_const_fn, "checking if item is const fn", + is_dllimport_foreign_item, "checking if item is dll import foreign item", +} + macro_rules! define_maps { (<$tcx:tt> $($(#[$attr:meta])* @@ -786,6 +798,10 @@ define_maps! { <'tcx> [] item_body_nested_bodies: metadata_dep_node(DefId) -> Rc>, [] const_is_rvalue_promotable_to_static: metadata_dep_node(DefId) -> bool, [] is_mir_available: metadata_dep_node(DefId) -> bool, + + [] is_const_fn: metadata_dep_node(DefId) -> bool, + [] is_default_impl: metadata_dep_node(DefId) -> bool, + [] is_dllimport_foreign_item: metadata_dep_node(DefId) -> bool, } fn coherent_trait_dep_node((_, def_id): (CrateNum, DefId)) -> DepNode { diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index 8b1aa0708807b..af9458ea47d3a 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -352,7 +352,7 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>, signal!(e, TypeckError) } } else { - if tcx.sess.cstore.is_const_fn(def_id) { + if tcx.is_const_fn(def_id) { tcx.sess.cstore.item_body(tcx, def_id) } else { signal!(e, TypeckError) diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index a1794ec2d82ca..de3216897616a 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -11,7 +11,7 @@ use cstore; use encoder; use locator; -use schema; +use schema::{self, EntryKind}; use rustc::dep_graph::DepTrackingMapConfig; use rustc::middle::cstore::{CrateStore, CrateSource, LibSource, DepKind, @@ -22,7 +22,7 @@ use rustc::middle::lang_items; use rustc::session::Session; use rustc::ty::{self, TyCtxt}; use rustc::ty::maps::Providers; -use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX}; use rustc::dep_graph::DepNode; use rustc::hir::map::{DefKey, DefPath, DisambiguatedDefPathData}; @@ -128,6 +128,16 @@ provide! { <'tcx> tcx, def_id, cdata !cdata.is_proc_macro(def_id.index) && cdata.maybe_entry(def_id.index).and_then(|item| item.decode(cdata).mir).is_some() } + is_const_fn => { cdata.is_const_fn(def_id.index) } + is_default_impl => { + match cdata.entry(def_id.index).kind { + EntryKind::DefaultImpl(_) => true, + _ => false, + } + } + is_dllimport_foreign_item => { + cdata.dllimport_foreign_items.contains(&def_id.index) + } } impl CrateStore for cstore::CStore { @@ -195,17 +205,6 @@ impl CrateStore for cstore::CStore { self.get_crate_data(def.krate).get_associated_item(def.index) } - fn is_const_fn(&self, did: DefId) -> bool - { - self.dep_graph.read(DepNode::MetaData(did)); - self.get_crate_data(did.krate).is_const_fn(did.index) - } - - fn is_default_impl(&self, impl_did: DefId) -> bool { - self.dep_graph.read(DepNode::MetaData(impl_did)); - self.get_crate_data(impl_did.krate).is_default_impl(impl_did.index) - } - fn is_foreign_item(&self, did: DefId) -> bool { self.get_crate_data(did.krate).is_foreign_item(did.index) } @@ -219,14 +218,6 @@ impl CrateStore for cstore::CStore { self.get_crate_data(def_id.krate).exported_symbols.contains(&def_id.index) } - fn is_dllimport_foreign_item(&self, def_id: DefId) -> bool { - if def_id.krate == LOCAL_CRATE { - self.dllimport_foreign_items.borrow().contains(&def_id.index) - } else { - self.get_crate_data(def_id.krate).is_dllimport_foreign_item(def_id.index) - } - } - fn dylib_dependency_formats(&self, cnum: CrateNum) -> Vec<(CrateNum, LinkagePreference)> { diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index ae755adcf5fbb..251ea46cd9d03 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -1018,17 +1018,6 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn is_dllimport_foreign_item(&self, id: DefIndex) -> bool { - self.dllimport_foreign_items.contains(&id) - } - - pub fn is_default_impl(&self, impl_id: DefIndex) -> bool { - match self.entry(impl_id).kind { - EntryKind::DefaultImpl(_) => true, - _ => false, - } - } - pub fn closure_kind(&self, closure_id: DefIndex) -> ty::ClosureKind { match self.entry(closure_id).kind { EntryKind::Closure(data) => data.decode(self).kind, diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 4b1c82f383f85..641157eb38529 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -117,7 +117,7 @@ pub fn is_const_fn(tcx: TyCtxt, def_id: DefId) -> bool { false } } else { - tcx.sess.cstore.is_const_fn(def_id) + tcx.is_const_fn(def_id) } } diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index 608238dfe3735..5dbd9930c78f8 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -102,7 +102,7 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> { fn_like.constness() == hir::Constness::Const }) } else { - self.tcx.sess.cstore.is_const_fn(def_id) + self.tcx.is_const_fn(def_id) }; } } diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs index dc788dc4b4834..75190d3fd1cde 100644 --- a/src/librustc_trans/callee.rs +++ b/src/librustc_trans/callee.rs @@ -111,7 +111,7 @@ pub fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } if ccx.use_dll_storage_attrs() && - ccx.sess().cstore.is_dllimport_foreign_item(instance.def_id()) + ccx.tcx().is_dllimport_foreign_item(instance.def_id()) { unsafe { llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport); diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs index 6afb340107d66..a0a1228fd6196 100644 --- a/src/librustc_trans/consts.rs +++ b/src/librustc_trans/consts.rs @@ -199,7 +199,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef { g }; - if ccx.use_dll_storage_attrs() && ccx.sess().cstore.is_dllimport_foreign_item(def_id) { + if ccx.use_dll_storage_attrs() && ccx.tcx().is_dllimport_foreign_item(def_id) { // For foreign (native) libs we know the exact storage type to use. unsafe { llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport); diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 9dea0e3d83088..b410673c70920 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -167,7 +167,7 @@ pub fn build_external_trait(cx: &DocContext, did: DefId) -> clean::Trait { fn build_external_function(cx: &DocContext, did: DefId) -> clean::Function { let sig = cx.tcx.type_of(did).fn_sig(); - let constness = if cx.tcx.sess.cstore.is_const_fn(did) { + let constness = if cx.tcx.is_const_fn(did) { hir::Constness::Const } else { hir::Constness::NotConst @@ -306,7 +306,7 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec) { } // If this is a defaulted impl, then bail out early here - if tcx.sess.cstore.is_default_impl(did) { + if tcx.is_default_impl(did) { return ret.push(clean::Item { inner: clean::DefaultImplItem(clean::DefaultImpl { // FIXME: this should be decoded @@ -368,7 +368,7 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec) { clean::TyMethodItem(clean::TyMethod { unsafety, decl, generics, abi }) => { - let constness = if tcx.sess.cstore.is_const_fn(item.def_id) { + let constness = if tcx.is_const_fn(item.def_id) { hir::Constness::Const } else { hir::Constness::NotConst From e5868e6ed5a6ec4fa08cab36db2b2ce70f286a7b Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Sat, 6 May 2017 02:49:17 -0700 Subject: [PATCH 2/2] [WIP] queryify more metadata and plumb tcx --- src/librustc/dep_graph/dep_node.rs | 2 + src/librustc/middle/cstore.rs | 10 -- src/librustc/ty/maps.rs | 29 ++++ src/librustc_driver/driver.rs | 15 +- src/librustc_metadata/cstore_impl.rs | 202 ++++++++++++----------- src/librustc_trans/back/link.rs | 70 +++++--- src/librustc_trans/back/lto.rs | 42 ++--- src/librustc_trans/back/symbol_export.rs | 5 +- src/librustc_trans/back/write.rs | 131 ++++++++------- 9 files changed, 284 insertions(+), 222 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 37b8a56d9166b..f7b42d6996103 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -50,6 +50,7 @@ pub enum DepNode { // Represents the metadata for a given HIR node, typically found // in an extern crate. MetaData(D), + MetaDataByCrateNum(CrateNum), // Represents some artifact that we save to disk. Note that these // do not have a def-id as part of their identifier. @@ -208,6 +209,7 @@ impl DepNode { MirKeys => Some(MirKeys), LateLintCheck => Some(LateLintCheck), TransWriteMetadata => Some(TransWriteMetadata), + MetaDataByCrateNum(c) => Some(MetaDataByCrateNum(c)), // work product names do not need to be mapped, because // they are always absolute. diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 13ed7408e4472..0910a419f0f5f 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -223,10 +223,6 @@ pub trait CrateStore { fn crate_hash(&self, cnum: CrateNum) -> Svh; fn crate_disambiguator(&self, cnum: CrateNum) -> Symbol; fn plugin_registrar_fn(&self, cnum: CrateNum) -> Option; - fn derive_registrar_fn(&self, cnum: CrateNum) -> Option; - fn native_libraries(&self, cnum: CrateNum) -> Vec; - fn exported_symbols(&self, cnum: CrateNum) -> Vec; - fn is_no_builtins(&self, cnum: CrateNum) -> bool; // resolve fn retrace_path(&self, @@ -354,12 +350,6 @@ impl CrateStore for DummyCrateStore { -> Symbol { bug!("crate_disambiguator") } fn plugin_registrar_fn(&self, cnum: CrateNum) -> Option { bug!("plugin_registrar_fn") } - fn derive_registrar_fn(&self, cnum: CrateNum) -> Option - { bug!("derive_registrar_fn") } - fn native_libraries(&self, cnum: CrateNum) -> Vec - { bug!("native_libraries") } - fn exported_symbols(&self, cnum: CrateNum) -> Vec { bug!("exported_symbols") } - fn is_no_builtins(&self, cnum: CrateNum) -> bool { bug!("is_no_builtins") } // resolve fn retrace_path(&self, diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 6887387227f11..6c99034acad49 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -13,6 +13,7 @@ use hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use hir::def::Def; use hir; use middle::const_val; +use middle::cstore::NativeLibrary; use middle::privacy::AccessLevels; use middle::region::RegionMaps; use mir; @@ -366,6 +367,25 @@ simple_query_description! { is_dllimport_foreign_item, "checking if item is dll import foreign item", } +macro_rules! cratenum_query_description { + ($($fn_name:ident, $desc:expr),*,) => { + $( + impl<'tcx> QueryDescription for queries::$fn_name<'tcx> { + fn describe(_tcx: TyCtxt, crate_num: CrateNum) -> String { + format!(concat!($desc, "`: crate {}`"), crate_num) + } + } + )* + } +} + +cratenum_query_description! { + derive_registrar_fn, "getting the derive_registrar_fn", + native_libraries, "getting native libraries", + exported_symbols, "getting the exported symbols", + is_no_builtins, "checking if is_no_builtins", +} + macro_rules! define_maps { (<$tcx:tt> $($(#[$attr:meta])* @@ -802,6 +822,11 @@ define_maps! { <'tcx> [] is_const_fn: metadata_dep_node(DefId) -> bool, [] is_default_impl: metadata_dep_node(DefId) -> bool, [] is_dllimport_foreign_item: metadata_dep_node(DefId) -> bool, + + [] derive_registrar_fn: cratenum_metadata_dep_node(CrateNum) -> Option, + [] native_libraries: cratenum_metadata_dep_node(CrateNum) -> Vec, + [] exported_symbols: cratenum_metadata_dep_node(CrateNum) -> Vec, + [] is_no_builtins: cratenum_metadata_dep_node(CrateNum) -> bool, } fn coherent_trait_dep_node((_, def_id): (CrateNum, DefId)) -> DepNode { @@ -820,6 +845,10 @@ fn metadata_dep_node(def_id: DefId) -> DepNode { DepNode::MetaData(def_id) } +fn cratenum_metadata_dep_node(crate_num: CrateNum) -> DepNode { + DepNode::MetaDataByCrateNum(crate_num) +} + fn mir_shim_dep_node(instance: ty::InstanceDef) -> DepNode { instance.dep_node() } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 9f0f567b6cee1..a2106f7b318dc 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -1065,9 +1065,11 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, /// Run LLVM itself, producing a bitcode file, assembly file or object file /// as a side effect. -pub fn phase_5_run_llvm_passes(sess: &Session, +pub fn phase_5_run_llvm_passes<'a, 'tcx>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, trans: &trans::CrateTranslation, outputs: &OutputFilenames) -> CompileResult { + let sess = tcx.sess; if sess.opts.cg.no_integrated_as || (sess.target.target.options.no_integrated_as && (outputs.outputs.contains_key(&OutputType::Object) || @@ -1076,7 +1078,7 @@ pub fn phase_5_run_llvm_passes(sess: &Session, let output_types = OutputTypes::new(&[(OutputType::Assembly, None)]); time(sess.time_passes(), "LLVM passes", - || write::run_passes(sess, trans, &output_types, outputs)); + || write::run_passes(tcx, trans, &output_types, outputs)); write::run_assembler(sess, outputs); @@ -1097,7 +1099,7 @@ pub fn phase_5_run_llvm_passes(sess: &Session, } else { time(sess.time_passes(), "LLVM passes", - || write::run_passes(sess, trans, &sess.opts.output_types, outputs)); + || write::run_passes(tcx, trans, &sess.opts.output_types, outputs)); } time(sess.time_passes(), @@ -1113,12 +1115,13 @@ pub fn phase_5_run_llvm_passes(sess: &Session, /// Run the linker on any artifacts that resulted from the LLVM run. /// This should produce either a finished executable or library. -pub fn phase_6_link_output(sess: &Session, +pub fn phase_6_link_output<'a, 'tcx>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, trans: &trans::CrateTranslation, outputs: &OutputFilenames) { - time(sess.time_passes(), + time(tcx.sess.time_passes(), "linking", - || link::link_binary(sess, trans, outputs, &trans.crate_name.as_str())); + || link::link_binary(tcx, trans, outputs, &trans.crate_name.as_str())); } fn escape_dep_filename(filename: &str) -> String { diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index de3216897616a..8679387c5c4cd 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -44,10 +44,19 @@ use rustc::hir; use std::collections::BTreeMap; macro_rules! provide { - (<$lt:tt> $tcx:ident, $def_id:ident, $cdata:ident $($name:ident => $compute:block)*) => { + (<$lt:tt> $tcx:ident, $def_id:ident, $cdata:ident, $cnum:ident + ByDefId + { + $($cdata_fn_name:ident => $cdata_fn_compute:block)* + } + ByCrateNum + { + $($cnum_fn_name:ident => $cnum_fn_compute:block)* + } + ) => { pub fn provide<$lt>(providers: &mut Providers<$lt>) { - $(fn $name<'a, $lt:$lt>($tcx: TyCtxt<'a, $lt, $lt>, $def_id: DefId) - -> as + $(fn $cdata_fn_name<'a, $lt:$lt>($tcx: TyCtxt<'a, $lt, $lt>, $def_id: DefId) + -> as DepTrackingMapConfig>::Value { assert!(!$def_id.is_local()); @@ -56,87 +65,114 @@ macro_rules! provide { let $cdata = $tcx.sess.cstore.crate_data_as_rc_any($def_id.krate); let $cdata = $cdata.downcast_ref::() .expect("CrateStore crated ata is not a CrateMetadata"); - $compute + $cdata_fn_compute + })* + + $(fn $cnum_fn_name<'a, $lt:$lt>($tcx: TyCtxt<'a, $lt, $lt>, $cnum: CrateNum) + -> as + DepTrackingMapConfig>::Value { + let $cdata = $tcx.sess.cstore.crate_data_as_rc_any($cnum); + let $cdata = $cdata.downcast_ref::() + .expect("CrateStore crated ata is not a CrateMetadata"); + $cnum_fn_compute })* *providers = Providers { - $($name,)* + $($cdata_fn_name,)* + $($cnum_fn_name,)* ..*providers }; } } } -provide! { <'tcx> tcx, def_id, cdata - type_of => { cdata.get_type(def_id.index, tcx) } - generics_of => { tcx.alloc_generics(cdata.get_generics(def_id.index)) } - predicates_of => { cdata.get_predicates(def_id.index, tcx) } - super_predicates_of => { cdata.get_super_predicates(def_id.index, tcx) } - trait_def => { - tcx.alloc_trait_def(cdata.get_trait_def(def_id.index)) - } - adt_def => { cdata.get_adt_def(def_id.index, tcx) } - adt_destructor => { - let _ = cdata; - tcx.calculate_dtor(def_id, &mut |_,_| Ok(())) - } - variances_of => { Rc::new(cdata.get_item_variances(def_id.index)) } - associated_item_def_ids => { - let mut result = vec![]; - cdata.each_child_of_item(def_id.index, |child| result.push(child.def.def_id())); - Rc::new(result) - } - associated_item => { cdata.get_associated_item(def_id.index) } - impl_trait_ref => { cdata.get_impl_trait(def_id.index, tcx) } - impl_polarity => { cdata.get_impl_polarity(def_id.index) } - coerce_unsized_info => { - cdata.get_coerce_unsized_info(def_id.index).unwrap_or_else(|| { - bug!("coerce_unsized_info: `{:?}` is missing its info", def_id); - }) - } - optimized_mir => { - let mir = cdata.maybe_get_optimized_mir(tcx, def_id.index).unwrap_or_else(|| { - bug!("get_optimized_mir: missing MIR for `{:?}`", def_id) - }); +provide! { <'tcx> tcx, def_id, cdata, cnum - let mir = tcx.alloc_mir(mir); - - mir - } - mir_const_qualif => { cdata.mir_const_qualif(def_id.index) } - typeck_tables_of => { cdata.item_body_tables(def_id.index, tcx) } - closure_kind => { cdata.closure_kind(def_id.index) } - closure_type => { cdata.closure_ty(def_id.index, tcx) } - inherent_impls => { Rc::new(cdata.get_inherent_implementations_for_type(def_id.index)) } - is_foreign_item => { cdata.is_foreign_item(def_id.index) } - describe_def => { cdata.get_def(def_id.index) } - def_span => { cdata.get_span(def_id.index, &tcx.sess) } - stability => { cdata.get_stability(def_id.index) } - deprecation => { cdata.get_deprecation(def_id.index) } - item_body_nested_bodies => { - let map: BTreeMap<_, _> = cdata.entry(def_id.index).ast.into_iter().flat_map(|ast| { - ast.decode(cdata).nested_bodies.decode(cdata).map(|body| (body.id(), body)) - }).collect(); - - Rc::new(map) - } - const_is_rvalue_promotable_to_static => { - cdata.entry(def_id.index).ast.expect("const item missing `ast`") - .decode(cdata).rvalue_promotable_to_static - } - is_mir_available => { - !cdata.is_proc_macro(def_id.index) && - cdata.maybe_entry(def_id.index).and_then(|item| item.decode(cdata).mir).is_some() - } - is_const_fn => { cdata.is_const_fn(def_id.index) } - is_default_impl => { - match cdata.entry(def_id.index).kind { - EntryKind::DefaultImpl(_) => true, - _ => false, + ByDefId + { + type_of => { cdata.get_type(def_id.index, tcx) } + generics_of => { tcx.alloc_generics(cdata.get_generics(def_id.index)) } + predicates_of => { cdata.get_predicates(def_id.index, tcx) } + super_predicates_of => { cdata.get_super_predicates(def_id.index, tcx) } + trait_def => { + tcx.alloc_trait_def(cdata.get_trait_def(def_id.index)) + } + adt_def => { cdata.get_adt_def(def_id.index, tcx) } + adt_destructor => { + let _ = cdata; + tcx.calculate_dtor(def_id, &mut |_,_| Ok(())) + } + variances_of => { Rc::new(cdata.get_item_variances(def_id.index)) } + associated_item_def_ids => { + let mut result = vec![]; + cdata.each_child_of_item(def_id.index, |child| result.push(child.def.def_id())); + Rc::new(result) + } + associated_item => { cdata.get_associated_item(def_id.index) } + impl_trait_ref => { cdata.get_impl_trait(def_id.index, tcx) } + impl_polarity => { cdata.get_impl_polarity(def_id.index) } + coerce_unsized_info => { + cdata.get_coerce_unsized_info(def_id.index).unwrap_or_else(|| { + bug!("coerce_unsized_info: `{:?}` is missing its info", def_id); + }) + } + optimized_mir => { + let mir = cdata.maybe_get_optimized_mir(tcx, def_id.index).unwrap_or_else(|| { + bug!("get_optimized_mir: missing MIR for `{:?}`", def_id) + }); + + let mir = tcx.alloc_mir(mir); + + mir + } + mir_const_qualif => { cdata.mir_const_qualif(def_id.index) } + typeck_tables_of => { cdata.item_body_tables(def_id.index, tcx) } + closure_kind => { cdata.closure_kind(def_id.index) } + closure_type => { cdata.closure_ty(def_id.index, tcx) } + inherent_impls => { Rc::new(cdata.get_inherent_implementations_for_type(def_id.index)) } + is_foreign_item => { cdata.is_foreign_item(def_id.index) } + describe_def => { cdata.get_def(def_id.index) } + def_span => { cdata.get_span(def_id.index, &tcx.sess) } + stability => { cdata.get_stability(def_id.index) } + deprecation => { cdata.get_deprecation(def_id.index) } + item_body_nested_bodies => { + let map: BTreeMap<_, _> = cdata.entry(def_id.index).ast.into_iter().flat_map(|ast| { + ast.decode(cdata).nested_bodies.decode(cdata).map(|body| (body.id(), body)) + }).collect(); + + Rc::new(map) + } + const_is_rvalue_promotable_to_static => { + cdata.entry(def_id.index).ast.expect("const item missing `ast`") + .decode(cdata).rvalue_promotable_to_static + } + is_mir_available => { + !cdata.is_proc_macro(def_id.index) && + cdata.maybe_entry(def_id.index).and_then(|item| item.decode(cdata).mir).is_some() + } + is_const_fn => { cdata.is_const_fn(def_id.index) } + is_default_impl => { + match cdata.entry(def_id.index).kind { + EntryKind::DefaultImpl(_) => true, + _ => false, + } + } + is_dllimport_foreign_item => { + cdata.dllimport_foreign_items.contains(&def_id.index) } } - is_dllimport_foreign_item => { - cdata.dllimport_foreign_items.contains(&def_id.index) + + ByCrateNum + { + derive_registrar_fn => { + cdata.root.macro_derive_registrar.map(|index| DefId { + krate: cnum, + index: index + }) + } + native_libraries => { cdata.get_native_libraries() } + exported_symbols => { cdata.get_exported_symbols() } + is_no_builtins => { cdata.is_no_builtins() } } } @@ -306,28 +342,6 @@ impl CrateStore for cstore::CStore { }) } - fn derive_registrar_fn(&self, cnum: CrateNum) -> Option - { - self.get_crate_data(cnum).root.macro_derive_registrar.map(|index| DefId { - krate: cnum, - index: index - }) - } - - fn native_libraries(&self, cnum: CrateNum) -> Vec - { - self.get_crate_data(cnum).get_native_libraries() - } - - fn exported_symbols(&self, cnum: CrateNum) -> Vec - { - self.get_crate_data(cnum).get_exported_symbols() - } - - fn is_no_builtins(&self, cnum: CrateNum) -> bool { - self.get_crate_data(cnum).is_no_builtins() - } - fn retrace_path(&self, cnum: CrateNum, path: &[DisambiguatedDefPathData]) diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index e42e69d2a76e2..9c28ce82f5122 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -31,6 +31,7 @@ use rustc::hir::svh::Svh; use rustc_back::tempdir::TempDir; use rustc_back::PanicStrategy; use rustc_incremental::IncrementalHashesMap; +use rustc::ty::TyCtxt; use context::get_reloc_model; use llvm; @@ -188,10 +189,12 @@ pub fn remove(sess: &Session, path: &Path) { /// Perform the linkage portion of the compilation phase. This will generate all /// of the requested outputs for this compilation session. -pub fn link_binary(sess: &Session, +pub fn link_binary<'a, 'tcx: 'a>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, trans: &CrateTranslation, outputs: &OutputFilenames, crate_name: &str) -> Vec { + let sess = tcx.sess; let mut out_filenames = Vec::new(); for &crate_type in sess.crate_types.borrow().iter() { // Ignore executable crates if we have -Z no-trans, as they will error. @@ -205,7 +208,7 @@ pub fn link_binary(sess: &Session, bug!("invalid output type `{:?}` for target os `{}`", crate_type, sess.opts.target_triple); } - let mut out_files = link_binary_output(sess, trans, crate_type, outputs, crate_name); + let mut out_files = link_binary_output(tcx, trans, crate_type, outputs, crate_name); out_filenames.append(&mut out_files); } @@ -362,11 +365,13 @@ fn check_file_is_writeable(file: &Path, sess: &Session) { } } -fn link_binary_output(sess: &Session, +fn link_binary_output<'a, 'tcx: 'a>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, trans: &CrateTranslation, crate_type: config::CrateType, outputs: &OutputFilenames, crate_name: &str) -> Vec { + let sess = tcx.sess; let objects = object_filenames(trans, outputs); for file in &objects { @@ -394,10 +399,10 @@ fn link_binary_output(sess: &Session, tmpdir.path()).build(); } config::CrateTypeStaticlib => { - link_staticlib(sess, &objects, &out_filename, tmpdir.path()); + link_staticlib(tcx, &objects, &out_filename, tmpdir.path()); } _ => { - link_natively(sess, crate_type, &objects, &out_filename, trans, + link_natively(tcx, crate_type, &objects, &out_filename, trans, outputs, tmpdir.path()); } } @@ -639,14 +644,18 @@ fn write_rlib_bytecode_object_v1(writer: &mut Write, // There's no need to include metadata in a static archive, so ensure to not // link in the metadata object file (and also don't prepare the archive with a // metadata file). -fn link_staticlib(sess: &Session, objects: &[PathBuf], out_filename: &Path, +fn link_staticlib<'a, 'tcx>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + objects: &[PathBuf], + out_filename: &Path, tempdir: &Path) { + let sess = tcx.sess; let mut ab = link_rlib(sess, None, objects, out_filename, tempdir); let mut all_native_libs = vec![]; each_linked_rlib(sess, &mut |cnum, path| { - let name = sess.cstore.crate_name(cnum); - let native_libs = sess.cstore.native_libraries(cnum); + let name = tcx.sess.cstore.crate_name(cnum); + let native_libs = tcx.native_libraries(cnum); // Here when we include the rlib into our staticlib we need to make a // decision whether to include the extra object files along the way. @@ -667,7 +676,7 @@ fn link_staticlib(sess: &Session, objects: &[PathBuf], out_filename: &Path, }); ab.add_rlib(path, &name.as_str(), sess.lto(), skip_object_files).unwrap(); - all_native_libs.extend(sess.cstore.native_libraries(cnum)); + all_native_libs.extend(tcx.native_libraries(cnum)); }); ab.update_symbols(); @@ -696,13 +705,16 @@ fn link_staticlib(sess: &Session, objects: &[PathBuf], out_filename: &Path, // // This will invoke the system linker/cc to create the resulting file. This // links to all upstream files as well. -fn link_natively(sess: &Session, +fn link_natively<'a, 'tcx: 'a>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_type: config::CrateType, objects: &[PathBuf], out_filename: &Path, trans: &CrateTranslation, outputs: &OutputFilenames, tmpdir: &Path) { + let sess = tcx.sess; + info!("preparing {:?} from {:?} to {:?}", crate_type, objects, out_filename); let flavor = sess.linker_flavor(); @@ -735,7 +747,7 @@ fn link_natively(sess: &Session, { let mut linker = trans.linker_info.to_linker(cmd, &sess); - link_args(&mut *linker, sess, crate_type, tmpdir, + link_args(&mut *linker, tcx, crate_type, tmpdir, objects, out_filename, outputs, trans); cmd = linker.finalize(); } @@ -856,8 +868,9 @@ fn link_natively(sess: &Session, } } -fn link_args(cmd: &mut Linker, - sess: &Session, +fn link_args<'a, 'tcx: 'a>( + cmd: &mut Linker, + tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_type: config::CrateType, tmpdir: &Path, objects: &[PathBuf], @@ -865,6 +878,8 @@ fn link_args(cmd: &mut Linker, outputs: &OutputFilenames, trans: &CrateTranslation) { + let sess = tcx.sess; + // The default library location, we need this to find the runtime. // The location of crates will be determined as needed. let lib_path = sess.target_filesearch(PathKind::All).get_lib_path(); @@ -964,8 +979,8 @@ fn link_args(cmd: &mut Linker, // in this DAG so far because they're only dylibs and dylibs can only depend // on other dylibs (e.g. other native deps). add_local_native_libraries(cmd, sess); - add_upstream_rust_crates(cmd, sess, crate_type, tmpdir); - add_upstream_native_libraries(cmd, sess, crate_type); + add_upstream_rust_crates(cmd, tcx, crate_type, tmpdir); + add_upstream_native_libraries(cmd, tcx, crate_type); // # Telling the linker what we're doing @@ -1047,8 +1062,9 @@ fn add_local_native_libraries(cmd: &mut Linker, sess: &Session) { // Rust crates are not considered at all when creating an rlib output. All // dependencies will be linked when producing the final output (instead of // the intermediate rlib version) -fn add_upstream_rust_crates(cmd: &mut Linker, - sess: &Session, +fn add_upstream_rust_crates<'a, 'tcx: 'a>( + cmd: &mut Linker, + tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_type: config::CrateType, tmpdir: &Path) { // All of the heavy lifting has previously been accomplished by the @@ -1058,6 +1074,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker, // Linking to a rlib involves just passing it to the linker (the linker // will slurp up the object files inside), and linking to a dynamic library // involves just passing the right -l flag. + let sess = tcx.sess; let formats = sess.dependency_formats.borrow(); let data = formats.get(&crate_type).unwrap(); @@ -1086,7 +1103,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker, Linkage::NotLinked | Linkage::IncludedFromDylib => {} Linkage::Static => { - add_static_crate(cmd, sess, tmpdir, crate_type, cnum); + add_static_crate(cmd, tcx, tmpdir, crate_type, cnum); } Linkage::Dynamic => { add_dynamic_crate(cmd, sess, &src.dylib.unwrap().0) @@ -1100,7 +1117,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker, // was already "included" in a dylib (e.g. `libstd` when `-C prefer-dynamic` // is used) if let Some(cnum) = compiler_builtins { - add_static_crate(cmd, sess, tmpdir, crate_type, cnum); + add_static_crate(cmd, tcx, tmpdir, crate_type, cnum); } // Converts a library file-stem into a cc -l argument @@ -1185,18 +1202,19 @@ fn add_upstream_rust_crates(cmd: &mut Linker, // (aka we're making an executable), we can just pass the rlib blindly to // the linker (fast) because it's fine if it's not actually included as // we're at the end of the dependency chain. - fn add_static_crate(cmd: &mut Linker, - sess: &Session, + fn add_static_crate<'a, 'tcx: 'a>(cmd: &mut Linker, + tcx: TyCtxt<'a, 'tcx, 'tcx>, tmpdir: &Path, crate_type: config::CrateType, cnum: CrateNum) { + let sess = tcx.sess; let src = sess.cstore.used_crate_source(cnum); let cratepath = &src.rlib.unwrap().0; // See the comment above in `link_staticlib` and `link_rlib` for why if // there's a static library that's not relevant we skip all object // files. - let native_libs = sess.cstore.native_libraries(cnum); + let native_libs = tcx.native_libraries(cnum); let skip_native = native_libs.iter().any(|lib| { lib.kind == NativeLibraryKind::NativeStatic && !relevant_lib(sess, lib) }); @@ -1242,7 +1260,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker, // LTO module. Note that `#![no_builtins]` is excluded from LTO, // though, so we let that object file slide. let skip_because_lto = sess.lto() && is_rust_object && - !sess.cstore.is_no_builtins(cnum); + !tcx.is_no_builtins(cnum); if skip_because_cfg_say_so || skip_because_lto { archive.remove_file(&f); @@ -1308,7 +1326,8 @@ fn add_upstream_rust_crates(cmd: &mut Linker, // generic function calls a native function, then the generic function must // be instantiated in the target crate, meaning that the native symbol must // also be resolved in the target crate. -fn add_upstream_native_libraries(cmd: &mut Linker, sess: &Session, crate_type: config::CrateType) { +fn add_upstream_native_libraries<'a, 'tcx>( + cmd: &mut Linker, tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_type: config::CrateType) { // Be sure to use a topological sorting of crates because there may be // interdependencies between native libraries. When passing -nodefaultlibs, // for example, almost all native libraries depend on libc, so we have to @@ -1318,12 +1337,13 @@ fn add_upstream_native_libraries(cmd: &mut Linker, sess: &Session, crate_type: c // This passes RequireStatic, but the actual requirement doesn't matter, // we're just getting an ordering of crate numbers, we're not worried about // the paths. + let sess = tcx.sess; let formats = sess.dependency_formats.borrow(); let data = formats.get(&crate_type).unwrap(); let crates = sess.cstore.used_crates(LinkagePreference::RequireStatic); for (cnum, _) in crates { - for lib in sess.cstore.native_libraries(cnum) { + for lib in tcx.native_libraries(cnum) { if !relevant_lib(sess, &lib) { continue } diff --git a/src/librustc_trans/back/lto.rs b/src/librustc_trans/back/lto.rs index e23ddd2542a80..426091568368e 100644 --- a/src/librustc_trans/back/lto.rs +++ b/src/librustc_trans/back/lto.rs @@ -11,13 +11,14 @@ use back::link; use back::write; use back::symbol_export::{self, ExportedSymbols}; -use rustc::session::{self, config}; +use rustc::session::config; use llvm; use llvm::archive_ro::ArchiveRO; use llvm::{ModuleRef, TargetMachineRef, True, False}; use rustc::util::common::time; use rustc::util::common::path2cstr; use rustc::hir::def_id::LOCAL_CRATE; +use rustc::ty::TyCtxt; use back::write::{ModuleConfig, with_llvm_pmb}; use libc; @@ -38,30 +39,31 @@ pub fn crate_type_allows_lto(crate_type: config::CrateType) -> bool { } } -pub fn run(sess: &session::Session, +pub fn run<'a, 'tcx: 'a>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, llmod: ModuleRef, tm: TargetMachineRef, exported_symbols: &ExportedSymbols, config: &ModuleConfig, temp_no_opt_bc_filename: &Path) { - if sess.opts.cg.prefer_dynamic { - sess.struct_err("cannot prefer dynamic linking when performing LTO") + if tcx.sess.opts.cg.prefer_dynamic { + tcx.sess.struct_err("cannot prefer dynamic linking when performing LTO") .note("only 'staticlib', 'bin', and 'cdylib' outputs are \ supported with LTO") .emit(); - sess.abort_if_errors(); + tcx.sess.abort_if_errors(); } // Make sure we actually can run LTO - for crate_type in sess.crate_types.borrow().iter() { + for crate_type in tcx.sess.crate_types.borrow().iter() { if !crate_type_allows_lto(*crate_type) { - sess.fatal("lto can only be run for executables, cdylibs and \ + tcx.sess.fatal("lto can only be run for executables, cdylibs and \ static library outputs"); } } let export_threshold = - symbol_export::crates_export_threshold(&sess.crate_types.borrow()); + symbol_export::crates_export_threshold(&tcx.sess.crate_types.borrow()); let symbol_filter = &|&(ref name, level): &(String, _)| { if symbol_export::is_below_threshold(level, export_threshold) { @@ -82,9 +84,9 @@ pub fn run(sess: &session::Session, // For each of our upstream dependencies, find the corresponding rlib and // load the bitcode from the archive. Then merge it into the current LLVM // module that we've got. - link::each_linked_rlib(sess, &mut |cnum, path| { + link::each_linked_rlib(tcx.sess, &mut |cnum, path| { // `#![no_builtins]` crates don't participate in LTO. - if sess.cstore.is_no_builtins(cnum) { + if tcx.is_no_builtins(cnum) { return; } @@ -101,7 +103,7 @@ pub fn run(sess: &session::Session, let bc_encoded = data.data(); let bc_decoded = if is_versioned_bytecode_format(bc_encoded) { - time(sess.time_passes(), &format!("decode {}", name), || { + time(tcx.sess.time_passes(), &format!("decode {}", name), || { // Read the version let version = extract_bytecode_format_version(bc_encoded); @@ -115,24 +117,24 @@ pub fn run(sess: &session::Session, match flate::inflate_bytes(compressed_data) { Ok(inflated) => inflated, Err(_) => { - sess.fatal(&format!("failed to decompress bc of `{}`", + tcx.sess.fatal(&format!("failed to decompress bc of `{}`", name)) } } } else { - sess.fatal(&format!("Unsupported bytecode format version {}", + tcx.sess.fatal(&format!("Unsupported bytecode format version {}", version)) } }) } else { - time(sess.time_passes(), &format!("decode {}", name), || { + time(tcx.sess.time_passes(), &format!("decode {}", name), || { // the object must be in the old, pre-versioning format, so // simply inflate everything and let LLVM decide if it can // make sense of it match flate::inflate_bytes(bc_encoded) { Ok(bc) => bc, Err(_) => { - sess.fatal(&format!("failed to decompress bc of `{}`", + tcx.sess.fatal(&format!("failed to decompress bc of `{}`", name)) } } @@ -141,11 +143,11 @@ pub fn run(sess: &session::Session, let ptr = bc_decoded.as_ptr(); debug!("linking {}", name); - time(sess.time_passes(), &format!("ll link {}", name), || unsafe { + time(tcx.sess.time_passes(), &format!("ll link {}", name), || unsafe { if !llvm::LLVMRustLinkInExternalBitcode(llmod, ptr as *const libc::c_char, bc_decoded.len() as libc::size_t) { - write::llvm_err(sess.diagnostic(), + write::llvm_err(tcx.sess.diagnostic(), format!("failed to load bc of `{}`", name)); } @@ -164,13 +166,13 @@ pub fn run(sess: &session::Session, arr.len() as libc::size_t); } - if sess.no_landing_pads() { + if tcx.sess.no_landing_pads() { unsafe { llvm::LLVMRustMarkAllFunctionsNounwind(llmod); } } - if sess.opts.cg.save_temps { + if tcx.sess.opts.cg.save_temps { let cstr = path2cstr(temp_no_opt_bc_filename); unsafe { llvm::LLVMWriteBitcodeToFile(llmod, cstr.as_ptr()); @@ -200,7 +202,7 @@ pub fn run(sess: &session::Session, assert!(!pass.is_null()); llvm::LLVMRustAddPass(pm, pass); - time(sess.time_passes(), "LTO passes", || + time(tcx.sess.time_passes(), "LTO passes", || llvm::LLVMRunPassManager(pm, llmod)); llvm::LLVMDisposePassManager(pm); diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs index ddd86c4679934..e1953ca21d064 100644 --- a/src/librustc_trans/back/symbol_export.rs +++ b/src/librustc_trans/back/symbol_export.rs @@ -80,7 +80,7 @@ impl ExportedSymbols { // If this crate is a plugin and/or a custom derive crate, then // we're not even going to link those in so we skip those crates. if scx.sess().cstore.plugin_registrar_fn(cnum).is_some() || - scx.sess().cstore.derive_registrar_fn(cnum).is_some() { + scx.tcx().derive_registrar_fn(cnum).is_some() { continue; } @@ -97,8 +97,7 @@ impl ExportedSymbols { scx.sess().cstore.is_compiler_builtins(cnum); let crate_exports = scx - .sess() - .cstore + .tcx() .exported_symbols(cnum) .iter() .map(|&def_id| { diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 3492403a1bf8e..c23256163cdfd 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -12,6 +12,7 @@ use back::lto; use back::link::{get_linker, remove}; use back::symbol_export::ExportedSymbols; use rustc_incremental::{save_trans_partition, in_incr_comp_dir}; +use rustc::ty::TyCtxt; use session::config::{OutputFilenames, OutputTypes, Passes, SomePasses, AllPasses, Sanitizer}; use session::Session; use session::config::{self, OutputType}; @@ -334,10 +335,10 @@ impl ModuleConfig { } /// Additional resources used by optimize_and_codegen (not module specific) -struct CodegenContext<'a> { +struct CodegenContext<'a, 'tcx: 'a> { // Extra resources used for LTO: (sess, reachable). This will be `None` // when running in a worker thread. - lto_ctxt: Option<(&'a Session, &'a ExportedSymbols)>, + lto_ctxt: Option<(TyCtxt<'a, 'tcx, 'tcx>, &'a ExportedSymbols)>, // Handler to use for diagnostics produced during codegen. handler: &'a Handler, // LLVM passes added by plugins. @@ -351,36 +352,36 @@ struct CodegenContext<'a> { incr_comp_session_dir: Option } -impl<'a> CodegenContext<'a> { - fn new_with_session(sess: &'a Session, +impl<'a, 'tcx: 'a> CodegenContext<'a, 'tcx> { + fn new_with_session(tcx: TyCtxt<'a, 'tcx, 'tcx>, exported_symbols: &'a ExportedSymbols) - -> CodegenContext<'a> { + -> CodegenContext<'a, 'tcx> { CodegenContext { - lto_ctxt: Some((sess, exported_symbols)), - handler: sess.diagnostic(), - plugin_passes: sess.plugin_llvm_passes.borrow().clone(), - remark: sess.opts.cg.remark.clone(), + lto_ctxt: Some((tcx, exported_symbols)), + handler: tcx.sess.diagnostic(), + plugin_passes: tcx.sess.plugin_llvm_passes.borrow().clone(), + remark: tcx.sess.opts.cg.remark.clone(), worker: 0, - incr_comp_session_dir: sess.incr_comp_session_dir_opt().map(|r| r.clone()) + incr_comp_session_dir: tcx.sess.incr_comp_session_dir_opt().map(|r| r.clone()) } } } -struct HandlerFreeVars<'a> { +struct HandlerFreeVars<'a, 'tcx: 'a> { llcx: ContextRef, - cgcx: &'a CodegenContext<'a>, + cgcx: &'a CodegenContext<'a, 'tcx>, } -unsafe extern "C" fn report_inline_asm<'a, 'b>(cgcx: &'a CodegenContext<'a>, +unsafe extern "C" fn report_inline_asm<'a, 'b, 'tcx>(cgcx: &'a CodegenContext<'a, 'tcx>, msg: &'b str, cookie: c_uint) { use syntax::ext::hygiene::Mark; match cgcx.lto_ctxt { - Some((sess, _)) => { + Some((tcx, _)) => { match Mark::from_u32(cookie).expn_info() { - Some(ei) => sess.span_err(ei.call_site, msg), - None => sess.err(msg), + Some(ei) => tcx.sess.span_err(ei.call_site, msg), + None => tcx.sess.err(msg), }; } @@ -527,11 +528,11 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, llvm::LLVMDisposePassManager(mpm); match cgcx.lto_ctxt { - Some((sess, exported_symbols)) if sess.lto() => { - time(sess.time_passes(), "all lto passes", || { + Some((tcx, exported_symbols)) if tcx.sess.lto() => { + time(tcx.sess.time_passes(), "all lto passes", || { let temp_no_opt_bc_filename = output_names.temp_path_ext("no-opt.lto.bc", module_name); - lto::run(sess, + lto::run(tcx, llmod, tm, exported_symbols, @@ -656,7 +657,7 @@ pub fn cleanup_llvm(trans: &CrateTranslation) { } } -pub fn run_passes(sess: &Session, +pub fn run_passes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trans: &CrateTranslation, output_types: &OutputTypes, crate_output: &OutputFilenames) { @@ -665,28 +666,28 @@ pub fn run_passes(sess: &Session, // case, but it would be confusing to have the validity of // `-Z lto -C codegen-units=2` depend on details of the crate being // compiled, so we complain regardless. - if sess.lto() && sess.opts.cg.codegen_units > 1 { + if tcx.sess.lto() && tcx.sess.opts.cg.codegen_units > 1 { // This case is impossible to handle because LTO expects to be able // to combine the entire crate and all its dependencies into a // single compilation unit, but each codegen unit is in a separate // LLVM context, so they can't easily be combined. - sess.fatal("can't perform LTO when using multiple codegen units"); + tcx.sess.fatal("can't perform LTO when using multiple codegen units"); } // Sanity check - assert!(trans.modules.len() == sess.opts.cg.codegen_units || - sess.opts.debugging_opts.incremental.is_some() || - !sess.opts.output_types.should_trans() || - sess.opts.debugging_opts.no_trans); + assert!(trans.modules.len() == tcx.sess.opts.cg.codegen_units || + tcx.sess.opts.debugging_opts.incremental.is_some() || + !tcx.sess.opts.output_types.should_trans() || + tcx.sess.opts.debugging_opts.no_trans); - let tm = create_target_machine(sess); + let tm = create_target_machine(tcx.sess); // Figure out what we actually need to build. - let mut modules_config = ModuleConfig::new(tm, sess.opts.cg.passes.clone()); + let mut modules_config = ModuleConfig::new(tm, tcx.sess.opts.cg.passes.clone()); let mut metadata_config = ModuleConfig::new(tm, vec![]); - if let Some(ref sanitizer) = sess.opts.debugging_opts.sanitizer { + if let Some(ref sanitizer) = tcx.sess.opts.debugging_opts.sanitizer { match *sanitizer { Sanitizer::Address => { modules_config.passes.push("asan".to_owned()); @@ -702,11 +703,11 @@ pub fn run_passes(sess: &Session, } } - modules_config.opt_level = Some(get_llvm_opt_level(sess.opts.optimize)); - modules_config.opt_size = Some(get_llvm_opt_size(sess.opts.optimize)); + modules_config.opt_level = Some(get_llvm_opt_level(tcx.sess.opts.optimize)); + modules_config.opt_size = Some(get_llvm_opt_size(tcx.sess.opts.optimize)); // Save all versions of the bytecode if we're saving our temporaries. - if sess.opts.cg.save_temps { + if tcx.sess.opts.cg.save_temps { modules_config.emit_no_opt_bc = true; modules_config.emit_bc = true; modules_config.emit_lto_bc = true; @@ -717,10 +718,10 @@ pub fn run_passes(sess: &Session, // Whenever an rlib is created, the bitcode is inserted into the // archive in order to allow LTO against it. let needs_crate_bitcode = - sess.crate_types.borrow().contains(&config::CrateTypeRlib) && - sess.opts.output_types.contains_key(&OutputType::Exe); + tcx.sess.crate_types.borrow().contains(&config::CrateTypeRlib) && + tcx.sess.opts.output_types.contains_key(&OutputType::Exe); let needs_crate_object = - sess.opts.output_types.contains_key(&OutputType::Exe); + tcx.sess.opts.output_types.contains_key(&OutputType::Exe); if needs_crate_bitcode { modules_config.emit_bc = true; } @@ -734,7 +735,7 @@ pub fn run_passes(sess: &Session, // If we're not using the LLVM assembler, this function // could be invoked specially with output_type_assembly, so // in this case we still want the metadata object file. - if !sess.opts.output_types.contains_key(&OutputType::Assembly) { + if !tcx.sess.opts.output_types.contains_key(&OutputType::Assembly) { metadata_config.emit_obj = true; } } @@ -749,8 +750,8 @@ pub fn run_passes(sess: &Session, } } - modules_config.set_flags(sess, trans); - metadata_config.set_flags(sess, trans); + modules_config.set_flags(tcx.sess, trans); + metadata_config.set_flags(tcx.sess, trans); // Populate a buffer with a list of codegen threads. Items are processed in @@ -759,7 +760,7 @@ pub fn run_passes(sess: &Session, let mut work_items = Vec::with_capacity(1 + trans.modules.len()); { - let work = build_work_item(sess, + let work = build_work_item(tcx.sess, trans.metadata_module.clone(), metadata_config.clone(), crate_output.clone()); @@ -767,14 +768,14 @@ pub fn run_passes(sess: &Session, } for mtrans in trans.modules.iter() { - let work = build_work_item(sess, + let work = build_work_item(tcx.sess, mtrans.clone(), modules_config.clone(), crate_output.clone()); work_items.push(work); } - if sess.opts.debugging_opts.incremental_info { + if tcx.sess.opts.debugging_opts.incremental_info { dump_incremental_data(&trans); } @@ -787,9 +788,9 @@ pub fn run_passes(sess: &Session, // some discussion on how to improve this in the future. let num_workers = cmp::min(work_items.len() - 1, 32); if num_workers <= 1 { - run_work_singlethreaded(sess, &trans.exported_symbols, work_items); + run_work_singlethreaded(tcx, &trans.exported_symbols, work_items); } else { - run_work_multithreaded(sess, work_items, num_workers); + run_work_multithreaded(tcx, work_items, num_workers); } // If in incr. comp. mode, preserve the `.o` files for potential re-use @@ -806,7 +807,7 @@ pub fn run_passes(sess: &Session, files.push((OutputType::Bitcode, path)); } - save_trans_partition(sess, &mtrans.name, mtrans.symbol_name_hash, &files); + save_trans_partition(tcx.sess, &mtrans.name, mtrans.symbol_name_hash, &files); } // All codegen is finished. @@ -817,7 +818,7 @@ pub fn run_passes(sess: &Session, // Produce final compile outputs. let copy_gracefully = |from: &Path, to: &Path| { if let Err(e) = fs::copy(from, to) { - sess.err(&format!("could not copy {:?} to {:?}: {}", from, to, e)); + tcx.sess.err(&format!("could not copy {:?} to {:?}: {}", from, to, e)); } }; @@ -830,9 +831,9 @@ pub fn run_passes(sess: &Session, let path = crate_output.temp_path(output_type, module_name); copy_gracefully(&path, &crate_output.path(output_type)); - if !sess.opts.cg.save_temps && !keep_numbered { + if !tcx.sess.opts.cg.save_temps && !keep_numbered { // The user just wants `foo.x`, not `foo.#module-name#.x`. - remove(sess, &path); + remove(tcx.sess, &path); } } else { let ext = crate_output.temp_path(output_type, None) @@ -845,12 +846,12 @@ pub fn run_passes(sess: &Session, if crate_output.outputs.contains_key(&output_type) { // 2) Multiple codegen units, with `--emit foo=some_name`. We have // no good solution for this case, so warn the user. - sess.warn(&format!("ignoring emit path because multiple .{} files \ + tcx.sess.warn(&format!("ignoring emit path because multiple .{} files \ were produced", ext)); } else if crate_output.single_output_file.is_some() { // 3) Multiple codegen units, with `-o some_name`. We have // no good solution for this case, so warn the user. - sess.warn(&format!("ignoring -o because multiple .{} files \ + tcx.sess.warn(&format!("ignoring -o because multiple .{} files \ were produced", ext)); } else { // 4) Multiple codegen units, but no explicit name. We @@ -904,7 +905,7 @@ pub fn run_passes(sess: &Session, // We may create additional files if requested by the user (through // `-C save-temps` or `--emit=` flags). - if !sess.opts.cg.save_temps { + if !tcx.sess.opts.cg.save_temps { // Remove the temporary .#module-name#.o objects. If the user didn't // explicitly request bitcode (with --emit=bc), and the bitcode is not // needed for building an rlib, then we must remove .#module-name#.bc as @@ -923,27 +924,27 @@ pub fn run_passes(sess: &Session, // where .#module-name#.bc files are (maybe) deleted after making an // rlib. let keep_numbered_bitcode = needs_crate_bitcode || - (user_wants_bitcode && sess.opts.cg.codegen_units > 1); + (user_wants_bitcode && tcx.sess.opts.cg.codegen_units > 1); let keep_numbered_objects = needs_crate_object || - (user_wants_objects && sess.opts.cg.codegen_units > 1); + (user_wants_objects && tcx.sess.opts.cg.codegen_units > 1); for module_name in trans.modules.iter().map(|m| Some(&m.name[..])) { if modules_config.emit_obj && !keep_numbered_objects { let path = crate_output.temp_path(OutputType::Object, module_name); - remove(sess, &path); + remove(tcx.sess, &path); } if modules_config.emit_bc && !keep_numbered_bitcode { let path = crate_output.temp_path(OutputType::Bitcode, module_name); - remove(sess, &path); + remove(tcx.sess, &path); } } if metadata_config.emit_bc && !user_wants_bitcode { let path = crate_output.temp_path(OutputType::Bitcode, Some(&trans.metadata_module.name)); - remove(sess, &path); + remove(tcx.sess, &path); } } @@ -955,7 +956,7 @@ pub fn run_passes(sess: &Session, // FIXME: time_llvm_passes support - does this use a global context or // something? - if sess.opts.cg.codegen_units == 1 && sess.time_llvm_passes() { + if tcx.sess.opts.cg.codegen_units == 1 && tcx.sess.time_llvm_passes() { unsafe { llvm::LLVMRustPrintPassTimings(); } } } @@ -1032,10 +1033,11 @@ fn execute_work_item(cgcx: &CodegenContext, } } -fn run_work_singlethreaded(sess: &Session, +fn run_work_singlethreaded<'a, 'tcx: 'a>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, exported_symbols: &ExportedSymbols, work_items: Vec) { - let cgcx = CodegenContext::new_with_session(sess, exported_symbols); + let cgcx = CodegenContext::new_with_session(tcx, exported_symbols); // Since we're running single-threaded, we can pass the session to // the proc, allowing `optimize_and_codegen` to perform LTO. @@ -1044,7 +1046,8 @@ fn run_work_singlethreaded(sess: &Session, } } -fn run_work_multithreaded(sess: &Session, +fn run_work_multithreaded<'a, 'tcx: 'a>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, work_items: Vec, num_workers: usize) { assert!(num_workers > 0); @@ -1057,14 +1060,14 @@ fn run_work_multithreaded(sess: &Session, for i in 0..num_workers { let work_items_arc = work_items_arc.clone(); let diag_emitter = diag_emitter.clone(); - let plugin_passes = sess.plugin_llvm_passes.borrow().clone(); - let remark = sess.opts.cg.remark.clone(); + let plugin_passes = tcx.sess.plugin_llvm_passes.borrow().clone(); + let remark = tcx.sess.opts.cg.remark.clone(); let (tx, rx) = channel(); let mut tx = Some(tx); futures.push(rx); - let incr_comp_session_dir = sess.incr_comp_session_dir_opt().map(|r| r.clone()); + let incr_comp_session_dir = tcx.sess.incr_comp_session_dir_opt().map(|r| r.clone()); let depth = time_depth(); thread::Builder::new().name(format!("codegen-{}", i)).spawn(move || { @@ -1111,10 +1114,10 @@ fn run_work_multithreaded(sess: &Session, }, } // Display any new diagnostics. - diag_emitter.dump(sess.diagnostic()); + diag_emitter.dump(tcx.sess.diagnostic()); } if panicked { - sess.fatal("aborting due to worker thread panic"); + tcx.sess.fatal("aborting due to worker thread panic"); } }