Skip to content

Commit f2d827c

Browse files
authored
[profcheck] Require unknown metadata have an origin parameter (#157594)
Rather than passes using `!prof = !{!”unknown”}`​for cases where don’t have enough information to emit profile values, this patch captures the pass (or some other information) that can help diagnostics - i.e. `!{!”unknown”, !”some-pass-name”}`​. For example, suppose we emitted a `select`​ with the unknown metadata, and, later, end up needing to lower that to a conditional branch. If we observe (via sample profiling, for example) that the branch is biased and would have benefitted from a valid profile, the extra information can help speed up debugging. We can also (in a subsequent pass) generate optimization remarks about such lowered selects, with a similar aim - identify patterns lowering to `select`​ that may be worth some extra investment in extracting a more precise profile.
1 parent 613caa9 commit f2d827c

File tree

10 files changed

+73
-29
lines changed

10 files changed

+73
-29
lines changed

llvm/include/llvm/IR/ProfDataUtils.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,12 +177,15 @@ inline uint32_t scaleBranchCount(uint64_t Count, uint64_t Scale) {
177177
/// do not accidentally drop profile info, and this API is called in cases where
178178
/// the pass explicitly cannot provide that info. Defaulting it in would hide
179179
/// bugs where the pass forgets to transfer over or otherwise specify profile
180-
/// info.
181-
LLVM_ABI void setExplicitlyUnknownBranchWeights(Instruction &I);
180+
/// info. Use `PassName` to capture the pass name (i.e. DEBUG_TYPE) for
181+
/// debuggability.
182+
LLVM_ABI void setExplicitlyUnknownBranchWeights(Instruction &I,
183+
StringRef PassName);
182184

183185
/// Analogous to setExplicitlyUnknownBranchWeights, but for functions and their
184186
/// entry counts.
185-
LLVM_ABI void setExplicitlyUnknownFunctionEntryCount(Function &F);
187+
LLVM_ABI void setExplicitlyUnknownFunctionEntryCount(Function &F,
188+
StringRef PassName);
186189

187190
LLVM_ABI bool isExplicitlyUnknownProfileMetadata(const MDNode &MD);
188191
LLVM_ABI bool hasExplicitlyUnknownBranchWeights(const Instruction &I);

llvm/lib/IR/ProfDataUtils.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -242,24 +242,26 @@ bool extractProfTotalWeight(const Instruction &I, uint64_t &TotalVal) {
242242
return extractProfTotalWeight(I.getMetadata(LLVMContext::MD_prof), TotalVal);
243243
}
244244

245-
void setExplicitlyUnknownBranchWeights(Instruction &I) {
245+
void setExplicitlyUnknownBranchWeights(Instruction &I, StringRef PassName) {
246246
MDBuilder MDB(I.getContext());
247247
I.setMetadata(
248248
LLVMContext::MD_prof,
249249
MDNode::get(I.getContext(),
250-
MDB.createString(MDProfLabels::UnknownBranchWeightsMarker)));
250+
{MDB.createString(MDProfLabels::UnknownBranchWeightsMarker),
251+
MDB.createString(PassName)}));
251252
}
252253

253-
void setExplicitlyUnknownFunctionEntryCount(Function &F) {
254+
void setExplicitlyUnknownFunctionEntryCount(Function &F, StringRef PassName) {
254255
MDBuilder MDB(F.getContext());
255256
F.setMetadata(
256257
LLVMContext::MD_prof,
257258
MDNode::get(F.getContext(),
258-
MDB.createString(MDProfLabels::UnknownBranchWeightsMarker)));
259+
{MDB.createString(MDProfLabels::UnknownBranchWeightsMarker),
260+
MDB.createString(PassName)}));
259261
}
260262

261263
bool isExplicitlyUnknownProfileMetadata(const MDNode &MD) {
262-
if (MD.getNumOperands() != 1)
264+
if (MD.getNumOperands() != 2)
263265
return false;
264266
return MD.getOperand(0).equalsStr(MDProfLabels::UnknownBranchWeightsMarker);
265267
}

llvm/lib/IR/Verifier.cpp

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,7 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
631631
void verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
632632
const Value *V, bool IsIntrinsic, bool IsInlineAsm);
633633
void verifyFunctionMetadata(ArrayRef<std::pair<unsigned, MDNode *>> MDs);
634-
634+
void verifyUnknownProfileMetadata(MDNode *MD);
635635
void visitConstantExprsRecursively(const Constant *EntryC);
636636
void visitConstantExpr(const ConstantExpr *CE);
637637
void visitConstantPtrAuth(const ConstantPtrAuth *CPA);
@@ -2515,19 +2515,31 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
25152515
V);
25162516
}
25172517
}
2518+
void Verifier::verifyUnknownProfileMetadata(MDNode *MD) {
2519+
Check(MD->getNumOperands() == 2,
2520+
"'unknown' !prof should have a single additional operand", MD);
2521+
auto *PassName = dyn_cast<MDString>(MD->getOperand(1));
2522+
Check(PassName != nullptr,
2523+
"'unknown' !prof should have an additional operand of type "
2524+
"string");
2525+
Check(!PassName->getString().empty(),
2526+
"the 'unknown' !prof operand should not be an empty string");
2527+
}
25182528

25192529
void Verifier::verifyFunctionMetadata(
25202530
ArrayRef<std::pair<unsigned, MDNode *>> MDs) {
25212531
for (const auto &Pair : MDs) {
25222532
if (Pair.first == LLVMContext::MD_prof) {
25232533
MDNode *MD = Pair.second;
2534+
Check(MD->getNumOperands() >= 2,
2535+
"!prof annotations should have no less than 2 operands", MD);
25242536
// We may have functions that are synthesized by the compiler, e.g. in
25252537
// WPD, that we can't currently determine the entry count.
2526-
if (isExplicitlyUnknownProfileMetadata(*MD))
2538+
if (MD->getOperand(0).equalsStr(
2539+
MDProfLabels::UnknownBranchWeightsMarker)) {
2540+
verifyUnknownProfileMetadata(MD);
25272541
continue;
2528-
2529-
Check(MD->getNumOperands() >= 2,
2530-
"!prof annotations should have no less than 2 operands", MD);
2542+
}
25312543

25322544
// Check first operand.
25332545
Check(MD->getOperand(0) != nullptr, "first operand should not be null",
@@ -5054,8 +5066,7 @@ void Verifier::visitProfMetadata(Instruction &I, MDNode *MD) {
50545066
"'unknown' !prof should only appear on instructions on which "
50555067
"'branch_weights' would",
50565068
MD);
5057-
Check(MD->getNumOperands() == 1,
5058-
"'unknown' !prof should have no additional operands", MD);
5069+
verifyUnknownProfileMetadata(MD);
50595070
return;
50605071
}
50615072

llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1495,7 +1495,7 @@ void DevirtModule::tryICallBranchFunnel(
14951495

14961496
if (!JT->getEntryCount().has_value()) {
14971497
// FIXME: we could pass through thinlto the necessary information.
1498-
setExplicitlyUnknownFunctionEntryCount(*JT);
1498+
setExplicitlyUnknownFunctionEntryCount(*JT, DEBUG_TYPE);
14991499
}
15001500
}
15011501

llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ expandToSwitch(CallBase *CB, const JumpTableTy &JT, DomTreeUpdater &DTU,
186186
setBranchWeights(*Switch, downscaleWeights(BranchWeights),
187187
/*IsExpected=*/false);
188188
} else
189-
setExplicitlyUnknownBranchWeights(*Switch);
189+
setExplicitlyUnknownBranchWeights(*Switch, DEBUG_TYPE);
190190
if (PHI)
191191
CB->replaceAllUsesWith(PHI);
192192
CB->eraseFromParent();

llvm/test/Transforms/JumpTableToSwitch/basic.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ define i32 @function_with_jump_table_addrspace_42(i32 %index) addrspace(42) {
286286
; CHECK: [[META0]] = !{i64 5678}
287287
; CHECK: [[META1]] = !{i64 5555}
288288
; CHECK: [[PROF2]] = !{!"branch_weights", i32 0, i32 20, i32 5}
289-
; CHECK: [[PROF3]] = !{!"unknown"}
289+
; CHECK: [[PROF3]] = !{!"unknown", !"jump-table-to-switch"}
290290
;.
291291
; THRESHOLD-0: [[META0]] = !{i64 5678}
292292
; THRESHOLD-0: [[META1]] = !{i64 5555}

llvm/test/Transforms/PGOProfile/prof-inject-existing.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ no:
1414
}
1515

1616
!0 = !{!"branch_weights", i32 1, i32 2}
17-
!1 = !{!"unknown"}
17+
!1 = !{!"unknown", !"test"}
1818
; CHECK: define void @foo(i32 %i) !prof !0
1919
; CHECK: br i1 %c, label %yes, label %no, !prof !1
2020
; CHECK: !0 = !{!"function_entry_count", i64 1000}
2121
; CHECK: !1 = !{!"branch_weights", i32 1, i32 2}
22-
; CHECK: !2 = !{!"unknown"}
22+
; CHECK: !2 = !{!"unknown", !"test"}

llvm/test/Transforms/PGOProfile/prof-verify-existing.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ no:
1515

1616
!0 = !{!"function_entry_count", i32 1}
1717
!1 = !{!"branch_weights", i32 1, i32 2}
18-
!2 = !{!"unknown"}
18+
!2 = !{!"unknown", !"test"}
1919
; CHECK: define void @foo(i32 %i) !prof !0
2020
; CHECK: br i1 %c, label %yes, label %no, !prof !1
2121
; CHECK: !0 = !{!"function_entry_count", i64 1}
2222
; CHECK: !1 = !{!"branch_weights", i32 1, i32 2}
23-
; CHECK: !2 = !{!"unknown"}
23+
; CHECK: !2 = !{!"unknown", !"test"}

llvm/test/Transforms/WholeProgramDevirt/branch-funnel-profile.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
; NORETP: define hidden void @__typeid_typeid1_rv_0_branch_funnel(ptr nest %0, ...) !prof !11
1818
; NORETP: define internal void @branch_funnel(ptr nest %0, ...) !prof !11
1919
; NORETP: define internal void @branch_funnel.1(ptr nest %0, ...) !prof !11
20-
; NORETP: !11 = !{!"unknown"}
20+
; NORETP: !11 = !{!"unknown", !"wholeprogramdevirt"}
2121

2222
; O3: define hidden void @__typeid_typeid1_0_branch_funnel(ptr nest %0, ...) local_unnamed_addr #5 !prof !11
2323
; O3: define hidden void @__typeid_typeid1_rv_0_branch_funnel(ptr nest %0, ...) local_unnamed_addr #5 !prof !11
@@ -27,7 +27,7 @@
2727
; O3: define hidden void @__typeid_typeid3_rv_0_branch_funnel(ptr nest %0, ...) local_unnamed_addr #5 !prof !12
2828
; O3: !10 = !{!"function_entry_count", i64 1000}
2929
; O3: !11 = !{!"function_entry_count", i64 3000}
30-
; O3: !12 = !{!"unknown"}
30+
; O3: !12 = !{!"unknown", !"wholeprogramdevirt"}
3131

3232
target datalayout = "e-p:64:64"
3333
target triple = "x86_64-unknown-linux-gnu"

llvm/test/Verifier/branch-weight.ll

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
; RUN: opt -passes=verify %t/unknown-correct.ll --disable-output
1212

1313
; RUN: not opt -passes=verify %t/unknown-invalid.ll --disable-output 2>&1 | FileCheck %s --check-prefix=EXTRA-ARGS
14+
; RUN: not opt -passes=verify %t/unknown-noargs.ll --disable-output 2>&1 | FileCheck %s --check-prefix=NO-ARGS
15+
; RUN: not opt -passes=verify %t/unknown-empty.ll --disable-output 2>&1 | FileCheck %s --check-prefix=EMPTY-ARGS
1416
; RUN: opt -passes=verify %t/unknown-on-function1.ll -S -o - | FileCheck %s --check-prefix=ON-FUNCTION1
1517
; RUN: not opt -passes=verify %t/unknown-on-function2.ll --disable-output 2>&1 | FileCheck %s --check-prefix=ON-FUNCTION2
1618
; RUN: not opt -passes=verify %t/invalid-unknown-placement.ll --disable-output 2>&1 | FileCheck %s --check-prefix=INVALID-UNKNOWN-PLACEMENT
@@ -111,7 +113,7 @@ exit:
111113
ret i32 %r
112114
}
113115

114-
!0 = !{!"unknown"}
116+
!0 = !{!"unknown", !"test"}
115117

116118
;--- unknown-invalid.ll
117119
define void @test(i32 %a) {
@@ -124,14 +126,14 @@ no:
124126
}
125127

126128
!0 = !{!"unknown", i32 12, i32 67}
127-
; EXTRA-ARGS: 'unknown' !prof should have no additional operands
129+
; EXTRA-ARGS: 'unknown' !prof should have a single additional operand
128130

129131
;--- unknown-on-function1.ll
130132
define void @test() !prof !0 {
131133
ret void
132134
}
133135

134-
!0 = !{!"unknown"}
136+
!0 = !{!"unknown", !"test"}
135137
; ON-FUNCTION1: define void @test() !prof !0
136138

137139
;--- unknown-on-function2.ll
@@ -140,12 +142,38 @@ define void @test() !prof !0 {
140142
}
141143

142144
!0 = !{!"unknown", i64 123}
143-
; ON-FUNCTION2: first operand should be 'function_entry_count' or 'synthetic_function_entry_count'
145+
; ON-FUNCTION2: 'unknown' !prof should have an additional operand of type string
144146

145147
;--- invalid-unknown-placement.ll
146148
define i32 @test() {
147149
%r = add i32 1, 2, !prof !0
148150
ret i32 %r
149151
}
150-
!0 = !{!"unknown"}
152+
!0 = !{!"unknown", !"test"}
151153
; INVALID-UNKNOWN-PLACEMENT: 'unknown' !prof should only appear on instructions on which 'branch_weights' would
154+
155+
;--- unknown-noargs.ll
156+
define void @test(i32 %a) {
157+
%c = icmp eq i32 %a, 0
158+
br i1 %c, label %yes, label %no, !prof !0
159+
yes:
160+
ret void
161+
no:
162+
ret void
163+
}
164+
165+
!0 = !{!"unknown"}
166+
; NO-ARGS: 'unknown' !prof should have a single additional operand
167+
168+
;--- unknown-empty.ll
169+
define void @test(i32 %a) {
170+
%c = icmp eq i32 %a, 0
171+
br i1 %c, label %yes, label %no, !prof !0
172+
yes:
173+
ret void
174+
no:
175+
ret void
176+
}
177+
178+
!0 = !{!"unknown", !""}
179+
; EMPTY-ARGS: the 'unknown' !prof operand should not be an empty string

0 commit comments

Comments
 (0)