Rollup merge of #41287 - nikomatsakis:incr-comp-refactor-trans, r=eddyb
Miscellneous refactorings of trans This doesn't achieve any particular goal yet, but it's a collection of refactorings with the common goal of turning `SharedCrateContext` etc into stuff that we can use with on-demand and actually expect to hash in a stable fashion for incremental. Not there yet, clearly. r? @eddyb cc @michaelwoerister
This commit is contained in:
commit
adc2b10399
@ -53,7 +53,6 @@ pub use self::NativeLibraryKind::*;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct LinkMeta {
|
||||
pub crate_name: Symbol,
|
||||
pub crate_hash: Svh,
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,6 @@ pub use self::code_stats::{SizeKind, TypeSizeInfo, VariantInfo};
|
||||
|
||||
use dep_graph::DepGraph;
|
||||
use hir::def_id::{CrateNum, DefIndex};
|
||||
use hir::svh::Svh;
|
||||
use lint;
|
||||
use middle::cstore::CrateStore;
|
||||
use middle::dependency_format;
|
||||
@ -402,15 +401,14 @@ impl Session {
|
||||
|
||||
/// Returns the symbol name for the registrar function,
|
||||
/// given the crate Svh and the function DefIndex.
|
||||
pub fn generate_plugin_registrar_symbol(&self, svh: &Svh, index: DefIndex)
|
||||
pub fn generate_plugin_registrar_symbol(&self, disambiguator: Symbol, index: DefIndex)
|
||||
-> String {
|
||||
format!("__rustc_plugin_registrar__{}_{}", svh, index.as_usize())
|
||||
format!("__rustc_plugin_registrar__{}_{}", disambiguator, index.as_usize())
|
||||
}
|
||||
|
||||
pub fn generate_derive_registrar_symbol(&self,
|
||||
svh: &Svh,
|
||||
index: DefIndex) -> String {
|
||||
format!("__rustc_derive_registrar__{}_{}", svh, index.as_usize())
|
||||
pub fn generate_derive_registrar_symbol(&self, disambiguator: Symbol, index: DefIndex)
|
||||
-> String {
|
||||
format!("__rustc_derive_registrar__{}_{}", disambiguator, index.as_usize())
|
||||
}
|
||||
|
||||
pub fn sysroot<'a>(&'a self) -> &'a Path {
|
||||
|
@ -1140,7 +1140,7 @@ pub fn phase_6_link_output(sess: &Session,
|
||||
outputs: &OutputFilenames) {
|
||||
time(sess.time_passes(),
|
||||
"linking",
|
||||
|| link::link_binary(sess, trans, outputs, &trans.link.crate_name.as_str()));
|
||||
|| link::link_binary(sess, trans, outputs, &trans.crate_name.as_str()));
|
||||
}
|
||||
|
||||
fn escape_dep_filename(filename: &str) -> String {
|
||||
|
@ -600,7 +600,7 @@ impl<'a> CrateLoader<'a> {
|
||||
Err(err) => self.sess.span_fatal(span, &err),
|
||||
};
|
||||
|
||||
let sym = self.sess.generate_derive_registrar_symbol(&root.hash,
|
||||
let sym = self.sess.generate_derive_registrar_symbol(root.disambiguator,
|
||||
root.macro_derive_registrar.unwrap());
|
||||
let registrar = unsafe {
|
||||
let sym = match lib.symbol(&sym) {
|
||||
@ -654,7 +654,7 @@ impl<'a> CrateLoader<'a> {
|
||||
/// Look for a plugin registrar. Returns library path, crate
|
||||
/// SVH and DefIndex of the registrar function.
|
||||
pub fn find_plugin_registrar(&mut self, span: Span, name: &str)
|
||||
-> Option<(PathBuf, Svh, DefIndex)> {
|
||||
-> Option<(PathBuf, Symbol, DefIndex)> {
|
||||
let ekrate = self.read_extension_crate(span, &ExternCrateInfo {
|
||||
name: Symbol::intern(name),
|
||||
ident: Symbol::intern(name),
|
||||
@ -675,7 +675,7 @@ impl<'a> CrateLoader<'a> {
|
||||
let root = ekrate.metadata.get_root();
|
||||
match (ekrate.dylib.as_ref(), root.plugin_registrar_fn) {
|
||||
(Some(dylib), Some(reg)) => {
|
||||
Some((dylib.to_path_buf(), root.hash, reg))
|
||||
Some((dylib.to_path_buf(), root.disambiguator, reg))
|
||||
}
|
||||
(None, Some(_)) => {
|
||||
span_err!(self.sess, span, E0457,
|
||||
|
@ -14,7 +14,7 @@ use schema::*;
|
||||
|
||||
use rustc::middle::cstore::{LinkMeta, LinkagePreference, NativeLibrary,
|
||||
EncodedMetadata, EncodedMetadataHash};
|
||||
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId};
|
||||
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LOCAL_CRATE};
|
||||
use rustc::hir::map::definitions::DefPathTable;
|
||||
use rustc::middle::dependency_format::Linkage;
|
||||
use rustc::middle::lang_items;
|
||||
@ -1380,7 +1380,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
let link_meta = self.link_meta;
|
||||
let is_proc_macro = tcx.sess.crate_types.borrow().contains(&CrateTypeProcMacro);
|
||||
let root = self.lazy(&CrateRoot {
|
||||
name: link_meta.crate_name,
|
||||
name: tcx.crate_name(LOCAL_CRATE),
|
||||
triple: tcx.sess.opts.target_triple.clone(),
|
||||
hash: link_meta.crate_hash,
|
||||
disambiguator: tcx.sess.local_crate_disambiguator(),
|
||||
|
@ -100,8 +100,8 @@ impl<'a> PluginLoader<'a> {
|
||||
fn load_plugin(&mut self, span: Span, name: &str, args: Vec<ast::NestedMetaItem>) {
|
||||
let registrar = self.reader.find_plugin_registrar(span, name);
|
||||
|
||||
if let Some((lib, svh, index)) = registrar {
|
||||
let symbol = self.sess.generate_plugin_registrar_symbol(&svh, index);
|
||||
if let Some((lib, disambiguator, index)) = registrar {
|
||||
let symbol = self.sess.generate_plugin_registrar_symbol(disambiguator, index);
|
||||
let fun = self.dylink_registrar(span, lib, symbol);
|
||||
self.plugins.push(PluginRegistrar {
|
||||
fun: fun,
|
||||
|
@ -47,7 +47,6 @@ use std::str;
|
||||
use flate;
|
||||
use syntax::ast;
|
||||
use syntax::attr;
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax_pos::Span;
|
||||
|
||||
/// The LLVM module name containing crate-metadata. This includes a `.` on
|
||||
@ -136,11 +135,8 @@ pub fn find_crate_name(sess: Option<&Session>,
|
||||
"rust_out".to_string()
|
||||
}
|
||||
|
||||
pub fn build_link_meta(incremental_hashes_map: &IncrementalHashesMap,
|
||||
name: &str)
|
||||
-> LinkMeta {
|
||||
pub fn build_link_meta(incremental_hashes_map: &IncrementalHashesMap) -> LinkMeta {
|
||||
let r = LinkMeta {
|
||||
crate_name: Symbol::intern(name),
|
||||
crate_hash: Svh::new(incremental_hashes_map[&DepNode::Krate].to_smaller_hash()),
|
||||
};
|
||||
info!("{:?}", r);
|
||||
|
@ -15,6 +15,7 @@ use back::symbol_names::symbol_name;
|
||||
use util::nodemap::FxHashMap;
|
||||
use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE};
|
||||
use rustc::session::config;
|
||||
use rustc::ty::TyCtxt;
|
||||
use syntax::attr;
|
||||
use trans_item::TransItem;
|
||||
|
||||
@ -64,15 +65,15 @@ impl ExportedSymbols {
|
||||
}
|
||||
|
||||
if let Some(id) = scx.sess().derive_registrar_fn.get() {
|
||||
let svh = &scx.link_meta().crate_hash;
|
||||
let def_id = scx.tcx().hir.local_def_id(id);
|
||||
let idx = def_id.index;
|
||||
let registrar = scx.sess().generate_derive_registrar_symbol(svh, idx);
|
||||
let disambiguator = scx.sess().local_crate_disambiguator();
|
||||
let registrar = scx.sess().generate_derive_registrar_symbol(disambiguator, idx);
|
||||
local_crate.push((registrar, SymbolExportLevel::C));
|
||||
}
|
||||
|
||||
if scx.sess().crate_types.borrow().contains(&config::CrateTypeDylib) {
|
||||
local_crate.push((scx.metadata_symbol_name(),
|
||||
local_crate.push((metadata_symbol_name(scx.tcx()),
|
||||
SymbolExportLevel::Rust));
|
||||
}
|
||||
|
||||
@ -173,6 +174,12 @@ impl ExportedSymbols {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn metadata_symbol_name(tcx: TyCtxt) -> String {
|
||||
format!("rust_metadata_{}_{}",
|
||||
tcx.crate_name(LOCAL_CRATE),
|
||||
tcx.crate_disambiguator(LOCAL_CRATE))
|
||||
}
|
||||
|
||||
pub fn crate_export_threshold(crate_type: config::CrateType)
|
||||
-> SymbolExportLevel {
|
||||
match crate_type {
|
||||
|
@ -179,14 +179,14 @@ pub fn symbol_name<'a, 'tcx>(instance: Instance<'tcx>,
|
||||
|
||||
if let Some(id) = node_id {
|
||||
if scx.sess().plugin_registrar_fn.get() == Some(id) {
|
||||
let svh = &scx.link_meta().crate_hash;
|
||||
let idx = def_id.index;
|
||||
return scx.sess().generate_plugin_registrar_symbol(svh, idx);
|
||||
let disambiguator = scx.sess().local_crate_disambiguator();
|
||||
return scx.sess().generate_plugin_registrar_symbol(disambiguator, idx);
|
||||
}
|
||||
if scx.sess().derive_registrar_fn.get() == Some(id) {
|
||||
let svh = &scx.link_meta().crate_hash;
|
||||
let idx = def_id.index;
|
||||
return scx.sess().generate_derive_registrar_symbol(svh, idx);
|
||||
let disambiguator = scx.sess().local_crate_disambiguator();
|
||||
return scx.sess().generate_derive_registrar_symbol(disambiguator, idx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,13 +32,14 @@ use assert_module_sources;
|
||||
use back::link;
|
||||
use back::linker::LinkerInfo;
|
||||
use back::symbol_export::{self, ExportedSymbols};
|
||||
use llvm::{Linkage, ValueRef, Vector, get_param};
|
||||
use llvm::{ContextRef, Linkage, ModuleRef, ValueRef, Vector, get_param};
|
||||
use llvm;
|
||||
use rustc::hir::def_id::LOCAL_CRATE;
|
||||
use middle::lang_items::StartFnLangItem;
|
||||
use middle::cstore::EncodedMetadata;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::dep_graph::{AssertDepGraphSafe, DepNode, WorkProduct};
|
||||
use rustc::dep_graph::{AssertDepGraphSafe, DepNode};
|
||||
use rustc::middle::cstore::LinkMeta;
|
||||
use rustc::hir::map as hir_map;
|
||||
use rustc::util::common::time;
|
||||
use session::config::{self, NoDebugInfo};
|
||||
@ -56,7 +57,7 @@ use common::CrateContext;
|
||||
use common::{type_is_zero_size, val_ty};
|
||||
use common;
|
||||
use consts;
|
||||
use context::{SharedCrateContext, CrateContextList};
|
||||
use context::{self, LocalCrateContext, SharedCrateContext, Stats};
|
||||
use debuginfo;
|
||||
use declare;
|
||||
use machine;
|
||||
@ -724,11 +725,16 @@ fn contains_null(s: &str) -> bool {
|
||||
s.bytes().any(|b| b == 0)
|
||||
}
|
||||
|
||||
fn write_metadata(cx: &SharedCrateContext,
|
||||
exported_symbols: &NodeSet)
|
||||
-> EncodedMetadata {
|
||||
fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
|
||||
link_meta: &LinkMeta,
|
||||
exported_symbols: &NodeSet)
|
||||
-> (ContextRef, ModuleRef, EncodedMetadata) {
|
||||
use flate;
|
||||
|
||||
let (metadata_llcx, metadata_llmod) = unsafe {
|
||||
context::create_context_and_module(tcx.sess, "metadata")
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord)]
|
||||
enum MetadataKind {
|
||||
None,
|
||||
@ -736,7 +742,7 @@ fn write_metadata(cx: &SharedCrateContext,
|
||||
Compressed
|
||||
}
|
||||
|
||||
let kind = cx.sess().crate_types.borrow().iter().map(|ty| {
|
||||
let kind = tcx.sess.crate_types.borrow().iter().map(|ty| {
|
||||
match *ty {
|
||||
config::CrateTypeExecutable |
|
||||
config::CrateTypeStaticlib |
|
||||
@ -750,35 +756,35 @@ fn write_metadata(cx: &SharedCrateContext,
|
||||
}).max().unwrap();
|
||||
|
||||
if kind == MetadataKind::None {
|
||||
return EncodedMetadata {
|
||||
return (metadata_llcx, metadata_llmod, EncodedMetadata {
|
||||
raw_data: vec![],
|
||||
hashes: vec![],
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
let cstore = &cx.tcx().sess.cstore;
|
||||
let metadata = cstore.encode_metadata(cx.tcx(),
|
||||
cx.link_meta(),
|
||||
let cstore = &tcx.sess.cstore;
|
||||
let metadata = cstore.encode_metadata(tcx,
|
||||
&link_meta,
|
||||
exported_symbols);
|
||||
if kind == MetadataKind::Uncompressed {
|
||||
return metadata;
|
||||
return (metadata_llcx, metadata_llmod, metadata);
|
||||
}
|
||||
|
||||
assert!(kind == MetadataKind::Compressed);
|
||||
let mut compressed = cstore.metadata_encoding_version().to_vec();
|
||||
compressed.extend_from_slice(&flate::deflate_bytes(&metadata.raw_data));
|
||||
|
||||
let llmeta = C_bytes_in_context(cx.metadata_llcx(), &compressed);
|
||||
let llconst = C_struct_in_context(cx.metadata_llcx(), &[llmeta], false);
|
||||
let name = cx.metadata_symbol_name();
|
||||
let llmeta = C_bytes_in_context(metadata_llcx, &compressed);
|
||||
let llconst = C_struct_in_context(metadata_llcx, &[llmeta], false);
|
||||
let name = symbol_export::metadata_symbol_name(tcx);
|
||||
let buf = CString::new(name).unwrap();
|
||||
let llglobal = unsafe {
|
||||
llvm::LLVMAddGlobal(cx.metadata_llmod(), val_ty(llconst).to_ref(), buf.as_ptr())
|
||||
llvm::LLVMAddGlobal(metadata_llmod, val_ty(llconst).to_ref(), buf.as_ptr())
|
||||
};
|
||||
unsafe {
|
||||
llvm::LLVMSetInitializer(llglobal, llconst);
|
||||
let section_name =
|
||||
cx.tcx().sess.cstore.metadata_section_name(&cx.sess().target.target);
|
||||
tcx.sess.cstore.metadata_section_name(&tcx.sess.target.target);
|
||||
let name = CString::new(section_name).unwrap();
|
||||
llvm::LLVMSetSection(llglobal, name.as_ptr());
|
||||
|
||||
@ -787,15 +793,16 @@ fn write_metadata(cx: &SharedCrateContext,
|
||||
// metadata doesn't get loaded into memory.
|
||||
let directive = format!(".section {}", section_name);
|
||||
let directive = CString::new(directive).unwrap();
|
||||
llvm::LLVMSetModuleInlineAsm(cx.metadata_llmod(), directive.as_ptr())
|
||||
llvm::LLVMSetModuleInlineAsm(metadata_llmod, directive.as_ptr())
|
||||
}
|
||||
return metadata;
|
||||
return (metadata_llcx, metadata_llmod, metadata);
|
||||
}
|
||||
|
||||
/// Find any symbols that are defined in one compilation unit, but not declared
|
||||
/// in any other compilation unit. Give these symbols internal linkage.
|
||||
fn internalize_symbols<'a, 'tcx>(sess: &Session,
|
||||
ccxs: &CrateContextList<'a, 'tcx>,
|
||||
scx: &SharedCrateContext<'a, 'tcx>,
|
||||
llvm_modules: &[ModuleLlvm],
|
||||
symbol_map: &SymbolMap<'tcx>,
|
||||
exported_symbols: &ExportedSymbols) {
|
||||
let export_threshold =
|
||||
@ -810,7 +817,6 @@ fn internalize_symbols<'a, 'tcx>(sess: &Session,
|
||||
.map(|&(ref name, _)| &name[..])
|
||||
.collect::<FxHashSet<&str>>();
|
||||
|
||||
let scx = ccxs.shared();
|
||||
let tcx = scx.tcx();
|
||||
|
||||
let incr_comp = sess.opts.debugging_opts.incremental.is_some();
|
||||
@ -825,8 +831,8 @@ fn internalize_symbols<'a, 'tcx>(sess: &Session,
|
||||
// incremental compilation, we don't need to collect. See below for more
|
||||
// information.
|
||||
if !incr_comp {
|
||||
for ccx in ccxs.iter_need_trans() {
|
||||
for val in iter_globals(ccx.llmod()).chain(iter_functions(ccx.llmod())) {
|
||||
for ll in llvm_modules {
|
||||
for val in iter_globals(ll.llmod).chain(iter_functions(ll.llmod)) {
|
||||
let linkage = llvm::LLVMRustGetLinkage(val);
|
||||
// We only care about external declarations (not definitions)
|
||||
// and available_externally definitions.
|
||||
@ -862,8 +868,8 @@ fn internalize_symbols<'a, 'tcx>(sess: &Session,
|
||||
// Examine each external definition. If the definition is not used in
|
||||
// any other compilation unit, and is not reachable from other crates,
|
||||
// then give it internal linkage.
|
||||
for ccx in ccxs.iter_need_trans() {
|
||||
for val in iter_globals(ccx.llmod()).chain(iter_functions(ccx.llmod())) {
|
||||
for ll in llvm_modules {
|
||||
for val in iter_globals(ll.llmod).chain(iter_functions(ll.llmod)) {
|
||||
let linkage = llvm::LLVMRustGetLinkage(val);
|
||||
|
||||
let is_externally_visible = (linkage == llvm::Linkage::ExternalLinkage) ||
|
||||
@ -922,19 +928,20 @@ fn internalize_symbols<'a, 'tcx>(sess: &Session,
|
||||
// when using MSVC linker. We do this only for data, as linker can fix up
|
||||
// code references on its own.
|
||||
// See #26591, #27438
|
||||
fn create_imps(cx: &CrateContextList) {
|
||||
fn create_imps(sess: &Session,
|
||||
llvm_modules: &[ModuleLlvm]) {
|
||||
// The x86 ABI seems to require that leading underscores are added to symbol
|
||||
// names, so we need an extra underscore on 32-bit. There's also a leading
|
||||
// '\x01' here which disables LLVM's symbol mangling (e.g. no extra
|
||||
// underscores added in front).
|
||||
let prefix = if cx.shared().sess().target.target.target_pointer_width == "32" {
|
||||
let prefix = if sess.target.target.target_pointer_width == "32" {
|
||||
"\x01__imp__"
|
||||
} else {
|
||||
"\x01__imp_"
|
||||
};
|
||||
unsafe {
|
||||
for ccx in cx.iter_need_trans() {
|
||||
let exported: Vec<_> = iter_globals(ccx.llmod())
|
||||
for ll in llvm_modules {
|
||||
let exported: Vec<_> = iter_globals(ll.llmod)
|
||||
.filter(|&val| {
|
||||
llvm::LLVMRustGetLinkage(val) ==
|
||||
llvm::Linkage::ExternalLinkage &&
|
||||
@ -942,13 +949,13 @@ fn create_imps(cx: &CrateContextList) {
|
||||
})
|
||||
.collect();
|
||||
|
||||
let i8p_ty = Type::i8p(&ccx);
|
||||
let i8p_ty = Type::i8p_llcx(ll.llcx);
|
||||
for val in exported {
|
||||
let name = CStr::from_ptr(llvm::LLVMGetValueName(val));
|
||||
let mut imp_name = prefix.as_bytes().to_vec();
|
||||
imp_name.extend(name.to_bytes());
|
||||
let imp_name = CString::new(imp_name).unwrap();
|
||||
let imp = llvm::LLVMAddGlobal(ccx.llmod(),
|
||||
let imp = llvm::LLVMAddGlobal(ll.llmod,
|
||||
i8p_ty.to_ref(),
|
||||
imp_name.as_ptr() as *const _);
|
||||
let init = llvm::LLVMConstBitCast(val, i8p_ty.to_ref());
|
||||
@ -1058,28 +1065,28 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
// particular items that will be processed.
|
||||
let krate = tcx.hir.krate();
|
||||
|
||||
let ty::CrateAnalysis { reachable, name, .. } = analysis;
|
||||
let ty::CrateAnalysis { reachable, .. } = analysis;
|
||||
let exported_symbols = find_exported_symbols(tcx, reachable);
|
||||
|
||||
let check_overflow = tcx.sess.overflow_checks();
|
||||
|
||||
let link_meta = link::build_link_meta(incremental_hashes_map, &name);
|
||||
let link_meta = link::build_link_meta(incremental_hashes_map);
|
||||
|
||||
let shared_ccx = SharedCrateContext::new(tcx,
|
||||
link_meta.clone(),
|
||||
exported_symbols,
|
||||
check_overflow);
|
||||
// Translate the metadata.
|
||||
let metadata = time(tcx.sess.time_passes(), "write metadata", || {
|
||||
write_metadata(&shared_ccx, shared_ccx.exported_symbols())
|
||||
});
|
||||
let (metadata_llcx, metadata_llmod, metadata) =
|
||||
time(tcx.sess.time_passes(), "write metadata", || {
|
||||
write_metadata(tcx, &link_meta, shared_ccx.exported_symbols())
|
||||
});
|
||||
|
||||
let metadata_module = ModuleTranslation {
|
||||
name: link::METADATA_MODULE_NAME.to_string(),
|
||||
symbol_name_hash: 0, // we always rebuild metadata, at least for now
|
||||
source: ModuleSource::Translated(ModuleLlvm {
|
||||
llcx: shared_ccx.metadata_llcx(),
|
||||
llmod: shared_ccx.metadata_llmod(),
|
||||
llcx: metadata_llcx,
|
||||
llmod: metadata_llmod,
|
||||
}),
|
||||
};
|
||||
let no_builtins = attr::contains_name(&krate.attrs, "no_builtins");
|
||||
@ -1090,6 +1097,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
let empty_exported_symbols = ExportedSymbols::empty();
|
||||
let linker_info = LinkerInfo::new(&shared_ccx, &empty_exported_symbols);
|
||||
return CrateTranslation {
|
||||
crate_name: tcx.crate_name(LOCAL_CRATE),
|
||||
modules: vec![],
|
||||
metadata_module: metadata_module,
|
||||
link: link_meta,
|
||||
@ -1107,73 +1115,78 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
|
||||
let symbol_map = Rc::new(symbol_map);
|
||||
|
||||
let previous_work_products = trans_reuse_previous_work_products(&shared_ccx,
|
||||
&codegen_units,
|
||||
&symbol_map);
|
||||
|
||||
let crate_context_list = CrateContextList::new(&shared_ccx,
|
||||
codegen_units,
|
||||
previous_work_products,
|
||||
symbol_map.clone());
|
||||
let modules: Vec<_> = crate_context_list.iter_all()
|
||||
.map(|ccx| {
|
||||
let source = match ccx.previous_work_product() {
|
||||
Some(buf) => ModuleSource::Preexisting(buf.clone()),
|
||||
None => ModuleSource::Translated(ModuleLlvm {
|
||||
llcx: ccx.llcx(),
|
||||
llmod: ccx.llmod(),
|
||||
}),
|
||||
};
|
||||
|
||||
ModuleTranslation {
|
||||
name: String::from(ccx.codegen_unit().name()),
|
||||
symbol_name_hash: ccx.codegen_unit()
|
||||
.compute_symbol_name_hash(&shared_ccx,
|
||||
&symbol_map),
|
||||
source: source,
|
||||
}
|
||||
let mut all_stats = Stats::default();
|
||||
let modules: Vec<ModuleTranslation> = codegen_units
|
||||
.into_iter()
|
||||
.map(|cgu| {
|
||||
let dep_node = cgu.work_product_dep_node();
|
||||
let (stats, module) =
|
||||
tcx.dep_graph.with_task(dep_node,
|
||||
AssertDepGraphSafe(&shared_ccx),
|
||||
AssertDepGraphSafe((cgu, symbol_map.clone())),
|
||||
module_translation);
|
||||
all_stats.extend(stats);
|
||||
module
|
||||
})
|
||||
.collect();
|
||||
|
||||
assert_module_sources::assert_module_sources(tcx, &modules);
|
||||
fn module_translation<'a, 'tcx>(
|
||||
scx: AssertDepGraphSafe<&SharedCrateContext<'a, 'tcx>>,
|
||||
args: AssertDepGraphSafe<(CodegenUnit<'tcx>, Rc<SymbolMap<'tcx>>)>)
|
||||
-> (Stats, ModuleTranslation)
|
||||
{
|
||||
// FIXME(#40304): We ought to be using the id as a key and some queries, I think.
|
||||
let AssertDepGraphSafe(scx) = scx;
|
||||
let AssertDepGraphSafe((cgu, symbol_map)) = args;
|
||||
|
||||
// Instantiate translation items without filling out definitions yet...
|
||||
for ccx in crate_context_list.iter_need_trans() {
|
||||
let dep_node = ccx.codegen_unit().work_product_dep_node();
|
||||
tcx.dep_graph.with_task(dep_node,
|
||||
ccx,
|
||||
AssertDepGraphSafe(symbol_map.clone()),
|
||||
trans_decl_task);
|
||||
let cgu_name = String::from(cgu.name());
|
||||
let cgu_id = cgu.work_product_id();
|
||||
let symbol_name_hash = cgu.compute_symbol_name_hash(scx, &symbol_map);
|
||||
|
||||
fn trans_decl_task<'a, 'tcx>(ccx: CrateContext<'a, 'tcx>,
|
||||
symbol_map: AssertDepGraphSafe<Rc<SymbolMap<'tcx>>>) {
|
||||
// FIXME(#40304): Instead of this, the symbol-map should be an
|
||||
// on-demand thing that we compute.
|
||||
let AssertDepGraphSafe(symbol_map) = symbol_map;
|
||||
let cgu = ccx.codegen_unit();
|
||||
let trans_items = cgu.items_in_deterministic_order(ccx.tcx(), &symbol_map);
|
||||
for (trans_item, linkage) in trans_items {
|
||||
// Check whether there is a previous work-product we can
|
||||
// re-use. Not only must the file exist, and the inputs not
|
||||
// be dirty, but the hash of the symbols we will generate must
|
||||
// be the same.
|
||||
let previous_work_product =
|
||||
scx.dep_graph().previous_work_product(&cgu_id).and_then(|work_product| {
|
||||
if work_product.input_hash == symbol_name_hash {
|
||||
debug!("trans_reuse_previous_work_products: reusing {:?}", work_product);
|
||||
Some(work_product)
|
||||
} else {
|
||||
if scx.sess().opts.debugging_opts.incremental_info {
|
||||
println!("incremental: CGU `{}` invalidated because of \
|
||||
changed partitioning hash.",
|
||||
cgu.name());
|
||||
}
|
||||
debug!("trans_reuse_previous_work_products: \
|
||||
not reusing {:?} because hash changed to {:?}",
|
||||
work_product, symbol_name_hash);
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
if let Some(buf) = previous_work_product {
|
||||
// Don't need to translate this module.
|
||||
let module = ModuleTranslation {
|
||||
name: cgu_name,
|
||||
symbol_name_hash,
|
||||
source: ModuleSource::Preexisting(buf.clone())
|
||||
};
|
||||
return (Stats::default(), module);
|
||||
}
|
||||
|
||||
// Instantiate translation items without filling out definitions yet...
|
||||
let lcx = LocalCrateContext::new(scx, cgu, symbol_map.clone());
|
||||
let module = {
|
||||
let ccx = CrateContext::new(scx, &lcx);
|
||||
let trans_items = ccx.codegen_unit()
|
||||
.items_in_deterministic_order(ccx.tcx(), &symbol_map);
|
||||
for &(trans_item, linkage) in &trans_items {
|
||||
trans_item.predefine(&ccx, linkage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ... and now that we have everything pre-defined, fill out those definitions.
|
||||
for ccx in crate_context_list.iter_need_trans() {
|
||||
let dep_node = ccx.codegen_unit().work_product_dep_node();
|
||||
tcx.dep_graph.with_task(dep_node,
|
||||
ccx,
|
||||
AssertDepGraphSafe(symbol_map.clone()),
|
||||
trans_def_task);
|
||||
|
||||
fn trans_def_task<'a, 'tcx>(ccx: CrateContext<'a, 'tcx>,
|
||||
symbol_map: AssertDepGraphSafe<Rc<SymbolMap<'tcx>>>) {
|
||||
// FIXME(#40304): Instead of this, the symbol-map should be an
|
||||
// on-demand thing that we compute.
|
||||
let AssertDepGraphSafe(symbol_map) = symbol_map;
|
||||
let cgu = ccx.codegen_unit();
|
||||
let trans_items = cgu.items_in_deterministic_order(ccx.tcx(), &symbol_map);
|
||||
for (trans_item, _) in trans_items {
|
||||
// ... and now that we have everything pre-defined, fill out those definitions.
|
||||
for &(trans_item, _) in &trans_items {
|
||||
trans_item.define(&ccx);
|
||||
}
|
||||
|
||||
@ -1211,26 +1224,38 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
if ccx.sess().opts.debuginfo != NoDebugInfo {
|
||||
debuginfo::finalize(&ccx);
|
||||
}
|
||||
}
|
||||
|
||||
ModuleTranslation {
|
||||
name: cgu_name,
|
||||
symbol_name_hash,
|
||||
source: ModuleSource::Translated(ModuleLlvm {
|
||||
llcx: ccx.llcx(),
|
||||
llmod: ccx.llmod(),
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
(lcx.into_stats(), module)
|
||||
}
|
||||
|
||||
assert_module_sources::assert_module_sources(tcx, &modules);
|
||||
|
||||
symbol_names_test::report_symbol_names(&shared_ccx);
|
||||
|
||||
if shared_ccx.sess().trans_stats() {
|
||||
let stats = shared_ccx.stats();
|
||||
println!("--- trans stats ---");
|
||||
println!("n_glues_created: {}", stats.n_glues_created.get());
|
||||
println!("n_null_glues: {}", stats.n_null_glues.get());
|
||||
println!("n_real_glues: {}", stats.n_real_glues.get());
|
||||
println!("n_glues_created: {}", all_stats.n_glues_created.get());
|
||||
println!("n_null_glues: {}", all_stats.n_null_glues.get());
|
||||
println!("n_real_glues: {}", all_stats.n_real_glues.get());
|
||||
|
||||
println!("n_fns: {}", stats.n_fns.get());
|
||||
println!("n_inlines: {}", stats.n_inlines.get());
|
||||
println!("n_closures: {}", stats.n_closures.get());
|
||||
println!("n_fns: {}", all_stats.n_fns.get());
|
||||
println!("n_inlines: {}", all_stats.n_inlines.get());
|
||||
println!("n_closures: {}", all_stats.n_closures.get());
|
||||
println!("fn stats:");
|
||||
stats.fn_stats.borrow_mut().sort_by(|&(_, insns_a), &(_, insns_b)| {
|
||||
all_stats.fn_stats.borrow_mut().sort_by(|&(_, insns_a), &(_, insns_b)| {
|
||||
insns_b.cmp(&insns_a)
|
||||
});
|
||||
for tuple in stats.fn_stats.borrow().iter() {
|
||||
for tuple in all_stats.fn_stats.borrow().iter() {
|
||||
match *tuple {
|
||||
(ref name, insns) => {
|
||||
println!("{} insns, {}", insns, *name);
|
||||
@ -1240,7 +1265,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
}
|
||||
|
||||
if shared_ccx.sess().count_llvm_insns() {
|
||||
for (k, v) in shared_ccx.stats().llvm_insns.borrow().iter() {
|
||||
for (k, v) in all_stats.llvm_insns.borrow().iter() {
|
||||
println!("{:7} {}", *v, *k);
|
||||
}
|
||||
}
|
||||
@ -1250,11 +1275,23 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
let exported_symbols = ExportedSymbols::compute_from(&shared_ccx,
|
||||
&symbol_map);
|
||||
|
||||
// Get the list of llvm modules we created. We'll do a few wacky
|
||||
// transforms on them now.
|
||||
|
||||
let llvm_modules: Vec<_> =
|
||||
modules.iter()
|
||||
.filter_map(|module| match module.source {
|
||||
ModuleSource::Translated(llvm) => Some(llvm),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Now that we have all symbols that are exported from the CGUs of this
|
||||
// crate, we can run the `internalize_symbols` pass.
|
||||
time(shared_ccx.sess().time_passes(), "internalize symbols", || {
|
||||
internalize_symbols(sess,
|
||||
&crate_context_list,
|
||||
&shared_ccx,
|
||||
&llvm_modules,
|
||||
&symbol_map,
|
||||
&exported_symbols);
|
||||
});
|
||||
@ -1265,7 +1302,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
|
||||
if sess.target.target.options.is_like_msvc &&
|
||||
sess.crate_types.borrow().iter().any(|ct| *ct == config::CrateTypeRlib) {
|
||||
create_imps(&crate_context_list);
|
||||
create_imps(sess, &llvm_modules);
|
||||
}
|
||||
|
||||
let linker_info = LinkerInfo::new(&shared_ccx, &exported_symbols);
|
||||
@ -1282,6 +1319,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
});
|
||||
|
||||
CrateTranslation {
|
||||
crate_name: tcx.crate_name(LOCAL_CRATE),
|
||||
modules: modules,
|
||||
metadata_module: metadata_module,
|
||||
link: link_meta,
|
||||
@ -1480,43 +1518,6 @@ fn gather_type_sizes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
||||
}
|
||||
}
|
||||
|
||||
/// For each CGU, identify if we can reuse an existing object file (or
|
||||
/// maybe other context).
|
||||
fn trans_reuse_previous_work_products(scx: &SharedCrateContext,
|
||||
codegen_units: &[CodegenUnit],
|
||||
symbol_map: &SymbolMap)
|
||||
-> Vec<Option<WorkProduct>> {
|
||||
debug!("trans_reuse_previous_work_products()");
|
||||
codegen_units
|
||||
.iter()
|
||||
.map(|cgu| {
|
||||
let id = cgu.work_product_id();
|
||||
|
||||
let hash = cgu.compute_symbol_name_hash(scx, symbol_map);
|
||||
|
||||
debug!("trans_reuse_previous_work_products: id={:?} hash={}", id, hash);
|
||||
|
||||
if let Some(work_product) = scx.dep_graph().previous_work_product(&id) {
|
||||
if work_product.input_hash == hash {
|
||||
debug!("trans_reuse_previous_work_products: reusing {:?}", work_product);
|
||||
return Some(work_product);
|
||||
} else {
|
||||
if scx.sess().opts.debugging_opts.incremental_info {
|
||||
println!("incremental: CGU `{}` invalidated because of \
|
||||
changed partitioning hash.",
|
||||
cgu.name());
|
||||
}
|
||||
debug!("trans_reuse_previous_work_products: \
|
||||
not reusing {:?} because hash changed to {:?}",
|
||||
work_product, hash);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>)
|
||||
-> (Vec<CodegenUnit<'tcx>>, SymbolMap<'tcx>) {
|
||||
let time_passes = scx.sess().time_passes();
|
||||
|
@ -10,9 +10,7 @@
|
||||
|
||||
use llvm;
|
||||
use llvm::{ContextRef, ModuleRef, ValueRef};
|
||||
use rustc::dep_graph::{DepGraph, DepGraphSafe, DepNode, DepTrackingMap,
|
||||
DepTrackingMapConfig, WorkProduct};
|
||||
use middle::cstore::LinkMeta;
|
||||
use rustc::dep_graph::{DepGraph, DepGraphSafe, DepNode, DepTrackingMap, DepTrackingMapConfig};
|
||||
use rustc::hir;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::traits;
|
||||
@ -47,6 +45,7 @@ use syntax::symbol::InternedString;
|
||||
use syntax_pos::DUMMY_SP;
|
||||
use abi::Abi;
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct Stats {
|
||||
pub n_glues_created: Cell<usize>,
|
||||
pub n_null_glues: Cell<usize>,
|
||||
@ -60,19 +59,30 @@ pub struct Stats {
|
||||
pub fn_stats: RefCell<Vec<(String, usize)> >,
|
||||
}
|
||||
|
||||
impl Stats {
|
||||
pub fn extend(&mut self, stats: Stats) {
|
||||
self.n_glues_created.set(self.n_glues_created.get() + stats.n_glues_created.get());
|
||||
self.n_null_glues.set(self.n_null_glues.get() + stats.n_null_glues.get());
|
||||
self.n_real_glues.set(self.n_real_glues.get() + stats.n_real_glues.get());
|
||||
self.n_fns.set(self.n_fns.get() + stats.n_fns.get());
|
||||
self.n_inlines.set(self.n_inlines.get() + stats.n_inlines.get());
|
||||
self.n_closures.set(self.n_closures.get() + stats.n_closures.get());
|
||||
self.n_llvm_insns.set(self.n_llvm_insns.get() + stats.n_llvm_insns.get());
|
||||
self.llvm_insns.borrow_mut().extend(
|
||||
stats.llvm_insns.borrow().iter()
|
||||
.map(|(key, value)| (key.clone(), value.clone())));
|
||||
self.fn_stats.borrow_mut().append(&mut *stats.fn_stats.borrow_mut());
|
||||
}
|
||||
}
|
||||
|
||||
/// The shared portion of a `CrateContext`. There is one `SharedCrateContext`
|
||||
/// per crate. The data here is shared between all compilation units of the
|
||||
/// crate, so it must not contain references to any LLVM data structures
|
||||
/// (aside from metadata-related ones).
|
||||
pub struct SharedCrateContext<'a, 'tcx: 'a> {
|
||||
metadata_llmod: ModuleRef,
|
||||
metadata_llcx: ContextRef,
|
||||
|
||||
exported_symbols: NodeSet,
|
||||
link_meta: LinkMeta,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
empty_param_env: ty::ParameterEnvironment<'tcx>,
|
||||
stats: Stats,
|
||||
check_overflow: bool,
|
||||
|
||||
use_dll_storage_attrs: bool,
|
||||
@ -89,7 +99,7 @@ pub struct SharedCrateContext<'a, 'tcx: 'a> {
|
||||
pub struct LocalCrateContext<'tcx> {
|
||||
llmod: ModuleRef,
|
||||
llcx: ContextRef,
|
||||
previous_work_product: Option<WorkProduct>,
|
||||
stats: Stats,
|
||||
codegen_unit: CodegenUnit<'tcx>,
|
||||
needs_unwind_cleanup_cache: RefCell<FxHashMap<Ty<'tcx>, bool>>,
|
||||
/// Cache instances of monomorphic and polymorphic items
|
||||
@ -214,109 +224,25 @@ impl<'gcx> DepTrackingMapConfig for ProjectionCache<'gcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// This list owns a number of LocalCrateContexts and binds them to their common
|
||||
/// SharedCrateContext. This type just exists as a convenience, something to
|
||||
/// pass around all LocalCrateContexts with and get an iterator over them.
|
||||
pub struct CrateContextList<'a, 'tcx: 'a> {
|
||||
shared: &'a SharedCrateContext<'a, 'tcx>,
|
||||
local_ccxs: Vec<LocalCrateContext<'tcx>>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx: 'a> CrateContextList<'a, 'tcx> {
|
||||
pub fn new(shared_ccx: &'a SharedCrateContext<'a, 'tcx>,
|
||||
codegen_units: Vec<CodegenUnit<'tcx>>,
|
||||
previous_work_products: Vec<Option<WorkProduct>>,
|
||||
symbol_map: Rc<SymbolMap<'tcx>>)
|
||||
-> CrateContextList<'a, 'tcx> {
|
||||
CrateContextList {
|
||||
shared: shared_ccx,
|
||||
local_ccxs: codegen_units.into_iter().zip(previous_work_products).map(|(cgu, wp)| {
|
||||
LocalCrateContext::new(shared_ccx, cgu, wp, symbol_map.clone())
|
||||
}).collect()
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterate over all crate contexts, whether or not they need
|
||||
/// translation. That is, whether or not a `.o` file is available
|
||||
/// for re-use from a previous incr. comp.).
|
||||
pub fn iter_all<'b>(&'b self) -> CrateContextIterator<'b, 'tcx> {
|
||||
CrateContextIterator {
|
||||
shared: self.shared,
|
||||
index: 0,
|
||||
local_ccxs: &self.local_ccxs[..],
|
||||
filter_to_previous_work_product_unavail: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterator over all CCX that need translation (cannot reuse results from
|
||||
/// previous incr. comp.).
|
||||
pub fn iter_need_trans<'b>(&'b self) -> CrateContextIterator<'b, 'tcx> {
|
||||
CrateContextIterator {
|
||||
shared: self.shared,
|
||||
index: 0,
|
||||
local_ccxs: &self.local_ccxs[..],
|
||||
filter_to_previous_work_product_unavail: true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn shared(&self) -> &'a SharedCrateContext<'a, 'tcx> {
|
||||
self.shared
|
||||
}
|
||||
}
|
||||
|
||||
/// A CrateContext value binds together one LocalCrateContext with the
|
||||
/// SharedCrateContext. It exists as a convenience wrapper, so we don't have to
|
||||
/// pass around (SharedCrateContext, LocalCrateContext) tuples all over trans.
|
||||
pub struct CrateContext<'a, 'tcx: 'a> {
|
||||
shared: &'a SharedCrateContext<'a, 'tcx>,
|
||||
local_ccxs: &'a [LocalCrateContext<'tcx>],
|
||||
/// The index of `local` in `local_ccxs`. This is used in
|
||||
/// `maybe_iter(true)` to identify the original `LocalCrateContext`.
|
||||
index: usize,
|
||||
local_ccx: &'a LocalCrateContext<'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> CrateContext<'a, 'tcx> {
|
||||
pub fn new(shared: &'a SharedCrateContext<'a, 'tcx>,
|
||||
local_ccx: &'a LocalCrateContext<'tcx>)
|
||||
-> Self {
|
||||
CrateContext { shared, local_ccx }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> DepGraphSafe for CrateContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
pub struct CrateContextIterator<'a, 'tcx: 'a> {
|
||||
shared: &'a SharedCrateContext<'a, 'tcx>,
|
||||
local_ccxs: &'a [LocalCrateContext<'tcx>],
|
||||
index: usize,
|
||||
|
||||
/// if true, only return results where `previous_work_product` is none
|
||||
filter_to_previous_work_product_unavail: bool,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Iterator for CrateContextIterator<'a,'tcx> {
|
||||
type Item = CrateContext<'a, 'tcx>;
|
||||
|
||||
fn next(&mut self) -> Option<CrateContext<'a, 'tcx>> {
|
||||
loop {
|
||||
if self.index >= self.local_ccxs.len() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let index = self.index;
|
||||
self.index += 1;
|
||||
|
||||
let ccx = CrateContext {
|
||||
shared: self.shared,
|
||||
index: index,
|
||||
local_ccxs: self.local_ccxs,
|
||||
};
|
||||
|
||||
if
|
||||
self.filter_to_previous_work_product_unavail &&
|
||||
ccx.previous_work_product().is_some()
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return Some(ccx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_reloc_model(sess: &Session) -> llvm::RelocMode {
|
||||
let reloc_model_arg = match sess.opts.cg.relocation_model {
|
||||
Some(ref s) => &s[..],
|
||||
@ -347,7 +273,7 @@ pub fn is_pie_binary(sess: &Session) -> bool {
|
||||
!is_any_library(sess) && get_reloc_model(sess) == llvm::RelocMode::PIC
|
||||
}
|
||||
|
||||
unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextRef, ModuleRef) {
|
||||
pub unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextRef, ModuleRef) {
|
||||
let llcx = llvm::LLVMContextCreate();
|
||||
let mod_name = CString::new(mod_name).unwrap();
|
||||
let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx);
|
||||
@ -405,14 +331,9 @@ unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextR
|
||||
|
||||
impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'b, 'tcx, 'tcx>,
|
||||
link_meta: LinkMeta,
|
||||
exported_symbols: NodeSet,
|
||||
check_overflow: bool)
|
||||
-> SharedCrateContext<'b, 'tcx> {
|
||||
let (metadata_llcx, metadata_llmod) = unsafe {
|
||||
create_context_and_module(&tcx.sess, "metadata")
|
||||
};
|
||||
|
||||
// An interesting part of Windows which MSVC forces our hand on (and
|
||||
// apparently MinGW didn't) is the usage of `dllimport` and `dllexport`
|
||||
// attributes in LLVM IR as well as native dependencies (in C these
|
||||
@ -459,23 +380,9 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
|
||||
let use_dll_storage_attrs = tcx.sess.target.target.options.is_like_msvc;
|
||||
|
||||
SharedCrateContext {
|
||||
metadata_llmod: metadata_llmod,
|
||||
metadata_llcx: metadata_llcx,
|
||||
exported_symbols: exported_symbols,
|
||||
link_meta: link_meta,
|
||||
empty_param_env: tcx.empty_parameter_environment(),
|
||||
tcx: tcx,
|
||||
stats: Stats {
|
||||
n_glues_created: Cell::new(0),
|
||||
n_null_glues: Cell::new(0),
|
||||
n_real_glues: Cell::new(0),
|
||||
n_fns: Cell::new(0),
|
||||
n_inlines: Cell::new(0),
|
||||
n_closures: Cell::new(0),
|
||||
n_llvm_insns: Cell::new(0),
|
||||
llvm_insns: RefCell::new(FxHashMap()),
|
||||
fn_stats: RefCell::new(Vec::new()),
|
||||
},
|
||||
check_overflow: check_overflow,
|
||||
use_dll_storage_attrs: use_dll_storage_attrs,
|
||||
translation_items: RefCell::new(FxHashSet()),
|
||||
@ -492,14 +399,6 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
|
||||
ty.is_sized(self.tcx, &self.empty_param_env, DUMMY_SP)
|
||||
}
|
||||
|
||||
pub fn metadata_llmod(&self) -> ModuleRef {
|
||||
self.metadata_llmod
|
||||
}
|
||||
|
||||
pub fn metadata_llcx(&self) -> ContextRef {
|
||||
self.metadata_llcx
|
||||
}
|
||||
|
||||
pub fn exported_symbols<'a>(&'a self) -> &'a NodeSet {
|
||||
&self.exported_symbols
|
||||
}
|
||||
@ -512,10 +411,6 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
|
||||
&self.project_cache
|
||||
}
|
||||
|
||||
pub fn link_meta<'a>(&'a self) -> &'a LinkMeta {
|
||||
&self.link_meta
|
||||
}
|
||||
|
||||
pub fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
@ -528,10 +423,6 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
|
||||
&self.tcx.dep_graph
|
||||
}
|
||||
|
||||
pub fn stats<'a>(&'a self) -> &'a Stats {
|
||||
&self.stats
|
||||
}
|
||||
|
||||
pub fn use_dll_storage_attrs(&self) -> bool {
|
||||
self.use_dll_storage_attrs
|
||||
}
|
||||
@ -539,20 +430,13 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
|
||||
pub fn translation_items(&self) -> &RefCell<FxHashSet<TransItem<'tcx>>> {
|
||||
&self.translation_items
|
||||
}
|
||||
|
||||
pub fn metadata_symbol_name(&self) -> String {
|
||||
format!("rust_metadata_{}_{}",
|
||||
self.link_meta().crate_name,
|
||||
self.link_meta().crate_hash)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> LocalCrateContext<'tcx> {
|
||||
fn new<'a>(shared: &SharedCrateContext<'a, 'tcx>,
|
||||
codegen_unit: CodegenUnit<'tcx>,
|
||||
previous_work_product: Option<WorkProduct>,
|
||||
symbol_map: Rc<SymbolMap<'tcx>>)
|
||||
-> LocalCrateContext<'tcx> {
|
||||
pub fn new<'a>(shared: &SharedCrateContext<'a, 'tcx>,
|
||||
codegen_unit: CodegenUnit<'tcx>,
|
||||
symbol_map: Rc<SymbolMap<'tcx>>)
|
||||
-> LocalCrateContext<'tcx> {
|
||||
unsafe {
|
||||
// Append ".rs" to LLVM module identifier.
|
||||
//
|
||||
@ -578,7 +462,7 @@ impl<'tcx> LocalCrateContext<'tcx> {
|
||||
let local_ccx = LocalCrateContext {
|
||||
llmod: llmod,
|
||||
llcx: llcx,
|
||||
previous_work_product: previous_work_product,
|
||||
stats: Stats::default(),
|
||||
codegen_unit: codegen_unit,
|
||||
needs_unwind_cleanup_cache: RefCell::new(FxHashMap()),
|
||||
instances: RefCell::new(FxHashMap()),
|
||||
@ -647,10 +531,13 @@ impl<'tcx> LocalCrateContext<'tcx> {
|
||||
assert!(local_ccxs.len() == 1);
|
||||
CrateContext {
|
||||
shared: shared,
|
||||
index: 0,
|
||||
local_ccxs: local_ccxs
|
||||
local_ccx: &local_ccxs[0]
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_stats(self) -> Stats {
|
||||
self.stats
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
||||
@ -659,7 +546,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
||||
}
|
||||
|
||||
fn local(&self) -> &'b LocalCrateContext<'tcx> {
|
||||
&self.local_ccxs[self.index]
|
||||
self.local_ccx
|
||||
}
|
||||
|
||||
pub fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
|
||||
@ -688,10 +575,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
||||
self.local().llcx
|
||||
}
|
||||
|
||||
pub fn previous_work_product(&self) -> Option<&WorkProduct> {
|
||||
self.local().previous_work_product.as_ref()
|
||||
}
|
||||
|
||||
pub fn codegen_unit(&self) -> &CodegenUnit<'tcx> {
|
||||
&self.local().codegen_unit
|
||||
}
|
||||
@ -700,14 +583,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
||||
unsafe { llvm::LLVMRustGetModuleDataLayout(self.llmod()) }
|
||||
}
|
||||
|
||||
pub fn exported_symbols<'a>(&'a self) -> &'a NodeSet {
|
||||
&self.shared.exported_symbols
|
||||
}
|
||||
|
||||
pub fn link_meta<'a>(&'a self) -> &'a LinkMeta {
|
||||
&self.shared.link_meta
|
||||
}
|
||||
|
||||
pub fn needs_unwind_cleanup_cache(&self) -> &RefCell<FxHashMap<Ty<'tcx>, bool>> {
|
||||
&self.local().needs_unwind_cleanup_cache
|
||||
}
|
||||
@ -777,7 +652,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn stats<'a>(&'a self) -> &'a Stats {
|
||||
&self.shared.stats
|
||||
&self.local().stats
|
||||
}
|
||||
|
||||
pub fn int_type(&self) -> Type {
|
||||
|
@ -26,7 +26,7 @@ use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor,
|
||||
DICompositeType, DILexicalBlock, DIFlags};
|
||||
|
||||
use rustc::hir::def::CtorKind;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc::ty::fold::TypeVisitor;
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::util::TypeIdHasher;
|
||||
@ -810,7 +810,7 @@ pub fn compile_unit_metadata(scc: &SharedCrateContext,
|
||||
};
|
||||
|
||||
fn fallback_path(scc: &SharedCrateContext) -> CString {
|
||||
CString::new(scc.link_meta().crate_name.to_string()).unwrap()
|
||||
CString::new(scc.tcx().crate_name(LOCAL_CRATE).to_string()).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ pub fn is_node_local_to_unit(cx: &CrateContext, node_id: ast::NodeId) -> bool
|
||||
// visible). It might better to use the `exported_items` set from
|
||||
// `driver::CrateAnalysis` in the future, but (atm) this set is not
|
||||
// available in the translation pass.
|
||||
!cx.exported_symbols().contains(&node_id)
|
||||
!cx.shared().exported_symbols().contains(&node_id)
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
|
@ -40,6 +40,7 @@
|
||||
#![feature(conservative_impl_trait)]
|
||||
|
||||
use rustc::dep_graph::WorkProduct;
|
||||
use syntax_pos::symbol::Symbol;
|
||||
|
||||
extern crate flate;
|
||||
extern crate libc;
|
||||
@ -165,6 +166,7 @@ unsafe impl Send for ModuleTranslation { }
|
||||
unsafe impl Sync for ModuleTranslation { }
|
||||
|
||||
pub struct CrateTranslation {
|
||||
pub crate_name: Symbol,
|
||||
pub modules: Vec<ModuleTranslation>,
|
||||
pub metadata_module: ModuleTranslation,
|
||||
pub link: middle::cstore::LinkMeta,
|
||||
|
@ -11,7 +11,7 @@
|
||||
#![allow(non_upper_case_globals)]
|
||||
|
||||
use llvm;
|
||||
use llvm::{TypeRef, Bool, False, True, TypeKind};
|
||||
use llvm::{ContextRef, TypeRef, Bool, False, True, TypeKind};
|
||||
use llvm::{Float, Double, X86_FP80, PPC_FP128, FP128};
|
||||
|
||||
use context::CrateContext;
|
||||
@ -82,6 +82,10 @@ impl Type {
|
||||
ty!(llvm::LLVMInt8TypeInContext(ccx.llcx()))
|
||||
}
|
||||
|
||||
pub fn i8_llcx(llcx: ContextRef) -> Type {
|
||||
ty!(llvm::LLVMInt8TypeInContext(llcx))
|
||||
}
|
||||
|
||||
pub fn i16(ccx: &CrateContext) -> Type {
|
||||
ty!(llvm::LLVMInt16TypeInContext(ccx.llcx()))
|
||||
}
|
||||
@ -123,6 +127,10 @@ impl Type {
|
||||
Type::i8(ccx).ptr_to()
|
||||
}
|
||||
|
||||
pub fn i8p_llcx(llcx: ContextRef) -> Type {
|
||||
Type::i8_llcx(llcx).ptr_to()
|
||||
}
|
||||
|
||||
pub fn int(ccx: &CrateContext) -> Type {
|
||||
match &ccx.tcx().sess.target.target.target_pointer_width[..] {
|
||||
"16" => Type::i16(ccx),
|
||||
|
Loading…
x
Reference in New Issue
Block a user