Skip to content

Commit 8acb881

Browse files
committed
[PGO] Add a threshold for number of critical edges in PGO
For some auto-generated sources, we have a huge number of critical edges (like from switch statements). We have seen instance of 183777 critical edges in one function. After we split the critical edges in PGO instrumentation/profile-use pass, the CFG is so large that we have compiler time issues in downstream passes (like in machine CSE and block placement). Here I add a threshold to skip PGO if the number of critical edges are too large. The threshold is large enough so that it will not affect the majority of PGO compilation. Also sync the logic for skipping instrumentation and profile-use. I think this is the correct thing to do. Differential Revision: https://reviews.llvm.org/D137184
1 parent c10a847 commit 8acb881

File tree

2 files changed

+67
-9
lines changed

2 files changed

+67
-9
lines changed

llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -302,12 +302,17 @@ static cl::opt<std::string> PGOTraceFuncHash(
302302

303303
static cl::opt<unsigned> PGOFunctionSizeThreshold(
304304
"pgo-function-size-threshold", cl::Hidden,
305-
cl::desc("Do not instrument functions smaller than this threshold"));
305+
cl::desc("Do not instrument functions smaller than this threshold."));
306306

307307
static cl::opt<bool> MatchMemProf(
308308
"pgo-match-memprof", cl::init(true), cl::Hidden,
309309
cl::desc("Perform matching and annotation of memprof profiles."));
310310

311+
static cl::opt<unsigned> PGOFunctionCriticalEdgeThreshold(
312+
"pgo-critical-edge-threshold", cl::init(20000), cl::Hidden,
313+
cl::desc("Do not instrument functions with the number of critical edges "
314+
" greater than this threshold."));
315+
311316
namespace llvm {
312317
// Command line option to turn on CFG dot dump after profile annotation.
313318
// Defined in Analysis/BlockFrequencyInfo.cpp: -pgo-view-counts
@@ -1846,6 +1851,38 @@ static void collectComdatMembers(
18461851
ComdatMembers.insert(std::make_pair(C, &GA));
18471852
}
18481853

1854+
// Don't perform PGO instrumeatnion / profile-use.
1855+
static bool skipPGO(const Function &F) {
1856+
if (F.isDeclaration())
1857+
return true;
1858+
if (F.hasFnAttribute(llvm::Attribute::NoProfile))
1859+
return true;
1860+
if (F.hasFnAttribute(llvm::Attribute::SkipProfile))
1861+
return true;
1862+
if (F.getInstructionCount() < PGOFunctionSizeThreshold)
1863+
return true;
1864+
1865+
// If there are too many critical edges, PGO might cause
1866+
// compiler time problem. Skip PGO if the number of
1867+
// critical edges execeed the threshold.
1868+
unsigned NumCriticalEdges = 0;
1869+
for (auto &BB : F) {
1870+
const Instruction *TI = BB.getTerminator();
1871+
for (unsigned I = 0, E = TI->getNumSuccessors(); I != E; ++I) {
1872+
if (isCriticalEdge(TI, I))
1873+
NumCriticalEdges++;
1874+
}
1875+
}
1876+
if (NumCriticalEdges > PGOFunctionCriticalEdgeThreshold) {
1877+
LLVM_DEBUG(dbgs() << "In func " << F.getName()
1878+
<< ", NumCriticalEdges=" << NumCriticalEdges
1879+
<< " exceed the threshold. Skip PGO.\n");
1880+
return true;
1881+
}
1882+
1883+
return false;
1884+
}
1885+
18491886
static bool InstrumentAllFunctions(
18501887
Module &M, function_ref<TargetLibraryInfo &(Function &)> LookupTLI,
18511888
function_ref<BranchProbabilityInfo *(Function &)> LookupBPI,
@@ -1858,13 +1895,7 @@ static bool InstrumentAllFunctions(
18581895
collectComdatMembers(M, ComdatMembers);
18591896

18601897
for (auto &F : M) {
1861-
if (F.isDeclaration())
1862-
continue;
1863-
if (F.hasFnAttribute(llvm::Attribute::NoProfile))
1864-
continue;
1865-
if (F.hasFnAttribute(llvm::Attribute::SkipProfile))
1866-
continue;
1867-
if (F.getInstructionCount() < PGOFunctionSizeThreshold)
1898+
if (skipPGO(F))
18681899
continue;
18691900
auto &TLI = LookupTLI(F);
18701901
auto *BPI = LookupBPI(F);
@@ -2092,7 +2123,7 @@ static bool annotateAllFunctions(
20922123
if (PGOInstrumentEntry.getNumOccurrences() > 0)
20932124
InstrumentFuncEntry = PGOInstrumentEntry;
20942125
for (auto &F : M) {
2095-
if (F.isDeclaration())
2126+
if (skipPGO(F))
20962127
continue;
20972128
auto &TLI = LookupTLI(F);
20982129
auto *BPI = LookupBPI(F);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
; Test the critical edge threahold
2+
; RUN: opt < %s -passes=pgo-instr-gen -pgo-critical-edge-threshold=1 -pgo-instrument-entry=true -S | FileCheck %s
3+
4+
@sum = dso_local global i32 0, align 4
5+
6+
define void @foo(i32 %a, i32 %b) {
7+
entry:
8+
%tobool.not = icmp eq i32 %a, 0
9+
br i1 %tobool.not, label %if.end4, label %if.then
10+
11+
if.then:
12+
%0 = load i32, ptr @sum, align 4
13+
%inc = add nsw i32 %0, 1
14+
store i32 %inc, ptr @sum, align 4
15+
%tobool1.not = icmp eq i32 %b, 0
16+
br i1 %tobool1.not, label %if.end4, label %if.then2
17+
18+
if.then2:
19+
%inc3 = add nsw i32 %0, 2
20+
store i32 %inc3, ptr @sum, align 4
21+
br label %if.end4
22+
23+
if.end4:
24+
ret void
25+
}
26+
27+
; CHECK-NOT: call void @llvm.instrprof.increment(ptr @__profn_foo

0 commit comments

Comments
 (0)