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]Extract the heuristic to find vtable for an indirect call into a helper function #81024

Merged
merged 5 commits into from
May 7, 2024

Conversation

minglotus-6
Copy link
Contributor

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

@minglotus-6 minglotus-6 changed the title [NFC]Refactor [NFC]Extract the heuristic to find vtable for an indirect call into a helper function for re-use Feb 7, 2024
@minglotus-6 minglotus-6 changed the title [NFC]Extract the heuristic to find vtable for an indirect call into a helper function for re-use [NFC]Extract the heuristic to find vtable for an indirect call into a helper function Feb 7, 2024
@minglotus-6 minglotus-6 marked this pull request as ready for review February 8, 2024 02:21
@llvmbot
Copy link
Collaborator

llvmbot commented Feb 8, 2024

@llvm/pr-subscribers-llvm-analysis

Author: Mingming Liu (minglotus-6)

Changes

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

1 Files Affected:

  • (modified) llvm/include/llvm/Analysis/IndirectCallVisitor.h (+36-27)
diff --git a/llvm/include/llvm/Analysis/IndirectCallVisitor.h b/llvm/include/llvm/Analysis/IndirectCallVisitor.h
index c8429e52bee96..5969241a179ea 100644
--- a/llvm/include/llvm/Analysis/IndirectCallVisitor.h
+++ b/llvm/include/llvm/Analysis/IndirectCallVisitor.h
@@ -28,6 +28,38 @@ struct PGOIndirectCallVisitor : public InstVisitor<PGOIndirectCallVisitor> {
   std::vector<Instruction *> ProfiledAddresses;
   PGOIndirectCallVisitor(InstructionType Type) : Type(Type) {}
 
+  // Given an indirect call instruction, try to find the the following pattern
+  //
+  // %vtable = load ptr, ptr %obj
+  // %vfn = getelementptr inbounds ptr, ptr %vtable, i64 1
+  // %2 = load ptr, ptr %vfn
+  // $call = tail call i32 %2
+  //
+  // A heuristic is used to find the address feeding instructions.
+  static Instruction *tryGetVTableInstruction(CallBase *CB) {
+    assert(CB != nullptr && "Caller guaranteed");
+    LoadInst *LI = dyn_cast<LoadInst>(CB->getCalledOperand());
+
+    if (LI != nullptr) {
+      Value *FuncPtr = LI->getPointerOperand(); // GEP (or bitcast)
+      Value *VTablePtr = FuncPtr->stripInBoundsConstantOffsets();
+      // FIXME: Add support in the frontend so LLVM type intrinsics are
+      // emitted without LTO. This way, added intrinsics could filter
+      // non-vtable instructions and reduce instrumentation overhead.
+      // Since a non-vtable profiled address is not within the address
+      // range of vtable objects, it's stored as zero in indexed profiles.
+      // A pass that looks up symbol with an zero hash will (almost) always
+      // find nullptr and skip the actual transformation (e.g., comparison
+      // of symbols). So the performance overhead from non-vtable profiled
+      // address is negligible if exists at all. Comparing loaded address
+      // with symbol address guarantees correctness.
+      if (VTablePtr != nullptr && isa<Instruction>(VTablePtr)) {
+        return cast<Instruction>(VTablePtr);
+      }
+    }
+    return nullptr;
+  }
+
   void visitCallBase(CallBase &Call) {
     if (Call.isIndirectCall()) {
       IndirectCalls.push_back(&Call);
@@ -35,33 +67,10 @@ struct PGOIndirectCallVisitor : public InstVisitor<PGOIndirectCallVisitor> {
       if (Type != InstructionType::kVTableVal)
         return;
 
-      LoadInst *LI = dyn_cast<LoadInst>(Call.getCalledOperand());
-      // The code pattern to look for
-      //
-      // %vtable = load ptr, ptr %b
-      // %vfn = getelementptr inbounds ptr, ptr %vtable, i64 1
-      // %2 = load ptr, ptr %vfn
-      // %call = tail call i32 %2(ptr %b)
-      //
-      // %vtable is the vtable address value to profile, and
-      // %2 is the indirect call target address to profile.
-      if (LI != nullptr) {
-        Value *Ptr = LI->getPointerOperand();
-        Value *VTablePtr = Ptr->stripInBoundsConstantOffsets();
-        // This is a heuristic to find address feeding instructions.
-        // FIXME: Add support in the frontend so LLVM type intrinsics are
-        // emitted without LTO. This way, added intrinsics could filter
-        // non-vtable instructions and reduce instrumentation overhead.
-        // Since a non-vtable profiled address is not within the address
-        // range of vtable objects, it's stored as zero in indexed profiles.
-        // A pass that looks up symbol with an zero hash will (almost) always
-        // find nullptr and skip the actual transformation (e.g., comparison
-        // of symbols). So the performance overhead from non-vtable profiled
-        // address is negligible if exists at all. Comparing loaded address
-        // with symbol address guarantees correctness.
-        if (VTablePtr != nullptr && isa<Instruction>(VTablePtr)) {
-          ProfiledAddresses.push_back(cast<Instruction>(VTablePtr));
-        }
+      Instruction *VPtr =
+          PGOIndirectCallVisitor::tryGetVTableInstruction(&Call);
+      if (VPtr) {
+        ProfiledAddresses.push_back(VPtr);
       }
     }
   }

@minglotus-6 minglotus-6 changed the base branch from users/minglotus-6/spr/main.nfcrefactor to main April 12, 2024 00:11
@minglotus-6 minglotus-6 marked this pull request as ready for review April 12, 2024 00:12
@minglotus-6 minglotus-6 merged commit 879245e into main May 7, 2024
4 checks passed
@minglotus-6 minglotus-6 deleted the users/minglotus-6/spr/nfcrefactor branch May 7, 2024 04:39
@minglotus-6 minglotus-6 restored the users/minglotus-6/spr/nfcrefactor branch May 24, 2024 21:22
@minglotus-6 minglotus-6 deleted the users/minglotus-6/spr/nfcrefactor branch May 24, 2024 21:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants