-
Notifications
You must be signed in to change notification settings - Fork 11.9k
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
[InstrPGO][TypeProf]Annotate vtable types when they are present in the profile #99402
Conversation
…profiles and 'enable-vtable-value-profiling' is not explicitly off
@llvm/pr-subscribers-llvm-transforms @llvm/pr-subscribers-pgo Author: Mingming Liu (minglotus-6) ChangesBefore this change, when It's better to automatically annotate vtable profiles if
Full diff: https://github.com/llvm/llvm-project/pull/99402.diff 2 Files Affected:
diff --git a/compiler-rt/test/profile/Linux/instrprof-vtable-value-prof.cpp b/compiler-rt/test/profile/Linux/instrprof-vtable-value-prof.cpp
index 24a96a227393a..83ceb9b0cf556 100644
--- a/compiler-rt/test/profile/Linux/instrprof-vtable-value-prof.cpp
+++ b/compiler-rt/test/profile/Linux/instrprof-vtable-value-prof.cpp
@@ -109,6 +109,26 @@
// ICTEXT: {{.*}}instrprof-vtable-value-prof.cpp;_ZTVN12_GLOBAL__N_18Derived2E:750
// ICTEXT: _ZTV8Derived1:250
+// When vtable value profiles exist, pgo-instr-use pass should annotate them
+// even if `-enable-vtable-value-profiling` is not explicitly on.
+// RUN: %clangxx -m64 -fprofile-use=test.profdata -fuse-ld=lld -O2 \
+// RUN: -mllvm -print-after=pgo-instr-use -mllvm -filter-print-funcs=main \
+// RUN: -mllvm -print-module-scope %s 2>&1 | FileCheck %s --check-prefix=ANNOTATE
+
+// ANNOTATE-NOT: Inconsistent number of value sites
+// ANNOTATE: !{!"VP", i32 2
+
+// When vtable value profiles exist, pgo-instr-use pass will not annotate them
+// if `-enable-vtable-profile-use` is explicitly set to false to discard vtable
+// value profiles.
+// RUN: %clangxx -m64 -fprofile-use=test.profdata -fuse-ld=lld -O2 \
+// RUN: -mllvm -enable-vtable-profile-use=false -mllvm -print-after=pgo-instr-use \
+// RUN: -mllvm -filter-print-funcs=main -mllvm -print-module-scope %s 2>&1 | \
+// RUN: FileCheck %s --check-prefix=OMIT
+
+// OMIT: Inconsistent number of value sites
+// OMIT-NOT: !{!"VP", i32 2
+
// Test indirect call promotion transformation using vtable profiles.
// - Build with `-g` to enable debug information.
// - In real world settings, ICP pass is disabled in prelink pipeline. In
@@ -128,12 +148,12 @@
// RUN: | FileCheck %s --check-prefixes=REMARK,IR --implicit-check-not="!VP"
// For the indirect call site `ptr->func`
-// REMARK: instrprof-vtable-value-prof.cpp:205:19: Promote indirect call to _ZN12_GLOBAL__N_18Derived24funcEii with count 150 out of 200, sink 1 instruction(s) and compare 1 vtable(s): {_ZTVN12_GLOBAL__N_18Derived2E}
-// REMARK: instrprof-vtable-value-prof.cpp:205:19: Promote indirect call to _ZN8Derived14funcEii with count 50 out of 50, sink 1 instruction(s) and compare 1 vtable(s): {_ZTV8Derived1}
+// REMARK: instrprof-vtable-value-prof.cpp:227:19: Promote indirect call to _ZN12_GLOBAL__N_18Derived24funcEii with count 150 out of 200, sink 1 instruction(s) and compare 1 vtable(s): {_ZTVN12_GLOBAL__N_18Derived2E}
+// REMARK: instrprof-vtable-value-prof.cpp:227:19: Promote indirect call to _ZN8Derived14funcEii with count 50 out of 50, sink 1 instruction(s) and compare 1 vtable(s): {_ZTV8Derived1}
//
// For the indirect call site `delete ptr`
-// REMARK: instrprof-vtable-value-prof.cpp:207:5: Promote indirect call to _ZN12_GLOBAL__N_18Derived2D0Ev with count 750 out of 1000, sink 2 instruction(s) and compare 1 vtable(s): {_ZTVN12_GLOBAL__N_18Derived2E}
-// REMARK: instrprof-vtable-value-prof.cpp:207:5: Promote indirect call to _ZN8Derived1D0Ev with count 250 out of 250, sink 2 instruction(s) and compare 1 vtable(s): {_ZTV8Derived1}
+// REMARK: instrprof-vtable-value-prof.cpp:229:5: Promote indirect call to _ZN12_GLOBAL__N_18Derived2D0Ev with count 750 out of 1000, sink 2 instruction(s) and compare 1 vtable(s): {_ZTVN12_GLOBAL__N_18Derived2E}
+// REMARK: instrprof-vtable-value-prof.cpp:229:5: Promote indirect call to _ZN8Derived1D0Ev with count 250 out of 250, sink 2 instruction(s) and compare 1 vtable(s): {_ZTV8Derived1}
// The IR matchers for indirect callsite `ptr->func`.
// IR-LABEL: @main
diff --git a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
index 35b1bbf21be97..2baca05988808 100644
--- a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
+++ b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
@@ -1096,7 +1096,7 @@ class PGOUseFunc {
: F(Func), M(Modu), BFI(BFIin), PSI(PSI),
FuncInfo(Func, TLI, ComdatMembers, false, BPI, BFIin, IsCS,
InstrumentFuncEntry, HasSingleByteCoverage),
- FreqAttr(FFA_Normal), IsCS(IsCS) {}
+ FreqAttr(FFA_Normal), IsCS(IsCS), VPC(Func, TLI) {}
void handleInstrProfError(Error Err, uint64_t MismatchedFuncSum);
@@ -1178,6 +1178,8 @@ class PGOUseFunc {
// Is to use the context sensitive profile.
bool IsCS;
+ ValueProfileCollector VPC;
+
// Find the Instrumented BB and set the value. Return false on error.
bool setInstrumentedCounts(const std::vector<uint64_t> &CountFromProfile);
@@ -1755,8 +1757,18 @@ void PGOUseFunc::annotateValueSites() {
void PGOUseFunc::annotateValueSites(uint32_t Kind) {
assert(Kind <= IPVK_Last);
unsigned ValueSiteIndex = 0;
- auto &ValueSites = FuncInfo.ValueSites[Kind];
unsigned NumValueSites = ProfileRecord.getNumValueSites(Kind);
+ // FuncPGOInstrumentation ctor finds value sites for each kind. It runs on the
+ // common path of pgo-instr-gen and pgo-instr-use, and vtable kind path
+ // is gated by `-enable-vtable-value-profiling`. If vtable profiles are
+ // present, not explicitly discarded and vtable sites remain empty, try to
+ // find the sites again.
+ if (NumValueSites > 0 && Kind == IPVK_VTableTarget &&
+ FuncInfo.ValueSites[Kind].empty() &&
+ !(EnableVTableProfileUse.getNumOccurrences() &&
+ EnableVTableProfileUse == false))
+ FuncInfo.ValueSites[IPVK_VTableTarget] = VPC.get(IPVK_VTableTarget);
+ auto &ValueSites = FuncInfo.ValueSites[Kind];
if (NumValueSites != ValueSites.size()) {
auto &Ctx = M->getContext();
Ctx.diagnose(DiagnosticInfoPGOProfile(
|
// common path of pgo-instr-gen and pgo-instr-use, and vtable kind path | ||
// is gated by `-enable-vtable-value-profiling`. If vtable profiles are | ||
// present, not explicitly discarded and vtable sites remain empty, try to | ||
// find the sites again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why can't this just always be done here:
llvm-project/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
Lines 606 to 607 in d06b55e
if (EnableVTableValueProfiling) | |
ValueSites[IPVK_VTableTarget] = VPC.get(IPVK_VTableTarget); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This runs on the common path of pgo-instr-gen
and pgo-instr-run
. There isn't a reliably way to tell if iFDO profile are generated with --enable-vtable-value-profiling
or not [1], and it's preferred to have an option to disable VPC.get(IPVK_VTableTarget)
(which iterates instructions and collect instrumentation sites via InstVisitor)
As discussed, I simplified this code by
- Enable value-profile-collector (VPC) instruction iteration for optimized build.
- Allow skipping
VPC.get(IPVK_VTableTarget)
[1] if a program doesn't use vtable but its instrumented profiles are generated with --enable-vtable-value-profiling=true
, iterating function profile record won't tell this with the current profile format.
if (NumValueSites > 0 && Kind == IPVK_VTableTarget && | ||
FuncInfo.ValueSites[Kind].empty() && | ||
!(EnableVTableProfileUse.getNumOccurrences() && | ||
EnableVTableProfileUse == false)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this need to depend on whether we are using it in the optimization passes? Won't we then get matching warnings if someone disables that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EnableVTableProfileUse.getNumOccurrences() && EnableVTableProfileUse == false
meant to allow skipping VPC.get(IPVK_VTableTarget)
. Now this PR uses -icp-max-num-vtables
to do that.
While adding TODOs to speed up optimized build by skipping VPC.get(<value-profile-kind>)
if there are no value profiles of this kind in function profile record, I realized VPC.get(<value-profile-kind>)
for optimized build is necessary to compute function cfg hash with IR and detect profile mismatch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm with a suggestion below
// Collect value sites for 'pgo-instr-use' pass if `icp-max-num-vtables` | ||
// is not zero. | ||
if (EnableVTableValueProfiling || | ||
(!CreateGlobalVar && MaxNumVTableAnnotations != 0)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a comment about why the !CreateGlobalVar
check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I didn't realize 36b85b8 would cause benign warnings when profile is generated in enable-vtable-value-profiling=false
when we discussed earlier.
I updated the PR to conditionally compute the vtable value sites and annotate profiles iff function profile record has vtable value profiles.
Regarding rollout, it'd make sense to keep enable-vtable-value-profiling
consistent in instrumentation and optimized build.
…ofile record has vtable profiles
// ANNOTATE: !{!"VP", i32 2 | ||
|
||
// When vtable value profiles exist, pgo-instr-use pass will not annotate them | ||
// if `-max-num-vtable-annotaitons` is set to zero. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo in. "annotaitons". However, this isn't the option used in the test below? It does seem to be what is used in the source code, however.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The option name is wrong. I corrected it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused though because the code in the PR checks MaxNumVTableAnnotations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah this is because the option variable name is MaxNumVTableAnnotations
but its registered string is icp-max-num-vtables
.
llvm-project/llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp
Lines 48 to 50 in bee2654
cl::opt<unsigned> MaxNumVTableAnnotations( | |
"icp-max-num-vtables", cl::init(6), cl::Hidden, | |
cl::desc("Max number of vtables annotated for a vtable load instruction.")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I see. I was thrown off by the naming difference.
// indirect call sites into account so it doesn't hash the number of | ||
// instrumented vtables; as a side effect it makes it easier to enable | ||
// profiling and profile use in two steps if needed. | ||
if (NumValueSites > 0 && Kind == IPVK_VTableTarget && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a TODO to remove this if/when -enable-vtable-value-profiling
is on by default?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
…e profile (llvm#99402) Before this change, when `file.profdata` have vtable profiles but `--enable-vtable-value-profiling` is not on for optimized build, warnings from this line [1] will show up. They are benign for performance but confusing. It's better to automatically annotate vtable profiles if `file.profdata` has them. This PR implements it in profile use pass. * If `-icp-max-num-vtables` is zero (default value is 6), vtable profiles won't be annotated. [1] https://github.com/llvm/llvm-project/blob/464d321ee8dde1eaf14b5537eaf030e6df513849/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp#L1762-L1768
…e profile (#99402) Summary: Before this change, when `file.profdata` have vtable profiles but `--enable-vtable-value-profiling` is not on for optimized build, warnings from this line [1] will show up. They are benign for performance but confusing. It's better to automatically annotate vtable profiles if `file.profdata` has them. This PR implements it in profile use pass. * If `-icp-max-num-vtables` is zero (default value is 6), vtable profiles won't be annotated. [1] https://github.com/llvm/llvm-project/blob/464d321ee8dde1eaf14b5537eaf030e6df513849/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp#L1762-L1768 Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D60251294
Before this change, when
file.profdata
have vtable profiles but--enable-vtable-value-profiling
is not on for optimized build, warnings from this line will show up. They are benign for performance but confusing.It's better to automatically annotate vtable profiles if
file.profdata
has them. This change implements it in profile use pass.-icp-max-num-vtables
is zero (default value is 6), vtable profiles won't be annotated.