diff options
| author | Augie Fackler <augie@google.com> | 2024-01-19 14:42:43 -0500 |
|---|---|---|
| committer | Augie Fackler <augie@google.com> | 2024-05-22 14:04:22 -0400 |
| commit | aa91871539ca518e81af58485df895f8db30496a (patch) | |
| tree | f85780059b3da25ef6922a5f981d3ab880aa5f92 /compiler/rustc_codegen_llvm/src | |
| parent | e8fbd991287f637f95016a71ddc13438415bbe59 (diff) | |
| download | rust-aa91871539ca518e81af58485df895f8db30496a.tar.gz rust-aa91871539ca518e81af58485df895f8db30496a.zip | |
rustc_codegen_llvm: add support for writing summary bitcode
Typical uses of ThinLTO don't have any use for this as a standalone file, but distributed ThinLTO uses this to make the linker phase more efficient. With clang you'd do something like `clang -flto=thin -fthin-link-bitcode=foo.indexing.o -c foo.c` and then get both foo.o (full of bitcode) and foo.indexing.o (just the summary or index part of the bitcode). That's then usable by a two-stage linking process that's more friendly to distributed build systems like bazel, which is why I'm working on this area. I talked some to @teresajohnson about naming in this area, as things seem to be a little confused between various blog posts and build systems. "bitcode index" and "bitcode summary" tend to be a little too ambiguous, and she tends to use "thin link bitcode" and "minimized bitcode" (which matches the descriptions in LLVM). Since the clang option is thin-link-bitcode, I went with that to try and not add a new spelling in the world. Per @dtolnay, you can work around the lack of this by using `lld --thinlto-index-only` to do the indexing on regular .o files of bitcode, but that is a bit wasteful on actions when we already have all the information in rustc and could just write out the matching minimized bitcode. I didn't test that at all in our infrastructure, because by the time I learned that I already had this patch largely written.
Diffstat (limited to 'compiler/rustc_codegen_llvm/src')
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/back/lto.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/back/write.rs | 32 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 2 |
3 files changed, 37 insertions, 5 deletions
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index e61af863dc0..740939eb6bb 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -687,6 +687,14 @@ impl ThinBufferMethods for ThinBuffer { slice::from_raw_parts(ptr, len) } } + + fn thin_link_data(&self) -> &[u8] { + unsafe { + let ptr = llvm::LLVMRustThinLTOBufferThinLinkDataPtr(self.0) as *const _; + let len = llvm::LLVMRustThinLTOBufferThinLinkDataLen(self.0); + slice::from_raw_parts(ptr, len) + } + } } impl Drop for ThinBuffer { diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 49f9d7ddab6..de12ae4ecc8 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -708,6 +708,8 @@ pub(crate) unsafe fn codegen( // asm from LLVM and use `gcc` to create the object file. let bc_out = cgcx.output_filenames.temp_path(OutputType::Bitcode, module_name); + let bc_index_out = + cgcx.output_filenames.temp_path(OutputType::ThinLinkBitcode, module_name); let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, module_name); if config.bitcode_needed() { @@ -716,6 +718,7 @@ pub(crate) unsafe fn codegen( .generic_activity_with_arg("LLVM_module_codegen_make_bitcode", &*module.name); let thin = ThinBuffer::new(llmod, config.emit_thin_lto); let data = thin.data(); + let index_data = thin.thin_link_data(); if let Some(bitcode_filename) = bc_out.file_name() { cgcx.prof.artifact_size( @@ -725,12 +728,31 @@ pub(crate) unsafe fn codegen( ); } + if let Some(thin_link_bitcode_filename) = bc_index_out.file_name() { + cgcx.prof.artifact_size( + "llvm_bitcode_summary", + thin_link_bitcode_filename.to_string_lossy(), + index_data.len() as u64, + ); + + let _timer = cgcx.prof.generic_activity_with_arg( + "LLVM_module_codegen_emit_bitcode_index", + &*module.name, + ); + if let Err(err) = fs::write(&bc_index_out, index_data) { + dcx.emit_err(WriteBytecode { path: &bc_index_out, err }); + } + } + if config.emit_bc || config.emit_obj == EmitObj::Bitcode { - let _timer = cgcx - .prof - .generic_activity_with_arg("LLVM_module_codegen_emit_bitcode", &*module.name); - if let Err(err) = fs::write(&bc_out, data) { - dcx.emit_err(WriteBytecode { path: &bc_out, err }); + { + let _timer = cgcx.prof.generic_activity_with_arg( + "LLVM_module_codegen_emit_bitcode", + &*module.name, + ); + if let Err(err) = fs::write(&bc_out, data) { + dcx.emit_err(WriteBytecode { path: &bc_out, err }); + } } } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 7a34e21628d..648e7f12890 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2354,6 +2354,8 @@ extern "C" { pub fn LLVMRustThinLTOBufferFree(M: &'static mut ThinLTOBuffer); pub fn LLVMRustThinLTOBufferPtr(M: &ThinLTOBuffer) -> *const c_char; pub fn LLVMRustThinLTOBufferLen(M: &ThinLTOBuffer) -> size_t; + pub fn LLVMRustThinLTOBufferThinLinkDataPtr(M: &ThinLTOBuffer) -> *const c_char; + pub fn LLVMRustThinLTOBufferThinLinkDataLen(M: &ThinLTOBuffer) -> size_t; pub fn LLVMRustCreateThinLTOData( Modules: *const ThinLTOModule, NumModules: c_uint, |
