Skip to content

Commit

Permalink
Auto merge of rust-lang#98162 - nextsilicon:support_lto_embed_bitcode…
Browse files Browse the repository at this point in the history
…, r=davidtwco

Allow to disable thinLTO buffer to support lto-embed-bitcode lld feature

Hello
This change is to fix issue (rust-lang#84395) in which passing "-lto-embed-bitcode=optimized" to lld when linking rust code via linker-plugin-lto doesn't produce the expected result.

Instead of emitting a single unified module into a llvmbc section of the linked elf, it emits multiple submodules.
This is caused because rustc emits the BC modules after running llvm `createWriteThinLTOBitcodePass` pass.
Which in turn triggers a thinLTO linkage and causes the said issue.

This patch allows via compiler flag (-Cemit-thin-lto=<bool>) to select between running `createWriteThinLTOBitcodePass` and `createBitcodeWriterPass`.
Note this pattern of selecting between those 2 passes is common inside of LLVM code.
The default is to match the old behavior.
  • Loading branch information
bors committed Jul 21, 2022
2 parents ceeb5ad + 724c912 commit 74f600b
Show file tree
Hide file tree
Showing 10 changed files with 32 additions and 7 deletions.
6 changes: 3 additions & 3 deletions compiler/rustc_codegen_llvm/src/back/lto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ pub(crate) fn run_thin(

pub(crate) fn prepare_thin(module: ModuleCodegen<ModuleLlvm>) -> (String, ThinBuffer) {
let name = module.name.clone();
let buffer = ThinBuffer::new(module.module_llvm.llmod());
let buffer = ThinBuffer::new(module.module_llvm.llmod(), true);
(name, buffer)
}

Expand Down Expand Up @@ -695,9 +695,9 @@ unsafe impl Send for ThinBuffer {}
unsafe impl Sync for ThinBuffer {}

impl ThinBuffer {
pub fn new(m: &llvm::Module) -> ThinBuffer {
pub fn new(m: &llvm::Module, is_thin: bool) -> ThinBuffer {
unsafe {
let buffer = llvm::LLVMRustThinLTOBufferCreate(m);
let buffer = llvm::LLVMRustThinLTOBufferCreate(m, is_thin);
ThinBuffer(buffer)
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -790,7 +790,7 @@ pub(crate) unsafe fn codegen(
let _timer = cgcx
.prof
.generic_activity_with_arg("LLVM_module_codegen_make_bitcode", &*module.name);
let thin = ThinBuffer::new(llmod);
let thin = ThinBuffer::new(llmod, config.emit_thin_lto);
let data = thin.data();

if let Some(bitcode_filename) = bc_out.file_name() {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2470,7 +2470,7 @@ extern "C" {
pub fn LLVMRustModuleBufferFree(p: &'static mut ModuleBuffer);
pub fn LLVMRustModuleCost(M: &Module) -> u64;

pub fn LLVMRustThinLTOBufferCreate(M: &Module) -> &'static mut ThinLTOBuffer;
pub fn LLVMRustThinLTOBufferCreate(M: &Module, is_thin: bool) -> &'static mut ThinLTOBuffer;
pub fn LLVMRustThinLTOBufferFree(M: &'static mut ThinLTOBuffer);
pub fn LLVMRustThinLTOBufferPtr(M: &ThinLTOBuffer) -> *const c_char;
pub fn LLVMRustThinLTOBufferLen(M: &ThinLTOBuffer) -> size_t;
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_codegen_ssa/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ pub struct ModuleConfig {
pub emit_ir: bool,
pub emit_asm: bool,
pub emit_obj: EmitObj,
pub emit_thin_lto: bool,
pub bc_cmdline: String,

// Miscellaneous flags. These are mostly copied from command-line
Expand Down Expand Up @@ -218,6 +219,7 @@ impl ModuleConfig {
false
),
emit_obj,
emit_thin_lto: sess.opts.unstable_opts.emit_thin_lto,
bc_cmdline: sess.target.bitcode_llvm_cmdline.to_string(),

verify_llvm_ir: sess.verify_llvm_ir(),
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(drop_tracking, true);
tracked!(dual_proc_macros, true);
tracked!(dwarf_version, Some(5));
tracked!(emit_thin_lto, false);
tracked!(fewer_names, Some(true));
tracked!(force_unstable_if_unmarked, true);
tracked!(fuel, Some(("abc".to_string(), 99)));
Expand Down
9 changes: 7 additions & 2 deletions compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "llvm/Transforms/Utils/AddDiscriminators.h"
#include "llvm/Transforms/Utils/FunctionImportUtils.h"
#include "llvm/LTO/LTO.h"
#include "llvm/Bitcode/BitcodeWriterPass.h"
#include "llvm-c/Transforms/PassManagerBuilder.h"

#include "llvm/Transforms/Instrumentation.h"
Expand Down Expand Up @@ -1638,13 +1639,17 @@ struct LLVMRustThinLTOBuffer {
};

extern "C" LLVMRustThinLTOBuffer*
LLVMRustThinLTOBufferCreate(LLVMModuleRef M) {
LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin) {
auto Ret = std::make_unique<LLVMRustThinLTOBuffer>();
{
raw_string_ostream OS(Ret->data);
{
legacy::PassManager PM;
PM.add(createWriteThinLTOBitcodePass(OS));
if (is_thin) {
PM.add(createWriteThinLTOBitcodePass(OS));
} else {
PM.add(createBitcodeWriterPass(OS));
}
PM.run(*unwrap(M));
}
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1279,6 +1279,8 @@ options! {
"version of DWARF debug information to emit (default: 2 or 4, depending on platform)"),
emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED],
"emit a section containing stack size metadata (default: no)"),
emit_thin_lto: bool = (true, parse_bool, [TRACKED],
"emit the bc module with thin LTO info (default: yes)"),
fewer_names: Option<bool> = (None, parse_opt_bool, [TRACKED],
"reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) \
(default: no)"),
Expand Down
11 changes: 11 additions & 0 deletions src/test/run-make-fulldeps/issue-84395-lto-embed-bitcode/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# needs-matching-clang

# This test makes sure the embed bitcode in elf created with
# lto-embed-bitcode=optimized is valid llvm BC module.

-include ../../run-make-fulldeps/tools.mk

all:
$(RUSTC) test.rs --target $(TARGET) -Clink-arg=-fuse-ld=lld -Clinker-plugin-lto -Clinker=$(CLANG) -Clink-arg=-Wl,--plugin-opt=-lto-embed-bitcode=optimized -Zemit-thin-lto=no
$(LLVM_BIN_DIR)/objcopy --dump-section .llvmbc=$(TMPDIR)/test.bc $(TMPDIR)/test
$(LLVM_BIN_DIR)/llvm-dis $(TMPDIR)/test.bc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
println!("Hello World!");
}
1 change: 1 addition & 0 deletions src/test/rustdoc-ui/z-help.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
-Z dump-mir-spanview=val -- in addition to `.mir` files, create `.html` files to view spans for all `statement`s (including terminators), only `terminator` spans, or computed `block` spans (one span encompassing a block's terminator and all statements). If `-Z instrument-coverage` is also enabled, create an additional `.html` file showing the computed coverage spans.
-Z dwarf-version=val -- version of DWARF debug information to emit (default: 2 or 4, depending on platform)
-Z emit-stack-sizes=val -- emit a section containing stack size metadata (default: no)
-Z emit-thin-lto=val -- emit the bc module with thin LTO info (default: yes)
-Z fewer-names=val -- reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) (default: no)
-Z force-unstable-if-unmarked=val -- force all crates to be `rustc_private` unstable (default: no)
-Z fuel=val -- set the optimization fuel quota for a crate
Expand Down

0 comments on commit 74f600b

Please sign in to comment.