about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-11-04 12:20:55 +0000
committerbors <bors@rust-lang.org>2018-11-04 12:20:55 +0000
commitac708826b0d97e105f91a4cde41bfe14cff032f2 (patch)
tree8c8cc81d722920ada33dc5e97d1ad7d2bd3d6512
parent86b88e6a85f4c532c58cdcdabf6050c6170628e0 (diff)
parent9e479c2818eac337657c52791b12955002582dfd (diff)
downloadrust-ac708826b0d97e105f91a4cde41bfe14cff032f2.tar.gz
rust-ac708826b0d97e105f91a4cde41bfe14cff032f2.zip
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
-rw-r--r--src/Cargo.lock14
-rw-r--r--src/librustc_codegen_llvm/back/archive.rs24
-rw-r--r--src/librustc_codegen_llvm/back/link.rs7
-rw-r--r--src/librustc_codegen_llvm/back/lto.rs2
-rw-r--r--src/librustc_codegen_llvm/back/write.rs6
-rw-r--r--src/librustc_codegen_llvm/base.rs155
-rw-r--r--src/librustc_codegen_llvm/lib.rs34
-rw-r--r--src/librustc_codegen_utils/Cargo.toml4
-rw-r--r--src/librustc_codegen_utils/command.rs (renamed from src/librustc_codegen_llvm/back/command.rs)0
-rw-r--r--src/librustc_codegen_utils/lib.rs49
-rw-r--r--src/librustc_codegen_utils/link.rs3
-rw-r--r--src/librustc_codegen_utils/linker.rs (renamed from src/librustc_codegen_llvm/back/linker.rs)27
-rw-r--r--src/librustc_codegen_utils/symbol_export.rs (renamed from src/librustc_codegen_llvm/back/symbol_export.rs)2
-rw-r--r--src/librustc_metadata/Cargo.toml1
-rw-r--r--src/librustc_metadata/creader.rs4
-rw-r--r--src/librustc_metadata/lib.rs31
-rw-r--r--src/librustc_metadata_utils/Cargo.toml14
-rw-r--r--src/librustc_metadata_utils/lib.rs42
-rw-r--r--src/librustc_mir/lib.rs1
-rw-r--r--src/librustc_mir/monomorphize/partitioning.rs163
20 files changed, 280 insertions, 303 deletions
diff --git a/src/Cargo.lock b/src/Cargo.lock
index 2b00cde7f19..b4317864502 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -2141,11 +2141,13 @@ dependencies = [
  "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)",
  "rustc 0.0.0",
+ "rustc_allocator 0.0.0",
  "rustc_data_structures 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_target 0.0.0",
+ "serialize 0.0.0",
  "syntax 0.0.0",
  "syntax_pos 0.0.0",
 ]
@@ -2289,7 +2291,6 @@ dependencies = [
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
- "rustc_metadata_utils 0.0.0",
  "rustc_target 0.0.0",
  "serialize 0.0.0",
  "syntax 0.0.0",
@@ -2298,15 +2299,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "rustc_metadata_utils"
-version = "0.0.0"
-dependencies = [
- "rustc 0.0.0",
- "syntax 0.0.0",
- "syntax_pos 0.0.0",
-]
-
-[[package]]
 name = "rustc_mir"
 version = "0.0.0"
 dependencies = [
diff --git a/src/librustc_codegen_llvm/back/archive.rs b/src/librustc_codegen_llvm/back/archive.rs
index af9efc6d7c4..ce4cb1ea3a0 100644
--- a/src/librustc_codegen_llvm/back/archive.rs
+++ b/src/librustc_codegen_llvm/back/archive.rs
@@ -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 {
     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
     /// search in the relevant locations for a library named `name`.
     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.add_archive(&location, |_| false).unwrap_or_else(|e| {
             self.config.sess.fatal(&format!("failed to add native library {}: {}",
diff --git a/src/librustc_codegen_llvm/back/link.rs b/src/librustc_codegen_llvm/back/link.rs
index 86c6a5e65b0..dd95c3d9862 100644
--- a/src/librustc_codegen_llvm/back/link.rs
+++ b/src/librustc_codegen_llvm/back/link.rs
@@ -12,8 +12,6 @@ use back::wasm;
 use cc::windows_registry;
 use super::archive::{ArchiveBuilder, ArchiveConfig};
 use super::bytecode::RLIB_BYTECODE_EXTENSION;
-use super::linker::Linker;
-use super::command::Command;
 use super::rpath::RPathConfig;
 use super::rpath;
 use metadata::METADATA_FILENAME;
@@ -31,6 +29,8 @@ use rustc::hir::def_id::CrateNum;
 use tempfile::{Builder as TempFileBuilder, TempDir};
 use rustc_target::spec::{PanicStrategy, RelroLevel, LinkerFlavor};
 use rustc_data_structures::fx::FxHashSet;
+use rustc_codegen_utils::linker::Linker;
+use rustc_codegen_utils::command::Command;
 use context::get_reloc_model;
 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,
                   out_filename, codegen_results);
         cmd = linker.finalize();
diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs
index 61856236a14..8f940e0d22a 100644
--- a/src/librustc_codegen_llvm/back/lto.rs
+++ b/src/librustc_codegen_llvm/back/lto.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 use back::bytecode::{DecodedBytecode, RLIB_BYTECODE_EXTENSION};
-use back::symbol_export;
 use back::write::{ModuleConfig, with_llvm_pmb, CodegenContext};
 use back::write::{self, DiagnosticHandlers, pre_lto_bitcode_filename};
 use errors::{FatalError, Handler};
@@ -24,6 +23,7 @@ use rustc::middle::exported_symbols::SymbolExportLevel;
 use rustc::session::config::{self, Lto};
 use rustc::util::common::time_ext;
 use rustc_data_structures::fx::FxHashMap;
+use rustc_codegen_utils::symbol_export;
 use time_graph::Timeline;
 use {ModuleCodegen, ModuleLlvm, ModuleKind};
 
diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs
index b5ed256cef6..a88ce69604b 100644
--- a/src/librustc_codegen_llvm/back/write.rs
+++ b/src/librustc_codegen_llvm/back/write.rs
@@ -12,9 +12,6 @@ use attributes;
 use back::bytecode::{self, RLIB_BYTECODE_EXTENSION};
 use back::lto::{self, ModuleBuffer, ThinBuffer, SerializedModule};
 use back::link::{self, get_linker, remove};
-use back::command::Command;
-use back::linker::LinkerInfo;
-use back::symbol_export::ExportedSymbols;
 use base;
 use consts;
 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_data_structures::small_c_str::SmallCStr;
 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::emitter::{Emitter};
 use syntax::attr;
diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs
index 876fa993e12..9736994fc07 100644
--- a/src/librustc_codegen_llvm/base.rs
+++ b/src/librustc_codegen_llvm/base.rs
@@ -54,7 +54,6 @@ use attributes;
 use builder::{Builder, MemFlags};
 use callee;
 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 common::{C_struct_in_context, C_array, val_ty};
 use consts;
@@ -64,13 +63,13 @@ use declare;
 use meth;
 use mir;
 use monomorphize::Instance;
-use monomorphize::partitioning::{self, PartitioningStrategy, CodegenUnit, CodegenUnitExt};
+use monomorphize::partitioning::{CodegenUnit, CodegenUnitExt};
 use rustc_codegen_utils::symbol_names_test;
 use time_graph;
-use mono_item::{MonoItem, BaseMonoItemExt, MonoItemExt};
+use mono_item::{MonoItem, MonoItemExt};
 use type_::Type;
 use type_of::LayoutLlvmExt;
-use rustc::util::nodemap::{FxHashMap, DefIdSet};
+use rustc::util::nodemap::FxHashMap;
 use CrateInfo;
 use rustc_data_structures::small_c_str::SmallCStr;
 use rustc_data_structures::sync::Lrc;
@@ -80,7 +79,6 @@ use std::cmp;
 use std::ffi::CString;
 use std::i32;
 use std::ops::{Deref, DerefMut};
-use std::sync::Arc;
 use std::sync::mpsc;
 use std::time::{Instant, Duration};
 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));
 }
 
-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 {
     pub fn new(tcx: TyCtxt) -> 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>,
                                   cgu_name: InternedString)
                                   -> Stats {
@@ -1318,24 +1188,7 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     }
 }
 
-pub fn provide(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) {
+pub fn provide_both(providers: &mut Providers) {
     providers.dllimport_foreign_items = |tcx, krate| {
         let module_map = tcx.foreign_modules(krate);
         let module_map = module_map.iter()
diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs
index 63a8ab077e5..5d9bae5412e 100644
--- a/src/librustc_codegen_llvm/lib.rs
+++ b/src/librustc_codegen_llvm/lib.rs
@@ -71,7 +71,6 @@ use back::bytecode::RLIB_BYTECODE_EXTENSION;
 
 pub use llvm_util::target_features;
 use std::any::Any;
-use std::path::{PathBuf};
 use std::sync::mpsc;
 use rustc_data_structures::sync::Lrc;
 
@@ -87,20 +86,17 @@ use rustc::util::time_graph;
 use rustc::util::nodemap::{FxHashSet, FxHashMap};
 use rustc::util::profiling::ProfileCategory;
 use rustc_mir::monomorphize;
+use rustc_codegen_utils::{CompiledModule, ModuleKind};
 use rustc_codegen_utils::codegen_backend::CodegenBackend;
 use rustc_data_structures::svh::Svh;
 
 mod diagnostics;
 
 mod back {
-    pub use rustc_codegen_utils::symbol_names;
     mod archive;
     pub mod bytecode;
-    mod command;
-    pub mod linker;
     pub mod link;
     pub mod lto;
-    pub mod symbol_export;
     pub mod write;
     mod rpath;
     pub mod wasm;
@@ -194,15 +190,15 @@ impl CodegenBackend for LlvmCodegenBackend {
     }
 
     fn provide(&self, providers: &mut ty::query::Providers) {
-        back::symbol_names::provide(providers);
-        back::symbol_export::provide(providers);
-        base::provide(providers);
+        rustc_codegen_utils::symbol_export::provide(providers);
+        rustc_codegen_utils::symbol_names::provide(providers);
+        base::provide_both(providers);
         attributes::provide(providers);
     }
 
     fn provide_extern(&self, providers: &mut ty::query::Providers) {
-        back::symbol_export::provide_extern(providers);
-        base::provide_extern(providers);
+        rustc_codegen_utils::symbol_export::provide_extern(providers);
+        base::provide_both(providers);
         attributes::provide_extern(providers);
     }
 
@@ -281,13 +277,6 @@ struct CachedModuleCodegen {
     source: WorkProduct,
 }
 
-#[derive(Copy, Clone, Debug, PartialEq)]
-enum ModuleKind {
-    Regular,
-    Metadata,
-    Allocator,
-}
-
 impl ModuleCodegen {
     fn into_compiled_module(self,
                             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 {
     llcx: &'static mut llvm::Context,
     llmod_raw: *const llvm::Module,
@@ -377,7 +357,7 @@ struct CodegenResults {
     crate_hash: Svh,
     metadata: rustc::middle::cstore::EncodedMetadata,
     windows_subsystem: Option<String>,
-    linker_info: back::linker::LinkerInfo,
+    linker_info: rustc_codegen_utils::linker::LinkerInfo,
     crate_info: CrateInfo,
 }
 
diff --git a/src/librustc_codegen_utils/Cargo.toml b/src/librustc_codegen_utils/Cargo.toml
index a1f4a323f84..4c57e978414 100644
--- a/src/librustc_codegen_utils/Cargo.toml
+++ b/src/librustc_codegen_utils/Cargo.toml
@@ -13,11 +13,13 @@ test = false
 flate2 = "1.0"
 log = "0.4"
 
+serialize = { path = "../libserialize" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
 rustc = { path = "../librustc" }
+rustc_allocator = { path = "../librustc_allocator" }
 rustc_target = { path = "../librustc_target" }
 rustc_data_structures = { path = "../librustc_data_structures" }
+rustc_metadata = { path = "../librustc_metadata" }
 rustc_mir = { path = "../librustc_mir" }
 rustc_incremental = { path = "../librustc_incremental" }
-rustc_metadata_utils = { path = "../librustc_metadata_utils" }
diff --git a/src/librustc_codegen_llvm/back/command.rs b/src/librustc_codegen_utils/command.rs
index 9ebbdd7c3c9..9ebbdd7c3c9 100644
--- a/src/librustc_codegen_llvm/back/command.rs
+++ b/src/librustc_codegen_utils/command.rs
diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs
index 03b3b20a4e7..f0ce1e9b0ef 100644
--- a/src/librustc_codegen_utils/lib.rs
+++ b/src/librustc_codegen_utils/lib.rs
@@ -30,20 +30,28 @@ extern crate flate2;
 #[macro_use]
 extern crate log;
 
+extern crate serialize;
 #[macro_use]
 extern crate rustc;
+extern crate rustc_allocator;
 extern crate rustc_target;
+extern crate rustc_metadata;
 extern crate rustc_mir;
 extern crate rustc_incremental;
 extern crate syntax;
 extern crate syntax_pos;
 #[macro_use] extern crate rustc_data_structures;
-extern crate rustc_metadata_utils;
 
+use std::path::PathBuf;
+
+use rustc::session::Session;
 use rustc::ty::TyCtxt;
 
+pub mod command;
 pub mod link;
+pub mod linker;
 pub mod codegen_backend;
+pub mod symbol_export;
 pub mod symbol_names;
 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 }
diff --git a/src/librustc_codegen_utils/link.rs b/src/librustc_codegen_utils/link.rs
index 66e98793f42..b11aa687326 100644
--- a/src/librustc_codegen_utils/link.rs
+++ b/src/librustc_codegen_utils/link.rs
@@ -13,7 +13,6 @@ use rustc::session::Session;
 use std::path::{Path, PathBuf};
 use syntax::{ast, attr};
 use syntax_pos::Span;
-use rustc_metadata_utils::validate_crate_name;
 
 pub fn out_filename(sess: &Session,
                 crate_type: config::CrateType,
@@ -52,7 +51,7 @@ pub fn find_crate_name(sess: Option<&Session>,
                        attrs: &[ast::Attribute],
                        input: &Input) -> String {
     let validate = |s: String, span: Option<Span>| {
-        validate_crate_name(sess, &s, span);
+        ::rustc_metadata::validate_crate_name(sess, &s, span);
         s
     };
 
diff --git a/src/librustc_codegen_llvm/back/linker.rs b/src/librustc_codegen_utils/linker.rs
index e18c8b9dec4..c1f41fd509a 100644
--- a/src/librustc_codegen_llvm/back/linker.rs
+++ b/src/librustc_codegen_utils/linker.rs
@@ -15,9 +15,7 @@ use std::io::prelude::*;
 use std::io::{self, BufWriter};
 use std::path::{Path, PathBuf};
 
-use back::archive;
-use back::command::Command;
-use back::symbol_export;
+use command::Command;
 use rustc::hir::def_id::{LOCAL_CRATE, CrateNum};
 use rustc::middle::dependency_format::Linkage;
 use rustc::session::Session;
@@ -26,7 +24,6 @@ use rustc::session::config::{self, CrateType, OptLevel, DebugInfo,
 use rustc::ty::TyCtxt;
 use rustc_target::spec::{LinkerFlavor, LldFlavor};
 use serialize::{json, Encoder};
-use llvm_util;
 
 /// For all the linkers we support, and information they might
 /// 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,
-                         cmd: Command,
-                         sess: &'a Session,
-                         flavor: LinkerFlavor) -> Box<dyn Linker+'a> {
+    pub fn to_linker<'a>(
+        &'a self,
+        cmd: Command,
+        sess: &'a Session,
+        flavor: LinkerFlavor,
+        target_cpu: &'a str,
+    ) -> Box<dyn Linker+'a> {
         match flavor {
             LinkerFlavor::Lld(LldFlavor::Link) |
             LinkerFlavor::Msvc => {
@@ -70,6 +70,7 @@ impl LinkerInfo {
                     info: self,
                     hinted_static: false,
                     is_ld: false,
+                    target_cpu,
                 }) as Box<dyn Linker>
             }
 
@@ -82,6 +83,7 @@ impl LinkerInfo {
                     info: self,
                     hinted_static: false,
                     is_ld: true,
+                    target_cpu,
                 }) as Box<dyn Linker>
             }
 
@@ -144,6 +146,7 @@ pub struct GccLinker<'a> {
     hinted_static: bool, // Keeps track of the current hinting mode.
     // Link as ld
     is_ld: bool,
+    target_cpu: &'a str,
 }
 
 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=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() {
             config::Lto::Thin |
@@ -263,7 +267,7 @@ impl<'a> Linker for GccLinker<'a> {
             // -force_load is the macOS equivalent of --whole-archive, but it
             // involves passing the full path to the library to link.
             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);
         }
     }
@@ -898,7 +902,8 @@ impl<'a> Linker for EmLinker<'a> {
 fn exported_symbols(tcx: TyCtxt, crate_type: CrateType) -> Vec<String> {
     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() {
         if level.is_below_threshold(export_threshold) {
             symbols.push(symbol.symbol_name(tcx).to_string());
diff --git a/src/librustc_codegen_llvm/back/symbol_export.rs b/src/librustc_codegen_utils/symbol_export.rs
index 6b1b0b94fd9..2d650f7f18d 100644
--- a/src/librustc_codegen_llvm/back/symbol_export.rs
+++ b/src/librustc_codegen_utils/symbol_export.rs
@@ -11,7 +11,7 @@
 use rustc_data_structures::sync::Lrc;
 use std::sync::Arc;
 
-use monomorphize::Instance;
+use rustc::ty::Instance;
 use rustc::hir;
 use rustc::hir::Node;
 use rustc::hir::CodegenFnAttrFlags;
diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml
index 6142fe78149..338824d5efe 100644
--- a/src/librustc_metadata/Cargo.toml
+++ b/src/librustc_metadata/Cargo.toml
@@ -20,4 +20,3 @@ serialize = { path = "../libserialize" }
 syntax = { path = "../libsyntax" }
 syntax_ext = { path = "../libsyntax_ext" }
 syntax_pos = { path = "../libsyntax_pos" }
-rustc_metadata_utils = { path = "../librustc_metadata_utils" }
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index 4b96735eb77..7733ab2e246 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -30,8 +30,6 @@ use rustc::util::common::record_time;
 use rustc::util::nodemap::FxHashSet;
 use rustc::hir::map::Definitions;
 
-use rustc_metadata_utils::validate_crate_name;
-
 use std::ops::Deref;
 use std::path::PathBuf;
 use std::{cmp, fs};
@@ -1106,7 +1104,7 @@ impl<'a> CrateLoader<'a> {
                        item.ident, orig_name);
                 let orig_name = match 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));
                         orig_name
                     }
diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs
index 7008166b903..0cc0707a3a5 100644
--- a/src/librustc_metadata/lib.rs
+++ b/src/librustc_metadata/lib.rs
@@ -38,7 +38,6 @@ extern crate serialize as rustc_serialize; // used by deriving
 extern crate rustc_errors as errors;
 extern crate syntax_ext;
 extern crate proc_macro;
-extern crate rustc_metadata_utils;
 
 #[macro_use]
 extern crate rustc;
@@ -64,4 +63,34 @@ pub mod cstore;
 pub mod dynamic_lib;
 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 }
diff --git a/src/librustc_metadata_utils/Cargo.toml b/src/librustc_metadata_utils/Cargo.toml
deleted file mode 100644
index 4a5e20376bf..00000000000
--- a/src/librustc_metadata_utils/Cargo.toml
+++ /dev/null
@@ -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" }
diff --git a/src/librustc_metadata_utils/lib.rs b/src/librustc_metadata_utils/lib.rs
deleted file mode 100644
index a1e5150390a..00000000000
--- a/src/librustc_metadata_utils/lib.rs
+++ /dev/null
@@ -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();
-    }
-}
diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs
index 9c4b92aa274..1a35f4da20b 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -93,6 +93,7 @@ pub fn provide(providers: &mut Providers) {
     borrow_check::provide(providers);
     shim::provide(providers);
     transform::provide(providers);
+    monomorphize::partitioning::provide(providers);
     providers.const_eval = const_eval::const_eval_provider;
     providers.const_eval_raw = const_eval::const_eval_raw_provider;
     providers.check_match = hair::pattern::check_match;
diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs
index f0a35ca7adb..2c2bfc995e4 100644
--- a/src/librustc_mir/monomorphize/partitioning.rs
+++ b/src/librustc_mir/monomorphize/partitioning.rs
@@ -102,21 +102,27 @@
 //! source-level module, functions from the same module will be available for
 //! 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::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::mir::mono::{Linkage, Visibility, CodegenUnitNameBuilder};
 use rustc::middle::exported_symbols::SymbolExportLevel;
 use rustc::ty::{self, TyCtxt, InstanceDef};
 use rustc::ty::item_path::characteristic_def_id_of_type;
-use rustc::util::nodemap::{FxHashMap, FxHashSet};
-use std::collections::hash_map::Entry;
-use std::cmp;
-use syntax::ast::NodeId;
-use syntax::symbol::InternedString;
+use rustc::ty::query::Providers;
+use rustc::util::common::time;
+use rustc::util::nodemap::{DefIdSet, FxHashMap, FxHashSet};
 use rustc::mir::mono::MonoItem;
+
+use monomorphize::collector::InliningMap;
+use monomorphize::collector::{self, MonoItemCollectionMode};
 use monomorphize::item::{MonoItemExt, InstantiationMode};
 
 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))
+    };
+}