Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 1357af3

Browse files
committedApr 29, 2020
Auto merge of #71528 - alexcrichton:no-more-bitcode, r=nnethercote
Store LLVM bitcode in object files, not compressed This commit is an attempted resurrection of #70458 where LLVM bitcode emitted by rustc into rlibs is stored into object file sections rather than in a separate file. The main rationale for doing this is that when rustc emits bitcode it will no longer use a custom compression scheme which makes it both easier to interoperate with existing tools and also cuts down on compile time since this compression isn't happening. The blocker for this in #70458 turned out to be that native linkers didn't handle the new sections well, causing the sections to either trigger bugs in the linker or actually end up in the final linked artifact. This commit attempts to address these issues by ensuring that native linkers ignore the new sections by inserting custom flags with module-level inline assembly. Note that this does not currently change the API of the compiler at all. The pre-existing `-C bitcode-in-rlib` flag is co-opted to indicate whether the bitcode should be present in the object file or not. Finally, note that an important consequence of this commit, which is also one of its primary purposes, is to enable rustc's `-Clto` bitcode loading to load rlibs produced with `-Clinker-plugin-lto`. The goal here is that when you're building with LTO Cargo will tell rustc to skip codegen of all intermediate crates and only generate LLVM IR. Today rustc will generate both object code and LLVM IR, but the object code is later simply thrown away, wastefully.
2 parents fa51f81 + ef89cc8 commit 1357af3

File tree

18 files changed

+189
-266
lines changed

18 files changed

+189
-266
lines changed
 

‎src/doc/rustc/src/codegen-options/index.md

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,32 @@ a version of this list for your exact compiler by running `rustc -C help`.
77

88
This option is deprecated and does nothing.
99

10+
## bitcode-in-rlib
11+
12+
This flag controls whether or not the compiler puts LLVM bitcode into generated
13+
rlibs. It takes one of the following values:
14+
15+
* `y`, `yes`, `on`, or no value: put bitcode in rlibs (the default).
16+
* `n`, `no`, or `off`: omit bitcode from rlibs.
17+
18+
LLVM bitcode is only needed when link-time optimization (LTO) is being
19+
performed, but it is enabled by default for backwards compatibility reasons.
20+
21+
The use of `-C bitcode-in-rlib=no` can significantly improve compile times and
22+
reduce generated file sizes. For these reasons, Cargo uses `-C
23+
bitcode-in-rlib=no` whenever possible. Likewise, if you are building directly
24+
with `rustc` we recommend using `-C bitcode-in-rlib=no` whenever you are not
25+
using LTO.
26+
27+
If combined with `-C lto`, `-C bitcode-in-rlib=no` will cause `rustc` to abort
28+
at start-up, because the combination is invalid.
29+
30+
> **Note**: the implementation of this flag today is to enable the
31+
> `-Zembed-bitcode` option. When bitcode is embedded into an rlib then all
32+
> object files within the rlib will have a special section (typically named
33+
> `.llvmbc`, depends on the platform though) which contains LLVM bytecode. This
34+
> section of the object file will not appear in the final linked artifact.
35+
1036
## code-model
1137

1238
This option lets you choose which code model to use.
@@ -422,26 +448,6 @@ This also supports the feature `+crt-static` and `-crt-static` to control
422448
Each target and [`target-cpu`](#target-cpu) has a default set of enabled
423449
features.
424450

425-
## bitcode-in-rlib
426-
427-
This flag controls whether or not the compiler puts compressed LLVM bitcode
428-
into generated rlibs. It takes one of the following values:
429-
430-
* `y`, `yes`, `on`, or no value: put bitcode in rlibs (the default).
431-
* `n`, `no`, or `off`: omit bitcode from rlibs.
432-
433-
LLVM bitcode is only needed when link-time optimization (LTO) is being
434-
performed, but it is enabled by default for backwards compatibility reasons.
435-
436-
The use of `-C bitcode-in-rlib=no` can significantly improve compile times and
437-
reduce generated file sizes. For these reasons, Cargo uses `-C
438-
bitcode-in-rlib=no` whenever possible. Likewise, if you are building directly
439-
with `rustc` we recommend using `-C bitcode-in-rlib=no` whenever you are not
440-
using LTO.
441-
442-
If combined with `-C lto`, `-C bitcode-in-rlib=no` will cause `rustc` to abort
443-
at start-up, because the combination is invalid.
444-
445451
[option-emit]: ../command-line-arguments.md#option-emit
446452
[option-o-optimize]: ../command-line-arguments.md#option-o-optimize
447453
[profile-guided optimization]: ../profile-guided-optimization.md

‎src/librustc_codegen_llvm/back/archive.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::str;
1010
use crate::llvm::archive_ro::{ArchiveRO, Child};
1111
use crate::llvm::{self, ArchiveKind};
1212
use rustc_codegen_ssa::back::archive::{find_library, ArchiveBuilder};
13-
use rustc_codegen_ssa::{looks_like_rust_object_file, METADATA_FILENAME, RLIB_BYTECODE_EXTENSION};
13+
use rustc_codegen_ssa::{looks_like_rust_object_file, METADATA_FILENAME};
1414
use rustc_session::Session;
1515
use rustc_span::symbol::Symbol;
1616

@@ -129,8 +129,8 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
129129
let obj_start = name.to_owned();
130130

131131
self.add_archive(rlib, move |fname: &str| {
132-
// Ignore bytecode/metadata files, no matter the name.
133-
if fname.ends_with(RLIB_BYTECODE_EXTENSION) || fname == METADATA_FILENAME {
132+
// Ignore metadata files, no matter the name.
133+
if fname == METADATA_FILENAME {
134134
return true;
135135
}
136136

‎src/librustc_codegen_llvm/back/bytecode.rs

Lines changed: 0 additions & 141 deletions
This file was deleted.

‎src/librustc_codegen_llvm/back/lto.rs

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use crate::back::bytecode::DecodedBytecode;
21
use crate::back::write::{
32
self, save_temp_bitcode, to_llvm_opt_settings, with_llvm_pmb, DiagnosticHandlers,
43
};
@@ -10,7 +9,7 @@ use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModul
109
use rustc_codegen_ssa::back::symbol_export;
1110
use rustc_codegen_ssa::back::write::{CodegenContext, FatLTOInput, ModuleConfig};
1211
use rustc_codegen_ssa::traits::*;
13-
use rustc_codegen_ssa::{ModuleCodegen, ModuleKind, RLIB_BYTECODE_EXTENSION};
12+
use rustc_codegen_ssa::{looks_like_rust_object_file, ModuleCodegen, ModuleKind};
1413
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1514
use rustc_errors::{FatalError, Handler};
1615
use rustc_hir::def_id::LOCAL_CRATE;
@@ -111,29 +110,46 @@ fn prepare_lto(
111110
}
112111

113112
let archive = ArchiveRO::open(&path).expect("wanted an rlib");
114-
let bytecodes = archive
113+
let obj_files = archive
115114
.iter()
116115
.filter_map(|child| child.ok().and_then(|c| c.name().map(|name| (name, c))))
117-
.filter(|&(name, _)| name.ends_with(RLIB_BYTECODE_EXTENSION));
118-
for (name, data) in bytecodes {
119-
let _timer =
120-
cgcx.prof.generic_activity_with_arg("LLVM_lto_load_upstream_bitcode", name);
121-
info!("adding bytecode {}", name);
122-
let bc_encoded = data.data();
123-
124-
let (bc, id) = match DecodedBytecode::new(bc_encoded) {
125-
Ok(b) => Ok((b.bytecode(), b.identifier().to_string())),
126-
Err(e) => Err(diag_handler.fatal(&e)),
127-
}?;
128-
let bc = SerializedModule::FromRlib(bc);
129-
upstream_modules.push((bc, CString::new(id).unwrap()));
116+
.filter(|&(name, _)| looks_like_rust_object_file(name));
117+
for (name, child) in obj_files {
118+
info!("adding bitcode from {}", name);
119+
match get_bitcode_slice_from_object_data(child.data()) {
120+
Ok(data) => {
121+
let module = SerializedModule::FromRlib(data.to_vec());
122+
upstream_modules.push((module, CString::new(name).unwrap()));
123+
}
124+
Err(msg) => return Err(diag_handler.fatal(&msg)),
125+
}
130126
}
131127
}
132128
}
133129

134130
Ok((symbol_white_list, upstream_modules))
135131
}
136132

133+
fn get_bitcode_slice_from_object_data(obj: &[u8]) -> Result<&[u8], String> {
134+
let mut len = 0;
135+
let data =
136+
unsafe { llvm::LLVMRustGetBitcodeSliceFromObjectData(obj.as_ptr(), obj.len(), &mut len) };
137+
if !data.is_null() {
138+
assert!(len != 0);
139+
let bc = unsafe { slice::from_raw_parts(data, len) };
140+
141+
// `bc` must be a sub-slice of `obj`.
142+
assert!(obj.as_ptr() <= bc.as_ptr());
143+
assert!(bc[bc.len()..bc.len()].as_ptr() <= obj[obj.len()..obj.len()].as_ptr());
144+
145+
Ok(bc)
146+
} else {
147+
assert!(len == 0);
148+
let msg = llvm::last_error().unwrap_or_else(|| "unknown LLVM error".to_string());
149+
Err(format!("failed to get bitcode from object file for LTO ({})", msg))
150+
}
151+
}
152+
137153
/// Performs fat LTO by merging all modules into a single one and returning it
138154
/// for further optimization.
139155
pub(crate) fn run_fat(

‎src/librustc_codegen_llvm/back/write.rs

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use crate::attributes;
2-
use crate::back::bytecode;
32
use crate::back::lto::ThinBuffer;
43
use crate::back::profiling::{
54
selfprofile_after_pass_callback, selfprofile_before_pass_callback, LlvmSelfProfiler,
@@ -16,7 +15,7 @@ use crate::ModuleLlvm;
1615
use log::debug;
1716
use rustc_codegen_ssa::back::write::{BitcodeSection, CodegenContext, EmitObj, ModuleConfig};
1817
use rustc_codegen_ssa::traits::*;
19-
use rustc_codegen_ssa::{CompiledModule, ModuleCodegen, RLIB_BYTECODE_EXTENSION};
18+
use rustc_codegen_ssa::{CompiledModule, ModuleCodegen};
2019
use rustc_data_structures::small_c_str::SmallCStr;
2120
use rustc_errors::{FatalError, Handler};
2221
use rustc_fs_util::{link_or_copy, path_to_c_string};
@@ -654,19 +653,6 @@ pub(crate) unsafe fn codegen(
654653
);
655654
embed_bitcode(cgcx, llcx, llmod, Some(data));
656655
}
657-
658-
if config.emit_bc_compressed {
659-
let _timer = cgcx.prof.generic_activity_with_arg(
660-
"LLVM_module_codegen_emit_compressed_bitcode",
661-
&module.name[..],
662-
);
663-
let dst = bc_out.with_extension(RLIB_BYTECODE_EXTENSION);
664-
let data = bytecode::encode(&module.name, data);
665-
if let Err(e) = fs::write(&dst, data) {
666-
let msg = format!("failed to write bytecode to {}: {}", dst.display(), e);
667-
diag_handler.err(&msg);
668-
}
669-
}
670656
} else if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Marker) {
671657
embed_bitcode(cgcx, llcx, llmod, None);
672658
}
@@ -777,7 +763,6 @@ pub(crate) unsafe fn codegen(
777763
Ok(module.into_compiled_module(
778764
config.emit_obj != EmitObj::None,
779765
config.emit_bc,
780-
config.emit_bc_compressed,
781766
&cgcx.output_filenames,
782767
))
783768
}
@@ -832,6 +817,55 @@ unsafe fn embed_bitcode(
832817
let section = if is_apple { "__LLVM,__cmdline\0" } else { ".llvmcmd\0" };
833818
llvm::LLVMSetSection(llglobal, section.as_ptr().cast());
834819
llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage);
820+
821+
// We're adding custom sections to the output object file, but we definitely
822+
// do not want these custom sections to make their way into the final linked
823+
// executable. The purpose of these custom sections is for tooling
824+
// surrounding object files to work with the LLVM IR, if necessary. For
825+
// example rustc's own LTO will look for LLVM IR inside of the object file
826+
// in these sections by default.
827+
//
828+
// To handle this is a bit different depending on the object file format
829+
// used by the backend, broken down into a few different categories:
830+
//
831+
// * Mach-O - this is for macOS. Inspecting the source code for the native
832+
// linker here shows that the `.llvmbc` and `.llvmcmd` sections are
833+
// automatically skipped by the linker. In that case there's nothing extra
834+
// that we need to do here.
835+
//
836+
// * Wasm - the native LLD linker is hard-coded to skip `.llvmbc` and
837+
// `.llvmcmd` sections, so there's nothing extra we need to do.
838+
//
839+
// * COFF - if we don't do anything the linker will by default copy all
840+
// these sections to the output artifact, not what we want! To subvert
841+
// this we want to flag the sections we inserted here as
842+
// `IMAGE_SCN_LNK_REMOVE`. Unfortunately though LLVM has no native way to
843+
// do this. Thankfully though we can do this with some inline assembly,
844+
// which is easy enough to add via module-level global inline asm.
845+
//
846+
// * ELF - this is very similar to COFF above. One difference is that these
847+
// sections are removed from the output linked artifact when
848+
// `--gc-sections` is passed, which we pass by default. If that flag isn't
849+
// passed though then these sections will show up in the final output.
850+
// Additionally the flag that we need to set here is `SHF_EXCLUDE`.
851+
if is_apple
852+
|| cgcx.opts.target_triple.triple().starts_with("wasm")
853+
|| cgcx.opts.target_triple.triple().starts_with("asmjs")
854+
{
855+
// nothing to do here
856+
} else if cgcx.opts.target_triple.triple().contains("windows") {
857+
let asm = "
858+
.section .llvmbc,\"n\"
859+
.section .llvmcmd,\"n\"
860+
";
861+
llvm::LLVMRustAppendModuleInlineAsm(llmod, asm.as_ptr().cast(), asm.len());
862+
} else {
863+
let asm = "
864+
.section .llvmbc,\"e\"
865+
.section .llvmcmd,\"e\"
866+
";
867+
llvm::LLVMRustAppendModuleInlineAsm(llmod, asm.as_ptr().cast(), asm.len());
868+
}
835869
}
836870

837871
pub unsafe fn with_llvm_pmb(

‎src/librustc_codegen_llvm/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ use std::sync::Arc;
4040

4141
mod back {
4242
pub mod archive;
43-
pub mod bytecode;
4443
pub mod lto;
4544
mod profiling;
4645
pub mod write;

‎src/librustc_codegen_llvm/llvm/ffi.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2137,6 +2137,11 @@ extern "C" {
21372137
len: usize,
21382138
Identifier: *const c_char,
21392139
) -> Option<&Module>;
2140+
pub fn LLVMRustGetBitcodeSliceFromObjectData(
2141+
Data: *const u8,
2142+
len: usize,
2143+
out_len: &mut usize,
2144+
) -> *const u8;
21402145
pub fn LLVMRustThinLTOGetDICompileUnit(
21412146
M: &Module,
21422147
CU1: &mut *mut c_void,

‎src/librustc_codegen_ssa/back/link.rs

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,7 @@ use super::archive::ArchiveBuilder;
1818
use super::command::Command;
1919
use super::linker::Linker;
2020
use super::rpath::{self, RPathConfig};
21-
use crate::{
22-
looks_like_rust_object_file, CodegenResults, CrateInfo, METADATA_FILENAME,
23-
RLIB_BYTECODE_EXTENSION,
24-
};
21+
use crate::{looks_like_rust_object_file, CodegenResults, CrateInfo, METADATA_FILENAME};
2522

2623
use cc::windows_registry;
2724
use tempfile::{Builder as TempFileBuilder, TempDir};
@@ -130,10 +127,6 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
130127
remove(sess, obj);
131128
}
132129
}
133-
for obj in codegen_results.modules.iter().filter_map(|m| m.bytecode_compressed.as_ref())
134-
{
135-
remove(sess, obj);
136-
}
137130
if let Some(ref metadata_module) = codegen_results.metadata_module {
138131
if let Some(ref obj) = metadata_module.object {
139132
remove(sess, obj);
@@ -143,9 +136,6 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
143136
if let Some(ref obj) = allocator_module.object {
144137
remove(sess, obj);
145138
}
146-
if let Some(ref bc) = allocator_module.bytecode_compressed {
147-
remove(sess, bc);
148-
}
149139
}
150140
}
151141
});
@@ -378,14 +368,6 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(
378368
// contain the metadata in a separate file.
379369
ab.add_file(&emit_metadata(sess, &codegen_results.metadata, tmpdir));
380370

381-
// For LTO purposes, the bytecode of this library is also inserted
382-
// into the archive.
383-
for bytecode in
384-
codegen_results.modules.iter().filter_map(|m| m.bytecode_compressed.as_ref())
385-
{
386-
ab.add_file(bytecode);
387-
}
388-
389371
// After adding all files to the archive, we need to update the
390372
// symbol table of the archive. This currently dies on macOS (see
391373
// #11162), and isn't necessary there anyway
@@ -1829,7 +1811,7 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(
18291811

18301812
let mut any_objects = false;
18311813
for f in archive.src_files() {
1832-
if f.ends_with(RLIB_BYTECODE_EXTENSION) || f == METADATA_FILENAME {
1814+
if f == METADATA_FILENAME {
18331815
archive.remove_file(&f);
18341816
continue;
18351817
}

‎src/librustc_codegen_ssa/back/write.rs

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use super::symbol_export::symbol_name_for_instance_in_crate;
55

66
use crate::{
77
CachedModuleCodegen, CodegenResults, CompiledModule, CrateInfo, ModuleCodegen, ModuleKind,
8-
RLIB_BYTECODE_EXTENSION,
98
};
109

1110
use crate::traits::*;
@@ -100,7 +99,6 @@ pub struct ModuleConfig {
10099
pub emit_pre_lto_bc: bool,
101100
pub emit_no_opt_bc: bool,
102101
pub emit_bc: bool,
103-
pub emit_bc_compressed: bool,
104102
pub emit_ir: bool,
105103
pub emit_asm: bool,
106104
pub emit_obj: EmitObj,
@@ -150,9 +148,10 @@ impl ModuleConfig {
150148
|| sess.opts.cg.linker_plugin_lto.enabled()
151149
{
152150
EmitObj::Bitcode
153-
} else if sess.opts.debugging_opts.embed_bitcode {
151+
} else if sess.opts.debugging_opts.embed_bitcode || need_crate_bitcode_for_rlib(sess) {
152+
let force_full = need_crate_bitcode_for_rlib(sess);
154153
match sess.opts.optimize {
155-
config::OptLevel::No | config::OptLevel::Less => {
154+
config::OptLevel::No | config::OptLevel::Less if !force_full => {
156155
EmitObj::ObjectCode(BitcodeSection::Marker)
157156
}
158157
_ => EmitObj::ObjectCode(BitcodeSection::Full),
@@ -204,16 +203,6 @@ impl ModuleConfig {
204203
save_temps || sess.opts.output_types.contains_key(&OutputType::Bitcode),
205204
save_temps
206205
),
207-
emit_bc_compressed: match kind {
208-
ModuleKind::Regular | ModuleKind::Allocator => {
209-
// Emit compressed bitcode files for the crate if we're
210-
// emitting an rlib. Whenever an rlib is created, the
211-
// bitcode is inserted into the archive in order to allow
212-
// LTO against it.
213-
need_crate_bitcode_for_rlib(sess)
214-
}
215-
ModuleKind::Metadata => false,
216-
},
217206
emit_ir: if_regular!(
218207
sess.opts.output_types.contains_key(&OutputType::LlvmAssembly),
219208
false
@@ -269,7 +258,6 @@ impl ModuleConfig {
269258

270259
pub fn bitcode_needed(&self) -> bool {
271260
self.emit_bc
272-
|| self.emit_bc_compressed
273261
|| self.emit_obj == EmitObj::Bitcode
274262
|| self.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full)
275263
}
@@ -495,9 +483,6 @@ fn copy_all_cgu_workproducts_to_incr_comp_cache_dir(
495483
if let Some(ref path) = module.bytecode {
496484
files.push((WorkProductFileKind::Bytecode, path.clone()));
497485
}
498-
if let Some(ref path) = module.bytecode_compressed {
499-
files.push((WorkProductFileKind::BytecodeCompressed, path.clone()));
500-
}
501486

502487
if let Some((id, product)) =
503488
copy_cgu_workproducts_to_incr_comp_cache_dir(sess, &module.name, &files)
@@ -834,7 +819,6 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
834819
let incr_comp_session_dir = cgcx.incr_comp_session_dir.as_ref().unwrap();
835820
let mut object = None;
836821
let mut bytecode = None;
837-
let mut bytecode_compressed = None;
838822
for (kind, saved_file) in &module.source.saved_files {
839823
let obj_out = match kind {
840824
WorkProductFileKind::Object => {
@@ -847,14 +831,6 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
847831
bytecode = Some(path.clone());
848832
path
849833
}
850-
WorkProductFileKind::BytecodeCompressed => {
851-
let path = cgcx
852-
.output_filenames
853-
.temp_path(OutputType::Bitcode, Some(&module.name))
854-
.with_extension(RLIB_BYTECODE_EXTENSION);
855-
bytecode_compressed = Some(path.clone());
856-
path
857-
}
858834
};
859835
let source_file = in_incr_comp_dir(&incr_comp_session_dir, &saved_file);
860836
debug!(
@@ -876,14 +852,12 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
876852

877853
assert_eq!(object.is_some(), module_config.emit_obj != EmitObj::None);
878854
assert_eq!(bytecode.is_some(), module_config.emit_bc);
879-
assert_eq!(bytecode_compressed.is_some(), module_config.emit_bc_compressed);
880855

881856
Ok(WorkItemResult::Compiled(CompiledModule {
882857
name: module.name,
883858
kind: ModuleKind::Regular,
884859
object,
885860
bytecode,
886-
bytecode_compressed,
887861
}))
888862
}
889863

‎src/librustc_codegen_ssa/lib.rs

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -55,31 +55,18 @@ pub struct ModuleCodegen<M> {
5555

5656
// FIXME(eddyb) maybe include the crate name in this?
5757
pub const METADATA_FILENAME: &str = "lib.rmeta";
58-
pub const RLIB_BYTECODE_EXTENSION: &str = "bc.z";
5958

6059
impl<M> ModuleCodegen<M> {
6160
pub fn into_compiled_module(
6261
self,
6362
emit_obj: bool,
6463
emit_bc: bool,
65-
emit_bc_compressed: bool,
6664
outputs: &OutputFilenames,
6765
) -> CompiledModule {
6866
let object = emit_obj.then(|| outputs.temp_path(OutputType::Object, Some(&self.name)));
6967
let bytecode = emit_bc.then(|| outputs.temp_path(OutputType::Bitcode, Some(&self.name)));
70-
let bytecode_compressed = emit_bc_compressed.then(|| {
71-
outputs
72-
.temp_path(OutputType::Bitcode, Some(&self.name))
73-
.with_extension(RLIB_BYTECODE_EXTENSION)
74-
});
75-
76-
CompiledModule {
77-
name: self.name.clone(),
78-
kind: self.kind,
79-
object,
80-
bytecode,
81-
bytecode_compressed,
82-
}
68+
69+
CompiledModule { name: self.name.clone(), kind: self.kind, object, bytecode }
8370
}
8471
}
8572

@@ -89,7 +76,6 @@ pub struct CompiledModule {
8976
pub kind: ModuleKind,
9077
pub object: Option<PathBuf>,
9178
pub bytecode: Option<PathBuf>,
92-
pub bytecode_compressed: Option<PathBuf>,
9379
}
9480

9581
pub struct CachedModuleCodegen {

‎src/librustc_incremental/persist/work_product.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ pub fn copy_cgu_workproducts_to_incr_comp_cache_dir(
2121
let extension = match kind {
2222
WorkProductFileKind::Object => "o",
2323
WorkProductFileKind::Bytecode => "bc",
24-
WorkProductFileKind::BytecodeCompressed => "bc.z",
2524
};
2625
let file_name = format!("{}.{}", cgu_name, extension);
2726
let path_in_incr_dir = in_incr_comp_dir_sess(sess, &file_name);

‎src/librustc_query_system/dep_graph/graph.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -868,7 +868,6 @@ pub struct WorkProduct {
868868
pub enum WorkProductFileKind {
869869
Object,
870870
Bytecode,
871-
BytecodeCompressed,
872871
}
873872

874873
#[derive(Clone)]

‎src/rustllvm/PassWrapper.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include "llvm/IR/AssemblyAnnotationWriter.h"
1414
#include "llvm/IR/IntrinsicInst.h"
1515
#include "llvm/IR/Verifier.h"
16+
#include "llvm/Object/ObjectFile.h"
17+
#include "llvm/Object/IRObjectFile.h"
1618
#include "llvm/Passes/PassBuilder.h"
1719
#if LLVM_VERSION_GE(9, 0)
1820
#include "llvm/Passes/StandardInstrumentations.h"
@@ -1475,6 +1477,32 @@ LLVMRustParseBitcodeForLTO(LLVMContextRef Context,
14751477
return wrap(std::move(*SrcOrError).release());
14761478
}
14771479

1480+
// Find the bitcode section in the object file data and return it as a slice.
1481+
// Fail if the bitcode section is present but empty.
1482+
//
1483+
// On success, the return value is the pointer to the start of the slice and
1484+
// `out_len` is filled with the (non-zero) length. On failure, the return value
1485+
// is `nullptr` and `out_len` is set to zero.
1486+
extern "C" const char*
1487+
LLVMRustGetBitcodeSliceFromObjectData(const char *data,
1488+
size_t len,
1489+
size_t *out_len) {
1490+
*out_len = 0;
1491+
1492+
StringRef Data(data, len);
1493+
MemoryBufferRef Buffer(Data, ""); // The id is unused.
1494+
1495+
Expected<MemoryBufferRef> BitcodeOrError =
1496+
object::IRObjectFile::findBitcodeInMemBuffer(Buffer);
1497+
if (!BitcodeOrError) {
1498+
LLVMRustSetLastError(toString(BitcodeOrError.takeError()).c_str());
1499+
return nullptr;
1500+
}
1501+
1502+
*out_len = BitcodeOrError->getBufferSize();
1503+
return BitcodeOrError->getBufferStart();
1504+
}
1505+
14781506
// Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
14791507
// the comment in `back/lto.rs` for why this exists.
14801508
extern "C" void
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// compile-flags: -Clinker-plugin-lto
2+
// no-prefer-dynamic
3+
4+
#![crate_type = "rlib"]
5+
6+
pub fn foo() {}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
warning: Linking globals named 'foo': symbol multiply defined!
22

3-
error: failed to load bc of "lto_duplicate_symbols2.3a1fbbbh-cgu.0":
3+
error: failed to load bc of "lto-duplicate-symbols2.lto_duplicate_symbols2.3a1fbbbh-cgu.0.rcgu.o":
44

55
error: aborting due to previous error; 1 warning emitted
66

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// compile-flags: -C lto
2+
// aux-build:lto-rustc-loads-linker-plugin.rs
3+
// run-pass
4+
// no-prefer-dynamic
5+
6+
// This test ensures that if a dependency was compiled with
7+
// `-Clinker-plugin-lto` then we can compile with `-Clto` and still link against
8+
// that upstream rlib. This should work because LTO implies we're not actually
9+
// linking against upstream rlibs since we're generating the object code
10+
// locally. This test will fail if rustc can't find bytecode in rlibs compiled
11+
// with `-Clinker-plugin-lto`.
12+
13+
extern crate lto_rustc_loads_linker_plugin;
14+
15+
fn main() {
16+
lto_rustc_loads_linker_plugin::foo();
17+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// compile-flags: -C lto=thin
2+
// aux-build:lto-rustc-loads-linker-plugin.rs
3+
// run-pass
4+
// no-prefer-dynamic
5+
6+
// Same as the adjacent `lto-thin-rustc-loads-linker-plugin.rs` test, only with
7+
// ThinLTO.
8+
9+
extern crate lto_rustc_loads_linker_plugin;
10+
11+
fn main() {
12+
lto_rustc_loads_linker_plugin::foo();
13+
}

0 commit comments

Comments
 (0)
Please sign in to comment.