[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 10:37:52 PDT 2025
https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/133230
>From eccadcc971a3be06234ddac013d0d5cb848aa331 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/3] 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 0df20c84aab1808d26036293c3cc45dfec4218eb 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/3] 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}
>From d0e10cbcf22f04dea22aaa3c72699c259595d36b Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Sat, 12 Apr 2025 19:18:05 +0200
Subject: [PATCH 3/3] Split test
---
.../Transforms/ThinLTOBitcodeWriter/split.ll | 24 +++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/llvm/test/Transforms/ThinLTOBitcodeWriter/split.ll b/llvm/test/Transforms/ThinLTOBitcodeWriter/split.ll
index 8b4ef0820debc..2d5cfaa02d565 100644
--- a/llvm/test/Transforms/ThinLTOBitcodeWriter/split.ll
+++ b/llvm/test/Transforms/ThinLTOBitcodeWriter/split.ll
@@ -6,8 +6,8 @@
; RUN: llvm-modextract -b -n 0 -o %t0.thinlink.bc %t2
; RUN: llvm-modextract -b -n 1 -o %t1.thinlink.bc %t2
; RUN: not llvm-modextract -b -n 2 -o - %t 2>&1 | FileCheck --check-prefix=ERROR %s
-; RUN: llvm-dis -o - %t0.bc | FileCheck --check-prefix=M0 %s
-; RUN: llvm-dis -o - %t1.bc | FileCheck --check-prefix=M1 %s
+; RUN: llvm-dis -preserve-ll-uselistorder -o - %t0.bc | FileCheck --check-prefix=M0 %s
+; RUN: llvm-dis -preserve-ll-uselistorder -o - %t1.bc | FileCheck --check-prefix=M1 %s
; RUN: llvm-bcanalyzer -dump %t0.bc | FileCheck --check-prefix=BCA0 %s
; RUN: llvm-bcanalyzer -dump %t1.bc | FileCheck --check-prefix=BCA1 %s
@@ -34,11 +34,31 @@ $g = comdat any
; M1: @g = global i8 42, comdat, !type !0
@g = global i8 42, comdat, !type !0
+; M0: @g1 = external global i8{{$}}
+; M1: @g1 = global i8 43, !type !0
+ at g1 = global i8 43, !type !0
+
; M0: define ptr @f()
; M1-NOT: @f()
define ptr @f() {
ret ptr @g
}
+; M0: define void @h(ptr %ptr)
+; M1-NOT: @h(
+
+define void @h(ptr %ptr) {
+ store ptr @g1, ptr %ptr
+ store ptr @g1, ptr %ptr
+ store ptr @g1, ptr %ptr
+ store ptr @g1, ptr %ptr
+ ret void
+}
+
+; M0: uselistorder ptr @g1, { 3, 2, 0, 1 }
+; M1-NOT: uselistorder
+
+uselistorder ptr @g1, { 3, 2, 0, 1 }
+
; M1: !0 = !{i32 0, !"typeid"}
!0 = !{i32 0, !"typeid"}
More information about the llvm-commits
mailing list