14#ifndef LLVM_TRANSFORMS_UTILS_SAMPLEPROFILEINFERENCE_H
15#define LLVM_TRANSFORMS_UTILS_SAMPLEPROFILEINFERENCE_H
124 using Edge = std::pair<const BasicBlockT *, const BasicBlockT *>;
132 : F(F), Successors(Successors), SampleBlockWeights(SampleBlockWeights) {}
136 : F(F), Successors(Successors), SampleBlockWeights(SampleBlockWeights),
137 SampleEdgeWeights(SampleEdgeWeights) {}
145 createFlowFunction(
const std::vector<const BasicBlockT *> &BasicBlocks,
151 void findUnlikelyJumps(
const std::vector<const BasicBlockT *> &BasicBlocks,
170template <
typename BT>
182 for (
const auto &BB : F) {
192 std::vector<const BasicBlockT *> BasicBlocks;
193 BlockIndex.
reserve(Reachable.size());
194 BasicBlocks.reserve(Reachable.size());
195 for (
const auto &BB : F) {
196 if (Reachable.count(&BB) && InverseReachable.
count(&BB)) {
197 BlockIndex[&BB] = BasicBlocks.size();
198 BasicBlocks.push_back(&BB);
202 BlockWeights.
clear();
204 bool HasSamples =
false;
205 for (
const auto *BB : BasicBlocks) {
206 auto It = SampleBlockWeights.find(BB);
207 if (It != SampleBlockWeights.end() && It->second > 0) {
209 BlockWeights[BB] = It->second;
213 if (BasicBlocks.size() <= 1 || !HasSamples) {
218 FlowFunction Func = createFlowFunction(BasicBlocks, BlockIndex);
226 for (
const auto *BB : BasicBlocks) {
227 BlockWeights[BB] = Func.Blocks[BlockIndex[BB]].Flow;
229 for (
auto &Jump : Func.Jumps) {
230 Edge E = std::make_pair(BasicBlocks[Jump.Source], BasicBlocks[Jump.Target]);
231 EdgeWeights[
E] = Jump.Flow;
236 for (
auto &
I : BlockWeights) {
237 assert(Reachable.contains(
I.first));
240 for (
auto &
I : EdgeWeights) {
241 assert(Reachable.contains(
I.first.first) &&
242 Reachable.contains(
I.first.second));
244 InverseReachable.
contains(
I.first.second));
249template <
typename BT>
250FlowFunction SampleProfileInference<BT>::createFlowFunction(
251 const std::vector<const BasicBlockT *> &BasicBlocks,
254 Func.Blocks.reserve(BasicBlocks.size());
256 for (
const auto *BB : BasicBlocks) {
258 auto It = SampleBlockWeights.find(BB);
259 if (It != SampleBlockWeights.end()) {
260 Block.HasUnknownWeight =
false;
261 Block.Weight = It->second;
263 Block.HasUnknownWeight =
true;
270 for (
const auto *BB : BasicBlocks) {
271 for (
auto *Succ : Successors[BB]) {
272 if (!BlockIndex.
count(Succ))
275 Jump.
Source = BlockIndex[BB];
276 Jump.Target = BlockIndex[Succ];
277 auto It = SampleEdgeWeights.
find(std::make_pair(BB, Succ));
278 if (It != SampleEdgeWeights.end()) {
279 Jump.HasUnknownWeight =
false;
280 Jump.Weight = It->second;
282 Jump.HasUnknownWeight =
true;
285 Func.Jumps.push_back(Jump);
288 for (
auto &Jump :
Func.Jumps) {
289 uint64_t Src = Jump.Source;
290 uint64_t Dst = Jump.Target;
291 Func.Blocks[Src].SuccJumps.push_back(&Jump);
292 Func.Blocks[Dst].PredJumps.push_back(&Jump);
296 findUnlikelyJumps(BasicBlocks, Successors, Func);
299 for (
size_t I = 0;
I <
Func.Blocks.size();
I++) {
300 if (
Func.Blocks[
I].isEntry()) {
305 assert(
Func.Entry == 0 &&
"incorrect index of the entry block");
308 auto &EntryBlock =
Func.Blocks[
Func.Entry];
309 if (EntryBlock.Weight == 0 && !EntryBlock.HasUnknownWeight) {
310 EntryBlock.Weight = 1;
311 EntryBlock.HasUnknownWeight =
false;
317template <
typename BT>
318inline void SampleProfileInference<BT>::findUnlikelyJumps(
319 const std::vector<const BasicBlockT *> &BasicBlocks,
322template <
typename BT>
323inline bool SampleProfileInference<BT>::isExit(
const BasicBlockT *BB) {
324 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)
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.