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 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits