1//=== ValueProfilePlugins.inc - set of plugins used by ValueProfileCollector =//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains a set of plugin classes used in ValueProfileCollectorImpl.
10// Each plugin is responsible for collecting Value Profiling candidates for a
11// particular optimization.
12// Each plugin must satisfy the interface described in ValueProfileCollector.cpp
13//
14//===----------------------------------------------------------------------===//
15
16#include "ValueProfileCollector.h"
17#include "llvm/Analysis/IndirectCallVisitor.h"
18#include "llvm/Analysis/TargetLibraryInfo.h"
19#include "llvm/IR/InstVisitor.h"
20
21using namespace llvm;
22using CandidateInfo = ValueProfileCollector::CandidateInfo;
23
24namespace llvm {
25extern cl::opt<bool> MemOPOptMemcmpBcmp;
26} // end namespace llvm
27
28///--------------------------- MemIntrinsicPlugin ------------------------------
29class MemIntrinsicPlugin : public InstVisitor<MemIntrinsicPlugin> {
30 Function &F;
31 TargetLibraryInfo &TLI;
32 std::vector<CandidateInfo> *Candidates;
33
34public:
35 static constexpr InstrProfValueKind Kind = IPVK_MemOPSize;
36
37 MemIntrinsicPlugin(Function &Fn, TargetLibraryInfo &TLI)
38 : F(Fn), TLI(TLI), Candidates(nullptr) {}
39
40 void run(std::vector<CandidateInfo> &Cs) {
41 Candidates = &Cs;
42 visit(F);
43 Candidates = nullptr;
44 }
45 void visitMemIntrinsic(MemIntrinsic &MI) {
46 Value *Length = MI.getLength();
47 // Not instrument constant length calls.
48 if (isa<ConstantInt>(Val: Length))
49 return;
50
51 Instruction *InsertPt = &MI;
52 Instruction *AnnotatedInst = &MI;
53 Candidates->emplace_back(args: CandidateInfo{.V: Length, .InsertPt: InsertPt, .AnnotatedInst: AnnotatedInst});
54 }
55 void visitCallInst(CallInst &CI) {
56 if (!MemOPOptMemcmpBcmp)
57 return;
58 auto *F = CI.getCalledFunction();
59 if (!F)
60 return;
61 LibFunc Func = TLI.getLibFunc(CB: CI);
62 if (Func == LibFunc_memcmp || Func == LibFunc_bcmp) {
63 Value *Length = CI.getArgOperand(i: 2);
64 // Not instrument constant length calls.
65 if (isa<ConstantInt>(Val: Length))
66 return;
67 Instruction *InsertPt = &CI;
68 Instruction *AnnotatedInst = &CI;
69 Candidates->emplace_back(args: CandidateInfo{.V: Length, .InsertPt: InsertPt, .AnnotatedInst: AnnotatedInst});
70 }
71 }
72};
73
74///------------------------ IndirectCallPromotionPlugin ------------------------
75class IndirectCallPromotionPlugin {
76 Function &F;
77
78public:
79 static constexpr InstrProfValueKind Kind = IPVK_IndirectCallTarget;
80
81 IndirectCallPromotionPlugin(Function &Fn, TargetLibraryInfo &TLI) : F(Fn) {}
82
83 void run(std::vector<CandidateInfo> &Candidates) {
84 std::vector<CallBase *> Result = findIndirectCalls(F);
85 for (Instruction *I : Result) {
86 Value *Callee = cast<CallBase>(Val: I)->getCalledOperand();
87 Instruction *InsertPt = I;
88 Instruction *AnnotatedInst = I;
89 Candidates.emplace_back(args: CandidateInfo{.V: Callee, .InsertPt: InsertPt, .AnnotatedInst: AnnotatedInst});
90 }
91 }
92};
93
94///--------------------- VirtualTableValueProfilingPlugin --------------------
95class VTableProfilingPlugin {
96 Function &F;
97
98public:
99 static constexpr InstrProfValueKind Kind = IPVK_VTableTarget;
100
101 VTableProfilingPlugin(Function &Fn, TargetLibraryInfo &TLI) : F(Fn) {}
102
103 void run(std::vector<CandidateInfo> &Candidates) {
104 std::vector<Instruction *> Result = findVTableAddrs(F);
105 for (Instruction *I : Result) {
106 Instruction *InsertPt = I->getNextNode();
107 // When finding an insertion point, keep PHI and EH pad instructions
108 // before vp intrinsics. This is similar to
109 // `BasicBlock::getFirstInsertionPt`.
110 while (InsertPt && (dyn_cast<PHINode>(Val: InsertPt) || InsertPt->isEHPad()))
111 InsertPt = InsertPt->getNextNode();
112 // Skip instrumentating the value if InsertPt is the last instruction.
113 // FIXME: Set InsertPt to the end of basic block to instrument the value
114 // if InsertPt is the last instruction.
115 if (InsertPt == nullptr)
116 continue;
117
118 Instruction *AnnotatedInst = I;
119 Candidates.emplace_back(args: CandidateInfo{.V: I, .InsertPt: InsertPt, .AnnotatedInst: AnnotatedInst});
120 }
121 }
122};
123
124///----------------------- Registration of the plugins -------------------------
125/// For now, registering a plugin with the ValueProfileCollector is done by
126/// adding the plugin type to the VP_PLUGIN_LIST macro.
127#define VP_PLUGIN_LIST \
128 MemIntrinsicPlugin, IndirectCallPromotionPlugin, VTableProfilingPlugin
129