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)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct LinkMeta {
|
pub struct LinkMeta {
|
||||||
pub crate_name: Symbol,
|
|
||||||
pub crate_hash: Svh,
|
pub crate_hash: Svh,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@ pub use self::code_stats::{SizeKind, TypeSizeInfo, VariantInfo};
|
||||||
|
|
||||||
use dep_graph::DepGraph;
|
use dep_graph::DepGraph;
|
||||||
use hir::def_id::{CrateNum, DefIndex};
|
use hir::def_id::{CrateNum, DefIndex};
|
||||||
use hir::svh::Svh;
|
|
||||||
use lint;
|
use lint;
|
||||||
use middle::cstore::CrateStore;
|
use middle::cstore::CrateStore;
|
||||||
use middle::dependency_format;
|
use middle::dependency_format;
|
||||||
|
@ -402,15 +401,14 @@ impl Session {
|
||||||
|
|
||||||
/// Returns the symbol name for the registrar function,
|
/// Returns the symbol name for the registrar function,
|
||||||
/// given the crate Svh and the function DefIndex.
|
/// 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 {
|
-> String {
|
||||||
format!("__rustc_plugin_registrar__{}_{}", svh, index.as_usize())
|
format!("__rustc_plugin_registrar__{}_{}", disambiguator, index.as_usize())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_derive_registrar_symbol(&self,
|
pub fn generate_derive_registrar_symbol(&self, disambiguator: Symbol, index: DefIndex)
|
||||||
svh: &Svh,
|
-> String {
|
||||||
index: DefIndex) -> String {
|
format!("__rustc_derive_registrar__{}_{}", disambiguator, index.as_usize())
|
||||||
format!("__rustc_derive_registrar__{}_{}", svh, index.as_usize())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sysroot<'a>(&'a self) -> &'a Path {
|
pub fn sysroot<'a>(&'a self) -> &'a Path {
|
||||||
|
|
|
@ -1140,7 +1140,7 @@ pub fn phase_6_link_output(sess: &Session,
|
||||||
outputs: &OutputFilenames) {
|
outputs: &OutputFilenames) {
|
||||||
time(sess.time_passes(),
|
time(sess.time_passes(),
|
||||||
"linking",
|
"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 {
|
fn escape_dep_filename(filename: &str) -> String {
|
||||||
|
|
|
@ -600,7 +600,7 @@ impl<'a> CrateLoader<'a> {
|
||||||
Err(err) => self.sess.span_fatal(span, &err),
|
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());
|
root.macro_derive_registrar.unwrap());
|
||||||
let registrar = unsafe {
|
let registrar = unsafe {
|
||||||
let sym = match lib.symbol(&sym) {
|
let sym = match lib.symbol(&sym) {
|
||||||
|
@ -654,7 +654,7 @@ impl<'a> CrateLoader<'a> {
|
||||||
/// Look for a plugin registrar. Returns library path, crate
|
/// Look for a plugin registrar. Returns library path, crate
|
||||||
/// SVH and DefIndex of the registrar function.
|
/// SVH and DefIndex of the registrar function.
|
||||||
pub fn find_plugin_registrar(&mut self, span: Span, name: &str)
|
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 {
|
let ekrate = self.read_extension_crate(span, &ExternCrateInfo {
|
||||||
name: Symbol::intern(name),
|
name: Symbol::intern(name),
|
||||||
ident: Symbol::intern(name),
|
ident: Symbol::intern(name),
|
||||||
|
@ -675,7 +675,7 @@ impl<'a> CrateLoader<'a> {
|
||||||
let root = ekrate.metadata.get_root();
|
let root = ekrate.metadata.get_root();
|
||||||
match (ekrate.dylib.as_ref(), root.plugin_registrar_fn) {
|
match (ekrate.dylib.as_ref(), root.plugin_registrar_fn) {
|
||||||
(Some(dylib), Some(reg)) => {
|
(Some(dylib), Some(reg)) => {
|
||||||
Some((dylib.to_path_buf(), root.hash, reg))
|
Some((dylib.to_path_buf(), root.disambiguator, reg))
|
||||||
}
|
}
|
||||||
(None, Some(_)) => {
|
(None, Some(_)) => {
|
||||||
span_err!(self.sess, span, E0457,
|
span_err!(self.sess, span, E0457,
|
||||||
|
|
|
@ -14,7 +14,7 @@ use schema::*;
|
||||||
|
|
||||||
use rustc::middle::cstore::{LinkMeta, LinkagePreference, NativeLibrary,
|
use rustc::middle::cstore::{LinkMeta, LinkagePreference, NativeLibrary,
|
||||||
EncodedMetadata, EncodedMetadataHash};
|
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::hir::map::definitions::DefPathTable;
|
||||||
use rustc::middle::dependency_format::Linkage;
|
use rustc::middle::dependency_format::Linkage;
|
||||||
use rustc::middle::lang_items;
|
use rustc::middle::lang_items;
|
||||||
|
@ -1380,7 +1380,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
let link_meta = self.link_meta;
|
let link_meta = self.link_meta;
|
||||||
let is_proc_macro = tcx.sess.crate_types.borrow().contains(&CrateTypeProcMacro);
|
let is_proc_macro = tcx.sess.crate_types.borrow().contains(&CrateTypeProcMacro);
|
||||||
let root = self.lazy(&CrateRoot {
|
let root = self.lazy(&CrateRoot {
|
||||||
name: link_meta.crate_name,
|
name: tcx.crate_name(LOCAL_CRATE),
|
||||||
triple: tcx.sess.opts.target_triple.clone(),
|
triple: tcx.sess.opts.target_triple.clone(),
|
||||||
hash: link_meta.crate_hash,
|
hash: link_meta.crate_hash,
|
||||||
disambiguator: tcx.sess.local_crate_disambiguator(),
|
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>) {
|
fn load_plugin(&mut self, span: Span, name: &str, args: Vec<ast::NestedMetaItem>) {
|
||||||
let registrar = self.reader.find_plugin_registrar(span, name);
|
let registrar = self.reader.find_plugin_registrar(span, name);
|
||||||
|
|
||||||
if let Some((lib, svh, index)) = registrar {
|
if let Some((lib, disambiguator, index)) = registrar {
|
||||||
let symbol = self.sess.generate_plugin_registrar_symbol(&svh, index);
|
let symbol = self.sess.generate_plugin_registrar_symbol(disambiguator, index);
|
||||||
let fun = self.dylink_registrar(span, lib, symbol);
|
let fun = self.dylink_registrar(span, lib, symbol);
|
||||||
self.plugins.push(PluginRegistrar {
|
self.plugins.push(PluginRegistrar {
|
||||||
fun: fun,
|
fun: fun,
|
||||||
|
|
|
@ -47,7 +47,6 @@ use std::str;
|
||||||
use flate;
|
use flate;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
use syntax::symbol::Symbol;
|
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
|
|
||||||
/// The LLVM module name containing crate-metadata. This includes a `.` on
|
/// 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()
|
"rust_out".to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_link_meta(incremental_hashes_map: &IncrementalHashesMap,
|
pub fn build_link_meta(incremental_hashes_map: &IncrementalHashesMap) -> LinkMeta {
|
||||||
name: &str)
|
|
||||||
-> LinkMeta {
|
|
||||||
let r = LinkMeta {
|
let r = LinkMeta {
|
||||||
crate_name: Symbol::intern(name),
|
|
||||||
crate_hash: Svh::new(incremental_hashes_map[&DepNode::Krate].to_smaller_hash()),
|
crate_hash: Svh::new(incremental_hashes_map[&DepNode::Krate].to_smaller_hash()),
|
||||||
};
|
};
|
||||||
info!("{:?}", r);
|
info!("{:?}", r);
|
||||||
|
|
|
@ -15,6 +15,7 @@ use back::symbol_names::symbol_name;
|
||||||
use util::nodemap::FxHashMap;
|
use util::nodemap::FxHashMap;
|
||||||
use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE};
|
use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE};
|
||||||
use rustc::session::config;
|
use rustc::session::config;
|
||||||
|
use rustc::ty::TyCtxt;
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
use trans_item::TransItem;
|
use trans_item::TransItem;
|
||||||
|
|
||||||
|
@ -64,15 +65,15 @@ impl ExportedSymbols {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(id) = scx.sess().derive_registrar_fn.get() {
|
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 def_id = scx.tcx().hir.local_def_id(id);
|
||||||
let idx = def_id.index;
|
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));
|
local_crate.push((registrar, SymbolExportLevel::C));
|
||||||
}
|
}
|
||||||
|
|
||||||
if scx.sess().crate_types.borrow().contains(&config::CrateTypeDylib) {
|
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));
|
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)
|
pub fn crate_export_threshold(crate_type: config::CrateType)
|
||||||
-> SymbolExportLevel {
|
-> SymbolExportLevel {
|
||||||
match crate_type {
|
match crate_type {
|
||||||
|
|
|
@ -179,14 +179,14 @@ pub fn symbol_name<'a, 'tcx>(instance: Instance<'tcx>,
|
||||||
|
|
||||||
if let Some(id) = node_id {
|
if let Some(id) = node_id {
|
||||||
if scx.sess().plugin_registrar_fn.get() == Some(id) {
|
if scx.sess().plugin_registrar_fn.get() == Some(id) {
|
||||||
let svh = &scx.link_meta().crate_hash;
|
|
||||||
let idx = def_id.index;
|
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) {
|
if scx.sess().derive_registrar_fn.get() == Some(id) {
|
||||||
let svh = &scx.link_meta().crate_hash;
|
|
||||||
let idx = def_id.index;
|
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::link;
|
||||||
use back::linker::LinkerInfo;
|
use back::linker::LinkerInfo;
|
||||||
use back::symbol_export::{self, ExportedSymbols};
|
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 llvm;
|
||||||
use rustc::hir::def_id::LOCAL_CRATE;
|
use rustc::hir::def_id::LOCAL_CRATE;
|
||||||
use middle::lang_items::StartFnLangItem;
|
use middle::lang_items::StartFnLangItem;
|
||||||
use middle::cstore::EncodedMetadata;
|
use middle::cstore::EncodedMetadata;
|
||||||
use rustc::ty::{self, Ty, TyCtxt};
|
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::hir::map as hir_map;
|
||||||
use rustc::util::common::time;
|
use rustc::util::common::time;
|
||||||
use session::config::{self, NoDebugInfo};
|
use session::config::{self, NoDebugInfo};
|
||||||
|
@ -56,7 +57,7 @@ use common::CrateContext;
|
||||||
use common::{type_is_zero_size, val_ty};
|
use common::{type_is_zero_size, val_ty};
|
||||||
use common;
|
use common;
|
||||||
use consts;
|
use consts;
|
||||||
use context::{SharedCrateContext, CrateContextList};
|
use context::{self, LocalCrateContext, SharedCrateContext, Stats};
|
||||||
use debuginfo;
|
use debuginfo;
|
||||||
use declare;
|
use declare;
|
||||||
use machine;
|
use machine;
|
||||||
|
@ -724,11 +725,16 @@ fn contains_null(s: &str) -> bool {
|
||||||
s.bytes().any(|b| b == 0)
|
s.bytes().any(|b| b == 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_metadata(cx: &SharedCrateContext,
|
fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
|
||||||
exported_symbols: &NodeSet)
|
link_meta: &LinkMeta,
|
||||||
-> EncodedMetadata {
|
exported_symbols: &NodeSet)
|
||||||
|
-> (ContextRef, ModuleRef, EncodedMetadata) {
|
||||||
use flate;
|
use flate;
|
||||||
|
|
||||||
|
let (metadata_llcx, metadata_llmod) = unsafe {
|
||||||
|
context::create_context_and_module(tcx.sess, "metadata")
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(PartialEq, Eq, PartialOrd, Ord)]
|
||||||
enum MetadataKind {
|
enum MetadataKind {
|
||||||
None,
|
None,
|
||||||
|
@ -736,7 +742,7 @@ fn write_metadata(cx: &SharedCrateContext,
|
||||||
Compressed
|
Compressed
|
||||||
}
|
}
|
||||||
|
|
||||||
let kind = cx.sess().crate_types.borrow().iter().map(|ty| {
|
let kind = tcx.sess.crate_types.borrow().iter().map(|ty| {
|
||||||
match *ty {
|
match *ty {
|
||||||
config::CrateTypeExecutable |
|
config::CrateTypeExecutable |
|
||||||
config::CrateTypeStaticlib |
|
config::CrateTypeStaticlib |
|
||||||
|
@ -750,35 +756,35 @@ fn write_metadata(cx: &SharedCrateContext,
|
||||||
}).max().unwrap();
|
}).max().unwrap();
|
||||||
|
|
||||||
if kind == MetadataKind::None {
|
if kind == MetadataKind::None {
|
||||||
return EncodedMetadata {
|
return (metadata_llcx, metadata_llmod, EncodedMetadata {
|
||||||
raw_data: vec![],
|
raw_data: vec![],
|
||||||
hashes: vec![],
|
hashes: vec![],
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let cstore = &cx.tcx().sess.cstore;
|
let cstore = &tcx.sess.cstore;
|
||||||
let metadata = cstore.encode_metadata(cx.tcx(),
|
let metadata = cstore.encode_metadata(tcx,
|
||||||
cx.link_meta(),
|
&link_meta,
|
||||||
exported_symbols);
|
exported_symbols);
|
||||||
if kind == MetadataKind::Uncompressed {
|
if kind == MetadataKind::Uncompressed {
|
||||||
return metadata;
|
return (metadata_llcx, metadata_llmod, metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert!(kind == MetadataKind::Compressed);
|
assert!(kind == MetadataKind::Compressed);
|
||||||
let mut compressed = cstore.metadata_encoding_version().to_vec();
|
let mut compressed = cstore.metadata_encoding_version().to_vec();
|
||||||
compressed.extend_from_slice(&flate::deflate_bytes(&metadata.raw_data));
|
compressed.extend_from_slice(&flate::deflate_bytes(&metadata.raw_data));
|
||||||
|
|
||||||
let llmeta = C_bytes_in_context(cx.metadata_llcx(), &compressed);
|
let llmeta = C_bytes_in_context(metadata_llcx, &compressed);
|
||||||
let llconst = C_struct_in_context(cx.metadata_llcx(), &[llmeta], false);
|
let llconst = C_struct_in_context(metadata_llcx, &[llmeta], false);
|
||||||
let name = cx.metadata_symbol_name();
|
let name = symbol_export::metadata_symbol_name(tcx);
|
||||||
let buf = CString::new(name).unwrap();
|
let buf = CString::new(name).unwrap();
|
||||||
let llglobal = unsafe {
|
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 {
|
unsafe {
|
||||||
llvm::LLVMSetInitializer(llglobal, llconst);
|
llvm::LLVMSetInitializer(llglobal, llconst);
|
||||||
let section_name =
|
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();
|
let name = CString::new(section_name).unwrap();
|
||||||
llvm::LLVMSetSection(llglobal, name.as_ptr());
|
llvm::LLVMSetSection(llglobal, name.as_ptr());
|
||||||
|
|
||||||
|
@ -787,15 +793,16 @@ fn write_metadata(cx: &SharedCrateContext,
|
||||||
// metadata doesn't get loaded into memory.
|
// metadata doesn't get loaded into memory.
|
||||||
let directive = format!(".section {}", section_name);
|
let directive = format!(".section {}", section_name);
|
||||||
let directive = CString::new(directive).unwrap();
|
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
|
/// Find any symbols that are defined in one compilation unit, but not declared
|
||||||
/// in any other compilation unit. Give these symbols internal linkage.
|
/// in any other compilation unit. Give these symbols internal linkage.
|
||||||
fn internalize_symbols<'a, 'tcx>(sess: &Session,
|
fn internalize_symbols<'a, 'tcx>(sess: &Session,
|
||||||
ccxs: &CrateContextList<'a, 'tcx>,
|
scx: &SharedCrateContext<'a, 'tcx>,
|
||||||
|
llvm_modules: &[ModuleLlvm],
|
||||||
symbol_map: &SymbolMap<'tcx>,
|
symbol_map: &SymbolMap<'tcx>,
|
||||||
exported_symbols: &ExportedSymbols) {
|
exported_symbols: &ExportedSymbols) {
|
||||||
let export_threshold =
|
let export_threshold =
|
||||||
|
@ -810,7 +817,6 @@ fn internalize_symbols<'a, 'tcx>(sess: &Session,
|
||||||
.map(|&(ref name, _)| &name[..])
|
.map(|&(ref name, _)| &name[..])
|
||||||
.collect::<FxHashSet<&str>>();
|
.collect::<FxHashSet<&str>>();
|
||||||
|
|
||||||
let scx = ccxs.shared();
|
|
||||||
let tcx = scx.tcx();
|
let tcx = scx.tcx();
|
||||||
|
|
||||||
let incr_comp = sess.opts.debugging_opts.incremental.is_some();
|
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
|
// incremental compilation, we don't need to collect. See below for more
|
||||||
// information.
|
// information.
|
||||||
if !incr_comp {
|
if !incr_comp {
|
||||||
for ccx in ccxs.iter_need_trans() {
|
for ll in llvm_modules {
|
||||||
for val in iter_globals(ccx.llmod()).chain(iter_functions(ccx.llmod())) {
|
for val in iter_globals(ll.llmod).chain(iter_functions(ll.llmod)) {
|
||||||
let linkage = llvm::LLVMRustGetLinkage(val);
|
let linkage = llvm::LLVMRustGetLinkage(val);
|
||||||
// We only care about external declarations (not definitions)
|
// We only care about external declarations (not definitions)
|
||||||
// and available_externally 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
|
// Examine each external definition. If the definition is not used in
|
||||||
// any other compilation unit, and is not reachable from other crates,
|
// any other compilation unit, and is not reachable from other crates,
|
||||||
// then give it internal linkage.
|
// then give it internal linkage.
|
||||||
for ccx in ccxs.iter_need_trans() {
|
for ll in llvm_modules {
|
||||||
for val in iter_globals(ccx.llmod()).chain(iter_functions(ccx.llmod())) {
|
for val in iter_globals(ll.llmod).chain(iter_functions(ll.llmod)) {
|
||||||
let linkage = llvm::LLVMRustGetLinkage(val);
|
let linkage = llvm::LLVMRustGetLinkage(val);
|
||||||
|
|
||||||
let is_externally_visible = (linkage == llvm::Linkage::ExternalLinkage) ||
|
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
|
// when using MSVC linker. We do this only for data, as linker can fix up
|
||||||
// code references on its own.
|
// code references on its own.
|
||||||
// See #26591, #27438
|
// 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
|
// 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
|
// 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
|
// '\x01' here which disables LLVM's symbol mangling (e.g. no extra
|
||||||
// underscores added in front).
|
// 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__"
|
"\x01__imp__"
|
||||||
} else {
|
} else {
|
||||||
"\x01__imp_"
|
"\x01__imp_"
|
||||||
};
|
};
|
||||||
unsafe {
|
unsafe {
|
||||||
for ccx in cx.iter_need_trans() {
|
for ll in llvm_modules {
|
||||||
let exported: Vec<_> = iter_globals(ccx.llmod())
|
let exported: Vec<_> = iter_globals(ll.llmod)
|
||||||
.filter(|&val| {
|
.filter(|&val| {
|
||||||
llvm::LLVMRustGetLinkage(val) ==
|
llvm::LLVMRustGetLinkage(val) ==
|
||||||
llvm::Linkage::ExternalLinkage &&
|
llvm::Linkage::ExternalLinkage &&
|
||||||
|
@ -942,13 +949,13 @@ fn create_imps(cx: &CrateContextList) {
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let i8p_ty = Type::i8p(&ccx);
|
let i8p_ty = Type::i8p_llcx(ll.llcx);
|
||||||
for val in exported {
|
for val in exported {
|
||||||
let name = CStr::from_ptr(llvm::LLVMGetValueName(val));
|
let name = CStr::from_ptr(llvm::LLVMGetValueName(val));
|
||||||
let mut imp_name = prefix.as_bytes().to_vec();
|
let mut imp_name = prefix.as_bytes().to_vec();
|
||||||
imp_name.extend(name.to_bytes());
|
imp_name.extend(name.to_bytes());
|
||||||
let imp_name = CString::new(imp_name).unwrap();
|
let imp_name = CString::new(imp_name).unwrap();
|
||||||
let imp = llvm::LLVMAddGlobal(ccx.llmod(),
|
let imp = llvm::LLVMAddGlobal(ll.llmod,
|
||||||
i8p_ty.to_ref(),
|
i8p_ty.to_ref(),
|
||||||
imp_name.as_ptr() as *const _);
|
imp_name.as_ptr() as *const _);
|
||||||
let init = llvm::LLVMConstBitCast(val, i8p_ty.to_ref());
|
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.
|
// particular items that will be processed.
|
||||||
let krate = tcx.hir.krate();
|
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 exported_symbols = find_exported_symbols(tcx, reachable);
|
||||||
|
|
||||||
let check_overflow = tcx.sess.overflow_checks();
|
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,
|
let shared_ccx = SharedCrateContext::new(tcx,
|
||||||
link_meta.clone(),
|
|
||||||
exported_symbols,
|
exported_symbols,
|
||||||
check_overflow);
|
check_overflow);
|
||||||
// Translate the metadata.
|
// Translate the metadata.
|
||||||
let metadata = time(tcx.sess.time_passes(), "write metadata", || {
|
let (metadata_llcx, metadata_llmod, metadata) =
|
||||||
write_metadata(&shared_ccx, shared_ccx.exported_symbols())
|
time(tcx.sess.time_passes(), "write metadata", || {
|
||||||
});
|
write_metadata(tcx, &link_meta, shared_ccx.exported_symbols())
|
||||||
|
});
|
||||||
|
|
||||||
let metadata_module = ModuleTranslation {
|
let metadata_module = ModuleTranslation {
|
||||||
name: link::METADATA_MODULE_NAME.to_string(),
|
name: link::METADATA_MODULE_NAME.to_string(),
|
||||||
symbol_name_hash: 0, // we always rebuild metadata, at least for now
|
symbol_name_hash: 0, // we always rebuild metadata, at least for now
|
||||||
source: ModuleSource::Translated(ModuleLlvm {
|
source: ModuleSource::Translated(ModuleLlvm {
|
||||||
llcx: shared_ccx.metadata_llcx(),
|
llcx: metadata_llcx,
|
||||||
llmod: shared_ccx.metadata_llmod(),
|
llmod: metadata_llmod,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
let no_builtins = attr::contains_name(&krate.attrs, "no_builtins");
|
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 empty_exported_symbols = ExportedSymbols::empty();
|
||||||
let linker_info = LinkerInfo::new(&shared_ccx, &empty_exported_symbols);
|
let linker_info = LinkerInfo::new(&shared_ccx, &empty_exported_symbols);
|
||||||
return CrateTranslation {
|
return CrateTranslation {
|
||||||
|
crate_name: tcx.crate_name(LOCAL_CRATE),
|
||||||
modules: vec![],
|
modules: vec![],
|
||||||
metadata_module: metadata_module,
|
metadata_module: metadata_module,
|
||||||
link: link_meta,
|
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 symbol_map = Rc::new(symbol_map);
|
||||||
|
|
||||||
let previous_work_products = trans_reuse_previous_work_products(&shared_ccx,
|
let mut all_stats = Stats::default();
|
||||||
&codegen_units,
|
let modules: Vec<ModuleTranslation> = codegen_units
|
||||||
&symbol_map);
|
.into_iter()
|
||||||
|
.map(|cgu| {
|
||||||
let crate_context_list = CrateContextList::new(&shared_ccx,
|
let dep_node = cgu.work_product_dep_node();
|
||||||
codegen_units,
|
let (stats, module) =
|
||||||
previous_work_products,
|
tcx.dep_graph.with_task(dep_node,
|
||||||
symbol_map.clone());
|
AssertDepGraphSafe(&shared_ccx),
|
||||||
let modules: Vec<_> = crate_context_list.iter_all()
|
AssertDepGraphSafe((cgu, symbol_map.clone())),
|
||||||
.map(|ccx| {
|
module_translation);
|
||||||
let source = match ccx.previous_work_product() {
|
all_stats.extend(stats);
|
||||||
Some(buf) => ModuleSource::Preexisting(buf.clone()),
|
module
|
||||||
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,
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.collect();
|
.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...
|
let cgu_name = String::from(cgu.name());
|
||||||
for ccx in crate_context_list.iter_need_trans() {
|
let cgu_id = cgu.work_product_id();
|
||||||
let dep_node = ccx.codegen_unit().work_product_dep_node();
|
let symbol_name_hash = cgu.compute_symbol_name_hash(scx, &symbol_map);
|
||||||
tcx.dep_graph.with_task(dep_node,
|
|
||||||
ccx,
|
|
||||||
AssertDepGraphSafe(symbol_map.clone()),
|
|
||||||
trans_decl_task);
|
|
||||||
|
|
||||||
fn trans_decl_task<'a, 'tcx>(ccx: CrateContext<'a, 'tcx>,
|
// Check whether there is a previous work-product we can
|
||||||
symbol_map: AssertDepGraphSafe<Rc<SymbolMap<'tcx>>>) {
|
// re-use. Not only must the file exist, and the inputs not
|
||||||
// FIXME(#40304): Instead of this, the symbol-map should be an
|
// be dirty, but the hash of the symbols we will generate must
|
||||||
// on-demand thing that we compute.
|
// be the same.
|
||||||
let AssertDepGraphSafe(symbol_map) = symbol_map;
|
let previous_work_product =
|
||||||
let cgu = ccx.codegen_unit();
|
scx.dep_graph().previous_work_product(&cgu_id).and_then(|work_product| {
|
||||||
let trans_items = cgu.items_in_deterministic_order(ccx.tcx(), &symbol_map);
|
if work_product.input_hash == symbol_name_hash {
|
||||||
for (trans_item, linkage) in trans_items {
|
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);
|
trans_item.predefine(&ccx, linkage);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ... and now that we have everything pre-defined, fill out those definitions.
|
// ... and now that we have everything pre-defined, fill out those definitions.
|
||||||
for ccx in crate_context_list.iter_need_trans() {
|
for &(trans_item, _) in &trans_items {
|
||||||
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 {
|
|
||||||
trans_item.define(&ccx);
|
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 {
|
if ccx.sess().opts.debuginfo != NoDebugInfo {
|
||||||
debuginfo::finalize(&ccx);
|
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);
|
symbol_names_test::report_symbol_names(&shared_ccx);
|
||||||
|
|
||||||
if shared_ccx.sess().trans_stats() {
|
if shared_ccx.sess().trans_stats() {
|
||||||
let stats = shared_ccx.stats();
|
|
||||||
println!("--- trans stats ---");
|
println!("--- trans stats ---");
|
||||||
println!("n_glues_created: {}", stats.n_glues_created.get());
|
println!("n_glues_created: {}", all_stats.n_glues_created.get());
|
||||||
println!("n_null_glues: {}", stats.n_null_glues.get());
|
println!("n_null_glues: {}", all_stats.n_null_glues.get());
|
||||||
println!("n_real_glues: {}", stats.n_real_glues.get());
|
println!("n_real_glues: {}", all_stats.n_real_glues.get());
|
||||||
|
|
||||||
println!("n_fns: {}", stats.n_fns.get());
|
println!("n_fns: {}", all_stats.n_fns.get());
|
||||||
println!("n_inlines: {}", stats.n_inlines.get());
|
println!("n_inlines: {}", all_stats.n_inlines.get());
|
||||||
println!("n_closures: {}", stats.n_closures.get());
|
println!("n_closures: {}", all_stats.n_closures.get());
|
||||||
println!("fn stats:");
|
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)
|
insns_b.cmp(&insns_a)
|
||||||
});
|
});
|
||||||
for tuple in stats.fn_stats.borrow().iter() {
|
for tuple in all_stats.fn_stats.borrow().iter() {
|
||||||
match *tuple {
|
match *tuple {
|
||||||
(ref name, insns) => {
|
(ref name, insns) => {
|
||||||
println!("{} insns, {}", insns, *name);
|
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() {
|
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);
|
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,
|
let exported_symbols = ExportedSymbols::compute_from(&shared_ccx,
|
||||||
&symbol_map);
|
&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
|
// Now that we have all symbols that are exported from the CGUs of this
|
||||||
// crate, we can run the `internalize_symbols` pass.
|
// crate, we can run the `internalize_symbols` pass.
|
||||||
time(shared_ccx.sess().time_passes(), "internalize symbols", || {
|
time(shared_ccx.sess().time_passes(), "internalize symbols", || {
|
||||||
internalize_symbols(sess,
|
internalize_symbols(sess,
|
||||||
&crate_context_list,
|
&shared_ccx,
|
||||||
|
&llvm_modules,
|
||||||
&symbol_map,
|
&symbol_map,
|
||||||
&exported_symbols);
|
&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 &&
|
if sess.target.target.options.is_like_msvc &&
|
||||||
sess.crate_types.borrow().iter().any(|ct| *ct == config::CrateTypeRlib) {
|
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);
|
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 {
|
CrateTranslation {
|
||||||
|
crate_name: tcx.crate_name(LOCAL_CRATE),
|
||||||
modules: modules,
|
modules: modules,
|
||||||
metadata_module: metadata_module,
|
metadata_module: metadata_module,
|
||||||
link: link_meta,
|
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>)
|
fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>)
|
||||||
-> (Vec<CodegenUnit<'tcx>>, SymbolMap<'tcx>) {
|
-> (Vec<CodegenUnit<'tcx>>, SymbolMap<'tcx>) {
|
||||||
let time_passes = scx.sess().time_passes();
|
let time_passes = scx.sess().time_passes();
|
||||||
|
|
|
@ -10,9 +10,7 @@
|
||||||
|
|
||||||
use llvm;
|
use llvm;
|
||||||
use llvm::{ContextRef, ModuleRef, ValueRef};
|
use llvm::{ContextRef, ModuleRef, ValueRef};
|
||||||
use rustc::dep_graph::{DepGraph, DepGraphSafe, DepNode, DepTrackingMap,
|
use rustc::dep_graph::{DepGraph, DepGraphSafe, DepNode, DepTrackingMap, DepTrackingMapConfig};
|
||||||
DepTrackingMapConfig, WorkProduct};
|
|
||||||
use middle::cstore::LinkMeta;
|
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::traits;
|
use rustc::traits;
|
||||||
|
@ -47,6 +45,7 @@ use syntax::symbol::InternedString;
|
||||||
use syntax_pos::DUMMY_SP;
|
use syntax_pos::DUMMY_SP;
|
||||||
use abi::Abi;
|
use abi::Abi;
|
||||||
|
|
||||||
|
#[derive(Clone, Default)]
|
||||||
pub struct Stats {
|
pub struct Stats {
|
||||||
pub n_glues_created: Cell<usize>,
|
pub n_glues_created: Cell<usize>,
|
||||||
pub n_null_glues: Cell<usize>,
|
pub n_null_glues: Cell<usize>,
|
||||||
|
@ -60,19 +59,30 @@ pub struct Stats {
|
||||||
pub fn_stats: RefCell<Vec<(String, usize)> >,
|
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`
|
/// The shared portion of a `CrateContext`. There is one `SharedCrateContext`
|
||||||
/// per crate. The data here is shared between all compilation units of the
|
/// 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
|
/// crate, so it must not contain references to any LLVM data structures
|
||||||
/// (aside from metadata-related ones).
|
/// (aside from metadata-related ones).
|
||||||
pub struct SharedCrateContext<'a, 'tcx: 'a> {
|
pub struct SharedCrateContext<'a, 'tcx: 'a> {
|
||||||
metadata_llmod: ModuleRef,
|
|
||||||
metadata_llcx: ContextRef,
|
|
||||||
|
|
||||||
exported_symbols: NodeSet,
|
exported_symbols: NodeSet,
|
||||||
link_meta: LinkMeta,
|
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
empty_param_env: ty::ParameterEnvironment<'tcx>,
|
empty_param_env: ty::ParameterEnvironment<'tcx>,
|
||||||
stats: Stats,
|
|
||||||
check_overflow: bool,
|
check_overflow: bool,
|
||||||
|
|
||||||
use_dll_storage_attrs: bool,
|
use_dll_storage_attrs: bool,
|
||||||
|
@ -89,7 +99,7 @@ pub struct SharedCrateContext<'a, 'tcx: 'a> {
|
||||||
pub struct LocalCrateContext<'tcx> {
|
pub struct LocalCrateContext<'tcx> {
|
||||||
llmod: ModuleRef,
|
llmod: ModuleRef,
|
||||||
llcx: ContextRef,
|
llcx: ContextRef,
|
||||||
previous_work_product: Option<WorkProduct>,
|
stats: Stats,
|
||||||
codegen_unit: CodegenUnit<'tcx>,
|
codegen_unit: CodegenUnit<'tcx>,
|
||||||
needs_unwind_cleanup_cache: RefCell<FxHashMap<Ty<'tcx>, bool>>,
|
needs_unwind_cleanup_cache: RefCell<FxHashMap<Ty<'tcx>, bool>>,
|
||||||
/// Cache instances of monomorphic and polymorphic items
|
/// 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
|
/// A CrateContext value binds together one LocalCrateContext with the
|
||||||
/// SharedCrateContext. It exists as a convenience wrapper, so we don't have to
|
/// SharedCrateContext. It exists as a convenience wrapper, so we don't have to
|
||||||
/// pass around (SharedCrateContext, LocalCrateContext) tuples all over trans.
|
/// pass around (SharedCrateContext, LocalCrateContext) tuples all over trans.
|
||||||
pub struct CrateContext<'a, 'tcx: 'a> {
|
pub struct CrateContext<'a, 'tcx: 'a> {
|
||||||
shared: &'a SharedCrateContext<'a, 'tcx>,
|
shared: &'a SharedCrateContext<'a, 'tcx>,
|
||||||
local_ccxs: &'a [LocalCrateContext<'tcx>],
|
local_ccx: &'a LocalCrateContext<'tcx>,
|
||||||
/// The index of `local` in `local_ccxs`. This is used in
|
}
|
||||||
/// `maybe_iter(true)` to identify the original `LocalCrateContext`.
|
|
||||||
index: usize,
|
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> {
|
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 {
|
pub fn get_reloc_model(sess: &Session) -> llvm::RelocMode {
|
||||||
let reloc_model_arg = match sess.opts.cg.relocation_model {
|
let reloc_model_arg = match sess.opts.cg.relocation_model {
|
||||||
Some(ref s) => &s[..],
|
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
|
!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 llcx = llvm::LLVMContextCreate();
|
||||||
let mod_name = CString::new(mod_name).unwrap();
|
let mod_name = CString::new(mod_name).unwrap();
|
||||||
let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx);
|
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> {
|
impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
|
||||||
pub fn new(tcx: TyCtxt<'b, 'tcx, 'tcx>,
|
pub fn new(tcx: TyCtxt<'b, 'tcx, 'tcx>,
|
||||||
link_meta: LinkMeta,
|
|
||||||
exported_symbols: NodeSet,
|
exported_symbols: NodeSet,
|
||||||
check_overflow: bool)
|
check_overflow: bool)
|
||||||
-> SharedCrateContext<'b, 'tcx> {
|
-> 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
|
// An interesting part of Windows which MSVC forces our hand on (and
|
||||||
// apparently MinGW didn't) is the usage of `dllimport` and `dllexport`
|
// apparently MinGW didn't) is the usage of `dllimport` and `dllexport`
|
||||||
// attributes in LLVM IR as well as native dependencies (in C these
|
// 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;
|
let use_dll_storage_attrs = tcx.sess.target.target.options.is_like_msvc;
|
||||||
|
|
||||||
SharedCrateContext {
|
SharedCrateContext {
|
||||||
metadata_llmod: metadata_llmod,
|
|
||||||
metadata_llcx: metadata_llcx,
|
|
||||||
exported_symbols: exported_symbols,
|
exported_symbols: exported_symbols,
|
||||||
link_meta: link_meta,
|
|
||||||
empty_param_env: tcx.empty_parameter_environment(),
|
empty_param_env: tcx.empty_parameter_environment(),
|
||||||
tcx: tcx,
|
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,
|
check_overflow: check_overflow,
|
||||||
use_dll_storage_attrs: use_dll_storage_attrs,
|
use_dll_storage_attrs: use_dll_storage_attrs,
|
||||||
translation_items: RefCell::new(FxHashSet()),
|
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)
|
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 {
|
pub fn exported_symbols<'a>(&'a self) -> &'a NodeSet {
|
||||||
&self.exported_symbols
|
&self.exported_symbols
|
||||||
}
|
}
|
||||||
|
@ -512,10 +411,6 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
|
||||||
&self.project_cache
|
&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> {
|
pub fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
|
@ -528,10 +423,6 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
|
||||||
&self.tcx.dep_graph
|
&self.tcx.dep_graph
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stats<'a>(&'a self) -> &'a Stats {
|
|
||||||
&self.stats
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn use_dll_storage_attrs(&self) -> bool {
|
pub fn use_dll_storage_attrs(&self) -> bool {
|
||||||
self.use_dll_storage_attrs
|
self.use_dll_storage_attrs
|
||||||
}
|
}
|
||||||
|
@ -539,20 +430,13 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
|
||||||
pub fn translation_items(&self) -> &RefCell<FxHashSet<TransItem<'tcx>>> {
|
pub fn translation_items(&self) -> &RefCell<FxHashSet<TransItem<'tcx>>> {
|
||||||
&self.translation_items
|
&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> {
|
impl<'tcx> LocalCrateContext<'tcx> {
|
||||||
fn new<'a>(shared: &SharedCrateContext<'a, 'tcx>,
|
pub fn new<'a>(shared: &SharedCrateContext<'a, 'tcx>,
|
||||||
codegen_unit: CodegenUnit<'tcx>,
|
codegen_unit: CodegenUnit<'tcx>,
|
||||||
previous_work_product: Option<WorkProduct>,
|
symbol_map: Rc<SymbolMap<'tcx>>)
|
||||||
symbol_map: Rc<SymbolMap<'tcx>>)
|
-> LocalCrateContext<'tcx> {
|
||||||
-> LocalCrateContext<'tcx> {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
// Append ".rs" to LLVM module identifier.
|
// Append ".rs" to LLVM module identifier.
|
||||||
//
|
//
|
||||||
|
@ -578,7 +462,7 @@ impl<'tcx> LocalCrateContext<'tcx> {
|
||||||
let local_ccx = LocalCrateContext {
|
let local_ccx = LocalCrateContext {
|
||||||
llmod: llmod,
|
llmod: llmod,
|
||||||
llcx: llcx,
|
llcx: llcx,
|
||||||
previous_work_product: previous_work_product,
|
stats: Stats::default(),
|
||||||
codegen_unit: codegen_unit,
|
codegen_unit: codegen_unit,
|
||||||
needs_unwind_cleanup_cache: RefCell::new(FxHashMap()),
|
needs_unwind_cleanup_cache: RefCell::new(FxHashMap()),
|
||||||
instances: RefCell::new(FxHashMap()),
|
instances: RefCell::new(FxHashMap()),
|
||||||
|
@ -647,10 +531,13 @@ impl<'tcx> LocalCrateContext<'tcx> {
|
||||||
assert!(local_ccxs.len() == 1);
|
assert!(local_ccxs.len() == 1);
|
||||||
CrateContext {
|
CrateContext {
|
||||||
shared: shared,
|
shared: shared,
|
||||||
index: 0,
|
local_ccx: &local_ccxs[0]
|
||||||
local_ccxs: local_ccxs
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn into_stats(self) -> Stats {
|
||||||
|
self.stats
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
||||||
|
@ -659,7 +546,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn local(&self) -> &'b LocalCrateContext<'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> {
|
pub fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
|
||||||
|
@ -688,10 +575,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
||||||
self.local().llcx
|
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> {
|
pub fn codegen_unit(&self) -> &CodegenUnit<'tcx> {
|
||||||
&self.local().codegen_unit
|
&self.local().codegen_unit
|
||||||
}
|
}
|
||||||
|
@ -700,14 +583,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
||||||
unsafe { llvm::LLVMRustGetModuleDataLayout(self.llmod()) }
|
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>> {
|
pub fn needs_unwind_cleanup_cache(&self) -> &RefCell<FxHashMap<Ty<'tcx>, bool>> {
|
||||||
&self.local().needs_unwind_cleanup_cache
|
&self.local().needs_unwind_cleanup_cache
|
||||||
}
|
}
|
||||||
|
@ -777,7 +652,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stats<'a>(&'a self) -> &'a Stats {
|
pub fn stats<'a>(&'a self) -> &'a Stats {
|
||||||
&self.shared.stats
|
&self.local().stats
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn int_type(&self) -> Type {
|
pub fn int_type(&self) -> Type {
|
||||||
|
|
|
@ -26,7 +26,7 @@ use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor,
|
||||||
DICompositeType, DILexicalBlock, DIFlags};
|
DICompositeType, DILexicalBlock, DIFlags};
|
||||||
|
|
||||||
use rustc::hir::def::CtorKind;
|
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::fold::TypeVisitor;
|
||||||
use rustc::ty::subst::Substs;
|
use rustc::ty::subst::Substs;
|
||||||
use rustc::ty::util::TypeIdHasher;
|
use rustc::ty::util::TypeIdHasher;
|
||||||
|
@ -810,7 +810,7 @@ pub fn compile_unit_metadata(scc: &SharedCrateContext,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn fallback_path(scc: &SharedCrateContext) -> CString {
|
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
|
// visible). It might better to use the `exported_items` set from
|
||||||
// `driver::CrateAnalysis` in the future, but (atm) this set is not
|
// `driver::CrateAnalysis` in the future, but (atm) this set is not
|
||||||
// available in the translation pass.
|
// available in the translation pass.
|
||||||
!cx.exported_symbols().contains(&node_id)
|
!cx.shared().exported_symbols().contains(&node_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#![feature(conservative_impl_trait)]
|
#![feature(conservative_impl_trait)]
|
||||||
|
|
||||||
use rustc::dep_graph::WorkProduct;
|
use rustc::dep_graph::WorkProduct;
|
||||||
|
use syntax_pos::symbol::Symbol;
|
||||||
|
|
||||||
extern crate flate;
|
extern crate flate;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
@ -165,6 +166,7 @@ unsafe impl Send for ModuleTranslation { }
|
||||||
unsafe impl Sync for ModuleTranslation { }
|
unsafe impl Sync for ModuleTranslation { }
|
||||||
|
|
||||||
pub struct CrateTranslation {
|
pub struct CrateTranslation {
|
||||||
|
pub crate_name: Symbol,
|
||||||
pub modules: Vec<ModuleTranslation>,
|
pub modules: Vec<ModuleTranslation>,
|
||||||
pub metadata_module: ModuleTranslation,
|
pub metadata_module: ModuleTranslation,
|
||||||
pub link: middle::cstore::LinkMeta,
|
pub link: middle::cstore::LinkMeta,
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#![allow(non_upper_case_globals)]
|
#![allow(non_upper_case_globals)]
|
||||||
|
|
||||||
use llvm;
|
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 llvm::{Float, Double, X86_FP80, PPC_FP128, FP128};
|
||||||
|
|
||||||
use context::CrateContext;
|
use context::CrateContext;
|
||||||
|
@ -82,6 +82,10 @@ impl Type {
|
||||||
ty!(llvm::LLVMInt8TypeInContext(ccx.llcx()))
|
ty!(llvm::LLVMInt8TypeInContext(ccx.llcx()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn i8_llcx(llcx: ContextRef) -> Type {
|
||||||
|
ty!(llvm::LLVMInt8TypeInContext(llcx))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn i16(ccx: &CrateContext) -> Type {
|
pub fn i16(ccx: &CrateContext) -> Type {
|
||||||
ty!(llvm::LLVMInt16TypeInContext(ccx.llcx()))
|
ty!(llvm::LLVMInt16TypeInContext(ccx.llcx()))
|
||||||
}
|
}
|
||||||
|
@ -123,6 +127,10 @@ impl Type {
|
||||||
Type::i8(ccx).ptr_to()
|
Type::i8(ccx).ptr_to()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn i8p_llcx(llcx: ContextRef) -> Type {
|
||||||
|
Type::i8_llcx(llcx).ptr_to()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn int(ccx: &CrateContext) -> Type {
|
pub fn int(ccx: &CrateContext) -> Type {
|
||||||
match &ccx.tcx().sess.target.target.target_pointer_width[..] {
|
match &ccx.tcx().sess.target.target.target_pointer_width[..] {
|
||||||
"16" => Type::i16(ccx),
|
"16" => Type::i16(ccx),
|
||||||
|
|
Loading…
Reference in New Issue