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/IR/InstVisitor.h"
19
20using namespace llvm;
21using CandidateInfo = ValueProfileCollector::CandidateInfo;
22
23extern cl::opt<bool> MemOPOptMemcmpBcmp;
24
25///--------------------------- MemIntrinsicPlugin ------------------------------
26class MemIntrinsicPlugin : public InstVisitor<MemIntrinsicPlugin> {
27  Function &F;
28  TargetLibraryInfo &TLI;
29  std::vector<CandidateInfo> *Candidates;
30
31public:
32  static constexpr InstrProfValueKind Kind = IPVK_MemOPSize;
33
34  MemIntrinsicPlugin(Function &Fn, TargetLibraryInfo &TLI)
35      : F(Fn), TLI(TLI), Candidates(nullptr) {}
36
37  void run(std::vector<CandidateInfo> &Cs) {
38    Candidates = &Cs;
39    visit(F);
40    Candidates = nullptr;
41  }
42  void visitMemIntrinsic(MemIntrinsic &MI) {
43    Value *Length = MI.getLength();
44    // Not instrument constant length calls.
45    if (isa<ConstantInt>(Length))
46      return;
47
48    Instruction *InsertPt = &MI;
49    Instruction *AnnotatedInst = &MI;
50    Candidates->emplace_back(CandidateInfo{Length, InsertPt, AnnotatedInst});
51  }
52  void visitCallInst(CallInst &CI) {
53    if (!MemOPOptMemcmpBcmp)
54      return;
55    auto *F = CI.getCalledFunction();
56    if (!F)
57      return;
58    LibFunc Func;
59    if (TLI.getLibFunc(CI, Func) &&
60        (Func == LibFunc_memcmp || Func == LibFunc_bcmp)) {
61      Value *Length = CI.getArgOperand(2);
62      // Not instrument constant length calls.
63      if (isa<ConstantInt>(Length))
64        return;
65      Instruction *InsertPt = &CI;
66      Instruction *AnnotatedInst = &CI;
67      Candidates->emplace_back(CandidateInfo{Length, InsertPt, AnnotatedInst});
68    }
69  }
70};
71
72///------------------------ IndirectCallPromotionPlugin ------------------------
73class IndirectCallPromotionPlugin {
74  Function &F;
75
76public:
77  static constexpr InstrProfValueKind Kind = IPVK_IndirectCallTarget;
78
79  IndirectCallPromotionPlugin(Function &Fn, TargetLibraryInfo &TLI) : F(Fn) {}
80
81  void run(std::vector<CandidateInfo> &Candidates) {
82    std::vector<CallBase *> Result = findIndirectCalls(F);
83    for (Instruction *I : Result) {
84      Value *Callee = cast<CallBase>(I)->getCalledOperand();
85      Instruction *InsertPt = I;
86      Instruction *AnnotatedInst = I;
87      Candidates.emplace_back(CandidateInfo{Callee, InsertPt, AnnotatedInst});
88    }
89  }
90};
91
92///----------------------- Registration of the plugins -------------------------
93/// For now, registering a plugin with the ValueProfileCollector is done by
94/// adding the plugin type to the VP_PLUGIN_LIST macro.
95#define VP_PLUGIN_LIST           \
96    MemIntrinsicPlugin,          \
97    IndirectCallPromotionPlugin
98