mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[PGO] Fix PGO use ICE when there are unreachable BBs
For -O0 there might be unreachable BBs, which breaks the assumption that all the BBs have an auxiliary data structure. In this patch, we add another interface called findBBInfo() so that a nullptr can be returned for the unreachable BBs (and the callers can ignore those BBs). This fixes the bug reported https://llvm.org/bugs/show_bug.cgi?id=31209 Differential Revision: https://reviews.llvm.org/D27280 llvm-svn: 288528
This commit is contained in:
parent
564945a3af
commit
33fafefbc5
@ -78,6 +78,14 @@ public:
|
||||
return *It->second.get();
|
||||
}
|
||||
|
||||
// Give BB, return the auxiliary information if it's available.
|
||||
BBInfo *findBBInfo(const BasicBlock *BB) const {
|
||||
auto It = BBInfos.find(BB);
|
||||
if (It == BBInfos.end())
|
||||
return nullptr;
|
||||
return It->second.get();
|
||||
}
|
||||
|
||||
// Traverse the CFG using a stack. Find all the edges and assign the weight.
|
||||
// Edges with large weight will be put into MST first so they are less likely
|
||||
// to be instrumented.
|
||||
|
@ -327,6 +327,9 @@ public:
|
||||
// Return the auxiliary BB information.
|
||||
BBInfo &getBBInfo(const BasicBlock *BB) const { return MST.getBBInfo(BB); }
|
||||
|
||||
// Return the auxiliary BB information if available.
|
||||
BBInfo *findBBInfo(const BasicBlock *BB) const { return MST.findBBInfo(BB); }
|
||||
|
||||
// Dump edges and BB information.
|
||||
void dumpInfo(std::string Str = "") const {
|
||||
MST.dumpEdges(dbgs(), Twine("Dump Function ") + FuncName + " Hash: " +
|
||||
@ -386,7 +389,10 @@ void FuncPGOInstrumentation<Edge, BBInfo>::computeCFGHash() {
|
||||
const TerminatorInst *TI = BB.getTerminator();
|
||||
for (unsigned I = 0, E = TI->getNumSuccessors(); I != E; ++I) {
|
||||
BasicBlock *Succ = TI->getSuccessor(I);
|
||||
uint32_t Index = getBBInfo(Succ).Index;
|
||||
auto BI = findBBInfo(Succ);
|
||||
if (BI == nullptr)
|
||||
continue;
|
||||
uint32_t Index = BI->Index;
|
||||
for (int J = 0; J < 4; J++)
|
||||
Indexes.push_back((char)(Index >> (J * 8)));
|
||||
}
|
||||
@ -672,6 +678,11 @@ public:
|
||||
return FuncInfo.getBBInfo(BB);
|
||||
}
|
||||
|
||||
// Return the auxiliary BB information if available.
|
||||
UseBBInfo *findBBInfo(const BasicBlock *BB) const {
|
||||
return FuncInfo.findBBInfo(BB);
|
||||
}
|
||||
|
||||
private:
|
||||
Function &F;
|
||||
Module *M;
|
||||
@ -857,27 +868,29 @@ void PGOUseFunc::populateCounters() {
|
||||
// For efficient traversal, it's better to start from the end as most
|
||||
// of the instrumented edges are at the end.
|
||||
for (auto &BB : reverse(F)) {
|
||||
UseBBInfo &Count = getBBInfo(&BB);
|
||||
if (!Count.CountValid) {
|
||||
if (Count.UnknownCountOutEdge == 0) {
|
||||
Count.CountValue = sumEdgeCount(Count.OutEdges);
|
||||
Count.CountValid = true;
|
||||
UseBBInfo *Count = findBBInfo(&BB);
|
||||
if (Count == nullptr)
|
||||
continue;
|
||||
if (!Count->CountValid) {
|
||||
if (Count->UnknownCountOutEdge == 0) {
|
||||
Count->CountValue = sumEdgeCount(Count->OutEdges);
|
||||
Count->CountValid = true;
|
||||
Changes = true;
|
||||
} else if (Count.UnknownCountInEdge == 0) {
|
||||
Count.CountValue = sumEdgeCount(Count.InEdges);
|
||||
Count.CountValid = true;
|
||||
} else if (Count->UnknownCountInEdge == 0) {
|
||||
Count->CountValue = sumEdgeCount(Count->InEdges);
|
||||
Count->CountValid = true;
|
||||
Changes = true;
|
||||
}
|
||||
}
|
||||
if (Count.CountValid) {
|
||||
if (Count.UnknownCountOutEdge == 1) {
|
||||
uint64_t Total = Count.CountValue - sumEdgeCount(Count.OutEdges);
|
||||
setEdgeCount(Count.OutEdges, Total);
|
||||
if (Count->CountValid) {
|
||||
if (Count->UnknownCountOutEdge == 1) {
|
||||
uint64_t Total = Count->CountValue - sumEdgeCount(Count->OutEdges);
|
||||
setEdgeCount(Count->OutEdges, Total);
|
||||
Changes = true;
|
||||
}
|
||||
if (Count.UnknownCountInEdge == 1) {
|
||||
uint64_t Total = Count.CountValue - sumEdgeCount(Count.InEdges);
|
||||
setEdgeCount(Count.InEdges, Total);
|
||||
if (Count->UnknownCountInEdge == 1) {
|
||||
uint64_t Total = Count->CountValue - sumEdgeCount(Count->InEdges);
|
||||
setEdgeCount(Count->InEdges, Total);
|
||||
Changes = true;
|
||||
}
|
||||
}
|
||||
@ -887,14 +900,22 @@ void PGOUseFunc::populateCounters() {
|
||||
DEBUG(dbgs() << "Populate counts in " << NumPasses << " passes.\n");
|
||||
#ifndef NDEBUG
|
||||
// Assert every BB has a valid counter.
|
||||
for (auto &BB : F)
|
||||
assert(getBBInfo(&BB).CountValid && "BB count is not valid");
|
||||
for (auto &BB : F) {
|
||||
auto BI = findBBInfo(&BB);
|
||||
if (BI == nullptr)
|
||||
continue;
|
||||
assert(BI->CountValid && "BB count is not valid");
|
||||
}
|
||||
#endif
|
||||
uint64_t FuncEntryCount = getBBInfo(&*F.begin()).CountValue;
|
||||
F.setEntryCount(FuncEntryCount);
|
||||
uint64_t FuncMaxCount = FuncEntryCount;
|
||||
for (auto &BB : F)
|
||||
FuncMaxCount = std::max(FuncMaxCount, getBBInfo(&BB).CountValue);
|
||||
for (auto &BB : F) {
|
||||
auto BI = findBBInfo(&BB);
|
||||
if (BI == nullptr)
|
||||
continue;
|
||||
FuncMaxCount = std::max(FuncMaxCount, BI->CountValue);
|
||||
}
|
||||
markFunctionAttributes(FuncEntryCount, FuncMaxCount);
|
||||
|
||||
// Now annotate select instructions
|
||||
@ -974,7 +995,10 @@ void SelectInstVisitor::annotateOneSelectInst(SelectInst &SI) {
|
||||
uint64_t SCounts[2];
|
||||
SCounts[0] = CountFromProfile[*CurCtrIdx]; // True count
|
||||
++(*CurCtrIdx);
|
||||
uint64_t TotalCount = UseFunc->getBBInfo(SI.getParent()).CountValue;
|
||||
uint64_t TotalCount = 0;
|
||||
auto BI = UseFunc->findBBInfo(SI.getParent());
|
||||
if (BI != nullptr)
|
||||
TotalCount = BI->CountValue;
|
||||
// False Count
|
||||
SCounts[1] = (TotalCount > SCounts[0] ? TotalCount - SCounts[0] : 0);
|
||||
uint64_t MaxCount = std::max(SCounts[0], SCounts[1]);
|
||||
|
@ -0,0 +1,9 @@
|
||||
# IR level Instrumentation Flag
|
||||
:ir
|
||||
foo
|
||||
# Func Hash:
|
||||
12884901887
|
||||
# Num Counters:
|
||||
1
|
||||
# Counter Values:
|
||||
0
|
23
test/Transforms/PGOProfile/unreachable_bb.ll
Normal file
23
test/Transforms/PGOProfile/unreachable_bb.ll
Normal file
@ -0,0 +1,23 @@
|
||||
; RUN: llvm-profdata merge %S/Inputs/unreachable_bb.proftext -o %t.profdata
|
||||
; RUN: opt < %s -pgo-instr-use -pgo-test-profile-file=%t.profdata -S | FileCheck %s --check-prefix=USE
|
||||
; RUN: opt < %s -passes=pgo-instr-use -pgo-test-profile-file=%t.profdata -S | FileCheck %s --check-prefix=USE
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
define void @foo() {
|
||||
entry:
|
||||
call void @bar()
|
||||
unreachable
|
||||
return:
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @bar()
|
||||
|
||||
;USE: !0 = !{i32 1, !"ProfileSummary", !1}
|
||||
;USE: !1 = !{!2, !3, !4, !5, !6, !7, !8, !9}
|
||||
;USE: !2 = !{!"ProfileFormat", !"InstrProf"}
|
||||
;USE: !3 = !{!"TotalCount", i64 0}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user