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///----------------------- Registration of the plugins -------------------------
94/// For now, registering a plugin with the ValueProfileCollector is done by
95/// adding the plugin type to the VP_PLUGIN_LIST macro.
96#define VP_PLUGIN_LIST           \
97    MemIntrinsicPlugin,          \
98    IndirectCallPromotionPlugin
99