about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2020-03-26 21:44:02 +0100
committerGitHub <noreply@github.com>2020-03-26 21:44:02 +0100
commitb15423e72e48125a40a3192c2d49a48e54b5c314 (patch)
tree725261bda9e658628eaf547101c73a8e18806687
parent2fbb07525e2f07a815e780a4268b11916248b5a9 (diff)
parenta50cca920d06b831ce0a54e958d1e4e4dfcc350b (diff)
downloadrust-b15423e72e48125a40a3192c2d49a48e54b5c314.tar.gz
rust-b15423e72e48125a40a3192c2d49a48e54b5c314.zip
Rollup merge of #70384 - nnethercote:refactor-object-file-handling, r=alexcrichton
Refactor object file handling

Some preliminary clean-ups that grease the path to #66961.

r? @alexcrichton
-rw-r--r--src/librustc_codegen_llvm/back/write.rs87
-rw-r--r--src/librustc_codegen_ssa/back/write.rs82
-rw-r--r--src/librustc_target/spec/mod.rs6
3 files changed, 96 insertions, 79 deletions
diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs
index 5759eb2991a..1557630fc7a 100644
--- a/src/librustc_codegen_llvm/back/write.rs
+++ b/src/librustc_codegen_llvm/back/write.rs
@@ -16,7 +16,9 @@ use crate::ModuleLlvm;
 use log::debug;
 use rustc::bug;
 use rustc::ty::TyCtxt;
-use rustc_codegen_ssa::back::write::{run_assembler, CodegenContext, EmbedBitcode, ModuleConfig};
+use rustc_codegen_ssa::back::write::{
+    run_assembler, BitcodeSection, CodegenContext, EmitObj, ModuleConfig,
+};
 use rustc_codegen_ssa::traits::*;
 use rustc_codegen_ssa::{CompiledModule, ModuleCodegen, RLIB_BYTECODE_EXTENSION};
 use rustc_data_structures::small_c_str::SmallCStr;
@@ -651,7 +653,7 @@ pub(crate) unsafe fn codegen(
             let thin = ThinBuffer::new(llmod);
             let data = thin.data();
 
-            if config.emit_bc || config.obj_is_bitcode {
+            if config.emit_bc || config.emit_obj == EmitObj::Bitcode {
                 let _timer = cgcx.prof.generic_activity_with_arg(
                     "LLVM_module_codegen_emit_bitcode",
                     &module.name[..],
@@ -662,7 +664,7 @@ pub(crate) unsafe fn codegen(
                 }
             }
 
-            if config.embed_bitcode == EmbedBitcode::Full {
+            if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full) {
                 let _timer = cgcx.prof.generic_activity_with_arg(
                     "LLVM_module_codegen_embed_bitcode",
                     &module.name[..],
@@ -682,7 +684,7 @@ pub(crate) unsafe fn codegen(
                     diag_handler.err(&msg);
                 }
             }
-        } else if config.embed_bitcode == EmbedBitcode::Marker {
+        } else if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Marker) {
             embed_bitcode(cgcx, llcx, llmod, None);
         }
 
@@ -732,9 +734,9 @@ pub(crate) unsafe fn codegen(
             })?;
         }
 
-        let config_emit_normal_obj = config.emit_obj && !config.obj_is_bitcode;
+        let config_emit_object_code = matches!(config.emit_obj, EmitObj::ObjectCode(_));
 
-        if config.emit_asm || (config_emit_normal_obj && config.no_integrated_as) {
+        if config.emit_asm || (config_emit_object_code && config.no_integrated_as) {
             let _timer = cgcx
                 .prof
                 .generic_activity_with_arg("LLVM_module_codegen_emit_asm", &module.name[..]);
@@ -743,60 +745,65 @@ pub(crate) unsafe fn codegen(
             // We can't use the same module for asm and binary output, because that triggers
             // various errors like invalid IR or broken binaries, so we might have to clone the
             // module to produce the asm output
-            let llmod = if config.emit_obj { llvm::LLVMCloneModule(llmod) } else { llmod };
+            let llmod = if config_emit_object_code { llvm::LLVMCloneModule(llmod) } else { llmod };
             with_codegen(tm, llmod, config.no_builtins, |cpm| {
                 write_output_file(diag_handler, tm, cpm, llmod, &path, llvm::FileType::AssemblyFile)
             })?;
         }
 
-        if config_emit_normal_obj {
-            if !config.no_integrated_as {
-                let _timer = cgcx
-                    .prof
-                    .generic_activity_with_arg("LLVM_module_codegen_emit_obj", &module.name[..]);
-                with_codegen(tm, llmod, config.no_builtins, |cpm| {
-                    write_output_file(
-                        diag_handler,
-                        tm,
-                        cpm,
-                        llmod,
-                        &obj_out,
-                        llvm::FileType::ObjectFile,
-                    )
-                })?;
-            } else {
-                let _timer = cgcx
-                    .prof
-                    .generic_activity_with_arg("LLVM_module_codegen_asm_to_obj", &module.name[..]);
-                let assembly = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name);
-                run_assembler(cgcx, diag_handler, &assembly, &obj_out);
-
-                if !config.emit_asm && !cgcx.save_temps {
-                    drop(fs::remove_file(&assembly));
+        match config.emit_obj {
+            EmitObj::ObjectCode(_) => {
+                if !config.no_integrated_as {
+                    let _timer = cgcx.prof.generic_activity_with_arg(
+                        "LLVM_module_codegen_emit_obj",
+                        &module.name[..],
+                    );
+                    with_codegen(tm, llmod, config.no_builtins, |cpm| {
+                        write_output_file(
+                            diag_handler,
+                            tm,
+                            cpm,
+                            llmod,
+                            &obj_out,
+                            llvm::FileType::ObjectFile,
+                        )
+                    })?;
+                } else {
+                    let _timer = cgcx.prof.generic_activity_with_arg(
+                        "LLVM_module_codegen_asm_to_obj",
+                        &module.name[..],
+                    );
+                    let assembly =
+                        cgcx.output_filenames.temp_path(OutputType::Assembly, module_name);
+                    run_assembler(cgcx, diag_handler, &assembly, &obj_out);
+
+                    if !config.emit_asm && !cgcx.save_temps {
+                        drop(fs::remove_file(&assembly));
+                    }
                 }
             }
-        }
 
-        if config.obj_is_bitcode {
-            if config.emit_obj {
+            EmitObj::Bitcode => {
                 debug!("copying bitcode {:?} to obj {:?}", bc_out, obj_out);
                 if let Err(e) = link_or_copy(&bc_out, &obj_out) {
                     diag_handler.err(&format!("failed to copy bitcode to object file: {}", e));
                 }
-            }
 
-            if !config.emit_bc {
-                debug!("removing_bitcode {:?}", bc_out);
-                if let Err(e) = fs::remove_file(&bc_out) {
-                    diag_handler.err(&format!("failed to remove bitcode: {}", e));
+                if !config.emit_bc {
+                    debug!("removing_bitcode {:?}", bc_out);
+                    if let Err(e) = fs::remove_file(&bc_out) {
+                        diag_handler.err(&format!("failed to remove bitcode: {}", e));
+                    }
                 }
             }
+
+            EmitObj::None => {}
         }
 
         drop(handlers);
     }
     Ok(module.into_compiled_module(
-        config.emit_obj,
+        config.emit_obj != EmitObj::None,
         config.emit_bc,
         config.emit_bc_compressed,
         &cgcx.output_filenames,
diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs
index a4b5acdcd18..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,17 +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.target.target.options.embed_bitcode || 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
@@ -194,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)
     }
 }
 
@@ -397,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 =
@@ -416,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 => {}
@@ -880,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);
 
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index 6e5111bd701..6d688c12977 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -771,9 +771,6 @@ pub struct TargetOptions {
     /// rather than "default"
     pub default_hidden_visibility: bool,
 
-    /// Whether or not bitcode is embedded in object files
-    pub embed_bitcode: bool,
-
     /// Whether a .debug_gdb_scripts section will be added to the output object file
     pub emit_debug_gdb_scripts: bool,
 
@@ -893,7 +890,6 @@ impl Default for TargetOptions {
             no_builtins: false,
             codegen_backend: "llvm".to_string(),
             default_hidden_visibility: false,
-            embed_bitcode: false,
             emit_debug_gdb_scripts: true,
             requires_uwtable: false,
             simd_types_indirect: true,
@@ -1208,7 +1204,6 @@ impl Target {
         key!(no_builtins, bool);
         key!(codegen_backend);
         key!(default_hidden_visibility, bool);
-        key!(embed_bitcode, bool);
         key!(emit_debug_gdb_scripts, bool);
         key!(requires_uwtable, bool);
         key!(simd_types_indirect, bool);
@@ -1437,7 +1432,6 @@ impl ToJson for Target {
         target_option_val!(no_builtins);
         target_option_val!(codegen_backend);
         target_option_val!(default_hidden_visibility);
-        target_option_val!(embed_bitcode);
         target_option_val!(emit_debug_gdb_scripts);
         target_option_val!(requires_uwtable);
         target_option_val!(simd_types_indirect);