]> git.lizzy.rs Git - rust.git/commitdiff
Move metadata encoding earlier.
authorNicholas Nethercote <nnethercote@mozilla.com>
Fri, 26 Apr 2019 07:22:36 +0000 (17:22 +1000)
committerNicholas Nethercote <nnethercote@mozilla.com>
Tue, 30 Apr 2019 04:55:10 +0000 (14:55 +1000)
This commit separates metadata encoding (`tcx.encode_metadata`) from the
creation of the metadata module (which is now handled by
`write_compressed_metadata`, formerly `write_metadata`).

The metadata encoding now occurs slightly earlier in the pipeline, at
the very start of code generation within `start_codegen`.

Metadata *writing* still occurs near the end of compilation; that will
be moved forward in subsequent commits.

src/librustc_codegen_llvm/base.rs
src/librustc_codegen_llvm/lib.rs
src/librustc_codegen_ssa/base.rs
src/librustc_codegen_ssa/traits/backend.rs
src/librustc_codegen_utils/codegen_backend.rs
src/librustc_interface/passes.rs
src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs

index 7ea5e912309059dcc95cbed59a96c12320d0ab46..9077e89a4020eae8cc5b479ec13d83d6b1d89008 100644 (file)
@@ -28,7 +28,7 @@
 use rustc::middle::cstore::{EncodedMetadata};
 use rustc::ty::TyCtxt;
 use rustc::middle::exported_symbols;
-use rustc::session::config::{self, DebugInfo};
+use rustc::session::config::DebugInfo;
 use rustc_codegen_ssa::mono_item::MonoItemExt;
 use rustc_data_structures::small_c_str::SmallCStr;
 
 
 use crate::value::Value;
 
-
-pub fn write_metadata<'a, 'gcx>(
+pub fn write_compressed_metadata<'a, 'gcx>(
     tcx: TyCtxt<'a, 'gcx, 'gcx>,
+    metadata: &EncodedMetadata,
     llvm_module: &mut ModuleLlvm
-) -> EncodedMetadata {
+) {
     use std::io::Write;
     use flate2::Compression;
     use flate2::write::DeflateEncoder;
 
     let (metadata_llcx, metadata_llmod) = (&*llvm_module.llcx, llvm_module.llmod());
-
-    #[derive(PartialEq, Eq, PartialOrd, Ord)]
-    enum MetadataKind {
-        None,
-        Uncompressed,
-        Compressed
-    }
-
-    let kind = tcx.sess.crate_types.borrow().iter().map(|ty| {
-        match *ty {
-            config::CrateType::Executable |
-            config::CrateType::Staticlib |
-            config::CrateType::Cdylib => MetadataKind::None,
-
-            config::CrateType::Rlib => MetadataKind::Uncompressed,
-
-            config::CrateType::Dylib |
-            config::CrateType::ProcMacro => MetadataKind::Compressed,
-        }
-    }).max().unwrap_or(MetadataKind::None);
-
-    if kind == MetadataKind::None {
-        return EncodedMetadata::new();
-    }
-
-    let metadata = tcx.encode_metadata();
-    if kind == MetadataKind::Uncompressed {
-        return metadata;
-    }
-
-    assert!(kind == MetadataKind::Compressed);
     let mut compressed = tcx.metadata_encoding_version();
     DeflateEncoder::new(&mut compressed, Compression::fast())
         .write_all(&metadata.raw_data).unwrap();
@@ -107,7 +76,6 @@ enum MetadataKind {
         let directive = CString::new(directive).unwrap();
         llvm::LLVMSetModuleInlineAsm(metadata_llmod, directive.as_ptr())
     }
-    return metadata;
 }
 
 pub struct ValueIter<'ll> {
index 08424e7c3229acd10261b40cc6053a10e7edcdf4..09b284052b3c488414f140c4ec9ac96ab66de9d2 100644 (file)
@@ -110,12 +110,13 @@ fn new_metadata(&self, tcx: TyCtxt<'_, '_, '_>, mod_name: &str) -> ModuleLlvm {
         ModuleLlvm::new_metadata(tcx, mod_name)
     }
 
-    fn write_metadata<'b, 'gcx>(
+    fn write_compressed_metadata<'b, 'gcx>(
         &self,
         tcx: TyCtxt<'b, 'gcx, 'gcx>,
-        metadata: &mut ModuleLlvm
-    ) -> EncodedMetadata {
-        base::write_metadata(tcx, metadata)
+        metadata: &EncodedMetadata,
+        llvm_module: &mut ModuleLlvm
+    ) {
+        base::write_compressed_metadata(tcx, metadata, llvm_module)
     }
     fn codegen_allocator<'b, 'gcx>(
         &self,
@@ -289,9 +290,12 @@ fn provide_extern(&self, providers: &mut ty::query::Providers<'_>) {
     fn codegen_crate<'b, 'tcx>(
         &self,
         tcx: TyCtxt<'b, 'tcx, 'tcx>,
+        metadata: EncodedMetadata,
+        need_metadata_module: bool,
         rx: mpsc::Receiver<Box<dyn Any + Send>>
     ) -> Box<dyn Any> {
-        box rustc_codegen_ssa::base::codegen_crate(LlvmCodegenBackend(()), tcx, rx)
+        box rustc_codegen_ssa::base::codegen_crate(
+            LlvmCodegenBackend(()), tcx, metadata, need_metadata_module, rx)
     }
 
     fn join_codegen_and_link(
index 3046c069981cb31ae677c3b4ac0ea734343b7cd2..3cd47dfbb29fb7cf6387cecc36406e59999565b0 100644 (file)
@@ -17,6 +17,7 @@
 
 use rustc::dep_graph::cgu_reuse_tracker::CguReuse;
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
+use rustc::middle::cstore::EncodedMetadata;
 use rustc::middle::lang_items::StartFnLangItem;
 use rustc::middle::weak_lang_items;
 use rustc::mir::mono::{Stats, CodegenUnitNameBuilder};
@@ -25,7 +26,7 @@
 use rustc::ty::query::Providers;
 use rustc::middle::cstore::{self, LinkagePreference};
 use rustc::util::common::{time, print_time_passes_entry};
-use rustc::session::config::{self, CrateType, EntryFnType, Lto};
+use rustc::session::config::{self, EntryFnType, Lto};
 use rustc::session::Session;
 use rustc_mir::monomorphize::item::DefPathBasedNames;
 use rustc_mir::monomorphize::Instance;
@@ -530,26 +531,13 @@ fn create_entry_fn<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
 pub fn codegen_crate<B: ExtraBackendMethods>(
     backend: B,
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    metadata: EncodedMetadata,
+    need_metadata_module: bool,
     rx: mpsc::Receiver<Box<dyn Any + Send>>
 ) -> OngoingCodegen<B> {
 
     check_for_rustc_errors_attr(tcx);
 
-    let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx);
-
-    // Codegen the metadata.
-    tcx.sess.profiler(|p| p.start_activity("codegen crate metadata"));
-
-    let metadata_cgu_name = cgu_name_builder.build_cgu_name(LOCAL_CRATE,
-                                                            &["crate"],
-                                                            Some("metadata")).as_str()
-                                                                             .to_string();
-    let mut metadata_llvm_module = backend.new_metadata(tcx, &metadata_cgu_name);
-    let metadata = time(tcx.sess, "write metadata", || {
-        backend.write_metadata(tcx, &mut metadata_llvm_module)
-    });
-    tcx.sess.profiler(|p| p.end_activity("codegen crate metadata"));
-
     // Skip crate items and just output metadata in -Z no-codegen mode.
     if tcx.sess.opts.debugging_opts.no_codegen ||
        !tcx.sess.opts.output_types.should_codegen() {
@@ -569,6 +557,8 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
         return ongoing_codegen;
     }
 
+    let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx);
+
     // Run the monomorphization collector and partition the collected items into
     // codegen units.
     let codegen_units = tcx.collect_and_partition_mono_items(LOCAL_CRATE).1;
@@ -632,17 +622,21 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
         ongoing_codegen.submit_pre_codegened_module_to_llvm(tcx, allocator_module);
     }
 
-    let needs_metadata_module = tcx.sess.crate_types.borrow().iter().any(|ct| {
-        match *ct {
-            CrateType::Dylib |
-            CrateType::ProcMacro => true,
-            CrateType::Executable |
-            CrateType::Rlib |
-            CrateType::Staticlib |
-            CrateType::Cdylib => false,
-        }
-    });
-    if needs_metadata_module {
+    if need_metadata_module {
+        // Codegen the encoded metadata.
+        tcx.sess.profiler(|p| p.start_activity("codegen crate metadata"));
+
+        let metadata_cgu_name = cgu_name_builder.build_cgu_name(LOCAL_CRATE,
+                                                                &["crate"],
+                                                                Some("metadata")).as_str()
+                                                                                 .to_string();
+        let mut metadata_llvm_module = backend.new_metadata(tcx, &metadata_cgu_name);
+        time(tcx.sess, "write compressed metadata", || {
+            backend.write_compressed_metadata(tcx, &ongoing_codegen.metadata,
+                                              &mut metadata_llvm_module);
+        });
+        tcx.sess.profiler(|p| p.end_activity("codegen crate metadata"));
+
         let metadata_module = ModuleCodegen {
             name: metadata_cgu_name,
             module_llvm: metadata_llvm_module,
index a9e0eadb198a86f1fedea63c7b47f3763a6ede4d..530eba516a6c0c4a00094498a47424482809700d 100644 (file)
@@ -33,11 +33,12 @@ impl<'tcx, T> Backend<'tcx> for T where
 
 pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Send {
     fn new_metadata(&self, sess: TyCtxt<'_, '_, '_>, mod_name: &str) -> Self::Module;
-    fn write_metadata<'b, 'gcx>(
+    fn write_compressed_metadata<'b, 'gcx>(
         &self,
         tcx: TyCtxt<'b, 'gcx, 'gcx>,
-        metadata: &mut Self::Module,
-    ) -> EncodedMetadata;
+        metadata: &EncodedMetadata,
+        llvm_module: &mut Self::Module,
+    );
     fn codegen_allocator<'b, 'gcx>(
         &self,
         tcx: TyCtxt<'b, 'gcx, 'gcx>,
index 56eaffb1ca31dcad88a669c06b42548367b98fbe..191c6605b43ff4022e636c1fa6fe758ebcf15d35 100644 (file)
@@ -18,7 +18,7 @@
 use rustc::session::config::{OutputFilenames, PrintRequest};
 use rustc::ty::TyCtxt;
 use rustc::ty::query::Providers;
-use rustc::middle::cstore::MetadataLoader;
+use rustc::middle::cstore::{EncodedMetadata, MetadataLoader};
 use rustc::dep_graph::DepGraph;
 
 pub use rustc_data_structures::sync::MetadataRef;
@@ -37,6 +37,8 @@ fn diagnostics(&self) -> &[(&'static str, &'static str)] { &[] }
     fn codegen_crate<'a, 'tcx>(
         &self,
         tcx: TyCtxt<'a, 'tcx, 'tcx>,
+        metadata: EncodedMetadata,
+        need_metadata_module: bool,
         rx: mpsc::Receiver<Box<dyn Any + Send>>
     ) -> Box<dyn Any>;
 
index f8b1271b8b5c6b6a717a8fd08abe818429afda4b..38d641d2f60761994a8a964b3f1f4bd00b957882 100644 (file)
@@ -16,7 +16,7 @@
 use rustc::util::common::{time, ErrorReported};
 use rustc::util::profiling::ProfileCategory;
 use rustc::session::{CompileResult, CrateDisambiguator, Session};
-use rustc::session::config::{self, Input, OutputFilenames, OutputType};
+use rustc::session::config::{self, CrateType, Input, OutputFilenames, OutputType};
 use rustc::session::search_paths::PathKind;
 use rustc_allocator as allocator;
 use rustc_borrowck as borrowck;
@@ -999,6 +999,38 @@ fn analysis<'tcx>(
     Ok(())
 }
 
+fn encode_metadata<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> (middle::cstore::EncodedMetadata, bool) {
+    #[derive(PartialEq, Eq, PartialOrd, Ord)]
+    enum MetadataKind {
+        None,
+        Uncompressed,
+        Compressed
+    }
+
+    let metadata_kind = tcx.sess.crate_types.borrow().iter().map(|ty| {
+        match *ty {
+            CrateType::Executable |
+            CrateType::Staticlib |
+            CrateType::Cdylib => MetadataKind::None,
+
+            CrateType::Rlib => MetadataKind::Uncompressed,
+
+            CrateType::Dylib |
+            CrateType::ProcMacro => MetadataKind::Compressed,
+        }
+    }).max().unwrap_or(MetadataKind::None);
+
+    let need_metadata_module = metadata_kind == MetadataKind::Compressed;
+
+    let metadata = match metadata_kind {
+        MetadataKind::None => middle::cstore::EncodedMetadata::new(),
+        MetadataKind::Uncompressed |
+        MetadataKind::Compressed => tcx.encode_metadata(),
+    };
+
+    (metadata, need_metadata_module)
+}
+
 /// Runs the codegen backend, after which the AST and analysis can
 /// be discarded.
 pub fn start_codegen<'tcx>(
@@ -1013,11 +1045,17 @@ pub fn start_codegen<'tcx>(
     }
 
     time(tcx.sess, "resolving dependency formats", || {
-        ::rustc::middle::dependency_format::calculate(tcx)
+        middle::dependency_format::calculate(tcx)
+    });
+
+    let (metadata, need_metadata_module) = time(tcx.sess, "metadata encoding", || {
+        encode_metadata(tcx)
     });
 
     tcx.sess.profiler(|p| p.start_activity("codegen crate"));
-    let codegen = time(tcx.sess, "codegen", move || codegen_backend.codegen_crate(tcx, rx));
+    let codegen = time(tcx.sess, "codegen", move || {
+        codegen_backend.codegen_crate(tcx, metadata, need_metadata_module, rx)
+    });
     tcx.sess.profiler(|p| p.end_activity("codegen crate"));
 
     if log_enabled!(::log::Level::Info) {
index 5330470da16b038d218c4806dc73ac18fb2bc662..4e43aa96e1d853895e90754a9cd747a36fb83d12 100644 (file)
@@ -15,7 +15,7 @@
 use rustc::session::config::OutputFilenames;
 use rustc::ty::TyCtxt;
 use rustc::ty::query::Providers;
-use rustc::middle::cstore::MetadataLoader;
+use rustc::middle::cstore::{EncodedMetadata, MetadataLoader};
 use rustc::dep_graph::DepGraph;
 use rustc::util::common::ErrorReported;
 use rustc_codegen_utils::codegen_backend::CodegenBackend;
@@ -61,6 +61,8 @@ fn provide_extern(&self, providers: &mut Providers) {
     fn codegen_crate<'a, 'tcx>(
         &self,
         tcx: TyCtxt<'a, 'tcx, 'tcx>,
+        _metadata: EncodedMetadata,
+        _need_metadata_module: bool,
         _rx: mpsc::Receiver<Box<Any + Send>>
     ) -> Box<Any> {
         use rustc::hir::def_id::LOCAL_CRATE;