about summary refs log tree commit diff
path: root/src/librustc_codegen_ssa
diff options
context:
space:
mode:
authorNicholas Nethercote <nnethercote@mozilla.com>2020-03-24 12:24:52 +1100
committerNicholas Nethercote <nnethercote@mozilla.com>2020-03-26 13:49:02 +1100
commit87ef16c9dc7b4ebb46c1db3363e1a00586a819d8 (patch)
treee875b1c9e50b80e71c7def992292e79599018b80 /src/librustc_codegen_ssa
parente1d1db790fb3b2892bbe644c2d7ce1265352b0fd (diff)
downloadrust-87ef16c9dc7b4ebb46c1db3363e1a00586a819d8.tar.gz
rust-87ef16c9dc7b4ebb46c1db3363e1a00586a819d8.zip
Introduce `EmitObj`.
Currently, there are three fields in `ModuleConfig` that dictate
how object files are emitted: `emit_obj`, `obj_is_bitcode`, and
`embed_bitcode`.

Some of the combinations of these fields are nonsensical, in particular
having both `obj_is_bitcode` and `embed_bitcode` true at the same time.

Also, currently:
- we needlessly emit and then delete a bytecode file if `obj_is_bitcode`
  is true but `emit_obj` is false;
- we needlessly embed bitcode in the LLVM module if `embed_bitcode` is
  true and `emit_obj` is false.

This commit combines the three fields into one, with a new type
`EmitObj` (and the auxiliary `BitcodeSection`) which can encode five
different possibilities.

In the old code, `set_flags` would set `obj_is_bitcode` and
`embed_bitcode` on all three of the configs (`modules`, `allocator`,
`metadata`) if the relevant other conditions were met, even if no object
code needed to be emitted for one or more of them. Whereas
`start_async_codegen` would set `emit_obj`, but only for those configs
that need it.

In the new code, `start_async_codegen` does all the work of setting
`emit_obj`, and it only does that for the configs that need it.
`set_flags` no longer sets anything related to object file emission.
Diffstat (limited to 'src/librustc_codegen_ssa')
-rw-r--r--src/librustc_codegen_ssa/back/write.rs81
1 files changed, 49 insertions, 32 deletions
diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs
index 3a2ff24edb4..e9b3bf026b2 100644
--- a/src/librustc_codegen_ssa/back/write.rs
+++ b/src/librustc_codegen_ssa/back/write.rs
@@ -51,11 +51,31 @@ use std::thread;
 
 const PRE_LTO_BC_EXT: &str = "pre-lto.bc";
 
-/// The kind of bitcode to embed in object files.
-#[derive(PartialEq)]
-pub enum EmbedBitcode {
+/// What kind of object file to emit.
+#[derive(Clone, Copy, PartialEq)]
+pub enum EmitObj {
+    // No object file.
     None,
+
+    // Just uncompressed llvm bitcode. Provides easy compatibility with
+    // emscripten's ecc compiler, when used as the linker.
+    Bitcode,
+
+    // Object code, possibly augmented with a bitcode section.
+    ObjectCode(BitcodeSection),
+}
+
+/// What kind of llvm bitcode section to embed in an object file.
+#[derive(Clone, Copy, PartialEq)]
+pub enum BitcodeSection {
+    // No bitcode section.
+    None,
+
+    // An empty bitcode section (to placate tools such as the iOS linker that
+    // require this section even if they don't use it).
     Marker,
+
+    // A full, uncompressed bitcode section.
     Full,
 }
 
@@ -84,7 +104,7 @@ pub struct ModuleConfig {
     pub emit_bc_compressed: bool,
     pub emit_ir: bool,
     pub emit_asm: bool,
-    pub emit_obj: bool,
+    pub emit_obj: EmitObj,
     // Miscellaneous flags.  These are mostly copied from command-line
     // options.
     pub verify_llvm_ir: bool,
@@ -96,12 +116,7 @@ pub struct ModuleConfig {
     pub merge_functions: bool,
     pub inline_threshold: Option<usize>,
     pub new_llvm_pass_manager: Option<bool>,
-    // Instead of creating an object file by doing LLVM codegen, just
-    // make the object file bitcode. Provides easy compatibility with
-    // emscripten's ecc compiler, when used as the linker.
-    pub obj_is_bitcode: bool,
     pub no_integrated_as: bool,
-    pub embed_bitcode: EmbedBitcode,
 }
 
 impl ModuleConfig {
@@ -124,9 +139,7 @@ impl ModuleConfig {
             emit_bc_compressed: false,
             emit_ir: false,
             emit_asm: false,
-            emit_obj: false,
-            obj_is_bitcode: false,
-            embed_bitcode: EmbedBitcode::None,
+            emit_obj: EmitObj::None,
             no_integrated_as: false,
 
             verify_llvm_ir: false,
@@ -147,16 +160,6 @@ impl ModuleConfig {
         self.no_builtins = no_builtins || sess.target.target.options.no_builtins;
         self.inline_threshold = sess.opts.cg.inline_threshold;
         self.new_llvm_pass_manager = sess.opts.debugging_opts.new_llvm_pass_manager;
-        self.obj_is_bitcode =
-            sess.target.target.options.obj_is_bitcode || sess.opts.cg.linker_plugin_lto.enabled();
-        self.embed_bitcode = if sess.opts.debugging_opts.embed_bitcode {
-            match sess.opts.optimize {
-                config::OptLevel::No | config::OptLevel::Less => EmbedBitcode::Marker,
-                _ => EmbedBitcode::Full,
-            }
-        } else {
-            EmbedBitcode::None
-        };
 
         // Copy what clang does by turning on loop vectorization at O2 and
         // slp vectorization at O3. Otherwise configure other optimization aspects
@@ -193,9 +196,9 @@ impl ModuleConfig {
 
     pub fn bitcode_needed(&self) -> bool {
         self.emit_bc
-            || self.obj_is_bitcode
             || self.emit_bc_compressed
-            || self.embed_bitcode == EmbedBitcode::Full
+            || self.emit_obj == EmitObj::Bitcode
+            || self.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full)
     }
 }
 
@@ -396,6 +399,20 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
         allocator_config.emit_bc_compressed = true;
     }
 
+    let emit_obj =
+        if sess.target.target.options.obj_is_bitcode || sess.opts.cg.linker_plugin_lto.enabled() {
+            EmitObj::Bitcode
+        } else if sess.opts.debugging_opts.embed_bitcode {
+            match sess.opts.optimize {
+                config::OptLevel::No | config::OptLevel::Less => {
+                    EmitObj::ObjectCode(BitcodeSection::Marker)
+                }
+                _ => EmitObj::ObjectCode(BitcodeSection::Full),
+            }
+        } else {
+            EmitObj::ObjectCode(BitcodeSection::None)
+        };
+
     modules_config.emit_pre_lto_bc = need_pre_lto_bitcode_for_incr_comp(sess);
 
     modules_config.no_integrated_as =
@@ -415,20 +432,20 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
                 // could be invoked specially with output_type_assembly, so
                 // in this case we still want the metadata object file.
                 if !sess.opts.output_types.contains_key(&OutputType::Assembly) {
-                    metadata_config.emit_obj = true;
-                    allocator_config.emit_obj = true;
+                    metadata_config.emit_obj = emit_obj;
+                    allocator_config.emit_obj = emit_obj;
                 }
             }
             OutputType::Object => {
-                modules_config.emit_obj = true;
+                modules_config.emit_obj = emit_obj;
             }
             OutputType::Metadata => {
-                metadata_config.emit_obj = true;
+                metadata_config.emit_obj = emit_obj;
             }
             OutputType::Exe => {
-                modules_config.emit_obj = true;
-                metadata_config.emit_obj = true;
-                allocator_config.emit_obj = true;
+                modules_config.emit_obj = emit_obj;
+                metadata_config.emit_obj = emit_obj;
+                allocator_config.emit_obj = emit_obj;
             }
             OutputType::Mir => {}
             OutputType::DepInfo => {}
@@ -879,7 +896,7 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
         }
     }
 
-    assert_eq!(object.is_some(), module_config.emit_obj);
+    assert_eq!(object.is_some(), module_config.emit_obj != EmitObj::None);
     assert_eq!(bytecode.is_some(), module_config.emit_bc);
     assert_eq!(bytecode_compressed.is_some(), module_config.emit_bc_compressed);