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 24extern cl::opt<bool> MemOPOptMemcmpBcmp; 25 26///--------------------------- MemIntrinsicPlugin ------------------------------ 27class MemIntrinsicPlugin : public InstVisitor<MemIntrinsicPlugin> { 28 Function &F; 29 TargetLibraryInfo &TLI; 30 std::vector<CandidateInfo> *Candidates; 31 32public: 33 static constexpr InstrProfValueKind Kind = IPVK_MemOPSize; 34 35 MemIntrinsicPlugin(Function &Fn, TargetLibraryInfo &TLI) 36 : F(Fn), TLI(TLI), Candidates(nullptr) {} 37 38 void run(std::vector<CandidateInfo> &Cs) { 39 Candidates = &Cs; 40 visit(F); 41 Candidates = nullptr; 42 } 43 void visitMemIntrinsic(MemIntrinsic &MI) { 44 Value *Length = MI.getLength(); 45 // Not instrument constant length calls. 46 if (isa<ConstantInt>(Length)) 47 return; 48 49 Instruction *InsertPt = &MI; 50 Instruction *AnnotatedInst = &MI; 51 Candidates->emplace_back(CandidateInfo{Length, InsertPt, AnnotatedInst}); 52 } 53 void visitCallInst(CallInst &CI) { 54 if (!MemOPOptMemcmpBcmp) 55 return; 56 auto *F = CI.getCalledFunction(); 57 if (!F) 58 return; 59 LibFunc Func; 60 if (TLI.getLibFunc(CI, Func) && 61 (Func == LibFunc_memcmp || Func == LibFunc_bcmp)) { 62 Value *Length = CI.getArgOperand(2); 63 // Not instrument constant length calls. 64 if (isa<ConstantInt>(Length)) 65 return; 66 Instruction *InsertPt = &CI; 67 Instruction *AnnotatedInst = &CI; 68 Candidates->emplace_back(CandidateInfo{Length, InsertPt, AnnotatedInst}); 69 } 70 } 71}; 72 73///------------------------ IndirectCallPromotionPlugin ------------------------ 74class IndirectCallPromotionPlugin { 75 Function &F; 76 77public: 78 static constexpr InstrProfValueKind Kind = IPVK_IndirectCallTarget; 79 80 IndirectCallPromotionPlugin(Function &Fn, TargetLibraryInfo &TLI) : F(Fn) {} 81 82 void run(std::vector<CandidateInfo> &Candidates) { 83 std::vector<CallBase *> Result = findIndirectCalls(F); 84 for (Instruction *I : Result) { 85 Value *Callee = cast<CallBase>(I)->getCalledOperand(); 86 Instruction *InsertPt = I; 87 Instruction *AnnotatedInst = I; 88 Candidates.emplace_back(CandidateInfo{Callee, InsertPt, AnnotatedInst}); 89 } 90 } 91}; 92 93///--------------------- VirtualTableValueProfilingPlugin -------------------- 94class VTableProfilingPlugin { 95 Function &F; 96 97public: 98 static constexpr InstrProfValueKind Kind = IPVK_VTableTarget; 99 100 VTableProfilingPlugin(Function &Fn, TargetLibraryInfo &TLI) : F(Fn) {} 101 102 void run(std::vector<CandidateInfo> &Candidates) { 103 std::vector<Instruction *> Result = findVTableAddrs(F); 104 for (Instruction *I : Result) { 105 Instruction *InsertPt = I->getNextNonDebugInstruction(); 106 // When finding an insertion point, keep PHI and EH pad instructions 107 // before vp intrinsics. This is similar to 108 // `BasicBlock::getFirstInsertionPt`. 109 while (InsertPt && (dyn_cast<PHINode>(InsertPt) || InsertPt->isEHPad())) 110 InsertPt = InsertPt->getNextNonDebugInstruction(); 111 // Skip instrumentating the value if InsertPt is the last instruction. 112 // FIXME: Set InsertPt to the end of basic block to instrument the value 113 // if InsertPt is the last instruction. 114 if (InsertPt == nullptr) 115 continue; 116 117 Instruction *AnnotatedInst = I; 118 Candidates.emplace_back(CandidateInfo{I, InsertPt, AnnotatedInst}); 119 } 120 } 121}; 122 123///----------------------- Registration of the plugins ------------------------- 124/// For now, registering a plugin with the ValueProfileCollector is done by 125/// adding the plugin type to the VP_PLUGIN_LIST macro. 126#define VP_PLUGIN_LIST \ 127 MemIntrinsicPlugin, IndirectCallPromotionPlugin, VTableProfilingPlugin 128