Skip to content

Commit 6df2fbc

Browse files
authored
Unrolled build for #159029
Rollup merge of #159029 - erickt:lto-module-summaries, r=cuviper rustc_llvm: Emit module summaries when using -Clto=fat Currently, module summaries are only emitted with thin lto. If we would link full/fat lto'd rust code against lto'd c++ code built with CFI (or WPD), those passes would fail during the link step because the participating rust modules are missing module summaries. Rust code does not know at compile-time if it would be participating in some special link which may require module summaries, so this PR ensures module summaries are unconditionally emitted for full/fat lto, just like with thin lto. The WriteBitcodeToFile function just invokes the normal BitcodeWriterPass under the hood, but doesn't provide a way to set the argument for emitting module summaries. So this patch just adds the pass directly and sets that argument. This is a rebase of @PiJoules's #158099, which also should fix up the tests with the gcc tools.
2 parents 7608eb7 + a4bc26a commit 6df2fbc

4 files changed

Lines changed: 60 additions & 19 deletions

File tree

compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,27 @@ struct LLVMRustSanitizerOptions {
603603
extern "C" typedef void (*registerEnzymeAndPassPipelineFn)(
604604
llvm::PassBuilder &PB, bool augment);
605605

606+
/// Forces the bitcode writer to emit full LTO summary instead of thin LTO
607+
/// summary for embedded bitcode under Fat LTO.
608+
///
609+
/// Note the bitcode writer will only emit the full LTO block ID if the
610+
/// "ThinLTO" metadata is defined and explicitly set to zero. Otherwise, the
611+
/// thin LTO block ID will be emitted.
612+
static void forceFullLTOSummary(Module *M) {
613+
// This function may be called twice, such as if you call it with `-C lto=fat
614+
// --emit=llvm-bc`, so exit early if if we've already set up the module to
615+
// emit full LTO summaries.
616+
if (auto *Existing = M->getModuleFlag("ThinLTO")) {
617+
auto *Const = mdconst::extract<ConstantInt>(Existing);
618+
assert(Const->getZExtValue() == 0 &&
619+
"ThinLTO flag already set to non-zero");
620+
return;
621+
}
622+
623+
auto *Zero = ConstantInt::get(Type::getInt32Ty(M->getContext()), 0);
624+
M->addModuleFlag(Module::Error, "ThinLTO", Zero);
625+
}
626+
606627
extern "C" LLVMRustResult LLVMRustOptimize(
607628
LLVMModuleRef ModuleRef, LLVMTargetMachineRef TMRef,
608629
LLVMRustPassBuilderOptLevel OptLevelRust, LLVMRustOptStage OptStage,
@@ -943,14 +964,17 @@ extern "C" LLVMRustResult LLVMRustOptimize(
943964
}
944965
// For `-Copt-level=0`, and the pre-link fat/thin LTO stages.
945966
if (ThinLTOBufferRef && *ThinLTOBufferRef == nullptr) {
946-
// thin lto summaries prevent fat lto, so do not emit them if fat
947-
// lto is requested. See PR #136840 for background information.
967+
// thin lto summaries prevent fat lto, so emit a full summary instead if
968+
// fat lto is requested. See PR #136840 for background information.
948969
if (OptStage != LLVMRustOptStage::PreLinkFatLTO) {
949970
MPM.addPass(ThinLTOBitcodeWriterPass(
950971
ThinLTODataOS,
951972
ThinLTOSummaryBufferRef ? &ThinLinkDataOS : nullptr));
952973
} else {
953-
MPM.addPass(BitcodeWriterPass(ThinLTODataOS));
974+
forceFullLTOSummary(TheModule);
975+
MPM.addPass(BitcodeWriterPass(ThinLTODataOS,
976+
/*ShouldPreserveUseListOrder=*/false,
977+
/*EmitSummaryIndex=*/true));
954978
}
955979
*ThinLTOBufferRef = ThinLTOBuffer.release();
956980
if (ThinLTOSummaryBufferRef) {
@@ -1469,26 +1493,30 @@ extern "C" LLVMRustBuffer *LLVMRustModuleSerialize(LLVMModuleRef M,
14691493
{
14701494
auto OS = raw_string_ostream(Ret->data);
14711495
{
1472-
if (is_thin) {
1473-
PassBuilder PB;
1474-
LoopAnalysisManager LAM;
1475-
FunctionAnalysisManager FAM;
1476-
CGSCCAnalysisManager CGAM;
1477-
ModuleAnalysisManager MAM;
1478-
PB.registerModuleAnalyses(MAM);
1479-
PB.registerCGSCCAnalyses(CGAM);
1480-
PB.registerFunctionAnalyses(FAM);
1481-
PB.registerLoopAnalyses(LAM);
1482-
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
1483-
ModulePassManager MPM;
1496+
PassBuilder PB;
1497+
LoopAnalysisManager LAM;
1498+
FunctionAnalysisManager FAM;
1499+
CGSCCAnalysisManager CGAM;
1500+
ModuleAnalysisManager MAM;
1501+
PB.registerModuleAnalyses(MAM);
1502+
PB.registerCGSCCAnalyses(CGAM);
1503+
PB.registerFunctionAnalyses(FAM);
1504+
PB.registerLoopAnalyses(LAM);
1505+
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
1506+
1507+
ModulePassManager MPM;
14841508
#if LLVM_VERSION_GE(23, 0)
1485-
MPM.addPass(AssignGUIDPass());
1509+
MPM.addPass(AssignGUIDPass());
14861510
#endif
1511+
1512+
if (is_thin) {
14871513
MPM.addPass(ThinLTOBitcodeWriterPass(OS, nullptr));
1488-
MPM.run(*unwrap(M), MAM);
14891514
} else {
1490-
WriteBitcodeToFile(*unwrap(M), OS);
1515+
forceFullLTOSummary(unwrap(M));
1516+
MPM.addPass(BitcodeWriterPass(OS, /*ShouldPreserveUseListOrder=*/false,
1517+
/*EmitSummaryIndex=*/true));
14911518
}
1519+
MPM.run(*unwrap(M), MAM);
14921520
}
14931521
}
14941522
return Ret.release();

compiler/rustc_metadata/src/fs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ pub fn encode_and_write_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata {
9696
if tcx.sess.opts.json_artifact_notifications {
9797
tcx.dcx().emit_artifact_notification(out_filename.as_path(), "metadata");
9898
}
99-
(filename, None)
99+
(filename, Some(metadata_tmpdir))
100100
} else {
101101
(metadata_filename, Some(metadata_tmpdir))
102102
};
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#![no_std]
2+
3+
pub fn foo() {}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
use run_make_support::{llvm_bcanalyzer, rustc};
2+
3+
fn main() {
4+
rustc().input("foo.rs").crate_type("lib").arg("-Clto=fat").arg("--emit=llvm-bc").run();
5+
6+
llvm_bcanalyzer()
7+
.input("foo.bc")
8+
.run()
9+
.assert_stdout_contains("FULL_LTO_GLOBALVAL_SUMMARY_BLOCK");
10+
}

0 commit comments

Comments
 (0)