Auto merge of #98162 - nextsilicon:support_lto_embed_bitcode, r=davidtwco
Allow to disable thinLTO buffer to support lto-embed-bitcode lld feature Hello This change is to fix issue (https://github.com/rust-lang/rust/issues/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.
This commit is contained in:
commit
74f600b990
10 changed files with 32 additions and 7 deletions
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
@ -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(),
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -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"
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)"),
|
||||
|
|
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
fn main() {
|
||||
println!("Hello World!");
|
||||
}
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue