1//===- ValueProfileCollector.cpp - determine what to value profile --------===//
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// The implementation of the ValueProfileCollector via ValueProfileCollectorImpl
10//
11//===----------------------------------------------------------------------===//
12
13#include "ValueProfilePlugins.inc"
14#include "llvm/IR/InstIterator.h"
15#include "llvm/IR/IntrinsicInst.h"
16#include "llvm/InitializePasses.h"
17
18#include <cassert>
19
20using namespace llvm;
21
22namespace {
23
24/// A plugin-based class that takes an arbitrary number of Plugin types.
25/// Each plugin type must satisfy the following API:
26///  1) the constructor must take a `Function &f`. Typically, the plugin would
27///     scan the function looking for candidates.
28///  2) contain a member function with the following signature and name:
29///        void run(std::vector<CandidateInfo> &Candidates);
30///    such that the plugin would append its result into the vector parameter.
31///
32/// Plugins are defined in ValueProfilePlugins.inc
33template <class... Ts> class PluginChain;
34
35/// The type PluginChainFinal is the final chain of plugins that will be used by
36/// ValueProfileCollectorImpl.
37using PluginChainFinal = PluginChain<VP_PLUGIN_LIST>;
38
39template <> class PluginChain<> {
40public:
41  PluginChain(Function &F, TargetLibraryInfo &TLI) {}
42  void get(InstrProfValueKind K, std::vector<CandidateInfo> &Candidates) {}
43};
44
45template <class PluginT, class... Ts>
46class PluginChain<PluginT, Ts...> : public PluginChain<Ts...> {
47  PluginT Plugin;
48  using Base = PluginChain<Ts...>;
49
50public:
51  PluginChain(Function &F, TargetLibraryInfo &TLI)
52      : PluginChain<Ts...>(F, TLI), Plugin(F, TLI) {}
53
54  void get(InstrProfValueKind K, std::vector<CandidateInfo> &Candidates) {
55    if (K == PluginT::Kind)
56      Plugin.run(Candidates);
57    Base::get(K, Candidates);
58  }
59};
60
61} // end anonymous namespace
62
63/// ValueProfileCollectorImpl inherits the API of PluginChainFinal.
64class ValueProfileCollector::ValueProfileCollectorImpl : public PluginChainFinal {
65public:
66  using PluginChainFinal::PluginChainFinal;
67};
68
69ValueProfileCollector::ValueProfileCollector(Function &F,
70                                             TargetLibraryInfo &TLI)
71    : PImpl(new ValueProfileCollectorImpl(F, TLI)) {}
72
73ValueProfileCollector::~ValueProfileCollector() = default;
74
75std::vector<CandidateInfo>
76ValueProfileCollector::get(InstrProfValueKind Kind) const {
77  std::vector<CandidateInfo> Result;
78  PImpl->get(Kind, Result);
79  return Result;
80}
81