[llvm-branch-commits] [NFC]Extract the heuristic to find vtable for an indirect call into a helper function (PR #81024)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Feb 7 18:22:14 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-analysis
Author: Mingming Liu (minglotus-6)
<details>
<summary>Changes</summary>
* 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 https://github.com/llvm/llvm-project/pull/80762
---
Full diff: https://github.com/llvm/llvm-project/pull/81024.diff
1 Files Affected:
- (modified) llvm/include/llvm/Analysis/IndirectCallVisitor.h (+36-27)
``````````diff
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);
}
}
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/81024
More information about the llvm-branch-commits
mailing list