Skip to content
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

[NFC][IndirectCallProm] Refactor function-based conditional devirtualization and indirect call value profile update into one helper function #80762

Merged
merged 4 commits into from
Apr 11, 2024

Conversation

minglotus-6
Copy link
Contributor

@minglotus-6 minglotus-6 commented Feb 5, 2024

  • The motivation is to move indirect callee profile update inside the function-based speculative indirect-call promotion, so that there are fewer diffs the vtable-based transformation and profile update is implemented in a follow-up patch.
  • The Parent patch is [ThinLTO][TypeProf] Implement vtable def import #79381

@bwendling
Copy link
Collaborator

Please add a title and description.

@minglotus-6 minglotus-6 changed the title [NFC] [NFC] Refactor indirect-call IR transformations and indirect call value profile update into one helper function Feb 6, 2024
@minglotus-6 minglotus-6 changed the title [NFC] Refactor indirect-call IR transformations and indirect call value profile update into one helper function [NFC][IndirectCallProm] Refactor function-based conditional devirtualization and indirect call value profile update into one helper function Feb 6, 2024
@minglotus-6
Copy link
Contributor Author

Please add a title and description.

Done. I used a (temporary) short (and undescriptive) title to work around a lengthy branch name in spr-managed branches. More details on why this happens is elaborated in this discourse thread.

I'll keep it a draft for now and send this out together with a subsequent pull request which looks cleaner with this NFC one.

@@ -1260,6 +1260,8 @@ void annotateValueSite(Module &M, Instruction &Inst,
ArrayRef<InstrProfValueData> VDs,
uint64_t Sum, InstrProfValueKind ValueKind,
uint32_t MaxMDCount) {
if (VDs.empty())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this change?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, is this because you no longer check the "NumPromoted == NumVals" case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, the check NumPromoted == NumVals is removed so NumVals doesn't need to be passed as an argument to tryToPromoteWithFuncCmp.

  • NumVals == ICallProfDataRef.size() is always true, and NumPromoted <= NumVals is also true, so ICallProfDataRef.slice(NumPromoted) still returns a valid ArrayRef after the check is removed.

On a second thought, when if(TotalCount != 0) is true, it's also guaranteed ICallProfDataRef.slice(NumPromoted) is not empty so that ICallProfDataRef.slice(NumPromoted) returns a valid ArrayRef. Added an assert (assert(NumPromoted <= ICallProfDataRef.size()) just to make the condition that .slice relies on more explicit.

@@ -287,7 +290,18 @@ uint32_t IndirectCallPromoter::tryToPromote(
NumOfPGOICallPromotion++;
NumPromoted++;
}
return NumPromoted;

const bool Changed = (NumPromoted != 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just return false early if NumPromoted is 0 (then Changed can be removed and just return true at the end further below).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

Created using spr 1.3.4
@minglotus-6 minglotus-6 changed the title [NFC][IndirectCallProm] Refactor function-based conditional devirtualization and indirect call value profile update into one helper function [NFC] Feb 8, 2024
@minglotus-6 minglotus-6 marked this pull request as ready for review February 8, 2024 02:21
@llvmbot llvmbot added PGO Profile Guided Optimizations llvm:transforms labels Feb 8, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Feb 8, 2024

@llvm/pr-subscribers-llvm-transforms

@llvm/pr-subscribers-pgo

Author: Mingming Liu (minglotus-6)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/80762.diff

3 Files Affected:

  • (modified) llvm/include/llvm/ProfileData/InstrProf.h (+2)
  • (modified) llvm/lib/ProfileData/InstrProf.cpp (+2)
  • (modified) llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp (+28-21)
diff --git a/llvm/include/llvm/ProfileData/InstrProf.h b/llvm/include/llvm/ProfileData/InstrProf.h
index 248f62c7a81059..6cdceae5eeb960 100644
--- a/llvm/include/llvm/ProfileData/InstrProf.h
+++ b/llvm/include/llvm/ProfileData/InstrProf.h
@@ -277,6 +277,8 @@ void annotateValueSite(Module &M, Instruction &Inst,
                        uint32_t MaxMDCount = 3);
 
 /// Same as the above interface but using an ArrayRef, as well as \p Sum.
+/// This function will not annotate !prof metadata on the instruction if the
+/// referenced array is empty.
 void annotateValueSite(Module &M, Instruction &Inst,
                        ArrayRef<InstrProfValueData> VDs, uint64_t Sum,
                        InstrProfValueKind ValueKind, uint32_t MaxMDCount);
diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp
index 1d8b0a1aca95f2..91e79e8b2e9add 100644
--- a/llvm/lib/ProfileData/InstrProf.cpp
+++ b/llvm/lib/ProfileData/InstrProf.cpp
@@ -1260,6 +1260,8 @@ void annotateValueSite(Module &M, Instruction &Inst,
                        ArrayRef<InstrProfValueData> VDs,
                        uint64_t Sum, InstrProfValueKind ValueKind,
                        uint32_t MaxMDCount) {
+  if (VDs.empty())
+    return;
   LLVMContext &Ctx = M.getContext();
   MDBuilder MDHelper(Ctx);
   SmallVector<Metadata *, 3> Vals;
diff --git a/llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp b/llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp
index 7344fea1751719..23a7c6a20aecbc 100644
--- a/llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp
+++ b/llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp
@@ -136,11 +136,13 @@ class IndirectCallPromoter {
       const CallBase &CB, const ArrayRef<InstrProfValueData> &ValueDataRef,
       uint64_t TotalCount, uint32_t NumCandidates);
 
-  // Promote a list of targets for one indirect-call callsite. Return
-  // the number of promotions.
-  uint32_t tryToPromote(CallBase &CB,
-                        const std::vector<PromotionCandidate> &Candidates,
-                        uint64_t &TotalCount);
+  // Promote a list of targets for one indirect-call callsite by comparing
+  // indirect callee with functions. Returns true if there are IR
+  // transformations and false otherwise.
+  bool tryToPromoteWithFuncCmp(
+      CallBase &CB, const std::vector<PromotionCandidate> &Candidates,
+      uint64_t TotalCount, ArrayRef<InstrProfValueData> ICallProfDataRef,
+      uint32_t NumCandidates);
 
 public:
   IndirectCallPromoter(Function &Func, InstrProfSymtab *Symtab, bool SamplePGO,
@@ -273,9 +275,10 @@ CallBase &llvm::pgo::promoteIndirectCall(CallBase &CB, Function *DirectCallee,
 }
 
 // Promote indirect-call to conditional direct-call for one callsite.
-uint32_t IndirectCallPromoter::tryToPromote(
+bool IndirectCallPromoter::tryToPromoteWithFuncCmp(
     CallBase &CB, const std::vector<PromotionCandidate> &Candidates,
-    uint64_t &TotalCount) {
+    uint64_t TotalCount, ArrayRef<InstrProfValueData> ICallProfDataRef,
+    uint32_t NumCandidates) {
   uint32_t NumPromoted = 0;
 
   for (const auto &C : Candidates) {
@@ -287,7 +290,22 @@ uint32_t IndirectCallPromoter::tryToPromote(
     NumOfPGOICallPromotion++;
     NumPromoted++;
   }
-  return NumPromoted;
+
+  if (NumPromoted == 0)
+    return false;
+
+  // Adjust the MD.prof metadata. First delete the old one.
+  CB.setMetadata(LLVMContext::MD_prof, nullptr);
+
+  assert(NumPromoted <= ICallProfDataRef.size() &&
+         "Number of promoted functions should not be greater than the number "
+         "of values in profile metadata");
+  // Annotate the remaining value profiles if counter is not zero.
+  if (TotalCount != 0)
+    annotateValueSite(*F.getParent(), CB, ICallProfDataRef.slice(NumPromoted),
+                      TotalCount, IPVK_IndirectCallTarget, NumCandidates);
+
+  return true;
 }
 
 // Traverse all the indirect-call callsite and get the value profile
@@ -305,19 +323,8 @@ bool IndirectCallPromoter::processFunction(ProfileSummaryInfo *PSI) {
       continue;
     auto PromotionCandidates = getPromotionCandidatesForCallSite(
         *CB, ICallProfDataRef, TotalCount, NumCandidates);
-    uint32_t NumPromoted = tryToPromote(*CB, PromotionCandidates, TotalCount);
-    if (NumPromoted == 0)
-      continue;
-
-    Changed = true;
-    // Adjust the MD.prof metadata. First delete the old one.
-    CB->setMetadata(LLVMContext::MD_prof, nullptr);
-    // If all promoted, we don't need the MD.prof metadata.
-    if (TotalCount == 0 || NumPromoted == NumVals)
-      continue;
-    // Otherwise we need update with the un-promoted records back.
-    annotateValueSite(*F.getParent(), *CB, ICallProfDataRef.slice(NumPromoted),
-                      TotalCount, IPVK_IndirectCallTarget, NumCandidates);
+    Changed |= tryToPromoteWithFuncCmp(*CB, PromotionCandidates, TotalCount,
+                                       ICallProfDataRef, NumCandidates);
   }
   return Changed;
 }

@minglotus-6 minglotus-6 changed the title [NFC] [NFC][IndirectCallProm] Refactor function-based conditional devirtualization and indirect call value profile update into one helper function Feb 8, 2024
@minglotus-6 minglotus-6 marked this pull request as draft April 11, 2024 16:27
@minglotus-6 minglotus-6 changed the base branch from users/minglotus-6/spr/main.nfc to main April 11, 2024 17:24
@minglotus-6
Copy link
Contributor Author

Ran 'git merge main' and resolved the merge conflicts

@minglotus-6 minglotus-6 marked this pull request as ready for review April 11, 2024 17:24
@minglotus-6 minglotus-6 merged commit 08e210c into main Apr 11, 2024
14 of 17 checks passed
@minglotus-6 minglotus-6 deleted the users/minglotus-6/spr/nfc branch April 11, 2024 20:28
minglotus-6 added a commit that referenced this pull request May 7, 2024
… helper function (#81024)

* This way the helper function could be re-used by
indirect-call-promotion pass to find out the vtable for an indirect call
and extract the value profiles if any.
* The parent patch is #80762
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
llvm:transforms PGO Profile Guided Optimizations
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants