teak-llvm/llvm/lib/Transforms/Instrumentation/ValueProfileCollector.cpp
Bardia Mahjour f6c34de117 [PGO] Refactor Value Profiling into a plugin based oracle and create a well defined API for the plugins.
Summary: This PR creates a utility class called ValueProfileCollector that tells PGOInstrumentationGen and PGOInstrumentationUse what to value-profile and where to attach the profile metadata. It then refactors logic scattered in PGOInstrumentation.cpp into two plugins that plug into the ValueProfileCollector.

Authored By: Wael Yehia <wyehia@ca.ibm.com>

Reviewer: davidxl, tejohnson, xur

Reviewed By: davidxl, tejohnson, xur

Subscribers: llvm-commits

Tag: #llvm

Differential Revision: https://reviews.llvm.org/D67920

Patch By Wael Yehia <wyehia@ca.ibm.com>

llvm-svn: 373601
2019-10-03 14:20:50 +00:00

79 lines
2.5 KiB
C++

//===- ValueProfileCollector.cpp - determine what to value profile --------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// The implementation of the ValueProfileCollector via ValueProfileCollectorImpl
//
//===----------------------------------------------------------------------===//
#include "ValueProfilePlugins.inc"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/InitializePasses.h"
#include <cassert>
using namespace llvm;
namespace {
/// A plugin-based class that takes an arbitrary number of Plugin types.
/// Each plugin type must satisfy the following API:
/// 1) the constructor must take a `Function &f`. Typically, the plugin would
/// scan the function looking for candidates.
/// 2) contain a member function with the following signature and name:
/// void run(std::vector<CandidateInfo> &Candidates);
/// such that the plugin would append its result into the vector parameter.
///
/// Plugins are defined in ValueProfilePlugins.inc
template <class... Ts> class PluginChain;
/// The type PluginChainFinal is the final chain of plugins that will be used by
/// ValueProfileCollectorImpl.
using PluginChainFinal = PluginChain<VP_PLUGIN_LIST>;
template <> class PluginChain<> {
public:
PluginChain(Function &F) {}
void get(InstrProfValueKind K, std::vector<CandidateInfo> &Candidates) {}
};
template <class PluginT, class... Ts>
class PluginChain<PluginT, Ts...> : public PluginChain<Ts...> {
PluginT Plugin;
using Base = PluginChain<Ts...>;
public:
PluginChain(Function &F) : PluginChain<Ts...>(F), Plugin(F) {}
void get(InstrProfValueKind K, std::vector<CandidateInfo> &Candidates) {
if (K == PluginT::Kind)
Plugin.run(Candidates);
Base::get(K, Candidates);
}
};
} // end anonymous namespace
/// ValueProfileCollectorImpl inherits the API of PluginChainFinal.
class ValueProfileCollector::ValueProfileCollectorImpl : public PluginChainFinal {
public:
using PluginChainFinal::PluginChainFinal;
};
ValueProfileCollector::ValueProfileCollector(Function &F)
: PImpl(new ValueProfileCollectorImpl(F)) {}
ValueProfileCollector::~ValueProfileCollector() = default;
std::vector<CandidateInfo>
ValueProfileCollector::get(InstrProfValueKind Kind) const {
std::vector<CandidateInfo> Result;
PImpl->get(Kind, Result);
return Result;
}