rustc: add ability to output regular LTO bitcode modules

Adding the option to control from rustc CLI
if the resulted ".o" bitcode module files are with
thinLTO info or regular LTO info.

Allows using "-lto-embed-bitcode=optimized" during linkage
correctly.

Signed-off-by: Ziv Dunkelman <ziv.dunkelman@nextsilicon.com>
This commit is contained in:
Ziv Dunkelman 2022-06-08 17:30:16 +03:00
parent 0ed9c64c3e
commit 724c91234d
10 changed files with 32 additions and 7 deletions

View File

@ -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)
}
@ -709,9 +709,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)
}
}

View File

@ -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() {

View File

@ -2469,7 +2469,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;

View File

@ -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(),

View File

@ -734,6 +734,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)));

View File

@ -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));
}
}

View File

@ -1277,6 +1277,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)"),

View File

@ -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

View File

@ -0,0 +1,3 @@
fn main() {
println!("Hello World!");
}

View File

@ -35,6 +35,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