130 lines · plain
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-exception6//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 a11// particular optimization.12// Each plugin must satisfy the interface described in ValueProfileCollector.cpp13//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 llvm27 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>(Length))49 return;50 51 Instruction *InsertPt = &MI;52 Instruction *AnnotatedInst = &MI;53 Candidates->emplace_back(CandidateInfo{Length, InsertPt, 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;62 if (TLI.getLibFunc(CI, Func) &&63 (Func == LibFunc_memcmp || Func == LibFunc_bcmp)) {64 Value *Length = CI.getArgOperand(2);65 // Not instrument constant length calls.66 if (isa<ConstantInt>(Length))67 return;68 Instruction *InsertPt = &CI;69 Instruction *AnnotatedInst = &CI;70 Candidates->emplace_back(CandidateInfo{Length, InsertPt, AnnotatedInst});71 }72 }73};74 75///------------------------ IndirectCallPromotionPlugin ------------------------76class IndirectCallPromotionPlugin {77 Function &F;78 79public:80 static constexpr InstrProfValueKind Kind = IPVK_IndirectCallTarget;81 82 IndirectCallPromotionPlugin(Function &Fn, TargetLibraryInfo &TLI) : F(Fn) {}83 84 void run(std::vector<CandidateInfo> &Candidates) {85 std::vector<CallBase *> Result = findIndirectCalls(F);86 for (Instruction *I : Result) {87 Value *Callee = cast<CallBase>(I)->getCalledOperand();88 Instruction *InsertPt = I;89 Instruction *AnnotatedInst = I;90 Candidates.emplace_back(CandidateInfo{Callee, InsertPt, AnnotatedInst});91 }92 }93};94 95///--------------------- VirtualTableValueProfilingPlugin --------------------96class VTableProfilingPlugin {97 Function &F;98 99public:100 static constexpr InstrProfValueKind Kind = IPVK_VTableTarget;101 102 VTableProfilingPlugin(Function &Fn, TargetLibraryInfo &TLI) : F(Fn) {}103 104 void run(std::vector<CandidateInfo> &Candidates) {105 std::vector<Instruction *> Result = findVTableAddrs(F);106 for (Instruction *I : Result) {107 Instruction *InsertPt = I->getNextNode();108 // When finding an insertion point, keep PHI and EH pad instructions109 // before vp intrinsics. This is similar to110 // `BasicBlock::getFirstInsertionPt`.111 while (InsertPt && (dyn_cast<PHINode>(InsertPt) || InsertPt->isEHPad()))112 InsertPt = InsertPt->getNextNode();113 // Skip instrumentating the value if InsertPt is the last instruction.114 // FIXME: Set InsertPt to the end of basic block to instrument the value115 // if InsertPt is the last instruction.116 if (InsertPt == nullptr)117 continue;118 119 Instruction *AnnotatedInst = I;120 Candidates.emplace_back(CandidateInfo{I, InsertPt, AnnotatedInst});121 }122 }123};124 125///----------------------- Registration of the plugins -------------------------126/// For now, registering a plugin with the ValueProfileCollector is done by127/// adding the plugin type to the VP_PLUGIN_LIST macro.128#define VP_PLUGIN_LIST \129 MemIntrinsicPlugin, IndirectCallPromotionPlugin, VTableProfilingPlugin130