[llvm] [clang] [compiler-rt] [clang-tools-extra] [IRPGO][ValueProfile] Instrument virtual table address that could be used to do virtual table address comparision for indirect-call-promotion. (PR #66825)

Snehasish Kumar via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 8 11:47:39 PST 2023


================
@@ -12,27 +12,78 @@
 #ifndef LLVM_ANALYSIS_INDIRECTCALLVISITOR_H
 #define LLVM_ANALYSIS_INDIRECTCALLVISITOR_H
 
+#include "llvm/ADT/SetVector.h"
 #include "llvm/IR/InstVisitor.h"
 #include <vector>
 
 namespace llvm {
-// Visitor class that finds all indirect call.
+// Visitor class that finds indirect calls or instructions that gives vtable
+// value, depending on Type.
 struct PGOIndirectCallVisitor : public InstVisitor<PGOIndirectCallVisitor> {
+  enum class InstructionType {
+    kIndirectCall = 0,
+    kVTableVal = 1,
+  };
   std::vector<CallBase *> IndirectCalls;
-  PGOIndirectCallVisitor() = default;
+  std::vector<Instruction *> ProfiledAddresses;
+  PGOIndirectCallVisitor(InstructionType Type) : Type(Type) {}
 
   void visitCallBase(CallBase &Call) {
-    if (Call.isIndirectCall())
+    if (Call.isIndirectCall()) {
       IndirectCalls.push_back(&Call);
+
+      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.
----------------
snehasish wrote:

Can we drop the ones that don't belong to a vtable add range during merge instead of storing zero?

https://github.com/llvm/llvm-project/pull/66825


More information about the cfe-commits mailing list