106f32e7eSjoerg //===- ValueProfileCollector.cpp - determine what to value profile --------===//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg //
906f32e7eSjoerg // The implementation of the ValueProfileCollector via ValueProfileCollectorImpl
1006f32e7eSjoerg //
1106f32e7eSjoerg //===----------------------------------------------------------------------===//
1206f32e7eSjoerg 
1306f32e7eSjoerg #include "ValueProfilePlugins.inc"
14*da58b97aSjoerg #include "llvm/IR/Function.h"
1506f32e7eSjoerg #include "llvm/IR/InstIterator.h"
1606f32e7eSjoerg #include "llvm/IR/IntrinsicInst.h"
1706f32e7eSjoerg #include "llvm/InitializePasses.h"
1806f32e7eSjoerg #include <cassert>
1906f32e7eSjoerg 
2006f32e7eSjoerg using namespace llvm;
2106f32e7eSjoerg 
2206f32e7eSjoerg namespace {
2306f32e7eSjoerg 
2406f32e7eSjoerg /// A plugin-based class that takes an arbitrary number of Plugin types.
2506f32e7eSjoerg /// Each plugin type must satisfy the following API:
2606f32e7eSjoerg ///  1) the constructor must take a `Function &f`. Typically, the plugin would
2706f32e7eSjoerg ///     scan the function looking for candidates.
2806f32e7eSjoerg ///  2) contain a member function with the following signature and name:
2906f32e7eSjoerg ///        void run(std::vector<CandidateInfo> &Candidates);
3006f32e7eSjoerg ///    such that the plugin would append its result into the vector parameter.
3106f32e7eSjoerg ///
3206f32e7eSjoerg /// Plugins are defined in ValueProfilePlugins.inc
3306f32e7eSjoerg template <class... Ts> class PluginChain;
3406f32e7eSjoerg 
3506f32e7eSjoerg /// The type PluginChainFinal is the final chain of plugins that will be used by
3606f32e7eSjoerg /// ValueProfileCollectorImpl.
3706f32e7eSjoerg using PluginChainFinal = PluginChain<VP_PLUGIN_LIST>;
3806f32e7eSjoerg 
3906f32e7eSjoerg template <> class PluginChain<> {
4006f32e7eSjoerg public:
PluginChain(Function & F,TargetLibraryInfo & TLI)41*da58b97aSjoerg   PluginChain(Function &F, TargetLibraryInfo &TLI) {}
get(InstrProfValueKind K,std::vector<CandidateInfo> & Candidates)4206f32e7eSjoerg   void get(InstrProfValueKind K, std::vector<CandidateInfo> &Candidates) {}
4306f32e7eSjoerg };
4406f32e7eSjoerg 
4506f32e7eSjoerg template <class PluginT, class... Ts>
4606f32e7eSjoerg class PluginChain<PluginT, Ts...> : public PluginChain<Ts...> {
4706f32e7eSjoerg   PluginT Plugin;
4806f32e7eSjoerg   using Base = PluginChain<Ts...>;
4906f32e7eSjoerg 
5006f32e7eSjoerg public:
PluginChain(Function & F,TargetLibraryInfo & TLI)51*da58b97aSjoerg   PluginChain(Function &F, TargetLibraryInfo &TLI)
52*da58b97aSjoerg       : PluginChain<Ts...>(F, TLI), Plugin(F, TLI) {}
5306f32e7eSjoerg 
get(InstrProfValueKind K,std::vector<CandidateInfo> & Candidates)5406f32e7eSjoerg   void get(InstrProfValueKind K, std::vector<CandidateInfo> &Candidates) {
5506f32e7eSjoerg     if (K == PluginT::Kind)
5606f32e7eSjoerg       Plugin.run(Candidates);
5706f32e7eSjoerg     Base::get(K, Candidates);
5806f32e7eSjoerg   }
5906f32e7eSjoerg };
6006f32e7eSjoerg 
6106f32e7eSjoerg } // end anonymous namespace
6206f32e7eSjoerg 
6306f32e7eSjoerg /// ValueProfileCollectorImpl inherits the API of PluginChainFinal.
6406f32e7eSjoerg class ValueProfileCollector::ValueProfileCollectorImpl : public PluginChainFinal {
6506f32e7eSjoerg public:
6606f32e7eSjoerg   using PluginChainFinal::PluginChainFinal;
6706f32e7eSjoerg };
6806f32e7eSjoerg 
ValueProfileCollector(Function & F,TargetLibraryInfo & TLI)69*da58b97aSjoerg ValueProfileCollector::ValueProfileCollector(Function &F,
70*da58b97aSjoerg                                              TargetLibraryInfo &TLI)
71*da58b97aSjoerg     : PImpl(new ValueProfileCollectorImpl(F, TLI)) {}
7206f32e7eSjoerg 
7306f32e7eSjoerg ValueProfileCollector::~ValueProfileCollector() = default;
7406f32e7eSjoerg 
7506f32e7eSjoerg std::vector<CandidateInfo>
get(InstrProfValueKind Kind) const7606f32e7eSjoerg ValueProfileCollector::get(InstrProfValueKind Kind) const {
7706f32e7eSjoerg   std::vector<CandidateInfo> Result;
7806f32e7eSjoerg   PImpl->get(Kind, Result);
7906f32e7eSjoerg   return Result;
8006f32e7eSjoerg }
81