Skip to content

ThinLTO: Add flag to print uselistorder in bitcode writer pass #133230

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
24 changes: 14 additions & 10 deletions llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -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();
}
21 changes: 21 additions & 0 deletions llvm/test/Bitcode/thinlto-preserve-uselistorder.ll
Original file line number Diff line number Diff line change
@@ -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 }

@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 }
24 changes: 22 additions & 2 deletions llvm/test/Transforms/ThinLTOBitcodeWriter/split.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
@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"}
15 changes: 15 additions & 0 deletions llvm/test/Transforms/ThinLTOBitcodeWriter/unsplittable.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
}
Expand All @@ -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}
Expand Down
3 changes: 2 additions & 1 deletion llvm/tools/opt/NewPMDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
Loading