14#ifndef LLVM_TRANSFORMS_UTILS_SAMPLEPROFILEINFERENCE_H
15#define LLVM_TRANSFORMS_UTILS_SAMPLEPROFILEINFERENCE_H
125 using Edge = std::pair<const BasicBlockT *, const BasicBlockT *>;
133 : F(F), Successors(Successors), SampleBlockWeights(SampleBlockWeights) {}
137 : F(F), Successors(Successors), SampleBlockWeights(SampleBlockWeights),
138 SampleEdgeWeights(SampleEdgeWeights) {}
146 createFlowFunction(
const std::vector<const BasicBlockT *> &BasicBlocks,
152 void findUnlikelyJumps(
const std::vector<const BasicBlockT *> &BasicBlocks,
171template <
typename BT>
183 for (
const auto &BB : F) {
193 std::vector<const BasicBlockT *> BasicBlocks;
194 BlockIndex.
reserve(Reachable.size());
195 BasicBlocks.reserve(Reachable.size());
196 for (
const auto &BB : F) {
197 if (Reachable.count(&BB) && InverseReachable.
count(&BB)) {
198 BlockIndex[&BB] = BasicBlocks.size();
199 BasicBlocks.push_back(&BB);
203 BlockWeights.
clear();
205 bool HasSamples =
false;
206 for (
const auto *BB : BasicBlocks) {
207 auto It = SampleBlockWeights.find(BB);
208 if (It != SampleBlockWeights.end() && It->second > 0) {
210 BlockWeights[BB] = It->second;
214 if (BasicBlocks.size() <= 1 || !HasSamples) {
219 FlowFunction Func = createFlowFunction(BasicBlocks, BlockIndex);
227 for (
const auto *BB : BasicBlocks) {
228 BlockWeights[BB] = Func.Blocks[BlockIndex[BB]].Flow;
230 for (
auto &Jump : Func.Jumps) {
231 Edge E = std::make_pair(BasicBlocks[Jump.Source], BasicBlocks[Jump.Target]);
232 EdgeWeights[
E] = Jump.Flow;
237 for (
auto &
I : BlockWeights) {
238 assert(Reachable.contains(
I.first));
241 for (
auto &
I : EdgeWeights) {
242 assert(Reachable.contains(
I.first.first) &&
243 Reachable.contains(
I.first.second));
245 InverseReachable.
contains(
I.first.second));
250template <
typename BT>
251FlowFunction SampleProfileInference<BT>::createFlowFunction(
252 const std::vector<const BasicBlockT *> &BasicBlocks,
255 Func.Blocks.reserve(BasicBlocks.size());
257 for (
const auto *BB : BasicBlocks) {
259 auto It = SampleBlockWeights.find(BB);
260 if (It != SampleBlockWeights.end()) {
261 Block.HasUnknownWeight =
false;
262 Block.Weight = It->second;
264 Block.HasUnknownWeight =
true;
271 for (
const auto *BB : BasicBlocks) {
272 for (
auto *Succ : Successors[BB]) {
273 if (!BlockIndex.
count(Succ))
276 Jump.
Source = BlockIndex[BB];
277 Jump.Target = BlockIndex[Succ];
278 auto It = SampleEdgeWeights.
find(std::make_pair(BB, Succ));
279 if (It != SampleEdgeWeights.end()) {
280 Jump.HasUnknownWeight =
false;
281 Jump.Weight = It->second;
283 Jump.HasUnknownWeight =
true;
286 Func.Jumps.push_back(Jump);
289 for (
auto &Jump :
Func.Jumps) {
292 Func.Blocks[Src].SuccJumps.push_back(&Jump);
293 Func.Blocks[Dst].PredJumps.push_back(&Jump);
297 findUnlikelyJumps(BasicBlocks, Successors, Func);
300 for (
size_t I = 0;
I <
Func.Blocks.size();
I++) {
301 if (
Func.Blocks[
I].isEntry()) {
306 assert(
Func.Entry == 0 &&
"incorrect index of the entry block");
309 auto &EntryBlock =
Func.Blocks[
Func.Entry];
310 if (EntryBlock.Weight == 0 && !EntryBlock.HasUnknownWeight) {
311 EntryBlock.Weight = 1;
312 EntryBlock.HasUnknownWeight =
false;
318template <
typename BT>
319inline void SampleProfileInference<BT>::findUnlikelyJumps(
320 const std::vector<const BasicBlockT *> &BasicBlocks,
323template <
typename BT>
324inline bool SampleProfileInference<BT>::isExit(
const BasicBlockT *BB) {
325 return BB->succ_empty();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the DenseMap class.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
This file defines the SmallVector class.
iterator find(const_arg_type_t< KeyT > Val)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
void reserve(size_type NumEntries)
Grow the densemap so that it can contain at least NumEntries items before resizing again.
std::remove_pointer_t< NodeRef > BasicBlockT
DenseMap< const BasicBlockT *, uint64_t > BlockWeightMap
DenseMap< const BasicBlockT *, SmallVector< const BasicBlockT *, 8 > > BlockEdgeMap
typename GraphTraits< FT * >::NodeRef NodeRef
SampleProfileInference(FunctionT &F, BlockEdgeMap &Successors, BlockWeightMap &SampleBlockWeights, EdgeWeightMap &SampleEdgeWeights)
DenseMap< Edge, uint64_t > EdgeWeightMap
std::pair< const BasicBlockT *, const BasicBlockT * > Edge
void apply(BlockWeightMap &BlockWeights, EdgeWeightMap &EdgeWeights)
Apply the profile inference algorithm for a given function.
SampleProfileInference(FunctionT &F, BlockEdgeMap &Successors, BlockWeightMap &SampleBlockWeights)
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
bool contains(ConstPtrType Ptr) const
NodeAddr< FuncNode * > Func
This is an optimization pass for GlobalISel generic memory operations.
iterator_range< df_ext_iterator< T, SetTy > > depth_first_ext(const T &G, SetTy &S)
iterator_range< idf_ext_iterator< T, SetTy > > inverse_depth_first_ext(const T &G, SetTy &S)
LLVM_ABI void applyFlowInference(const ProfiParams &Params, FlowFunction &Func)
Apply the profile inference algorithm for a given function and provided profi options.
A wrapper of a binary basic block.
bool isEntry() const
Check if it is the entry block in the function.
bool isExit() const
Check if it is an exit block in the function.
std::vector< FlowJump * > PredJumps
std::vector< FlowJump * > SuccJumps
A wrapper of binary function with basic blocks and jumps.
std::vector< FlowJump > Jumps
Jumps between the basic blocks.
std::vector< FlowBlock > Blocks
Basic blocks in the function.
uint64_t Entry
The index of the entry block.
A wrapper of a jump between two basic blocks.
typename GraphType::UnknownGraphTypeError NodeRef
Various thresholds and options controlling the behavior of the profile inference algorithm.
unsigned CostJumpUnknownFTInc
The cost of increasing an unknown fall-through jump's count by one.
unsigned CostBlockInc
The cost of increasing a block's count by one.
unsigned CostJumpFTInc
The cost of increasing a fall-through jump's count by one.
bool RebalanceUnknown
Evenly re-distribute flow among unknown subgraphs.
const int64_t CostUnlikely
The cost of taking an unlikely block/jump.
unsigned CostJumpDec
The cost of decreasing a jump's count by one.
bool JoinIslands
Join isolated components having positive flow.
unsigned CostBlockZeroInc
The cost of increasing a count of zero-weight block by one.
unsigned CostBlockEntryDec
The cost of decreasing the entry block's count by one.
unsigned CostJumpInc
The cost of increasing a jump's count by one.
unsigned CostJumpUnknownInc
The cost of increasing an unknown jump's count by one.
unsigned CostBlockUnknownInc
The cost of increasing an unknown block's count by one.
unsigned CostJumpFTDec
The cost of decreasing a fall-through jump's count by one.
unsigned CostBlockDec
The cost of decreasing a block's count by one.
unsigned CostBlockEntryInc
The cost of increasing the entry block's count by one.
bool EvenFlowDistribution
Evenly distribute flow when there are multiple equally likely options.