[llvm] ThinLTO: Add flag to print uselistorder in bitcode writer pass (PR #133230)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Sat Apr 12 04:43:50 PDT 2025
https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/133230
>From c9c45e094f7c2ffc95d8bcd820250e6279e5f756 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Thu, 27 Mar 2025 17:00:57 +0700
Subject: [PATCH 1/2] ThinLTO: Add flag to print uselistorder in bitcode writer
pass
This is needed in llvm-reduce to avoid perturbing the uselistorder in
intermediate steps. Really llvm-reduce wants pure serialization with
no dependency on the pass manager. There are other optimizations mixed
in to the serialization here depending on metadata in the module, which
is also bad.
Part of #63621
---
.../Transforms/IPO/ThinLTOBitcodeWriter.h | 7 ++++--
.../Transforms/IPO/ThinLTOBitcodeWriter.cpp | 18 +++++++------
.../Bitcode/thinlto-preserve-uselistorder.ll | 25 +++++++++++++++++++
llvm/tools/opt/NewPMDriver.cpp | 3 ++-
4 files changed, 43 insertions(+), 10 deletions(-)
create mode 100644 llvm/test/Bitcode/thinlto-preserve-uselistorder.ll
diff --git a/llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h b/llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h
index 9bcb01c9dbe43..b8fed10404dfa 100644
--- a/llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h
+++ b/llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h
@@ -26,12 +26,15 @@ class ThinLTOBitcodeWriterPass
: public PassInfoMixin<ThinLTOBitcodeWriterPass> {
raw_ostream &OS;
raw_ostream *ThinLinkOS;
+ const bool ShouldPreserveUseListOrder;
public:
// Writes bitcode to OS. Also write thin link file to ThinLinkOS, if
// it's not nullptr.
- ThinLTOBitcodeWriterPass(raw_ostream &OS, raw_ostream *ThinLinkOS)
- : OS(OS), ThinLinkOS(ThinLinkOS) {}
+ ThinLTOBitcodeWriterPass(raw_ostream &OS, raw_ostream *ThinLinkOS,
+ bool ShouldPreserveUseListOrder = false)
+ : OS(OS), ThinLinkOS(ThinLinkOS),
+ ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {}
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
diff --git a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
index 88abc6e560580..5549e985bb98c 100644
--- a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
+++ b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
@@ -274,7 +274,8 @@ static bool enableUnifiedLTO(Module &M) {
// regular LTO bitcode file to OS.
void splitAndWriteThinLTOBitcode(
raw_ostream &OS, raw_ostream *ThinLinkOS,
- function_ref<AAResults &(Function &)> AARGetter, Module &M) {
+ function_ref<AAResults &(Function &)> AARGetter, Module &M,
+ const bool ShouldPreserveUseListOrder) {
std::string ModuleId = getUniqueModuleId(&M);
if (ModuleId.empty()) {
assert(!enableUnifiedLTO(M));
@@ -487,9 +488,9 @@ void splitAndWriteThinLTOBitcode(
// be used in the backends, and use that in the minimized bitcode
// produced for the full link.
ModuleHash ModHash = {{0}};
- W.writeModule(M, /*ShouldPreserveUseListOrder=*/false, &Index,
+ W.writeModule(M, ShouldPreserveUseListOrder, &Index,
/*GenerateHash=*/true, &ModHash);
- W.writeModule(*MergedM, /*ShouldPreserveUseListOrder=*/false, &MergedMIndex);
+ W.writeModule(*MergedM, ShouldPreserveUseListOrder, &MergedMIndex);
W.writeSymtab();
W.writeStrtab();
OS << Buffer;
@@ -530,13 +531,15 @@ bool hasTypeMetadata(Module &M) {
bool writeThinLTOBitcode(raw_ostream &OS, raw_ostream *ThinLinkOS,
function_ref<AAResults &(Function &)> AARGetter,
- Module &M, const ModuleSummaryIndex *Index) {
+ Module &M, const ModuleSummaryIndex *Index,
+ const bool ShouldPreserveUseListOrder) {
std::unique_ptr<ModuleSummaryIndex> NewIndex = nullptr;
// See if this module has any type metadata. If so, we try to split it
// or at least promote type ids to enable WPD.
if (hasTypeMetadata(M)) {
if (enableSplitLTOUnit(M)) {
- splitAndWriteThinLTOBitcode(OS, ThinLinkOS, AARGetter, M);
+ splitAndWriteThinLTOBitcode(OS, ThinLinkOS, AARGetter, M,
+ ShouldPreserveUseListOrder);
return true;
}
// Promote type ids as needed for index-based WPD.
@@ -564,7 +567,7 @@ bool writeThinLTOBitcode(raw_ostream &OS, raw_ostream *ThinLinkOS,
// be used in the backends, and use that in the minimized bitcode
// produced for the full link.
ModuleHash ModHash = {{0}};
- WriteBitcodeToFile(M, OS, /*ShouldPreserveUseListOrder=*/false, Index,
+ WriteBitcodeToFile(M, OS, ShouldPreserveUseListOrder, Index,
/*GenerateHash=*/true, &ModHash);
// If a minimized bitcode module was requested for the thin link, only
// the information that is needed by thin link will be written in the
@@ -590,7 +593,8 @@ llvm::ThinLTOBitcodeWriterPass::run(Module &M, ModuleAnalysisManager &AM) {
[&FAM](Function &F) -> AAResults & {
return FAM.getResult<AAManager>(F);
},
- M, &AM.getResult<ModuleSummaryIndexAnalysis>(M));
+ M, &AM.getResult<ModuleSummaryIndexAnalysis>(M),
+ ShouldPreserveUseListOrder);
return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
}
diff --git a/llvm/test/Bitcode/thinlto-preserve-uselistorder.ll b/llvm/test/Bitcode/thinlto-preserve-uselistorder.ll
new file mode 100644
index 0000000000000..f619f970b25c9
--- /dev/null
+++ b/llvm/test/Bitcode/thinlto-preserve-uselistorder.ll
@@ -0,0 +1,25 @@
+; Check that thin lto bitcode respects preserve-bc-uselistorder
+
+; Test without -thin-link-bitcode-file
+; RUN: opt --preserve-bc-uselistorder --thinlto-bc --thinlto-split-lto-unit < %s | llvm-dis --preserve-ll-uselistorder | FileCheck %s
+
+; Test with -thin-link-bitcode-file
+; RUN: opt --preserve-bc-uselistorder --thinlto-bc --thinlto-split-lto-unit -thin-link-bitcode-file=%t.thinlink.bc < %s | llvm-dis --preserve-ll-uselistorder | FileCheck %s
+
+; CHECK: uselistorder ptr @g, { 3, 2, 1, 0 }
+
+ at g = external global i32
+
+define void @func1() {
+ load i32, ptr @g
+ load i32, ptr @g
+ ret void
+}
+
+define void @func2() {
+ load i32, ptr @g
+ load i32, ptr @g
+ ret void
+}
+
+uselistorder ptr @g, { 3, 2, 1, 0 }
diff --git a/llvm/tools/opt/NewPMDriver.cpp b/llvm/tools/opt/NewPMDriver.cpp
index 730858918e27a..7d168a6ceb17c 100644
--- a/llvm/tools/opt/NewPMDriver.cpp
+++ b/llvm/tools/opt/NewPMDriver.cpp
@@ -519,7 +519,8 @@ bool llvm::runPassPipeline(
break;
case OK_OutputThinLTOBitcode:
MPM.addPass(ThinLTOBitcodeWriterPass(
- Out->os(), ThinLTOLinkOut ? &ThinLTOLinkOut->os() : nullptr));
+ Out->os(), ThinLTOLinkOut ? &ThinLTOLinkOut->os() : nullptr,
+ ShouldPreserveBitcodeUseListOrder));
break;
}
>From 660836c7a4ab3acee0d7e089eae3392c825a16d1 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Sat, 12 Apr 2025 12:58:33 +0200
Subject: [PATCH 2/2] Test another place
---
llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp | 6 +++---
.../ThinLTOBitcodeWriter/unsplittable.ll | 15 +++++++++++++++
2 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
index 5549e985bb98c..06f5d78d77e01 100644
--- a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
+++ b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
@@ -284,14 +284,14 @@ void splitAndWriteThinLTOBitcode(
ProfileSummaryInfo PSI(M);
M.addModuleFlag(Module::Error, "ThinLTO", uint32_t(0));
ModuleSummaryIndex Index = buildModuleSummaryIndex(M, nullptr, &PSI);
- WriteBitcodeToFile(M, OS, /*ShouldPreserveUseListOrder=*/false, &Index,
+ WriteBitcodeToFile(M, OS, ShouldPreserveUseListOrder, &Index,
/*UnifiedLTO=*/false);
if (ThinLinkOS)
// We don't have a ThinLTO part, but still write the module to the
// ThinLinkOS if requested so that the expected output file is produced.
- WriteBitcodeToFile(M, *ThinLinkOS, /*ShouldPreserveUseListOrder=*/false,
- &Index, /*UnifiedLTO=*/false);
+ WriteBitcodeToFile(M, *ThinLinkOS, ShouldPreserveUseListOrder, &Index,
+ /*UnifiedLTO=*/false);
return;
}
diff --git a/llvm/test/Transforms/ThinLTOBitcodeWriter/unsplittable.ll b/llvm/test/Transforms/ThinLTOBitcodeWriter/unsplittable.ll
index 033f1a09748d5..c961179fd3d07 100644
--- a/llvm/test/Transforms/ThinLTOBitcodeWriter/unsplittable.ll
+++ b/llvm/test/Transforms/ThinLTOBitcodeWriter/unsplittable.ll
@@ -5,6 +5,16 @@
; copy of the regular module.
; RUN: diff %t %t2
+
+; Do it again, with preserved uselistorder
+; RUN: opt --preserve-bc-uselistorder -thinlto-bc -thin-link-bitcode-file=%t2 -thinlto-split-lto-unit -o %t %s
+; RUN: llvm-dis --preserve-ll-uselistorder -o - %t | FileCheck -check-prefixes=CHECK,USELISTORDER %s
+; RUN: llvm-bcanalyzer -dump %t | FileCheck --check-prefix=BCA %s
+; When not splitting the module, the thin link bitcode file should simply be a
+; copy of the regular module.
+; RUN: diff %t %t2
+
+
; BCA: <FULL_LTO_GLOBALVAL_SUMMARY_BLOCK
; BCA-NOT: <GLOBALVAL_SUMMARY_BLOCK
@@ -18,6 +28,8 @@ declare void @sink(ptr)
; CHECK: define internal void @f()
define internal void @f() {
+ call void @sink(ptr @g)
+ call void @sink(ptr @g)
call void @sink(ptr @g)
ret void
}
@@ -28,6 +40,9 @@ define void @h() comdat {
ret void
}
+uselistorder ptr @g, { 2, 1, 0}
+; USELISTORDER: uselistorder ptr @g, { 2, 1, 0 }
+
; CHECK: !llvm.module.flags = !{![[FLAG1:[0-9]+]], ![[FLAG2:[0-9]+]]}
; CHECK: ![[FLAG1]] = !{i32 1, !"EnableSplitLTOUnit", i32 1}
; CHECK: ![[FLAG2]] = !{i32 1, !"ThinLTO", i32 0}
More information about the llvm-commits
mailing list