Auto merge of #55349 - bjorn3:rustc_mir_collect_and_partition_mono_items, r=oli-obk
Move collect_and_partition_mono_items to rustc_mir Most of the logic of it is inside rustc_mir anyway. Also removes the single function crate rustc_metadata_utils. Based on #55225
This commit is contained in:
commit
ac708826b0
20 changed files with 280 additions and 303 deletions
|
@ -2141,11 +2141,13 @@ dependencies = [
|
||||||
"flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc 0.0.0",
|
"rustc 0.0.0",
|
||||||
|
"rustc_allocator 0.0.0",
|
||||||
"rustc_data_structures 0.0.0",
|
"rustc_data_structures 0.0.0",
|
||||||
"rustc_incremental 0.0.0",
|
"rustc_incremental 0.0.0",
|
||||||
"rustc_metadata_utils 0.0.0",
|
"rustc_metadata 0.0.0",
|
||||||
"rustc_mir 0.0.0",
|
"rustc_mir 0.0.0",
|
||||||
"rustc_target 0.0.0",
|
"rustc_target 0.0.0",
|
||||||
|
"serialize 0.0.0",
|
||||||
"syntax 0.0.0",
|
"syntax 0.0.0",
|
||||||
"syntax_pos 0.0.0",
|
"syntax_pos 0.0.0",
|
||||||
]
|
]
|
||||||
|
@ -2289,7 +2291,6 @@ dependencies = [
|
||||||
"rustc 0.0.0",
|
"rustc 0.0.0",
|
||||||
"rustc_data_structures 0.0.0",
|
"rustc_data_structures 0.0.0",
|
||||||
"rustc_errors 0.0.0",
|
"rustc_errors 0.0.0",
|
||||||
"rustc_metadata_utils 0.0.0",
|
|
||||||
"rustc_target 0.0.0",
|
"rustc_target 0.0.0",
|
||||||
"serialize 0.0.0",
|
"serialize 0.0.0",
|
||||||
"syntax 0.0.0",
|
"syntax 0.0.0",
|
||||||
|
@ -2297,15 +2298,6 @@ dependencies = [
|
||||||
"syntax_pos 0.0.0",
|
"syntax_pos 0.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustc_metadata_utils"
|
|
||||||
version = "0.0.0"
|
|
||||||
dependencies = [
|
|
||||||
"rustc 0.0.0",
|
|
||||||
"syntax 0.0.0",
|
|
||||||
"syntax_pos 0.0.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_mir"
|
name = "rustc_mir"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
|
|
|
@ -52,28 +52,6 @@ enum Addition {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_library(name: &str, search_paths: &[PathBuf], sess: &Session)
|
|
||||||
-> PathBuf {
|
|
||||||
// On Windows, static libraries sometimes show up as libfoo.a and other
|
|
||||||
// times show up as foo.lib
|
|
||||||
let oslibname = format!("{}{}{}",
|
|
||||||
sess.target.target.options.staticlib_prefix,
|
|
||||||
name,
|
|
||||||
sess.target.target.options.staticlib_suffix);
|
|
||||||
let unixlibname = format!("lib{}.a", name);
|
|
||||||
|
|
||||||
for path in search_paths {
|
|
||||||
debug!("looking for {} inside {:?}", name, path);
|
|
||||||
let test = path.join(&oslibname);
|
|
||||||
if test.exists() { return test }
|
|
||||||
if oslibname != unixlibname {
|
|
||||||
let test = path.join(&unixlibname);
|
|
||||||
if test.exists() { return test }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sess.fatal(&format!("could not find native static library `{}`, \
|
|
||||||
perhaps an -L flag is missing?", name));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_relevant_child(c: &Child) -> bool {
|
fn is_relevant_child(c: &Child) -> bool {
|
||||||
match c.name() {
|
match c.name() {
|
||||||
|
@ -128,7 +106,7 @@ impl<'a> ArchiveBuilder<'a> {
|
||||||
/// Adds all of the contents of a native library to this archive. This will
|
/// Adds all of the contents of a native library to this archive. This will
|
||||||
/// search in the relevant locations for a library named `name`.
|
/// search in the relevant locations for a library named `name`.
|
||||||
pub fn add_native_library(&mut self, name: &str) {
|
pub fn add_native_library(&mut self, name: &str) {
|
||||||
let location = find_library(name, &self.config.lib_search_paths,
|
let location = ::rustc_codegen_utils::find_library(name, &self.config.lib_search_paths,
|
||||||
self.config.sess);
|
self.config.sess);
|
||||||
self.add_archive(&location, |_| false).unwrap_or_else(|e| {
|
self.add_archive(&location, |_| false).unwrap_or_else(|e| {
|
||||||
self.config.sess.fatal(&format!("failed to add native library {}: {}",
|
self.config.sess.fatal(&format!("failed to add native library {}: {}",
|
||||||
|
|
|
@ -12,8 +12,6 @@ use back::wasm;
|
||||||
use cc::windows_registry;
|
use cc::windows_registry;
|
||||||
use super::archive::{ArchiveBuilder, ArchiveConfig};
|
use super::archive::{ArchiveBuilder, ArchiveConfig};
|
||||||
use super::bytecode::RLIB_BYTECODE_EXTENSION;
|
use super::bytecode::RLIB_BYTECODE_EXTENSION;
|
||||||
use super::linker::Linker;
|
|
||||||
use super::command::Command;
|
|
||||||
use super::rpath::RPathConfig;
|
use super::rpath::RPathConfig;
|
||||||
use super::rpath;
|
use super::rpath;
|
||||||
use metadata::METADATA_FILENAME;
|
use metadata::METADATA_FILENAME;
|
||||||
|
@ -31,6 +29,8 @@ use rustc::hir::def_id::CrateNum;
|
||||||
use tempfile::{Builder as TempFileBuilder, TempDir};
|
use tempfile::{Builder as TempFileBuilder, TempDir};
|
||||||
use rustc_target::spec::{PanicStrategy, RelroLevel, LinkerFlavor};
|
use rustc_target::spec::{PanicStrategy, RelroLevel, LinkerFlavor};
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
|
use rustc_codegen_utils::linker::Linker;
|
||||||
|
use rustc_codegen_utils::command::Command;
|
||||||
use context::get_reloc_model;
|
use context::get_reloc_model;
|
||||||
use llvm;
|
use llvm;
|
||||||
|
|
||||||
|
@ -701,7 +701,8 @@ fn link_natively(sess: &Session,
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut linker = codegen_results.linker_info.to_linker(cmd, &sess, flavor);
|
let target_cpu = ::llvm_util::target_cpu(sess);
|
||||||
|
let mut linker = codegen_results.linker_info.to_linker(cmd, &sess, flavor, target_cpu);
|
||||||
link_args(&mut *linker, flavor, sess, crate_type, tmpdir,
|
link_args(&mut *linker, flavor, sess, crate_type, tmpdir,
|
||||||
out_filename, codegen_results);
|
out_filename, codegen_results);
|
||||||
cmd = linker.finalize();
|
cmd = linker.finalize();
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use back::bytecode::{DecodedBytecode, RLIB_BYTECODE_EXTENSION};
|
use back::bytecode::{DecodedBytecode, RLIB_BYTECODE_EXTENSION};
|
||||||
use back::symbol_export;
|
|
||||||
use back::write::{ModuleConfig, with_llvm_pmb, CodegenContext};
|
use back::write::{ModuleConfig, with_llvm_pmb, CodegenContext};
|
||||||
use back::write::{self, DiagnosticHandlers, pre_lto_bitcode_filename};
|
use back::write::{self, DiagnosticHandlers, pre_lto_bitcode_filename};
|
||||||
use errors::{FatalError, Handler};
|
use errors::{FatalError, Handler};
|
||||||
|
@ -24,6 +23,7 @@ use rustc::middle::exported_symbols::SymbolExportLevel;
|
||||||
use rustc::session::config::{self, Lto};
|
use rustc::session::config::{self, Lto};
|
||||||
use rustc::util::common::time_ext;
|
use rustc::util::common::time_ext;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
|
use rustc_codegen_utils::symbol_export;
|
||||||
use time_graph::Timeline;
|
use time_graph::Timeline;
|
||||||
use {ModuleCodegen, ModuleLlvm, ModuleKind};
|
use {ModuleCodegen, ModuleLlvm, ModuleKind};
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,6 @@ use attributes;
|
||||||
use back::bytecode::{self, RLIB_BYTECODE_EXTENSION};
|
use back::bytecode::{self, RLIB_BYTECODE_EXTENSION};
|
||||||
use back::lto::{self, ModuleBuffer, ThinBuffer, SerializedModule};
|
use back::lto::{self, ModuleBuffer, ThinBuffer, SerializedModule};
|
||||||
use back::link::{self, get_linker, remove};
|
use back::link::{self, get_linker, remove};
|
||||||
use back::command::Command;
|
|
||||||
use back::linker::LinkerInfo;
|
|
||||||
use back::symbol_export::ExportedSymbols;
|
|
||||||
use base;
|
use base;
|
||||||
use consts;
|
use consts;
|
||||||
use memmap;
|
use memmap;
|
||||||
|
@ -38,6 +35,9 @@ use rustc::util::common::{time_ext, time_depth, set_time_depth, print_time_passe
|
||||||
use rustc_fs_util::{path2cstr, link_or_copy};
|
use rustc_fs_util::{path2cstr, link_or_copy};
|
||||||
use rustc_data_structures::small_c_str::SmallCStr;
|
use rustc_data_structures::small_c_str::SmallCStr;
|
||||||
use rustc_data_structures::svh::Svh;
|
use rustc_data_structures::svh::Svh;
|
||||||
|
use rustc_codegen_utils::command::Command;
|
||||||
|
use rustc_codegen_utils::linker::LinkerInfo;
|
||||||
|
use rustc_codegen_utils::symbol_export::ExportedSymbols;
|
||||||
use errors::{self, Handler, Level, DiagnosticBuilder, FatalError, DiagnosticId};
|
use errors::{self, Handler, Level, DiagnosticBuilder, FatalError, DiagnosticId};
|
||||||
use errors::emitter::{Emitter};
|
use errors::emitter::{Emitter};
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
|
|
|
@ -54,7 +54,6 @@ use attributes;
|
||||||
use builder::{Builder, MemFlags};
|
use builder::{Builder, MemFlags};
|
||||||
use callee;
|
use callee;
|
||||||
use common::{C_bool, C_bytes_in_context, C_i32, C_usize};
|
use common::{C_bool, C_bytes_in_context, C_i32, C_usize};
|
||||||
use rustc_mir::monomorphize::collector::{self, MonoItemCollectionMode};
|
|
||||||
use rustc_mir::monomorphize::item::DefPathBasedNames;
|
use rustc_mir::monomorphize::item::DefPathBasedNames;
|
||||||
use common::{C_struct_in_context, C_array, val_ty};
|
use common::{C_struct_in_context, C_array, val_ty};
|
||||||
use consts;
|
use consts;
|
||||||
|
@ -64,13 +63,13 @@ use declare;
|
||||||
use meth;
|
use meth;
|
||||||
use mir;
|
use mir;
|
||||||
use monomorphize::Instance;
|
use monomorphize::Instance;
|
||||||
use monomorphize::partitioning::{self, PartitioningStrategy, CodegenUnit, CodegenUnitExt};
|
use monomorphize::partitioning::{CodegenUnit, CodegenUnitExt};
|
||||||
use rustc_codegen_utils::symbol_names_test;
|
use rustc_codegen_utils::symbol_names_test;
|
||||||
use time_graph;
|
use time_graph;
|
||||||
use mono_item::{MonoItem, BaseMonoItemExt, MonoItemExt};
|
use mono_item::{MonoItem, MonoItemExt};
|
||||||
use type_::Type;
|
use type_::Type;
|
||||||
use type_of::LayoutLlvmExt;
|
use type_of::LayoutLlvmExt;
|
||||||
use rustc::util::nodemap::{FxHashMap, DefIdSet};
|
use rustc::util::nodemap::FxHashMap;
|
||||||
use CrateInfo;
|
use CrateInfo;
|
||||||
use rustc_data_structures::small_c_str::SmallCStr;
|
use rustc_data_structures::small_c_str::SmallCStr;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
|
@ -80,7 +79,6 @@ use std::cmp;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::i32;
|
use std::i32;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::sync::Arc;
|
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use std::time::{Instant, Duration};
|
use std::time::{Instant, Duration};
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
|
@ -1011,128 +1009,6 @@ fn assert_and_save_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
||||||
|| rustc_incremental::save_dep_graph(tcx));
|
|| rustc_incremental::save_dep_graph(tcx));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_and_partition_mono_items<'a, 'tcx>(
|
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|
||||||
cnum: CrateNum,
|
|
||||||
) -> (Arc<DefIdSet>, Arc<Vec<Arc<CodegenUnit<'tcx>>>>)
|
|
||||||
{
|
|
||||||
assert_eq!(cnum, LOCAL_CRATE);
|
|
||||||
|
|
||||||
let collection_mode = match tcx.sess.opts.debugging_opts.print_mono_items {
|
|
||||||
Some(ref s) => {
|
|
||||||
let mode_string = s.to_lowercase();
|
|
||||||
let mode_string = mode_string.trim();
|
|
||||||
if mode_string == "eager" {
|
|
||||||
MonoItemCollectionMode::Eager
|
|
||||||
} else {
|
|
||||||
if mode_string != "lazy" {
|
|
||||||
let message = format!("Unknown codegen-item collection mode '{}'. \
|
|
||||||
Falling back to 'lazy' mode.",
|
|
||||||
mode_string);
|
|
||||||
tcx.sess.warn(&message);
|
|
||||||
}
|
|
||||||
|
|
||||||
MonoItemCollectionMode::Lazy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
if tcx.sess.opts.cg.link_dead_code {
|
|
||||||
MonoItemCollectionMode::Eager
|
|
||||||
} else {
|
|
||||||
MonoItemCollectionMode::Lazy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let (items, inlining_map) =
|
|
||||||
time(tcx.sess, "monomorphization collection", || {
|
|
||||||
collector::collect_crate_mono_items(tcx, collection_mode)
|
|
||||||
});
|
|
||||||
|
|
||||||
tcx.sess.abort_if_errors();
|
|
||||||
|
|
||||||
::rustc_mir::monomorphize::assert_symbols_are_distinct(tcx, items.iter());
|
|
||||||
|
|
||||||
let strategy = if tcx.sess.opts.incremental.is_some() {
|
|
||||||
PartitioningStrategy::PerModule
|
|
||||||
} else {
|
|
||||||
PartitioningStrategy::FixedUnitCount(tcx.sess.codegen_units())
|
|
||||||
};
|
|
||||||
|
|
||||||
let codegen_units = time(tcx.sess, "codegen unit partitioning", || {
|
|
||||||
partitioning::partition(tcx,
|
|
||||||
items.iter().cloned(),
|
|
||||||
strategy,
|
|
||||||
&inlining_map)
|
|
||||||
.into_iter()
|
|
||||||
.map(Arc::new)
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
});
|
|
||||||
|
|
||||||
let mono_items: DefIdSet = items.iter().filter_map(|mono_item| {
|
|
||||||
match *mono_item {
|
|
||||||
MonoItem::Fn(ref instance) => Some(instance.def_id()),
|
|
||||||
MonoItem::Static(def_id) => Some(def_id),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}).collect();
|
|
||||||
|
|
||||||
if tcx.sess.opts.debugging_opts.print_mono_items.is_some() {
|
|
||||||
let mut item_to_cgus: FxHashMap<_, Vec<_>> = Default::default();
|
|
||||||
|
|
||||||
for cgu in &codegen_units {
|
|
||||||
for (&mono_item, &linkage) in cgu.items() {
|
|
||||||
item_to_cgus.entry(mono_item)
|
|
||||||
.or_default()
|
|
||||||
.push((cgu.name().clone(), linkage));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut item_keys: Vec<_> = items
|
|
||||||
.iter()
|
|
||||||
.map(|i| {
|
|
||||||
let mut output = i.to_string(tcx);
|
|
||||||
output.push_str(" @@");
|
|
||||||
let mut empty = Vec::new();
|
|
||||||
let cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty);
|
|
||||||
cgus.as_mut_slice().sort_by_key(|&(ref name, _)| name.clone());
|
|
||||||
cgus.dedup();
|
|
||||||
for &(ref cgu_name, (linkage, _)) in cgus.iter() {
|
|
||||||
output.push_str(" ");
|
|
||||||
output.push_str(&cgu_name.as_str());
|
|
||||||
|
|
||||||
let linkage_abbrev = match linkage {
|
|
||||||
Linkage::External => "External",
|
|
||||||
Linkage::AvailableExternally => "Available",
|
|
||||||
Linkage::LinkOnceAny => "OnceAny",
|
|
||||||
Linkage::LinkOnceODR => "OnceODR",
|
|
||||||
Linkage::WeakAny => "WeakAny",
|
|
||||||
Linkage::WeakODR => "WeakODR",
|
|
||||||
Linkage::Appending => "Appending",
|
|
||||||
Linkage::Internal => "Internal",
|
|
||||||
Linkage::Private => "Private",
|
|
||||||
Linkage::ExternalWeak => "ExternalWeak",
|
|
||||||
Linkage::Common => "Common",
|
|
||||||
};
|
|
||||||
|
|
||||||
output.push_str("[");
|
|
||||||
output.push_str(linkage_abbrev);
|
|
||||||
output.push_str("]");
|
|
||||||
}
|
|
||||||
output
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
item_keys.sort();
|
|
||||||
|
|
||||||
for item in item_keys {
|
|
||||||
println!("MONO_ITEM {}", item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(Arc::new(mono_items), Arc::new(codegen_units))
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CrateInfo {
|
impl CrateInfo {
|
||||||
pub fn new(tcx: TyCtxt) -> CrateInfo {
|
pub fn new(tcx: TyCtxt) -> CrateInfo {
|
||||||
let mut info = CrateInfo {
|
let mut info = CrateInfo {
|
||||||
|
@ -1222,12 +1098,6 @@ impl CrateInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_codegened_item(tcx: TyCtxt, id: DefId) -> bool {
|
|
||||||
let (all_mono_items, _) =
|
|
||||||
tcx.collect_and_partition_mono_items(LOCAL_CRATE);
|
|
||||||
all_mono_items.contains(&id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
cgu_name: InternedString)
|
cgu_name: InternedString)
|
||||||
-> Stats {
|
-> Stats {
|
||||||
|
@ -1318,24 +1188,7 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn provide(providers: &mut Providers) {
|
pub fn provide_both(providers: &mut Providers) {
|
||||||
providers.collect_and_partition_mono_items =
|
|
||||||
collect_and_partition_mono_items;
|
|
||||||
|
|
||||||
providers.is_codegened_item = is_codegened_item;
|
|
||||||
|
|
||||||
providers.codegen_unit = |tcx, name| {
|
|
||||||
let (_, all) = tcx.collect_and_partition_mono_items(LOCAL_CRATE);
|
|
||||||
all.iter()
|
|
||||||
.find(|cgu| *cgu.name() == name)
|
|
||||||
.cloned()
|
|
||||||
.unwrap_or_else(|| panic!("failed to find cgu with name {:?}", name))
|
|
||||||
};
|
|
||||||
|
|
||||||
provide_extern(providers);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn provide_extern(providers: &mut Providers) {
|
|
||||||
providers.dllimport_foreign_items = |tcx, krate| {
|
providers.dllimport_foreign_items = |tcx, krate| {
|
||||||
let module_map = tcx.foreign_modules(krate);
|
let module_map = tcx.foreign_modules(krate);
|
||||||
let module_map = module_map.iter()
|
let module_map = module_map.iter()
|
||||||
|
|
|
@ -71,7 +71,6 @@ use back::bytecode::RLIB_BYTECODE_EXTENSION;
|
||||||
|
|
||||||
pub use llvm_util::target_features;
|
pub use llvm_util::target_features;
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::path::{PathBuf};
|
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
|
|
||||||
|
@ -87,20 +86,17 @@ use rustc::util::time_graph;
|
||||||
use rustc::util::nodemap::{FxHashSet, FxHashMap};
|
use rustc::util::nodemap::{FxHashSet, FxHashMap};
|
||||||
use rustc::util::profiling::ProfileCategory;
|
use rustc::util::profiling::ProfileCategory;
|
||||||
use rustc_mir::monomorphize;
|
use rustc_mir::monomorphize;
|
||||||
|
use rustc_codegen_utils::{CompiledModule, ModuleKind};
|
||||||
use rustc_codegen_utils::codegen_backend::CodegenBackend;
|
use rustc_codegen_utils::codegen_backend::CodegenBackend;
|
||||||
use rustc_data_structures::svh::Svh;
|
use rustc_data_structures::svh::Svh;
|
||||||
|
|
||||||
mod diagnostics;
|
mod diagnostics;
|
||||||
|
|
||||||
mod back {
|
mod back {
|
||||||
pub use rustc_codegen_utils::symbol_names;
|
|
||||||
mod archive;
|
mod archive;
|
||||||
pub mod bytecode;
|
pub mod bytecode;
|
||||||
mod command;
|
|
||||||
pub mod linker;
|
|
||||||
pub mod link;
|
pub mod link;
|
||||||
pub mod lto;
|
pub mod lto;
|
||||||
pub mod symbol_export;
|
|
||||||
pub mod write;
|
pub mod write;
|
||||||
mod rpath;
|
mod rpath;
|
||||||
pub mod wasm;
|
pub mod wasm;
|
||||||
|
@ -194,15 +190,15 @@ impl CodegenBackend for LlvmCodegenBackend {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn provide(&self, providers: &mut ty::query::Providers) {
|
fn provide(&self, providers: &mut ty::query::Providers) {
|
||||||
back::symbol_names::provide(providers);
|
rustc_codegen_utils::symbol_export::provide(providers);
|
||||||
back::symbol_export::provide(providers);
|
rustc_codegen_utils::symbol_names::provide(providers);
|
||||||
base::provide(providers);
|
base::provide_both(providers);
|
||||||
attributes::provide(providers);
|
attributes::provide(providers);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn provide_extern(&self, providers: &mut ty::query::Providers) {
|
fn provide_extern(&self, providers: &mut ty::query::Providers) {
|
||||||
back::symbol_export::provide_extern(providers);
|
rustc_codegen_utils::symbol_export::provide_extern(providers);
|
||||||
base::provide_extern(providers);
|
base::provide_both(providers);
|
||||||
attributes::provide_extern(providers);
|
attributes::provide_extern(providers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,13 +277,6 @@ struct CachedModuleCodegen {
|
||||||
source: WorkProduct,
|
source: WorkProduct,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
enum ModuleKind {
|
|
||||||
Regular,
|
|
||||||
Metadata,
|
|
||||||
Allocator,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ModuleCodegen {
|
impl ModuleCodegen {
|
||||||
fn into_compiled_module(self,
|
fn into_compiled_module(self,
|
||||||
emit_obj: bool,
|
emit_obj: bool,
|
||||||
|
@ -321,15 +310,6 @@ impl ModuleCodegen {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct CompiledModule {
|
|
||||||
name: String,
|
|
||||||
kind: ModuleKind,
|
|
||||||
object: Option<PathBuf>,
|
|
||||||
bytecode: Option<PathBuf>,
|
|
||||||
bytecode_compressed: Option<PathBuf>,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ModuleLlvm {
|
struct ModuleLlvm {
|
||||||
llcx: &'static mut llvm::Context,
|
llcx: &'static mut llvm::Context,
|
||||||
llmod_raw: *const llvm::Module,
|
llmod_raw: *const llvm::Module,
|
||||||
|
@ -377,7 +357,7 @@ struct CodegenResults {
|
||||||
crate_hash: Svh,
|
crate_hash: Svh,
|
||||||
metadata: rustc::middle::cstore::EncodedMetadata,
|
metadata: rustc::middle::cstore::EncodedMetadata,
|
||||||
windows_subsystem: Option<String>,
|
windows_subsystem: Option<String>,
|
||||||
linker_info: back::linker::LinkerInfo,
|
linker_info: rustc_codegen_utils::linker::LinkerInfo,
|
||||||
crate_info: CrateInfo,
|
crate_info: CrateInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,11 +13,13 @@ test = false
|
||||||
flate2 = "1.0"
|
flate2 = "1.0"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
|
||||||
|
serialize = { path = "../libserialize" }
|
||||||
syntax = { path = "../libsyntax" }
|
syntax = { path = "../libsyntax" }
|
||||||
syntax_pos = { path = "../libsyntax_pos" }
|
syntax_pos = { path = "../libsyntax_pos" }
|
||||||
rustc = { path = "../librustc" }
|
rustc = { path = "../librustc" }
|
||||||
|
rustc_allocator = { path = "../librustc_allocator" }
|
||||||
rustc_target = { path = "../librustc_target" }
|
rustc_target = { path = "../librustc_target" }
|
||||||
rustc_data_structures = { path = "../librustc_data_structures" }
|
rustc_data_structures = { path = "../librustc_data_structures" }
|
||||||
|
rustc_metadata = { path = "../librustc_metadata" }
|
||||||
rustc_mir = { path = "../librustc_mir" }
|
rustc_mir = { path = "../librustc_mir" }
|
||||||
rustc_incremental = { path = "../librustc_incremental" }
|
rustc_incremental = { path = "../librustc_incremental" }
|
||||||
rustc_metadata_utils = { path = "../librustc_metadata_utils" }
|
|
||||||
|
|
|
@ -30,20 +30,28 @@ extern crate flate2;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
|
extern crate serialize;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate rustc;
|
extern crate rustc;
|
||||||
|
extern crate rustc_allocator;
|
||||||
extern crate rustc_target;
|
extern crate rustc_target;
|
||||||
|
extern crate rustc_metadata;
|
||||||
extern crate rustc_mir;
|
extern crate rustc_mir;
|
||||||
extern crate rustc_incremental;
|
extern crate rustc_incremental;
|
||||||
extern crate syntax;
|
extern crate syntax;
|
||||||
extern crate syntax_pos;
|
extern crate syntax_pos;
|
||||||
#[macro_use] extern crate rustc_data_structures;
|
#[macro_use] extern crate rustc_data_structures;
|
||||||
extern crate rustc_metadata_utils;
|
|
||||||
|
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use rustc::session::Session;
|
||||||
use rustc::ty::TyCtxt;
|
use rustc::ty::TyCtxt;
|
||||||
|
|
||||||
|
pub mod command;
|
||||||
pub mod link;
|
pub mod link;
|
||||||
|
pub mod linker;
|
||||||
pub mod codegen_backend;
|
pub mod codegen_backend;
|
||||||
|
pub mod symbol_export;
|
||||||
pub mod symbol_names;
|
pub mod symbol_names;
|
||||||
pub mod symbol_names_test;
|
pub mod symbol_names_test;
|
||||||
|
|
||||||
|
@ -61,4 +69,43 @@ pub fn check_for_rustc_errors_attr(tcx: TyCtxt) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
|
pub enum ModuleKind {
|
||||||
|
Regular,
|
||||||
|
Metadata,
|
||||||
|
Allocator,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct CompiledModule {
|
||||||
|
pub name: String,
|
||||||
|
pub kind: ModuleKind,
|
||||||
|
pub object: Option<PathBuf>,
|
||||||
|
pub bytecode: Option<PathBuf>,
|
||||||
|
pub bytecode_compressed: Option<PathBuf>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn find_library(name: &str, search_paths: &[PathBuf], sess: &Session)
|
||||||
|
-> PathBuf {
|
||||||
|
// On Windows, static libraries sometimes show up as libfoo.a and other
|
||||||
|
// times show up as foo.lib
|
||||||
|
let oslibname = format!("{}{}{}",
|
||||||
|
sess.target.target.options.staticlib_prefix,
|
||||||
|
name,
|
||||||
|
sess.target.target.options.staticlib_suffix);
|
||||||
|
let unixlibname = format!("lib{}.a", name);
|
||||||
|
|
||||||
|
for path in search_paths {
|
||||||
|
debug!("looking for {} inside {:?}", name, path);
|
||||||
|
let test = path.join(&oslibname);
|
||||||
|
if test.exists() { return test }
|
||||||
|
if oslibname != unixlibname {
|
||||||
|
let test = path.join(&unixlibname);
|
||||||
|
if test.exists() { return test }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sess.fatal(&format!("could not find native static library `{}`, \
|
||||||
|
perhaps an -L flag is missing?", name));
|
||||||
|
}
|
||||||
|
|
||||||
__build_diagnostic_array! { librustc_codegen_utils, DIAGNOSTICS }
|
__build_diagnostic_array! { librustc_codegen_utils, DIAGNOSTICS }
|
||||||
|
|
|
@ -13,7 +13,6 @@ use rustc::session::Session;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use syntax::{ast, attr};
|
use syntax::{ast, attr};
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
use rustc_metadata_utils::validate_crate_name;
|
|
||||||
|
|
||||||
pub fn out_filename(sess: &Session,
|
pub fn out_filename(sess: &Session,
|
||||||
crate_type: config::CrateType,
|
crate_type: config::CrateType,
|
||||||
|
@ -52,7 +51,7 @@ pub fn find_crate_name(sess: Option<&Session>,
|
||||||
attrs: &[ast::Attribute],
|
attrs: &[ast::Attribute],
|
||||||
input: &Input) -> String {
|
input: &Input) -> String {
|
||||||
let validate = |s: String, span: Option<Span>| {
|
let validate = |s: String, span: Option<Span>| {
|
||||||
validate_crate_name(sess, &s, span);
|
::rustc_metadata::validate_crate_name(sess, &s, span);
|
||||||
s
|
s
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,7 @@ use std::io::prelude::*;
|
||||||
use std::io::{self, BufWriter};
|
use std::io::{self, BufWriter};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use back::archive;
|
use command::Command;
|
||||||
use back::command::Command;
|
|
||||||
use back::symbol_export;
|
|
||||||
use rustc::hir::def_id::{LOCAL_CRATE, CrateNum};
|
use rustc::hir::def_id::{LOCAL_CRATE, CrateNum};
|
||||||
use rustc::middle::dependency_format::Linkage;
|
use rustc::middle::dependency_format::Linkage;
|
||||||
use rustc::session::Session;
|
use rustc::session::Session;
|
||||||
|
@ -26,7 +24,6 @@ use rustc::session::config::{self, CrateType, OptLevel, DebugInfo,
|
||||||
use rustc::ty::TyCtxt;
|
use rustc::ty::TyCtxt;
|
||||||
use rustc_target::spec::{LinkerFlavor, LldFlavor};
|
use rustc_target::spec::{LinkerFlavor, LldFlavor};
|
||||||
use serialize::{json, Encoder};
|
use serialize::{json, Encoder};
|
||||||
use llvm_util;
|
|
||||||
|
|
||||||
/// For all the linkers we support, and information they might
|
/// For all the linkers we support, and information they might
|
||||||
/// need out of the shared crate context before we get rid of it.
|
/// need out of the shared crate context before we get rid of it.
|
||||||
|
@ -43,10 +40,13 @@ impl LinkerInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_linker<'a>(&'a self,
|
pub fn to_linker<'a>(
|
||||||
cmd: Command,
|
&'a self,
|
||||||
sess: &'a Session,
|
cmd: Command,
|
||||||
flavor: LinkerFlavor) -> Box<dyn Linker+'a> {
|
sess: &'a Session,
|
||||||
|
flavor: LinkerFlavor,
|
||||||
|
target_cpu: &'a str,
|
||||||
|
) -> Box<dyn Linker+'a> {
|
||||||
match flavor {
|
match flavor {
|
||||||
LinkerFlavor::Lld(LldFlavor::Link) |
|
LinkerFlavor::Lld(LldFlavor::Link) |
|
||||||
LinkerFlavor::Msvc => {
|
LinkerFlavor::Msvc => {
|
||||||
|
@ -70,6 +70,7 @@ impl LinkerInfo {
|
||||||
info: self,
|
info: self,
|
||||||
hinted_static: false,
|
hinted_static: false,
|
||||||
is_ld: false,
|
is_ld: false,
|
||||||
|
target_cpu,
|
||||||
}) as Box<dyn Linker>
|
}) as Box<dyn Linker>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +83,7 @@ impl LinkerInfo {
|
||||||
info: self,
|
info: self,
|
||||||
hinted_static: false,
|
hinted_static: false,
|
||||||
is_ld: true,
|
is_ld: true,
|
||||||
|
target_cpu,
|
||||||
}) as Box<dyn Linker>
|
}) as Box<dyn Linker>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,6 +146,7 @@ pub struct GccLinker<'a> {
|
||||||
hinted_static: bool, // Keeps track of the current hinting mode.
|
hinted_static: bool, // Keeps track of the current hinting mode.
|
||||||
// Link as ld
|
// Link as ld
|
||||||
is_ld: bool,
|
is_ld: bool,
|
||||||
|
target_cpu: &'a str,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> GccLinker<'a> {
|
impl<'a> GccLinker<'a> {
|
||||||
|
@ -204,7 +207,8 @@ impl<'a> GccLinker<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
self.linker_arg(&format!("-plugin-opt={}", opt_level));
|
self.linker_arg(&format!("-plugin-opt={}", opt_level));
|
||||||
self.linker_arg(&format!("-plugin-opt=mcpu={}", llvm_util::target_cpu(self.sess)));
|
let target_cpu = self.target_cpu;
|
||||||
|
self.linker_arg(&format!("-plugin-opt=mcpu={}", target_cpu));
|
||||||
|
|
||||||
match self.sess.lto() {
|
match self.sess.lto() {
|
||||||
config::Lto::Thin |
|
config::Lto::Thin |
|
||||||
|
@ -263,7 +267,7 @@ impl<'a> Linker for GccLinker<'a> {
|
||||||
// -force_load is the macOS equivalent of --whole-archive, but it
|
// -force_load is the macOS equivalent of --whole-archive, but it
|
||||||
// involves passing the full path to the library to link.
|
// involves passing the full path to the library to link.
|
||||||
self.linker_arg("-force_load");
|
self.linker_arg("-force_load");
|
||||||
let lib = archive::find_library(lib, search_path, &self.sess);
|
let lib = ::find_library(lib, search_path, &self.sess);
|
||||||
self.linker_arg(&lib);
|
self.linker_arg(&lib);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -898,7 +902,8 @@ impl<'a> Linker for EmLinker<'a> {
|
||||||
fn exported_symbols(tcx: TyCtxt, crate_type: CrateType) -> Vec<String> {
|
fn exported_symbols(tcx: TyCtxt, crate_type: CrateType) -> Vec<String> {
|
||||||
let mut symbols = Vec::new();
|
let mut symbols = Vec::new();
|
||||||
|
|
||||||
let export_threshold = symbol_export::crates_export_threshold(&[crate_type]);
|
let export_threshold =
|
||||||
|
::symbol_export::crates_export_threshold(&[crate_type]);
|
||||||
for &(symbol, level) in tcx.exported_symbols(LOCAL_CRATE).iter() {
|
for &(symbol, level) in tcx.exported_symbols(LOCAL_CRATE).iter() {
|
||||||
if level.is_below_threshold(export_threshold) {
|
if level.is_below_threshold(export_threshold) {
|
||||||
symbols.push(symbol.symbol_name(tcx).to_string());
|
symbols.push(symbol.symbol_name(tcx).to_string());
|
|
@ -11,7 +11,7 @@
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use monomorphize::Instance;
|
use rustc::ty::Instance;
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::hir::Node;
|
use rustc::hir::Node;
|
||||||
use rustc::hir::CodegenFnAttrFlags;
|
use rustc::hir::CodegenFnAttrFlags;
|
|
@ -20,4 +20,3 @@ serialize = { path = "../libserialize" }
|
||||||
syntax = { path = "../libsyntax" }
|
syntax = { path = "../libsyntax" }
|
||||||
syntax_ext = { path = "../libsyntax_ext" }
|
syntax_ext = { path = "../libsyntax_ext" }
|
||||||
syntax_pos = { path = "../libsyntax_pos" }
|
syntax_pos = { path = "../libsyntax_pos" }
|
||||||
rustc_metadata_utils = { path = "../librustc_metadata_utils" }
|
|
||||||
|
|
|
@ -30,8 +30,6 @@ use rustc::util::common::record_time;
|
||||||
use rustc::util::nodemap::FxHashSet;
|
use rustc::util::nodemap::FxHashSet;
|
||||||
use rustc::hir::map::Definitions;
|
use rustc::hir::map::Definitions;
|
||||||
|
|
||||||
use rustc_metadata_utils::validate_crate_name;
|
|
||||||
|
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::{cmp, fs};
|
use std::{cmp, fs};
|
||||||
|
@ -1106,7 +1104,7 @@ impl<'a> CrateLoader<'a> {
|
||||||
item.ident, orig_name);
|
item.ident, orig_name);
|
||||||
let orig_name = match orig_name {
|
let orig_name = match orig_name {
|
||||||
Some(orig_name) => {
|
Some(orig_name) => {
|
||||||
validate_crate_name(Some(self.sess), &orig_name.as_str(),
|
::validate_crate_name(Some(self.sess), &orig_name.as_str(),
|
||||||
Some(item.span));
|
Some(item.span));
|
||||||
orig_name
|
orig_name
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,6 @@ extern crate serialize as rustc_serialize; // used by deriving
|
||||||
extern crate rustc_errors as errors;
|
extern crate rustc_errors as errors;
|
||||||
extern crate syntax_ext;
|
extern crate syntax_ext;
|
||||||
extern crate proc_macro;
|
extern crate proc_macro;
|
||||||
extern crate rustc_metadata_utils;
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate rustc;
|
extern crate rustc;
|
||||||
|
@ -64,4 +63,34 @@ pub mod cstore;
|
||||||
pub mod dynamic_lib;
|
pub mod dynamic_lib;
|
||||||
pub mod locator;
|
pub mod locator;
|
||||||
|
|
||||||
|
pub fn validate_crate_name(
|
||||||
|
sess: Option<&rustc::session::Session>,
|
||||||
|
s: &str,
|
||||||
|
sp: Option<syntax_pos::Span>
|
||||||
|
) {
|
||||||
|
let mut err_count = 0;
|
||||||
|
{
|
||||||
|
let mut say = |s: &str| {
|
||||||
|
match (sp, sess) {
|
||||||
|
(_, None) => bug!("{}", s),
|
||||||
|
(Some(sp), Some(sess)) => sess.span_err(sp, s),
|
||||||
|
(None, Some(sess)) => sess.err(s),
|
||||||
|
}
|
||||||
|
err_count += 1;
|
||||||
|
};
|
||||||
|
if s.is_empty() {
|
||||||
|
say("crate name must not be empty");
|
||||||
|
}
|
||||||
|
for c in s.chars() {
|
||||||
|
if c.is_alphanumeric() { continue }
|
||||||
|
if c == '_' { continue }
|
||||||
|
say(&format!("invalid character `{}` in crate name: `{}`", c, s));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err_count > 0 {
|
||||||
|
sess.unwrap().abort_if_errors();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
__build_diagnostic_array! { librustc_metadata, DIAGNOSTICS }
|
__build_diagnostic_array! { librustc_metadata, DIAGNOSTICS }
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
[package]
|
|
||||||
authors = ["The Rust Project Developers"]
|
|
||||||
name = "rustc_metadata_utils"
|
|
||||||
version = "0.0.0"
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
name = "rustc_metadata_utils"
|
|
||||||
path = "lib.rs"
|
|
||||||
crate-type = ["dylib"]
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
rustc = { path = "../librustc" }
|
|
||||||
syntax = { path = "../libsyntax" }
|
|
||||||
syntax_pos = { path = "../libsyntax_pos" }
|
|
|
@ -1,42 +0,0 @@
|
||||||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate rustc;
|
|
||||||
extern crate syntax_pos;
|
|
||||||
|
|
||||||
use rustc::session::Session;
|
|
||||||
use syntax_pos::Span;
|
|
||||||
|
|
||||||
pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
|
|
||||||
let mut err_count = 0;
|
|
||||||
{
|
|
||||||
let mut say = |s: &str| {
|
|
||||||
match (sp, sess) {
|
|
||||||
(_, None) => bug!("{}", s),
|
|
||||||
(Some(sp), Some(sess)) => sess.span_err(sp, s),
|
|
||||||
(None, Some(sess)) => sess.err(s),
|
|
||||||
}
|
|
||||||
err_count += 1;
|
|
||||||
};
|
|
||||||
if s.is_empty() {
|
|
||||||
say("crate name must not be empty");
|
|
||||||
}
|
|
||||||
for c in s.chars() {
|
|
||||||
if c.is_alphanumeric() { continue }
|
|
||||||
if c == '_' { continue }
|
|
||||||
say(&format!("invalid character `{}` in crate name: `{}`", c, s));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err_count > 0 {
|
|
||||||
sess.unwrap().abort_if_errors();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -93,6 +93,7 @@ pub fn provide(providers: &mut Providers) {
|
||||||
borrow_check::provide(providers);
|
borrow_check::provide(providers);
|
||||||
shim::provide(providers);
|
shim::provide(providers);
|
||||||
transform::provide(providers);
|
transform::provide(providers);
|
||||||
|
monomorphize::partitioning::provide(providers);
|
||||||
providers.const_eval = const_eval::const_eval_provider;
|
providers.const_eval = const_eval::const_eval_provider;
|
||||||
providers.const_eval_raw = const_eval::const_eval_raw_provider;
|
providers.const_eval_raw = const_eval::const_eval_raw_provider;
|
||||||
providers.check_match = hair::pattern::check_match;
|
providers.check_match = hair::pattern::check_match;
|
||||||
|
|
|
@ -102,21 +102,27 @@
|
||||||
//! source-level module, functions from the same module will be available for
|
//! source-level module, functions from the same module will be available for
|
||||||
//! inlining, even when they are not marked #[inline].
|
//! inlining, even when they are not marked #[inline].
|
||||||
|
|
||||||
use monomorphize::collector::InliningMap;
|
use std::collections::hash_map::Entry;
|
||||||
|
use std::cmp;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use syntax::ast::NodeId;
|
||||||
|
use syntax::symbol::InternedString;
|
||||||
use rustc::dep_graph::{WorkProductId, WorkProduct, DepNode, DepConstructor};
|
use rustc::dep_graph::{WorkProductId, WorkProduct, DepNode, DepConstructor};
|
||||||
use rustc::hir::CodegenFnAttrFlags;
|
use rustc::hir::CodegenFnAttrFlags;
|
||||||
use rustc::hir::def_id::{DefId, LOCAL_CRATE, CRATE_DEF_INDEX};
|
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE, CRATE_DEF_INDEX};
|
||||||
use rustc::hir::map::DefPathData;
|
use rustc::hir::map::DefPathData;
|
||||||
use rustc::mir::mono::{Linkage, Visibility, CodegenUnitNameBuilder};
|
use rustc::mir::mono::{Linkage, Visibility, CodegenUnitNameBuilder};
|
||||||
use rustc::middle::exported_symbols::SymbolExportLevel;
|
use rustc::middle::exported_symbols::SymbolExportLevel;
|
||||||
use rustc::ty::{self, TyCtxt, InstanceDef};
|
use rustc::ty::{self, TyCtxt, InstanceDef};
|
||||||
use rustc::ty::item_path::characteristic_def_id_of_type;
|
use rustc::ty::item_path::characteristic_def_id_of_type;
|
||||||
use rustc::util::nodemap::{FxHashMap, FxHashSet};
|
use rustc::ty::query::Providers;
|
||||||
use std::collections::hash_map::Entry;
|
use rustc::util::common::time;
|
||||||
use std::cmp;
|
use rustc::util::nodemap::{DefIdSet, FxHashMap, FxHashSet};
|
||||||
use syntax::ast::NodeId;
|
|
||||||
use syntax::symbol::InternedString;
|
|
||||||
use rustc::mir::mono::MonoItem;
|
use rustc::mir::mono::MonoItem;
|
||||||
|
|
||||||
|
use monomorphize::collector::InliningMap;
|
||||||
|
use monomorphize::collector::{self, MonoItemCollectionMode};
|
||||||
use monomorphize::item::{MonoItemExt, InstantiationMode};
|
use monomorphize::item::{MonoItemExt, InstantiationMode};
|
||||||
|
|
||||||
pub use rustc::mir::mono::CodegenUnit;
|
pub use rustc::mir::mono::CodegenUnit;
|
||||||
|
@ -892,3 +898,146 @@ fn debug_dump<'a, 'b, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn collect_and_partition_mono_items<'a, 'tcx>(
|
||||||
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
|
cnum: CrateNum,
|
||||||
|
) -> (Arc<DefIdSet>, Arc<Vec<Arc<CodegenUnit<'tcx>>>>)
|
||||||
|
{
|
||||||
|
assert_eq!(cnum, LOCAL_CRATE);
|
||||||
|
|
||||||
|
let collection_mode = match tcx.sess.opts.debugging_opts.print_mono_items {
|
||||||
|
Some(ref s) => {
|
||||||
|
let mode_string = s.to_lowercase();
|
||||||
|
let mode_string = mode_string.trim();
|
||||||
|
if mode_string == "eager" {
|
||||||
|
MonoItemCollectionMode::Eager
|
||||||
|
} else {
|
||||||
|
if mode_string != "lazy" {
|
||||||
|
let message = format!("Unknown codegen-item collection mode '{}'. \
|
||||||
|
Falling back to 'lazy' mode.",
|
||||||
|
mode_string);
|
||||||
|
tcx.sess.warn(&message);
|
||||||
|
}
|
||||||
|
|
||||||
|
MonoItemCollectionMode::Lazy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
if tcx.sess.opts.cg.link_dead_code {
|
||||||
|
MonoItemCollectionMode::Eager
|
||||||
|
} else {
|
||||||
|
MonoItemCollectionMode::Lazy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let (items, inlining_map) =
|
||||||
|
time(tcx.sess, "monomorphization collection", || {
|
||||||
|
collector::collect_crate_mono_items(tcx, collection_mode)
|
||||||
|
});
|
||||||
|
|
||||||
|
tcx.sess.abort_if_errors();
|
||||||
|
|
||||||
|
::monomorphize::assert_symbols_are_distinct(tcx, items.iter());
|
||||||
|
|
||||||
|
let strategy = if tcx.sess.opts.incremental.is_some() {
|
||||||
|
PartitioningStrategy::PerModule
|
||||||
|
} else {
|
||||||
|
PartitioningStrategy::FixedUnitCount(tcx.sess.codegen_units())
|
||||||
|
};
|
||||||
|
|
||||||
|
let codegen_units = time(tcx.sess, "codegen unit partitioning", || {
|
||||||
|
partition(
|
||||||
|
tcx,
|
||||||
|
items.iter().cloned(),
|
||||||
|
strategy,
|
||||||
|
&inlining_map
|
||||||
|
)
|
||||||
|
.into_iter()
|
||||||
|
.map(Arc::new)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
});
|
||||||
|
|
||||||
|
let mono_items: DefIdSet = items.iter().filter_map(|mono_item| {
|
||||||
|
match *mono_item {
|
||||||
|
MonoItem::Fn(ref instance) => Some(instance.def_id()),
|
||||||
|
MonoItem::Static(def_id) => Some(def_id),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}).collect();
|
||||||
|
|
||||||
|
if tcx.sess.opts.debugging_opts.print_mono_items.is_some() {
|
||||||
|
let mut item_to_cgus: FxHashMap<_, Vec<_>> = Default::default();
|
||||||
|
|
||||||
|
for cgu in &codegen_units {
|
||||||
|
for (&mono_item, &linkage) in cgu.items() {
|
||||||
|
item_to_cgus.entry(mono_item)
|
||||||
|
.or_default()
|
||||||
|
.push((cgu.name().clone(), linkage));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut item_keys: Vec<_> = items
|
||||||
|
.iter()
|
||||||
|
.map(|i| {
|
||||||
|
let mut output = i.to_string(tcx);
|
||||||
|
output.push_str(" @@");
|
||||||
|
let mut empty = Vec::new();
|
||||||
|
let cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty);
|
||||||
|
cgus.as_mut_slice().sort_by_key(|&(ref name, _)| name.clone());
|
||||||
|
cgus.dedup();
|
||||||
|
for &(ref cgu_name, (linkage, _)) in cgus.iter() {
|
||||||
|
output.push_str(" ");
|
||||||
|
output.push_str(&cgu_name.as_str());
|
||||||
|
|
||||||
|
let linkage_abbrev = match linkage {
|
||||||
|
Linkage::External => "External",
|
||||||
|
Linkage::AvailableExternally => "Available",
|
||||||
|
Linkage::LinkOnceAny => "OnceAny",
|
||||||
|
Linkage::LinkOnceODR => "OnceODR",
|
||||||
|
Linkage::WeakAny => "WeakAny",
|
||||||
|
Linkage::WeakODR => "WeakODR",
|
||||||
|
Linkage::Appending => "Appending",
|
||||||
|
Linkage::Internal => "Internal",
|
||||||
|
Linkage::Private => "Private",
|
||||||
|
Linkage::ExternalWeak => "ExternalWeak",
|
||||||
|
Linkage::Common => "Common",
|
||||||
|
};
|
||||||
|
|
||||||
|
output.push_str("[");
|
||||||
|
output.push_str(linkage_abbrev);
|
||||||
|
output.push_str("]");
|
||||||
|
}
|
||||||
|
output
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
item_keys.sort();
|
||||||
|
|
||||||
|
for item in item_keys {
|
||||||
|
println!("MONO_ITEM {}", item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(Arc::new(mono_items), Arc::new(codegen_units))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn provide(providers: &mut Providers) {
|
||||||
|
providers.collect_and_partition_mono_items =
|
||||||
|
collect_and_partition_mono_items;
|
||||||
|
|
||||||
|
providers.is_codegened_item = |tcx, def_id| {
|
||||||
|
let (all_mono_items, _) =
|
||||||
|
tcx.collect_and_partition_mono_items(LOCAL_CRATE);
|
||||||
|
all_mono_items.contains(&def_id)
|
||||||
|
};
|
||||||
|
|
||||||
|
providers.codegen_unit = |tcx, name| {
|
||||||
|
let (_, all) = tcx.collect_and_partition_mono_items(LOCAL_CRATE);
|
||||||
|
all.iter()
|
||||||
|
.find(|cgu| *cgu.name() == name)
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_else(|| panic!("failed to find cgu with name {:?}", name))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue