[llvm] c5ac63e - ThinLTO: Add flag to print uselistorder in bitcode writer pass (#133230)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 14 11:34:06 PDT 2025
Author: Matt Arsenault
Date: 2025-04-14T20:34:02+02:00
New Revision: c5ac63e4fcd58c951f10c3902d8a6692e0a43c55
URL: https://github.com/llvm/llvm-project/commit/c5ac63e4fcd58c951f10c3902d8a6692e0a43c55
DIFF: https://github.com/llvm/llvm-project/commit/c5ac63e4fcd58c951f10c3902d8a6692e0a43c55.diff
LOG: ThinLTO: Add flag to print uselistorder in bitcode writer pass (#133230)
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
Added:
llvm/test/Bitcode/thinlto-preserve-uselistorder.ll
Modified:
llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h
llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
llvm/test/Transforms/ThinLTOBitcodeWriter/split.ll
llvm/test/Transforms/ThinLTOBitcodeWriter/unsplittable.ll
llvm/tools/opt/NewPMDriver.cpp
Removed:
################################################################################
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..06f5d78d77e01 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));
@@ -283,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;
}
@@ -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..e1c122ca91a17
--- /dev/null
+++ b/llvm/test/Bitcode/thinlto-preserve-uselistorder.ll
@@ -0,0 +1,21 @@
+; Check that thin lto bitcode respects preserve-bc-uselistorder
+
+; RUN: opt --preserve-bc-uselistorder --thinlto-bc --thinlto-split-lto-unit < %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/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"}
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}
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;
}
More information about the llvm-commits
mailing list