From 3fc09365468d30cd6570d3ce74b1a24d9e31d9f3 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Wed, 24 Apr 2019 09:08:25 +1000
Subject: [PATCH] Don't generate unnecessary rmeta files.

---
 src/librustc_codegen_ssa/back/link.rs  | 19 ++++++++++-------
 src/librustc_codegen_ssa/back/write.rs | 11 +++++-----
 src/librustc_codegen_ssa/base.rs       | 28 +++++++++++++++++---------
 src/librustc_codegen_ssa/lib.rs        |  2 +-
 4 files changed, 37 insertions(+), 23 deletions(-)

diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs
index 166234c83fca5..fe703ff4d25dd 100644
--- a/src/librustc_codegen_ssa/back/link.rs
+++ b/src/librustc_codegen_ssa/back/link.rs
@@ -83,14 +83,16 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(sess: &'a Session,
         for obj in codegen_results.modules.iter().filter_map(|m| m.bytecode_compressed.as_ref()) {
             remove(sess, obj);
         }
-        if let Some(ref obj) = codegen_results.metadata_module.object {
-            remove(sess, obj);
-        }
-        if let Some(ref allocator) = codegen_results.allocator_module {
-            if let Some(ref obj) = allocator.object {
+        if let Some(ref metadata_module) = codegen_results.metadata_module {
+            if let Some(ref obj) = metadata_module.object {
+                remove(sess, obj);
+            }
+         }
+        if let Some(ref allocator_module) = codegen_results.allocator_module {
+            if let Some(ref obj) = allocator_module.object {
                 remove(sess, obj);
             }
-            if let Some(ref bc) = allocator.bytecode_compressed {
+            if let Some(ref bc) = allocator_module.bytecode_compressed {
                 remove(sess, bc);
             }
         }
@@ -1067,7 +1069,10 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker,
     // object file, so we link that in here.
     if crate_type == config::CrateType::Dylib ||
        crate_type == config::CrateType::ProcMacro {
-        if let Some(obj) = codegen_results.metadata_module.object.as_ref() {
+        let obj = codegen_results.metadata_module
+            .as_ref()
+            .and_then(|m| m.object.as_ref());
+        if let Some(obj) = obj {
             cmd.add_object(obj);
         }
     }
diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs
index 4b02425d40d65..88a5e5a1aec3b 100644
--- a/src/librustc_codegen_ssa/back/write.rs
+++ b/src/librustc_codegen_ssa/back/write.rs
@@ -350,7 +350,7 @@ fn generate_lto_work<B: ExtraBackendMethods>(
 
 pub struct CompiledModules {
     pub modules: Vec<CompiledModule>,
-    pub metadata_module: CompiledModule,
+    pub metadata_module: Option<CompiledModule>,
     pub allocator_module: Option<CompiledModule>,
 }
 
@@ -682,8 +682,10 @@ fn produce_final_output_artifacts(sess: &Session,
         }
 
         if !user_wants_bitcode {
-            if let Some(ref path) = compiled_modules.metadata_module.bytecode {
-                remove(sess, &path);
+            if let Some(ref metadata_module) = compiled_modules.metadata_module {
+                if let Some(ref path) = metadata_module.bytecode {
+                    remove(sess, &path);
+                }
             }
 
             if let Some(ref allocator_module) = compiled_modules.allocator_module {
@@ -1564,9 +1566,6 @@ fn start_executing_work<B: ExtraBackendMethods>(
         // out deterministic results.
         compiled_modules.sort_by(|a, b| a.name.cmp(&b.name));
 
-        let compiled_metadata_module = compiled_metadata_module
-            .expect("Metadata module not compiled?");
-
         Ok(CompiledModules {
             modules: compiled_modules,
             metadata_module: compiled_metadata_module,
diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs
index 6cb54831a0743..3046c069981cb 100644
--- a/src/librustc_codegen_ssa/base.rs
+++ b/src/librustc_codegen_ssa/base.rs
@@ -25,7 +25,7 @@ use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, VariantIdx, HasTyCtxt};
 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, EntryFnType, Lto};
+use rustc::session::config::{self, CrateType, EntryFnType, Lto};
 use rustc::session::Session;
 use rustc_mir::monomorphize::item::DefPathBasedNames;
 use rustc_mir::monomorphize::Instance;
@@ -550,12 +550,6 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
     });
     tcx.sess.profiler(|p| p.end_activity("codegen crate metadata"));
 
-    let metadata_module = ModuleCodegen {
-        name: metadata_cgu_name,
-        module_llvm: metadata_llvm_module,
-        kind: ModuleKind::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() {
@@ -566,7 +560,6 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
             rx,
             1);
 
-        ongoing_codegen.submit_pre_codegened_module_to_llvm(tcx, metadata_module);
         ongoing_codegen.codegen_finished(tcx);
 
         assert_and_save_dep_graph(tcx);
@@ -639,7 +632,24 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
         ongoing_codegen.submit_pre_codegened_module_to_llvm(tcx, allocator_module);
     }
 
-    ongoing_codegen.submit_pre_codegened_module_to_llvm(tcx, metadata_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 {
+        let metadata_module = ModuleCodegen {
+            name: metadata_cgu_name,
+            module_llvm: metadata_llvm_module,
+            kind: ModuleKind::Metadata,
+        };
+        ongoing_codegen.submit_pre_codegened_module_to_llvm(tcx, metadata_module);
+    }
 
     // We sort the codegen units by size. This way we can schedule work for LLVM
     // a bit more efficiently.
diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs
index 9d3d6ef854990..4d7af7a643b66 100644
--- a/src/librustc_codegen_ssa/lib.rs
+++ b/src/librustc_codegen_ssa/lib.rs
@@ -154,7 +154,7 @@ pub struct CodegenResults {
     pub crate_name: Symbol,
     pub modules: Vec<CompiledModule>,
     pub allocator_module: Option<CompiledModule>,
-    pub metadata_module: CompiledModule,
+    pub metadata_module: Option<CompiledModule>,
     pub crate_hash: Svh,
     pub metadata: rustc::middle::cstore::EncodedMetadata,
     pub windows_subsystem: Option<String>,