#include "llvm/Analysis/BlockFrequencyInfoImpl.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SCCIterator.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/BlockFrequency.h"
#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/ScaledNumber.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <iterator>
#include <list>
#include <numeric>
#include <optional>
#include <utility>
#include <vector>
usingnamespacellvm;
usingnamespacellvm::bfi_detail;
#define DEBUG_TYPE …
namespace llvm {
cl::opt<bool> CheckBFIUnknownBlockQueries(
"check-bfi-unknown-block-queries",
cl::init(false), cl::Hidden,
cl::desc("Check if block frequency is queried for an unknown block "
"for debugging missed BFI updates"));
cl::opt<bool> UseIterativeBFIInference(
"use-iterative-bfi-inference", cl::Hidden,
cl::desc("Apply an iterative post-processing to infer correct BFI counts"));
cl::opt<unsigned> IterativeBFIMaxIterationsPerBlock(
"iterative-bfi-max-iterations-per-block", cl::init(1000), cl::Hidden,
cl::desc("Iterative inference: maximum number of update iterations "
"per block"));
cl::opt<double> IterativeBFIPrecision(
"iterative-bfi-precision", cl::init(1e-12), cl::Hidden,
cl::desc("Iterative inference: delta convergence precision; smaller values "
"typically lead to better results at the cost of worsen runtime"));
}
ScaledNumber<uint64_t> BlockMass::toScaled() const { … }
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void BlockMass::dump() const { print(dbgs()); }
#endif
static char getHexDigit(int N) { … }
raw_ostream &BlockMass::print(raw_ostream &OS) const { … }
namespace {
BlockNode;
Distribution;
WeightList;
Scaled64;
LoopData;
Weight;
FrequencyData;
struct DitheringDistributer { … };
}
DitheringDistributer::DitheringDistributer(Distribution &Dist,
const BlockMass &Mass) { … }
BlockMass DitheringDistributer::takeMass(uint32_t Weight) { … }
void Distribution::add(const BlockNode &Node, uint64_t Amount,
Weight::DistType Type) { … }
static void combineWeight(Weight &W, const Weight &OtherW) { … }
static void combineWeightsBySorting(WeightList &Weights) { … }
static void combineWeightsByHashing(WeightList &Weights) { … }
static void combineWeights(WeightList &Weights) { … }
static uint64_t shiftRightAndRound(uint64_t N, int Shift) { … }
void Distribution::normalize() { … }
void BlockFrequencyInfoImplBase::clear() { … }
static void cleanup(BlockFrequencyInfoImplBase &BFI) { … }
bool BlockFrequencyInfoImplBase::addToDist(Distribution &Dist,
const LoopData *OuterLoop,
const BlockNode &Pred,
const BlockNode &Succ,
uint64_t Weight) { … }
bool BlockFrequencyInfoImplBase::addLoopSuccessorsToDist(
const LoopData *OuterLoop, LoopData &Loop, Distribution &Dist) { … }
void BlockFrequencyInfoImplBase::computeLoopScale(LoopData &Loop) { … }
void BlockFrequencyInfoImplBase::packageLoop(LoopData &Loop) { … }
#ifndef NDEBUG
static void debugAssign(const BlockFrequencyInfoImplBase &BFI,
const DitheringDistributer &D, const BlockNode &T,
const BlockMass &M, const char *Desc) {
dbgs() << " => assign " << M << " (" << D.RemMass << ")";
if (Desc)
dbgs() << " [" << Desc << "]";
if (T.isValid())
dbgs() << " to " << BFI.getBlockName(T);
dbgs() << "\n";
}
#endif
void BlockFrequencyInfoImplBase::distributeMass(const BlockNode &Source,
LoopData *OuterLoop,
Distribution &Dist) { … }
static void convertFloatingToInteger(BlockFrequencyInfoImplBase &BFI,
const Scaled64 &Min, const Scaled64 &Max) { … }
static void unwrapLoop(BlockFrequencyInfoImplBase &BFI, LoopData &Loop) { … }
void BlockFrequencyInfoImplBase::unwrapLoops() { … }
void BlockFrequencyInfoImplBase::finalizeMetrics() { … }
BlockFrequency
BlockFrequencyInfoImplBase::getBlockFreq(const BlockNode &Node) const { … }
std::optional<uint64_t>
BlockFrequencyInfoImplBase::getBlockProfileCount(const Function &F,
const BlockNode &Node,
bool AllowSynthetic) const { … }
std::optional<uint64_t> BlockFrequencyInfoImplBase::getProfileCountFromFreq(
const Function &F, BlockFrequency Freq, bool AllowSynthetic) const { … }
bool
BlockFrequencyInfoImplBase::isIrrLoopHeader(const BlockNode &Node) { … }
Scaled64
BlockFrequencyInfoImplBase::getFloatingBlockFreq(const BlockNode &Node) const { … }
void BlockFrequencyInfoImplBase::setBlockFreq(const BlockNode &Node,
BlockFrequency Freq) { … }
std::string
BlockFrequencyInfoImplBase::getBlockName(const BlockNode &Node) const { … }
std::string
BlockFrequencyInfoImplBase::getLoopName(const LoopData &Loop) const { … }
void IrreducibleGraph::addNodesInLoop(const BFIBase::LoopData &OuterLoop) { … }
void IrreducibleGraph::addNodesInFunction() { … }
void IrreducibleGraph::indexNodes() { … }
void IrreducibleGraph::addEdge(IrrNode &Irr, const BlockNode &Succ,
const BFIBase::LoopData *OuterLoop) { … }
namespace llvm {
template <> struct GraphTraits<IrreducibleGraph> { … };
}
static void findIrreducibleHeaders(
const BlockFrequencyInfoImplBase &BFI,
const IrreducibleGraph &G,
const std::vector<const IrreducibleGraph::IrrNode *> &SCC,
LoopData::NodeList &Headers, LoopData::NodeList &Others) { … }
static void createIrreducibleLoop(
BlockFrequencyInfoImplBase &BFI, const IrreducibleGraph &G,
LoopData *OuterLoop, std::list<LoopData>::iterator Insert,
const std::vector<const IrreducibleGraph::IrrNode *> &SCC) { … }
iterator_range<std::list<LoopData>::iterator>
BlockFrequencyInfoImplBase::analyzeIrreducible(
const IrreducibleGraph &G, LoopData *OuterLoop,
std::list<LoopData>::iterator Insert) { … }
void
BlockFrequencyInfoImplBase::updateLoopWithIrreducible(LoopData &OuterLoop) { … }
void BlockFrequencyInfoImplBase::adjustLoopHeaderMass(LoopData &Loop) { … }
void BlockFrequencyInfoImplBase::distributeIrrLoopHeaderMass(Distribution &Dist) { … }