File indexing completed on 2026-05-10 08:43:13
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef LLVM_ANALYSIS_INDIRECTCALLVISITOR_H
0013 #define LLVM_ANALYSIS_INDIRECTCALLVISITOR_H
0014
0015 #include "llvm/IR/InstVisitor.h"
0016 #include <vector>
0017
0018 namespace llvm {
0019
0020
0021 struct PGOIndirectCallVisitor : public InstVisitor<PGOIndirectCallVisitor> {
0022 enum class InstructionType {
0023 kIndirectCall = 0,
0024 kVTableVal = 1,
0025 };
0026 std::vector<CallBase *> IndirectCalls;
0027 std::vector<Instruction *> ProfiledAddresses;
0028 PGOIndirectCallVisitor(InstructionType Type) : Type(Type) {}
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 static Instruction *tryGetVTableInstruction(CallBase *CB) {
0039 assert(CB != nullptr && "Caller guaranteed");
0040 if (!CB->isIndirectCall())
0041 return nullptr;
0042
0043 LoadInst *LI = dyn_cast<LoadInst>(CB->getCalledOperand());
0044 if (LI != nullptr) {
0045 Value *FuncPtr = LI->getPointerOperand();
0046 Value *VTablePtr = FuncPtr->stripInBoundsConstantOffsets();
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057 if (VTablePtr != nullptr && isa<Instruction>(VTablePtr))
0058 return cast<Instruction>(VTablePtr);
0059 }
0060 return nullptr;
0061 }
0062
0063 void visitCallBase(CallBase &Call) {
0064 if (Call.isIndirectCall()) {
0065 IndirectCalls.push_back(&Call);
0066
0067 if (Type != InstructionType::kVTableVal)
0068 return;
0069
0070 Instruction *VPtr =
0071 PGOIndirectCallVisitor::tryGetVTableInstruction(&Call);
0072 if (VPtr)
0073 ProfiledAddresses.push_back(VPtr);
0074 }
0075 }
0076
0077 private:
0078 InstructionType Type;
0079 };
0080
0081 inline std::vector<CallBase *> findIndirectCalls(Function &F) {
0082 PGOIndirectCallVisitor ICV(
0083 PGOIndirectCallVisitor::InstructionType::kIndirectCall);
0084 ICV.visit(F);
0085 return ICV.IndirectCalls;
0086 }
0087
0088 inline std::vector<Instruction *> findVTableAddrs(Function &F) {
0089 PGOIndirectCallVisitor ICV(
0090 PGOIndirectCallVisitor::InstructionType::kVTableVal);
0091 ICV.visit(F);
0092 return ICV.ProfiledAddresses;
0093 }
0094
0095 }
0096
0097 #endif