LLVM 24.0.0git
BlockFrequencyInfoImpl.h
Go to the documentation of this file.
1//==- BlockFrequencyInfoImpl.h - Block Frequency Implementation --*- C++ -*-==//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Shared implementation of BlockFrequency for IR and Machine Instructions.
10// See the documentation below for BlockFrequencyInfoImpl for details.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_ANALYSIS_BLOCKFREQUENCYINFOIMPL_H
15#define LLVM_ANALYSIS_BLOCKFREQUENCYINFOIMPL_H
16
17#include "llvm/ADT/BitVector.h"
18#include "llvm/ADT/DenseMap.h"
22#include "llvm/ADT/STLExtras.h"
26#include "llvm/ADT/Twine.h"
28#include "llvm/IR/BasicBlock.h"
29#include "llvm/IR/Function.h"
30#include "llvm/IR/ValueHandle.h"
35#include "llvm/Support/Debug.h"
36#include "llvm/Support/Format.h"
39#include <algorithm>
40#include <cassert>
41#include <cstddef>
42#include <cstdint>
43#include <deque>
44#include <iterator>
45#include <limits>
46#include <list>
47#include <optional>
48#include <queue>
49#include <string>
50#include <tuple>
51#include <utility>
52#include <vector>
53
54#define DEBUG_TYPE "block-freq"
55
56namespace llvm {
57/// Return -check-bfi-unknown-block-queries.
58LLVM_ABI bool shouldCheckBFIUnknownBlockQueries(const LLVMContext &C);
59
61/// Return -iterative-bfi-max-iterations-per-block.
62LLVM_ABI unsigned getIterativeBFIMaxIterationsPerBlock(const LLVMContext &C);
63/// Return -iterative-bfi-precision.
64LLVM_ABI double getIterativeBFIPrecision(const LLVMContext &C);
65
66class BranchProbabilityInfo;
67class CycleInfo;
68class Function;
69class MachineBasicBlock;
70class MachineBranchProbabilityInfo;
71class MachineCycleInfo;
72class MachineFunction;
73
74namespace bfi_detail {
75
76struct IrreducibleGraph;
77
78/// Mass of a block.
79///
80/// This class implements a sort of fixed-point fraction always between 0.0 and
81/// 1.0. getMass() == std::numeric_limits<uint64_t>::max() indicates a value of
82/// 1.0.
83///
84/// Masses can be added and subtracted. Simple saturation arithmetic is used,
85/// so arithmetic operations never overflow or underflow.
86///
87/// Masses can be multiplied. Multiplication treats full mass as 1.0 and uses
88/// an inexpensive floating-point algorithm that's off-by-one (almost, but not
89/// quite, maximum precision).
90///
91/// Masses can be scaled by \a BranchProbability at maximum precision.
92class BlockMass {
93 uint64_t Mass = 0;
94
95public:
96 BlockMass() = default;
97 explicit BlockMass(uint64_t Mass) : Mass(Mass) {}
98
99 static BlockMass getEmpty() { return BlockMass(); }
100
102 return BlockMass(std::numeric_limits<uint64_t>::max());
103 }
104
105 uint64_t getMass() const { return Mass; }
106
107 bool isFull() const { return Mass == std::numeric_limits<uint64_t>::max(); }
108 bool isEmpty() const { return !Mass; }
109
110 bool operator!() const { return isEmpty(); }
111
112 /// Add another mass.
113 ///
114 /// Adds another mass, saturating at \a isFull() rather than overflowing.
116 uint64_t Sum = Mass + X.Mass;
117 Mass = Sum < Mass ? std::numeric_limits<uint64_t>::max() : Sum;
118 return *this;
119 }
120
121 /// Subtract another mass.
122 ///
123 /// Subtracts another mass, saturating at \a isEmpty() rather than
124 /// undeflowing.
126 uint64_t Diff = Mass - X.Mass;
127 Mass = Diff > Mass ? 0 : Diff;
128 return *this;
129 }
130
132 Mass = P.scale(Mass);
133 return *this;
134 }
135
136 bool operator==(BlockMass X) const { return Mass == X.Mass; }
137 bool operator!=(BlockMass X) const { return Mass != X.Mass; }
138 bool operator<=(BlockMass X) const { return Mass <= X.Mass; }
139 bool operator>=(BlockMass X) const { return Mass >= X.Mass; }
140 bool operator<(BlockMass X) const { return Mass < X.Mass; }
141 bool operator>(BlockMass X) const { return Mass > X.Mass; }
142
143 /// Convert to scaled number.
144 ///
145 /// Convert to \a ScaledNumber. \a isFull() gives 1.0, while \a isEmpty()
146 /// gives slightly above 0.0.
148
149 LLVM_ABI void dump() const;
151};
152
154 return BlockMass(L) += R;
155}
157 return BlockMass(L) -= R;
158}
160 return BlockMass(L) *= R;
161}
163 return BlockMass(R) *= L;
164}
165
167 return X.print(OS);
168}
169
170} // end namespace bfi_detail
171
172/// Base class for BlockFrequencyInfoImpl
173///
174/// BlockFrequencyInfoImplBase has supporting data structures and some
175/// algorithms for BlockFrequencyInfoImplBase. Only algorithms that depend on
176/// the block type (or that call such algorithms) are skipped here.
177///
178/// Nevertheless, the majority of the overall algorithm documentation lives with
179/// BlockFrequencyInfoImpl. See there for details.
181public:
184
185 /// Representative of a block.
186 ///
187 /// This is a simple wrapper around an index into the reverse-post-order
188 /// traversal of the blocks.
189 ///
190 /// Unlike a block pointer, its order has meaning (location in the
191 /// topological sort) and it's class is the same regardless of block type.
192 struct BlockNode {
194
196
197 BlockNode() : Index(std::numeric_limits<uint32_t>::max()) {}
199
200 bool operator==(const BlockNode &X) const { return Index == X.Index; }
201 bool operator!=(const BlockNode &X) const { return Index != X.Index; }
202 bool operator<=(const BlockNode &X) const { return Index <= X.Index; }
203 bool operator>=(const BlockNode &X) const { return Index >= X.Index; }
204 bool operator<(const BlockNode &X) const { return Index < X.Index; }
205 bool operator>(const BlockNode &X) const { return Index > X.Index; }
206
207 bool isValid() const { return Index <= getMaxIndex(); }
208
209 static size_t getMaxIndex() {
210 return std::numeric_limits<uint32_t>::max() - 1;
211 }
212 };
213
214 /// Stats about a block itself.
219
220 /// Data about a loop.
221 ///
222 /// Contains the data necessary to represent a loop as a pseudo-node once it's
223 /// packaged.
224 struct LoopData {
227
228 LoopData *Parent; ///< The parent loop.
229 bool IsPackaged = false; ///< Whether this has been packaged.
230 // Has an irreducible SCC in its own nodes; sub-loops package theirs first.
232 // A multi-entry SCC rather than a natural loop.
233 bool IsIrreducible = false;
234 ExitMap Exits; ///< Successor edges (and weights).
235 NodeList Nodes; ///< Header and the members of the loop.
236 BlockMass BackedgeMass; ///< Mass that circulates, not exits.
239
241 : Parent(Parent), Nodes(1, Header) {}
242
243 /// An irreducible SCC. Its entries are equivalent as far as the enclosing
244 /// region is concerned, so the lowest-RPO member stands for the package
245 /// and solveIrreducibleMass distributes mass among them all.
248
249 bool isHeader(const BlockNode &Node) const { return Node == Nodes[0]; }
250
251 BlockNode getHeader() const { return Nodes[0]; }
252 bool isIrreducible() const { return IsIrreducible; }
253
254 NodeList::const_iterator members_begin() const { return Nodes.begin() + 1; }
255
260 };
261
262 /// Index of loop information.
263 struct WorkingData {
264 BlockNode Node; ///< This node.
265 LoopData *Loop = nullptr; ///< The loop this block is inside.
266 BlockMass Mass; ///< Mass distribution from the entry block.
267
269
270 bool isLoopHeader() const { return Loop && Loop->isHeader(Node); }
271
272 /// The innermost loop containing Node that Node does not head.
273 ///
274 /// A block can head several nested loops: an irreducible SCC's
275 /// representative may also head a sub-loop.
277 LoopData *L = Loop;
278 while (L && L->isHeader(Node))
279 L = L->Parent;
280 return L;
281 }
282
283 /// Resolve a node to its representative.
284 ///
285 /// Get the node currently representing Node, which could be a containing
286 /// loop.
287 ///
288 /// This function should only be called when distributing mass. As long as
289 /// there are no irreducible edges to Node, then it will have complexity
290 /// O(1) in this context.
291 ///
292 /// In general, the complexity is O(L), where L is the number of loop
293 /// headers Node has been packaged into. Since this method is called in
294 /// the context of distributing mass, L will be the number of loop headers
295 /// an early exit edge jumps out of.
297 auto *L = getPackagedLoop();
298 return L ? L->getHeader() : Node;
299 }
300
301 /// The outermost loop containing Node that is currently packaged, if any.
302 ///
303 /// Packaging is transient state: this answers what represents Node at the
304 /// level being processed, not where Node sits in the loop nest.
306 if (!Loop || !Loop->IsPackaged)
307 return nullptr;
308 auto *L = Loop;
309 while (L->Parent && L->Parent->IsPackaged)
310 L = L->Parent;
311 return L;
312 }
313
314 /// The mass slot for Node: its own, or that of the outermost packaged
315 /// loop it heads.
317 BlockMass *M = &Mass;
318 for (LoopData *L = Loop; L && L->IsPackaged && L->isHeader(Node);
319 L = L->Parent)
320 M = &L->Mass;
321 return *M;
322 }
323
324 /// Has ContainingLoop been packaged up?
325 bool isPackaged() const { return getResolvedNode() != Node; }
326
327 /// Has Loop been packaged up?
328 bool isAPackage() const { return isLoopHeader() && Loop->IsPackaged; }
329 };
330
331 /// Unscaled probability weight.
332 ///
333 /// Probability weight for an edge in the graph (including the
334 /// successor/target node).
335 ///
336 /// All edges in the original function are 32-bit. However, exit edges from
337 /// loop packages are taken from 64-bit exit masses, so we need 64-bits of
338 /// space in general.
339 ///
340 /// In addition to the raw weight amount, Weight stores the type of the edge
341 /// in the current context (i.e., the context of the loop being processed).
342 /// Is this a local edge within the loop, an exit from the loop, or a
343 /// backedge to the loop header?
354
355 /// Distribution of unscaled probability weight.
356 ///
357 /// Distribution of unscaled probability weight to a set of successors.
358 ///
359 /// This class collates the successor edge weights for later processing.
360 ///
361 /// \a DidOverflow indicates whether \a Total did overflow while adding to
362 /// the distribution. It should never overflow twice.
365
366 WeightList Weights; ///< Individual successor weights.
367 uint64_t Total = 0; ///< Sum of all weights.
368 bool DidOverflow = false; ///< Whether \a Total did overflow.
369
370 Distribution() = default;
371
372 void addLocal(const BlockNode &Node, uint64_t Amount) {
373 add(Node, Amount, Weight::Local);
374 }
375
376 void addExit(const BlockNode &Node, uint64_t Amount) {
377 add(Node, Amount, Weight::Exit);
378 }
379
380 void addBackedge(const BlockNode &Node, uint64_t Amount) {
381 add(Node, Amount, Weight::Backedge);
382 }
383
384 /// Normalize the distribution.
385 ///
386 /// Combines multiple edges to the same \a Weight::TargetNode and scales
387 /// down so that \a Total fits into 32-bits.
388 ///
389 /// This is linear in the size of \a Weights. For the vast majority of
390 /// cases, adjacent edge weights are combined by sorting WeightList and
391 /// combining adjacent weights. However, for very large edge lists an
392 /// auxiliary hash table is used.
393 LLVM_ABI void normalize();
394
395 private:
396 LLVM_ABI void add(const BlockNode &Node, uint64_t Amount,
398 };
399
400 /// Data about each block. This is used downstream.
401 std::vector<FrequencyData> Freqs;
402
403 /// Whether each block is an irreducible loop header.
404 /// This is used downstream.
406
407 /// Loop data: see initializeLoops().
408 std::vector<WorkingData> Working;
409
410 /// Indexed information about loops.
411 std::list<LoopData> Loops;
412
413 /// -check-bfi-unknown-block-queries of the function's context.
415
416 /// Has an irreducible SCC outside every loop.
418
419 /// Virtual destructor.
420 ///
421 /// Need a virtual destructor to mask the compiler warning about
422 /// getBlockName().
423 virtual ~BlockFrequencyInfoImplBase() = default;
424
425 /// Add all edges out of a packaged loop to the distribution.
426 ///
427 /// Adds all edges from LocalLoopHead to Dist. Calls addToDist() to add each
428 /// successor edge.
429 void addLoopSuccessorsToDist(const LoopData *OuterLoop, LoopData &Loop,
430 Distribution &Dist);
431
432 /// Add an edge to the distribution.
433 ///
434 /// Adds an edge to Succ to Dist. If \c LoopHead.isValid(), then whether the
435 /// edge is local/exit/backedge is in the context of LoopHead. Otherwise,
436 /// every edge should be a local edge (since all the loops are packaged up).
437 void addToDist(Distribution &Dist, const LoopData *OuterLoop,
438 const BlockNode &Pred, const BlockNode &Succ, uint64_t Weight);
439
440 /// Analyze irreducible SCCs.
441 ///
442 /// Separate irreducible SCCs from \c G, which is an explicit graph of \c
443 /// OuterLoop (or the top-level function, if \c OuterLoop is \c nullptr).
444 /// Insert them into \a Loops before \c Insert.
445 ///
446 /// \return the \c LoopData nodes representing the irreducible SCCs.
449 std::list<LoopData>::iterator Insert);
450
451 /// Distribute mass according to a distribution.
452 ///
453 /// Distributes the mass in Source according to Dist. If LoopHead.isValid(),
454 /// backedges and exits are stored in its entry in Loops.
455 ///
456 /// Mass is distributed in parallel from two copies of the source mass.
457 void distributeMass(const BlockNode &Source, LoopData *OuterLoop,
458 Distribution &Dist);
459
460 /// Compute the loop scale for a loop.
462
463 /// Package up a loop.
465
466 /// Unwrap loops.
467 void unwrapLoops();
468
469 /// Finalize frequency metrics.
470 ///
471 /// Calculates final frequencies and cleans up no-longer-needed data
472 /// structures.
473 void finalizeMetrics();
474
475 /// Clear all memory.
476 void clear();
477
478 virtual std::string getBlockName(const BlockNode &Node) const;
479 std::string getLoopName(const LoopData &Loop) const;
480
481 virtual raw_ostream &print(raw_ostream &OS) const { return OS; }
482 void dump() const { print(dbgs()); }
483
484 Scaled64 getFloatingBlockFreq(const BlockNode &Node) const;
485
486 BlockFrequency getBlockFreq(const BlockNode &Node) const;
487 std::optional<uint64_t> getBlockProfileCount(const Function &F,
488 const BlockNode &Node) const;
489 std::optional<uint64_t> getProfileCountFromFreq(const Function &F,
490 BlockFrequency Freq) const;
491 bool isIrrLoopHeader(const BlockNode &Node);
492
493 void setBlockFreq(const BlockNode &Node, BlockFrequency Freq);
494
496 assert(!Freqs.empty());
497 return BlockFrequency(Freqs[0].Integer);
498 }
499};
500
501namespace bfi_detail {
502
503template <class BlockT> struct TypeMap {};
516
517/// Get the name of a MachineBasicBlock.
518///
519/// Get the name of a MachineBasicBlock. It's templated so that including from
520/// CodeGen is unnecessary (that would be a layering issue).
521///
522/// This is used mainly for debug output. The name is similar to
523/// MachineBasicBlock::getFullName(), but skips the name of the function.
524template <class BlockT> std::string getBlockName(const BlockT *BB) {
525 assert(BB && "Unexpected nullptr");
526 auto MachineName = "BB" + Twine(BB->getNumber());
527 if (BB->getBasicBlock())
528 return (MachineName + "[" + BB->getName() + "]").str();
529 return MachineName.str();
530}
531/// Get the name of a BasicBlock.
532template <> inline std::string getBlockName(const BasicBlock *BB) {
533 assert(BB && "Unexpected nullptr");
534 return BB->getName().str();
535}
536
537/// Graph of irreducible control flow.
538///
539/// This graph is used for determining the SCCs in a loop (or top-level
540/// function) that has irreducible control flow.
541///
542/// During the block frequency algorithm, the local graphs are defined in a
543/// light-weight way, deferring to the \a BasicBlock or \a MachineBasicBlock
544/// graphs for most edges, but getting others from \a LoopData::ExitMap. The
545/// latter only has successor information.
546///
547/// \a IrreducibleGraph makes this graph explicit. It's in a form that can use
548/// \a GraphTraits (so that \a analyzeIrreducible() can use \a scc_iterator),
549/// and it explicitly lists predecessors and successors. The initialization
550/// that relies on \c MachineBasicBlock is defined in the header.
553
555
569 const IrrNode *StartIrr = nullptr;
570 std::vector<IrrNode> Nodes;
572
573 /// The position of \p N in \a Nodes, for indexing side tables.
574 unsigned getIndex(const IrrNode *N) const { return N - Nodes.data(); }
575
576 /// Construct an explicit graph containing irreducible control flow.
577 ///
578 /// Construct an explicit graph of the control flow in \c OuterLoop (or the
579 /// top-level function, if \c OuterLoop is \c nullptr). Uses \c
580 /// addBlockEdges to add block successors that have not been packaged into
581 /// loops.
582 ///
583 /// \a BlockFrequencyInfoImpl::computeIrreducibleMass() is the only expected
584 /// user of this.
585 template <class BlockEdgesAdder>
587 BlockEdgesAdder addBlockEdges) : BFI(BFI) {
588 initialize(OuterLoop, addBlockEdges);
589 }
590
591 template <class BlockEdgesAdder>
592 void initialize(const BFIBase::LoopData *OuterLoop,
593 BlockEdgesAdder addBlockEdges);
594 LLVM_ABI void addNodesInLoop(const BFIBase::LoopData &OuterLoop);
596
597 void addNode(const BlockNode &Node) {
598 Nodes.emplace_back(Node);
599 assert(BFI.Working[Node.Index].getMass().isEmpty() &&
600 "mass distributed before the region was packaged");
601 }
602
603 LLVM_ABI void indexNodes();
604 template <class BlockEdgesAdder>
605 void addEdges(const BlockNode &Node, const BFIBase::LoopData *OuterLoop,
606 BlockEdgesAdder addBlockEdges);
607 LLVM_ABI void addEdge(IrrNode &Irr, const BlockNode &Succ,
608 const BFIBase::LoopData *OuterLoop);
609};
610
611template <class BlockEdgesAdder>
613 BlockEdgesAdder addBlockEdges) {
614 if (OuterLoop) {
615 addNodesInLoop(*OuterLoop);
616 for (auto N : OuterLoop->Nodes)
617 addEdges(N, OuterLoop, addBlockEdges);
618 } else {
620 for (uint32_t Index = 0; Index < BFI.Working.size(); ++Index)
621 addEdges(Index, OuterLoop, addBlockEdges);
622 }
623 StartIrr = Lookup[Start.Index];
624}
625
626template <class BlockEdgesAdder>
628 const BFIBase::LoopData *OuterLoop,
629 BlockEdgesAdder addBlockEdges) {
630 auto L = Lookup.find(Node.Index);
631 if (L == Lookup.end())
632 return;
633 IrrNode &Irr = *L->second;
634 const auto &Working = BFI.Working[Node.Index];
635
636 if (Working.isAPackage())
637 for (const auto &I : Working.Loop->Exits)
638 addEdge(Irr, I.first, OuterLoop);
639 else
640 addBlockEdges(*this, Irr, OuterLoop);
641}
642
643} // end namespace bfi_detail
644
645/// Shared implementation for block frequency analysis.
646///
647/// This is a shared implementation of BlockFrequencyInfo and
648/// MachineBlockFrequencyInfo, and calculates the relative frequencies of
649/// blocks.
650///
651/// LoopInfo defines a loop as a "non-trivial" SCC dominated by a single block,
652/// which is called the header. A given loop, L, can have sub-loops, which are
653/// loops within the subgraph of L that exclude its header. (A "trivial" SCC
654/// consists of a single block that does not have a self-edge.)
655///
656/// In addition to loops, this algorithm has limited support for irreducible
657/// SCCs, which are SCCs with multiple entry blocks. Irreducible SCCs are
658/// found from CycleInfo before any mass is distributed, and packaged like a
659/// loop, with the lowest-RPO member standing for the package. There is no
660/// header to sweep from, so \a solveIrreducibleMass() distributes mass among
661/// the members by power iteration instead.
662///
663/// This algorithm leverages BlockMass and ScaledNumber to maintain precision,
664/// separates mass distribution from loop scaling, and dithers to eliminate
665/// probability mass loss.
666///
667/// The implementation is split between BlockFrequencyInfoImpl, which knows the
668/// type of graph being modelled (BasicBlock vs. MachineBasicBlock), and
669/// BlockFrequencyInfoImplBase, which doesn't. The base class uses \a
670/// BlockNode, a wrapper around a uint32_t. BlockNode is numbered from 0 in
671/// reverse-post order. This gives two advantages: it's easy to compare the
672/// relative ordering of two nodes, and maps keyed on BlockT can be represented
673/// by vectors.
674///
675/// This algorithm is O(V+E), unless there is irreducible control flow, in
676/// which case it's O(V*E) in the worst case.
677///
678/// These are the main stages:
679///
680/// 0. Reverse post-order traversal (\a initializeRPOT()).
681///
682/// Run a single post-order traversal and save it (in reverse) in RPOT.
683/// All other stages make use of this ordering. Save a lookup from BlockT
684/// to BlockNode (the index into RPOT) in Nodes.
685///
686/// 1. Loop initialization (\a initializeLoops()).
687///
688/// Translate LoopInfo/MachineLoopInfo into a form suitable for the rest of
689/// the algorithm. In particular, store the immediate members of each loop
690/// in reverse post-order.
691///
692/// 2. Calculate mass and scale in loops (\a computeMassInLoops()).
693///
694/// For each loop (bottom-up), distribute mass through the DAG resulting
695/// from ignoring backedges and treating sub-loops as a single pseudo-node.
696/// Track the backedge mass distributed to the loop header, and use it to
697/// calculate the loop scale (number of loop iterations). Immediate
698/// members that represent sub-loops will already have been visited and
699/// packaged into a pseudo-node.
700///
701/// Distributing mass in a loop is a reverse-post-order traversal through
702/// the loop. Start by assigning full mass to the Loop header. For each
703/// node in the loop:
704///
705/// - Fetch and categorize the weight distribution for its successors.
706/// If this is a packaged-subloop, the weight distribution is stored
707/// in \a LoopData::Exits. Otherwise, fetch it from
708/// BranchProbabilityInfo.
709///
710/// - Each successor is categorized as \a Weight::Local, a local edge
711/// within the current loop, \a Weight::Backedge, a backedge to the
712/// loop header, or \a Weight::Exit, any successor outside the loop.
713/// The weight, the successor, and its category are stored in \a
714/// Distribution. There can be multiple edges to each successor.
715/// \a computeIrreducibleMass() has packaged up every irreducible SCC
716/// by this point, so no backedge here targets a non-header.
717///
718/// - Normalize the distribution: scale weights down so that their sum
719/// is 32-bits, and coalesce multiple edges to the same node.
720///
721/// - Distribute the mass accordingly, dithering to minimize mass loss,
722/// as described in \a distributeMass().
723///
724/// An irreducible SCC is not swept. \a solveIrreducibleMass() iterates
725/// the SCC's internal chain towards its dominant eigenvector and reads the
726/// member masses, the exits and the circulating mass off that.
727///
728/// Finally, calculate the loop scale from the accumulated backedge mass.
729///
730/// 3. Distribute mass in the function (\a computeMassInFunction()).
731///
732/// Finally, distribute mass through the DAG resulting from packaging all
733/// loops in the function. This uses the same algorithm as distributing
734/// mass in a loop, except that there are no exit or backedge edges.
735///
736/// 4. Unpackage loops (\a unwrapLoops()).
737///
738/// Initialize each block's frequency to a floating point representation of
739/// its mass.
740///
741/// Visit loops top-down, scaling the frequencies of its immediate members
742/// by the loop's pseudo-node's frequency.
743///
744/// 5. Convert frequencies to a 64-bit range (\a finalizeMetrics()).
745///
746/// Using the min and max frequencies as a guide, translate floating point
747/// frequencies to an appropriate range in uint64_t.
748///
749/// It has some known flaws.
750///
751/// - The model of irreducible control flow is a rough approximation.
752///
753/// \a solveIrreducibleMass() settles an SCC's internal chain, but the mass
754/// entering each entry is unknown until the parent loop is distributed, so
755/// it aims at the quasi-stationary vector rather than the true occupancy.
756/// To get closer, partially compute mass in the parent loop and stop at
757/// the SCC: that gives the correct ratio of entry masses to adjust their
758/// relative frequencies with. Compute mass in the SCC, then continue
759/// propagation in the parent.
761 using BlockT = typename bfi_detail::TypeMap<BT>::BlockT;
762 using FunctionT = typename bfi_detail::TypeMap<BT>::FunctionT;
763 using BranchProbabilityInfoT =
765 using CycleInfoT = typename bfi_detail::TypeMap<BT>::CycleInfoT;
766 using Successor = GraphTraits<const BlockT *>;
767 using Predecessor = GraphTraits<Inverse<const BlockT *>>;
768
769 const BranchProbabilityInfoT *BPI = nullptr;
770 const CycleInfoT *CI = nullptr;
771 const FunctionT *F = nullptr;
772
773 // All blocks in reverse postorder.
774 std::vector<const BlockT *> RPOT;
775 /// Map from block number to number on RPOT/Freqs.
777 unsigned BlockNumberEpoch;
778
779 BlockNode getNode(const BlockT *BB) const {
780 assert(BlockNumberEpoch ==
782 unsigned BlockNumber = GraphTraits<const BlockT *>::getNumber(BB);
783 return BlockNumber < Nodes.size() ? Nodes[BlockNumber] : BlockNode();
784 }
785
786 const BlockT *getBlock(const BlockNode &Node) const {
787 assert(Node.Index < RPOT.size());
788 return RPOT[Node.Index];
789 }
790
791 /// Save a reverse post-order traversal of all the nodes.
792 void initializeRPOT();
793
794 /// Initialize loop data.
795 ///
796 /// Build up \a Loops using \a LoopInfo. \a LoopInfo gives us a mapping from
797 /// each block to the deepest loop it's in, but we need the inverse. For each
798 /// loop, we store in reverse post-order its "immediate" members, defined as
799 /// the header, the headers of immediate sub-loops, and all other blocks in
800 /// the loop that are not in sub-loops.
801 void initializeLoops();
802
803 /// Propagate to a block's successors.
804 ///
805 /// In the context of distributing mass through \c OuterLoop, divide the mass
806 /// currently assigned to \c Node between its successors.
807 void propagateMassToSuccessors(LoopData *OuterLoop, const BlockNode &Node);
808
809 /// Compute mass in a particular loop.
810 ///
811 /// Assign mass to \c Loop's header, and then for each block in \c Loop in
812 /// reverse post-order, distribute mass to its successors. Only visits nodes
813 /// that have not been packaged into sub-loops.
814 ///
815 /// \pre \a computeMassInLoop() has been called for each subloop of \c Loop,
816 /// and \a computeIrreducibleMass() for \c Loop if it contains irreducible
817 /// control flow.
818 void computeMassInLoop(LoopData &Loop);
819 void solveIrreducibleMass(LoopData &Loop);
820
821 /// Collect \c Node's successors, resolved through any package, with weights.
822 void getSuccWeights(const BlockNode &Node,
823 SmallVectorImpl<std::pair<BlockNode, uint64_t>> &Out);
824
825 /// Compute mass in (and package up) irreducible SCCs.
826 ///
827 /// Find the irreducible SCCs in \c OuterLoop, add them to \a Loops (in front
828 /// of \c Insert), and call \a computeMassInLoop() on each of them.
829 ///
830 /// If \c OuterLoop is \c nullptr, it refers to the top-level function.
831 ///
832 /// \pre \a computeMassInLoop() has been called for each subloop of \c
833 /// OuterLoop.
834 /// \pre \c OuterLoop has irreducible SCCs.
835 void computeIrreducibleMass(LoopData *OuterLoop,
836 std::list<LoopData>::iterator Insert);
837
838 /// Compute mass in all loops.
839 ///
840 /// For each loop bottom-up, call \a computeMassInLoop(), packaging
841 /// irreducible SCCs first via \a computeIrreducibleMass() where \a
842 /// initializeLoops() found them.
843 void computeMassInLoops();
844
845 /// Compute mass in the top-level function.
846 ///
847 /// Package up any top-level irreducible SCCs, assign mass to the entry
848 /// block, and then for each block in reverse post-order, distribute mass to
849 /// its successors. Skips nodes that have been packaged into loops.
850 ///
851 /// \pre \a computeMassInLoops() has been called.
852 void computeMassInFunction();
853
854 std::string getBlockName(const BlockNode &Node) const override {
855 return bfi_detail::getBlockName(getBlock(Node));
856 }
857
858 /// The current implementation for computing relative block frequencies does
859 /// not handle correctly control-flow graphs containing irreducible loops. To
860 /// resolve the problem, we apply a post-processing step, which iteratively
861 /// updates block frequencies based on the frequencies of their predesessors.
862 /// This corresponds to finding the stationary point of the Markov chain by
863 /// an iterative method aka "PageRank computation".
864 /// The algorithm takes at most O(|E| * IterativeBFIMaxIterations) steps but
865 /// typically converges faster.
866 ///
867 /// Decide whether we want to apply iterative inference for a given function.
868 bool needIterativeInference() const;
869
870 /// Apply an iterative post-processing to infer correct counts for irr loops.
871 void applyIterativeInference();
872
873 using ProbMatrixType = std::vector<std::vector<std::pair<size_t, Scaled64>>>;
874
875 /// Run iterative inference for a probability matrix and initial frequencies.
876 void iterativeInference(const ProbMatrixType &ProbMatrix,
877 const BitVector &Blocks,
878 std::vector<Scaled64> &Freq) const;
879
880 /// Find all blocks to apply inference on, that is, reachable from the entry
881 /// and backward reachable from exits along edges with positive probability.
882 void findReachableBlocks(BitVector &Blocks) const;
883
884 /// Build a matrix of probabilities with transitions (edges) between the
885 /// blocks: ProbMatrix[I] holds pairs (J, P), where Pr[J -> I | J] = P
886 void initTransitionProbabilities(const BitVector &Blocks,
887 ProbMatrixType &ProbMatrix) const;
888
889#ifndef NDEBUG
890 /// Compute the discrepancy between current block frequencies and the
891 /// probability matrix.
892 Scaled64 discrepancy(const ProbMatrixType &ProbMatrix,
893 const std::vector<Scaled64> &Freq) const;
894#endif
895
896public:
898
899 const FunctionT *getFunction() const { return F; }
900
901 void calculate(const FunctionT &F, const BranchProbabilityInfoT &BPI,
902 const CycleInfoT &CI);
903
905
906 BlockFrequency getBlockFreq(const BlockT *BB) const {
908 }
909
910 std::optional<uint64_t> getBlockProfileCount(const Function &F,
911 const BlockT *BB) const {
913 }
914
915 std::optional<uint64_t> getProfileCountFromFreq(const Function &F,
916 BlockFrequency Freq) const {
918 }
919
920 bool isIrrLoopHeader(const BlockT *BB) {
922 }
923
924 void setBlockFreq(const BlockT *BB, BlockFrequency Freq);
925
926 Scaled64 getFloatingBlockFreq(const BlockT *BB) const {
928 }
929
930 const BranchProbabilityInfoT &getBPI() const { return *BPI; }
931
932 /// Print the frequencies for the current function.
933 ///
934 /// Prints the frequencies for the blocks in the current function.
935 ///
936 /// Blocks are printed in the natural iteration order of the function, rather
937 /// than reverse post-order. This provides two advantages: writing -analyze
938 /// tests is easier (since blocks come out in source order), and even
939 /// unreachable blocks are printed.
940 ///
941 /// \a BlockFrequencyInfoImplBase::print() only knows reverse post-order, so
942 /// we need to override it here.
943 raw_ostream &print(raw_ostream &OS) const override;
944
946
948};
949
950template <class BT>
952 const BranchProbabilityInfoT &BPI,
953 const CycleInfoT &CI) {
954 // Save the parameters.
955 this->BPI = &BPI;
956 this->CI = &CI;
957 this->F = &F;
958
959 // Clean up left-over data structures.
961 RPOT.clear();
962 Nodes.clear();
964 shouldCheckBFIUnknownBlockQueries(F.getFunction().getContext());
965
966 LLVM_DEBUG(dbgs() << "\nblock-frequency: " << F.getName()
967 << "\n================="
968 << std::string(F.getName().size(), '=') << "\n");
969
970 // Mass flows over a DAG: loops are packaged into pseudo-nodes, and backedges
971 // accumulate as loop mass instead of being followed.
972
973 // Number blocks in reverse post-order; BlockNode comparisons use it.
974 initializeRPOT();
975 // Group blocks into the loops BFI represents, marking irreducible regions.
976 initializeLoops();
977
978 // Deepest loop first, so each is packaged before its parent needs it.
979 computeMassInLoops();
980 computeMassInFunction();
981 // Unpackage, scaling members by the loop's iterations and package mass.
982 unwrapLoops();
983 // Apply a post-processing step improving computed frequencies for functions
984 // with irreducible loops.
985 if (needIterativeInference())
986 applyIterativeInference();
988
989 if (this->CheckUnknownBlockQueries) {
990 // To detect BFI queries for unknown blocks, add entries for unreachable
991 // blocks, if any. This is to distinguish between known/existing unreachable
992 // blocks and unknown blocks.
993 for (const BlockT &BB : F)
994 if (!getNode(&BB).isValid())
996 }
997
998 RPOT.clear();
999}
1000
1001template <class BT>
1003 BlockFrequency Freq) {
1005 unsigned BlockNumber = GraphTraits<const BlockT *>::getNumber(BB);
1006 if (Nodes.size() <= BlockNumber)
1008 BlockNode &Node = Nodes[BlockNumber];
1009 if (!Node.isValid()) {
1010 // If BB is a newly added block after BFI is done, we need to create a new
1011 // BlockNode for it assigned with a new index. The index can be determined
1012 // by the size of Freqs.
1013 Node = BlockNode(Freqs.size());
1014 Freqs.emplace_back();
1015 }
1017}
1018
1019template <class BT> void BlockFrequencyInfoImpl<BT>::initializeRPOT() {
1020 const BlockT *Entry = &F->front();
1021 RPOT.reserve(F->size());
1022 for (const BlockT *BB : post_order(Entry))
1023 RPOT.emplace_back(BB);
1024 std::reverse(RPOT.begin(), RPOT.end());
1025
1026 assert(RPOT.size() - 1 <= BlockNode::getMaxIndex() &&
1027 "More nodes in function than Block Frequency Info supports");
1028
1029 LLVM_DEBUG(dbgs() << "reverse-post-order-traversal\n");
1032 for (auto [Idx, Block] : enumerate(RPOT)) {
1033 BlockNode Node = BlockNode(Idx);
1034 LLVM_DEBUG(dbgs() << " - " << Idx << ": " << getBlockName(Node) << "\n");
1036 }
1037
1038 Working.reserve(RPOT.size());
1039 for (size_t Index = 0; Index < RPOT.size(); ++Index)
1040 Working.emplace_back(Index);
1041 Freqs.resize(RPOT.size());
1042}
1043
1044template <class BT> void BlockFrequencyInfoImpl<BT>::initializeLoops() {
1045 LLVM_DEBUG(dbgs() << "loop-detection\n");
1046
1047 LLVM_DEBUG(CI->print(dbgs()));
1048
1049 // Whether \p C describes a loop for BFI. An entry of a cycle an edge
1050 // re-enters heads a loop the forest does not represent, because the cycle
1051 // absorbed it; which entry that is depends on the order the search found
1052 // them in. Represent none of them, so that equal entries stay equal, and
1053 // leave the region to the packaging computeIrreducibleMass does.
1054 auto hasLoop = [&](CycleRef C) {
1055 if (!CI->isReducible(C))
1056 return false;
1057 for (CycleRef A = CI->getParentCycle(C); A; A = CI->getParentCycle(A))
1058 if (!CI->isReducible(A) && CI->isEntry(A, CI->getHeader(C)))
1059 return false;
1060 return true;
1061 };
1062
1063 // Visit loops top down and assign them an index.
1064 std::deque<std::pair<CycleRef, LoopData *>> Q;
1065 for (CycleRef C : CI->toplevel_cycles())
1066 Q.emplace_back(C, nullptr);
1067 if (Q.empty())
1068 return; // Early exit if there are no cycles.
1069 while (!Q.empty()) {
1070 CycleRef Cycle = Q.front().first;
1071 LoopData *Parent = Q.front().second;
1072 Q.pop_front();
1073
1074 if (hasLoop(Cycle)) {
1075 BlockNode Header = getNode(CI->getHeader(Cycle));
1076 Loops.emplace_back(Parent, Header);
1077
1078 Working[Header.Index].Loop = &Loops.back();
1079 LLVM_DEBUG(dbgs() << " - loop = " << getBlockName(Header) << "\n");
1080 Parent = &Loops.back();
1081 } else if (!CI->isReducible(Cycle)) {
1082 // No LoopData yet; ask computeIrreducibleMass to package the SCC
1083 // that contains this cycle.
1084 if (Parent)
1085 Parent->ContainsIrreducible = true;
1086 else
1087 TopContainsIrreducible = true;
1088 }
1089
1090 for (CycleRef C : CI->children(Cycle))
1091 Q.emplace_back(C, Parent);
1092 }
1093
1094 // Visit nodes in reverse post-order and add them to their deepest containing
1095 // loop.
1096 for (size_t Index = 0; Index < RPOT.size(); ++Index) {
1097 // Loop headers have already been mostly mapped.
1098 if (Working[Index].isLoopHeader()) {
1099 LoopData *ContainingLoop = Working[Index].getContainingLoop();
1100 if (ContainingLoop)
1101 ContainingLoop->Nodes.push_back(Index);
1102 continue;
1103 }
1104
1105 CycleRef Cycle = CI->getCycle(RPOT[Index]);
1106 while (Cycle && !hasLoop(Cycle))
1107 Cycle = CI->getParentCycle(Cycle);
1108 if (!Cycle)
1109 continue;
1110
1111 // Add this node to its containing loop's member list.
1112 BlockNode Header = getNode(CI->getHeader(Cycle));
1113 assert(Header.isValid());
1114 const auto &HeaderData = Working[Header.Index];
1115 assert(HeaderData.isLoopHeader());
1116
1117 Working[Index].Loop = HeaderData.Loop;
1118 HeaderData.Loop->Nodes.push_back(Index);
1119 LLVM_DEBUG(dbgs() << " - loop = " << getBlockName(Header)
1120 << ": member = " << getBlockName(Index) << "\n");
1121 }
1122}
1123
1124template <class BT> void BlockFrequencyInfoImpl<BT>::computeMassInLoops() {
1125 // Visit loops with the deepest first, and the top-level loops last.
1126 // computeIrreducibleMass inserts each new loop immediately after *L.
1127 for (auto L = Loops.end(), B = Loops.begin(); L != B;) {
1128 --L;
1129 if (L->ContainsIrreducible)
1130 computeIrreducibleMass(&*L, std::next(L));
1131 computeMassInLoop(*L);
1132 }
1133}
1134
1135template <class BT>
1136void BlockFrequencyInfoImpl<BT>::computeMassInLoop(LoopData &Loop) {
1137 LLVM_DEBUG(dbgs() << "compute-mass-in-loop: " << getLoopName(Loop) << "\n");
1138
1139 if (Loop.isIrreducible()) {
1140 LLVM_DEBUG(dbgs() << "isIrreducible = true\n");
1141 solveIrreducibleMass(Loop);
1142 } else {
1143 Working[Loop.getHeader().Index].getMass() = BlockMass::getFull();
1144 propagateMassToSuccessors(&Loop, Loop.getHeader());
1145 for (const BlockNode &M : Loop.members())
1146 propagateMassToSuccessors(&Loop, M);
1147 }
1148
1149 computeLoopScale(Loop);
1150 packageLoop(Loop);
1151}
1152
1153template <class BT>
1154void BlockFrequencyInfoImpl<BT>::getSuccWeights(
1155 const BlockNode &Node,
1156 SmallVectorImpl<std::pair<BlockNode, uint64_t>> &Out) {
1157 Out.clear();
1158 if (auto *L = Working[Node.Index].getPackagedLoop()) {
1159 for (const auto &E : L->Exits)
1160 Out.emplace_back(Working[E.first.Index].getResolvedNode(),
1161 E.second.getMass());
1162 return;
1163 }
1164 const BlockT *BB = getBlock(Node);
1165 for (auto It : enumerate(children<const BlockT *>(BB))) {
1166 BlockNode Succ = getNode(It.value());
1167 if (!Succ.isValid())
1168 continue;
1169 uint64_t W =
1170 getWeightFromBranchProb(BPI->getEdgeProbability(BB, It.index()));
1171 Out.emplace_back(Working[Succ.Index].getResolvedNode(),
1172 std::max<uint64_t>(1, W));
1173 }
1174}
1175
1176// Distribute an irreducible SCC's mass among its members, and record the
1177// exits and circulating mass computeLoopScale() needs. For the transition
1178// matrix restricted to SCC members, use power iteration to find an approximate
1179// solution.
1180template <class BT>
1181void BlockFrequencyInfoImpl<BT>::solveIrreducibleMass(LoopData &Loop) {
1182 const size_t N = Loop.Nodes.size();
1183 // Intra-SCC edges (src, dst) and exit edges (src, target), both in src order.
1187 for (size_t I = 0; I != N; ++I) {
1188 getSuccWeights(Loop.Nodes[I], Succs);
1190 if (!Total)
1191 continue;
1192 Scaled64 InvTotal = Scaled64::getInverse(Total);
1193 for (const auto &S : Succs) {
1194 Scaled64 Pr = Scaled64(S.second, 0) * InvTotal;
1195 // createIrreducibleLoop sorted Nodes, so a member's position in the
1196 // matrix is where it lands in that list.
1197 auto It = llvm::lower_bound(Loop.Nodes, S.first);
1198 if (It != Loop.Nodes.end() && *It == S.first)
1199 P.emplace_back(I, It - Loop.Nodes.begin(), Pr);
1200 else
1201 Ex.emplace_back(I, S.first, Pr);
1202 }
1203 }
1204
1205 // irr_loop_header_weight is a measured block frequency, so pin the members
1206 // that carry one and let the rest settle around them. Weights that are all
1207 // zero anchor no scale, so start from a uniform split instead.
1209 SmallVector<bool> Pinned(N, false);
1210 Scaled64 Sum;
1211 for (size_t I = 0; I != N; ++I)
1212 if (auto W = getBlock(Loop.Nodes[I])->getIrrLoopHeaderWeight()) {
1213 F[I] = Scaled64(*W, 0);
1214 Pinned[I] = true;
1215 Sum += F[I];
1216 }
1217 if (Sum.isZero()) {
1218 Pinned.assign(N, false);
1219 F.assign(N, Scaled64::getInverse(N));
1220 Sum = llvm::sum_of(F, Scaled64::getZero());
1221 }
1222
1223 // A backstop, not a convergence criterion: a periodic SCC never settles.
1224 const unsigned MaxIterations = 16;
1225 // Mass leaks out of the SCC, so F decays geometrically. Sum tracks the
1226 // decay; Ratio divides it out so Delta compares directions, not sizes.
1227 for (unsigned It = 0; It != MaxIterations; ++It) {
1228 G.assign(N, Scaled64::getZero());
1229 for (auto [I, J, Pr] : P)
1230 G[J] += F[I] * Pr;
1231 Scaled64 New;
1232 for (size_t I = 0; I != N; ++I) {
1233 if (Pinned[I])
1234 G[I] = F[I];
1235 New += G[I];
1236 }
1237 if (New.isZero())
1238 break; // nothing circulates; keep the uniform split
1239 Scaled64 Ratio = New / Sum;
1240 Scaled64 Delta;
1241 for (size_t I = 0; I != N; ++I) {
1242 Scaled64 Was = Ratio * F[I];
1243 Delta += G[I] >= Was ? G[I] - Was : Was - G[I];
1244 F[I] = G[I];
1245 }
1246 Sum = New;
1247 if (Delta < New * Scaled64(1, -32))
1248 break;
1249 }
1250
1251 if (!Sum.isZero())
1252 for (auto &X : F)
1253 X = X / Sum;
1254
1255 for (size_t I = 0; I != N; ++I)
1256 Working[Loop.Nodes[I].Index].getMass() = BlockMass(F[I].scale(UINT64_MAX));
1257
1258 BlockMass TotalExit;
1259 for (auto [I, Succ, Pr] : Ex) {
1260 uint64_t M = (F[I] * Pr).scale(UINT64_MAX);
1261 Loop.Exits.emplace_back(Succ, BlockMass(M));
1262 TotalExit += BlockMass(M);
1263 }
1264 Loop.BackedgeMass = BlockMass::getFull() - TotalExit;
1265}
1266
1267template <class BT> void BlockFrequencyInfoImpl<BT>::computeMassInFunction() {
1268 if (TopContainsIrreducible)
1269 computeIrreducibleMass(nullptr, Loops.begin());
1270
1271 LLVM_DEBUG(dbgs() << "compute-mass-in-function\n");
1272 assert(!Working.empty() && "no blocks in function");
1273 assert(!Working[0].isLoopHeader() && "entry block is a loop header");
1274
1275 Working[0].getMass() = BlockMass::getFull();
1276 for (size_t i = 0, n = RPOT.size(); i != n; ++i) {
1277 // Check for nodes that have been packaged.
1278 if (Working[i].isPackaged())
1279 continue;
1280
1281 propagateMassToSuccessors(nullptr, BlockNode(i));
1282 }
1283}
1284
1285template <class BT>
1286bool BlockFrequencyInfoImpl<BT>::needIterativeInference() const {
1288 return false;
1289 if (!F->getFunction().hasProfileData())
1290 return false;
1291 // Apply iterative inference only if the function contains irreducible loops;
1292 // otherwise, computed block frequencies are reasonably correct.
1293 for (auto L = Loops.rbegin(), E = Loops.rend(); L != E; ++L) {
1294 if (L->isIrreducible())
1295 return true;
1296 }
1297 return false;
1298}
1299
1300template <class BT> void BlockFrequencyInfoImpl<BT>::applyIterativeInference() {
1301 // Extract blocks for processing: a block is considered for inference iff it
1302 // can be reached from the entry by edges with a positive probability.
1303 // Non-processed blocks are assigned with the zero frequency and are ignored
1304 // in the computation
1305 BitVector ReachableBlocks;
1306 findReachableBlocks(ReachableBlocks);
1307 if (ReachableBlocks.none())
1308 return;
1309
1310 // Extract initial frequencies for the reachable blocks
1311 auto Freq = std::vector<Scaled64>(ReachableBlocks.size());
1312 Scaled64 SumFreq;
1313 for (const BlockT &BB : *F) {
1315 if (!ReachableBlocks[Number])
1316 continue;
1317 Freq[Number] = getFloatingBlockFreq(&BB);
1318 SumFreq += Freq[Number];
1319 }
1320 assert(!SumFreq.isZero() && "empty initial block frequencies");
1321
1322 LLVM_DEBUG(dbgs() << "Applying iterative inference for " << F->getName()
1323 << " with " << ReachableBlocks.count() << " blocks\n");
1324
1325 // Normalizing frequencies so they sum up to 1.0
1326 for (auto &Value : Freq) {
1327 Value /= SumFreq;
1328 }
1329
1330 // Setting up edge probabilities using sparse matrix representation:
1331 // ProbMatrix[I] holds a vector of pairs (J, P) where Pr[J -> I | J] = P
1332 ProbMatrixType ProbMatrix;
1333 initTransitionProbabilities(ReachableBlocks, ProbMatrix);
1334
1335 // Run the propagation
1336 iterativeInference(ProbMatrix, ReachableBlocks, Freq);
1337
1338 // Assign computed frequency values
1339 for (const BlockT &BB : *F) {
1340 auto Node = getNode(&BB);
1341 if (!Node.isValid())
1342 continue;
1344 Freqs[Node.Index].Scaled =
1345 ReachableBlocks[Number] ? Freq[Number] : Scaled64::getZero();
1346 }
1347}
1348
1349template <class BT>
1350void BlockFrequencyInfoImpl<BT>::iterativeInference(
1351 const ProbMatrixType &ProbMatrix, const BitVector &Blocks,
1352 std::vector<Scaled64> &Freq) const {
1353 const LLVMContext &C = F->getFunction().getContext();
1354 const double PrecisionValue = getIterativeBFIPrecision(C);
1355 assert(0.0 < PrecisionValue && PrecisionValue < 1.0 &&
1356 "incorrectly specified precision");
1357 // Convert double precision to Scaled64
1358 const auto Precision =
1359 Scaled64::getInverse(static_cast<uint64_t>(1.0 / PrecisionValue));
1360 const size_t MaxIterations =
1361 getIterativeBFIMaxIterationsPerBlock(C) * Blocks.count();
1362
1363#ifndef NDEBUG
1364 LLVM_DEBUG(dbgs() << " Initial discrepancy = "
1365 << discrepancy(ProbMatrix, Freq).toString() << "\n");
1366#endif
1367
1368 // Successors[I] holds unique sucessors of the I-th block
1369 auto Successors = std::vector<std::vector<size_t>>(Freq.size());
1370 for (size_t I = 0; I < Freq.size(); I++) {
1371 for (const auto &Jump : ProbMatrix[I]) {
1372 Successors[Jump.first].push_back(I);
1373 }
1374 }
1375
1376 // To speedup computation, we maintain a set of "active" blocks whose
1377 // frequencies need to be updated based on the incoming edges.
1378 // The set is dynamic and changes after every update. Initially all blocks
1379 // with a positive frequency are active
1380 auto IsActive = BitVector(Freq.size(), false);
1381 std::queue<size_t> ActiveSet;
1382 for (unsigned I : Blocks.set_bits()) {
1383 if (Freq[I] > 0) {
1384 ActiveSet.push(I);
1385 IsActive[I] = true;
1386 }
1387 }
1388
1389 // Iterate over the blocks propagating frequencies
1390 size_t It = 0;
1391 while (It++ < MaxIterations && !ActiveSet.empty()) {
1392 size_t I = ActiveSet.front();
1393 ActiveSet.pop();
1394 IsActive[I] = false;
1395
1396 // Compute a new frequency for the block: NewFreq := Freq \times ProbMatrix.
1397 // A special care is taken for self-edges that needs to be scaled by
1398 // (1.0 - SelfProb), where SelfProb is the sum of probabilities on the edges
1399 Scaled64 NewFreq;
1400 Scaled64 OneMinusSelfProb = Scaled64::getOne();
1401 for (const auto &Jump : ProbMatrix[I]) {
1402 if (Jump.first == I) {
1403 OneMinusSelfProb -= Jump.second;
1404 } else {
1405 NewFreq += Freq[Jump.first] * Jump.second;
1406 }
1407 }
1408 if (OneMinusSelfProb != Scaled64::getOne())
1409 NewFreq /= OneMinusSelfProb;
1410
1411 // If the block's frequency has changed enough, then
1412 // make sure the block and its successors are in the active set
1413 auto Change = Freq[I] >= NewFreq ? Freq[I] - NewFreq : NewFreq - Freq[I];
1414 if (Change > Precision) {
1415 ActiveSet.push(I);
1416 IsActive[I] = true;
1417 for (size_t Succ : Successors[I]) {
1418 if (!IsActive[Succ]) {
1419 ActiveSet.push(Succ);
1420 IsActive[Succ] = true;
1421 }
1422 }
1423 }
1424
1425 // Update the frequency for the block
1426 Freq[I] = NewFreq;
1427 }
1428
1429 LLVM_DEBUG(dbgs() << " Completed " << It << " inference iterations"
1430 << format(" (%0.0f per block)", double(It) / Freq.size())
1431 << "\n");
1432#ifndef NDEBUG
1433 LLVM_DEBUG(dbgs() << " Final discrepancy = "
1434 << discrepancy(ProbMatrix, Freq).toString() << "\n");
1435#endif
1436}
1437
1438template <class BT>
1439void BlockFrequencyInfoImpl<BT>::findReachableBlocks(BitVector &Blocks) const {
1440 unsigned MaxNumber = GraphTraits<const FunctionT *>::getMaxNumber(F);
1441 auto number = [](const BlockT *BB) {
1443 };
1444
1445 // Find all blocks to apply inference on, that is, reachable from the entry
1446 // along edges with non-zero probablities
1447 std::queue<const BlockT *> Queue;
1448 BitVector Reachable(MaxNumber);
1449 const BlockT *Entry = &F->front();
1450 Queue.push(Entry);
1451 Reachable.set(number(Entry));
1452 while (!Queue.empty()) {
1453 const BlockT *SrcBB = Queue.front();
1454 Queue.pop();
1455 for (auto It : enumerate(children<const BlockT *>(SrcBB))) {
1456 auto EP = BPI->getEdgeProbability(SrcBB, It.index());
1457 if (EP.isZero())
1458 continue;
1459 unsigned Number = number(It.value());
1460 if (!Reachable.test(Number)) {
1461 Reachable.set(Number);
1462 Queue.push(It.value());
1463 }
1464 }
1465 }
1466
1467 // Find all blocks to apply inference on, that is, backward reachable from
1468 // the entry along (backward) edges with non-zero probablities
1469 BitVector InverseReachable(MaxNumber);
1470 for (const BlockT &BB : *F) {
1471 // An exit block is a block without any successors
1472 bool HasSucc = !llvm::children<const BlockT *>(&BB).empty();
1473 if (!HasSucc && Reachable.test(number(&BB))) {
1474 Queue.push(&BB);
1475 InverseReachable.set(number(&BB));
1476 }
1477 }
1478 while (!Queue.empty()) {
1479 const BlockT *SrcBB = Queue.front();
1480 Queue.pop();
1481 for (const BlockT *DstBB : inverse_children<const BlockT *>(SrcBB)) {
1482 auto EP = BPI->getEdgeProbability(DstBB, SrcBB);
1483 if (EP.isZero())
1484 continue;
1485 unsigned Number = number(DstBB);
1486 if (!InverseReachable.test(Number)) {
1487 InverseReachable.set(Number);
1488 Queue.push(DstBB);
1489 }
1490 }
1491 }
1492
1493 // Collect the result
1494 Reachable &= InverseReachable;
1495 Blocks = std::move(Reachable);
1496}
1497
1498template <class BT>
1499void BlockFrequencyInfoImpl<BT>::initTransitionProbabilities(
1500 const BitVector &Blocks, ProbMatrixType &ProbMatrix) const {
1501 const size_t NumBlocks = Blocks.size();
1502 auto Succs = std::vector<std::vector<std::pair<size_t, Scaled64>>>(NumBlocks);
1503 auto SumProb = std::vector<Scaled64>(NumBlocks);
1504
1505 // Find unique successors and corresponding probabilities for every block
1506 for (const BlockT &BB : *F) {
1508 if (!Blocks[Src])
1509 continue;
1511 for (auto It : enumerate(children<const BlockT *>(&BB))) {
1512 const BlockT *SI = It.value();
1514 // Ignore cold blocks
1515 if (!Blocks[Dst])
1516 continue;
1517 // Ignore parallel edges between BB and SI blocks
1518 if (!UniqueSuccs.insert(SI).second)
1519 continue;
1520 // Ignore jumps with zero probability
1521 auto EP = BPI->getEdgeProbability(&BB, It.index());
1522 if (EP.isZero())
1523 continue;
1524
1525 auto EdgeProb =
1526 Scaled64::getFraction(EP.getNumerator(), EP.getDenominator());
1527 Succs[Src].push_back(std::make_pair(Dst, EdgeProb));
1528 SumProb[Src] += EdgeProb;
1529 }
1530 }
1531
1532 // Add transitions for every jump with positive branch probability
1533 ProbMatrix = ProbMatrixType(NumBlocks);
1534 for (size_t Src = 0; Src < NumBlocks; Src++) {
1535 // Ignore blocks w/o successors
1536 if (Succs[Src].empty())
1537 continue;
1538
1539 assert(!SumProb[Src].isZero() && "Zero sum probability of non-exit block");
1540 for (auto &Jump : Succs[Src]) {
1541 size_t Dst = Jump.first;
1542 Scaled64 Prob = Jump.second;
1543 ProbMatrix[Dst].push_back(std::make_pair(Src, Prob / SumProb[Src]));
1544 }
1545 }
1546
1547 // Add transitions from sinks to the source
1548 size_t EntryIdx = GraphTraits<const BlockT *>::getNumber(&F->front());
1549 for (size_t Src = 0; Src < NumBlocks; Src++) {
1550 if (Blocks[Src] && Succs[Src].empty()) {
1551 ProbMatrix[EntryIdx].push_back(std::make_pair(Src, Scaled64::getOne()));
1552 }
1553 }
1554}
1555
1556#ifndef NDEBUG
1557template <class BT>
1558BlockFrequencyInfoImplBase::Scaled64 BlockFrequencyInfoImpl<BT>::discrepancy(
1559 const ProbMatrixType &ProbMatrix, const std::vector<Scaled64> &Freq) const {
1560 size_t EntryIdx = GraphTraits<const BlockT *>::getNumber(&F->front());
1561 assert(Freq[EntryIdx] > 0 &&
1562 "Incorrectly computed frequency of the entry block");
1563 Scaled64 Discrepancy;
1564 for (size_t I = 0; I < ProbMatrix.size(); I++) {
1565 Scaled64 Sum;
1566 for (const auto &Jump : ProbMatrix[I]) {
1567 Sum += Freq[Jump.first] * Jump.second;
1568 }
1569 Discrepancy += Freq[I] >= Sum ? Freq[I] - Sum : Sum - Freq[I];
1570 }
1571 // Normalizing by the frequency of the entry block
1572 return Discrepancy / Freq[EntryIdx];
1573}
1574#endif
1575
1576template <class BT>
1577void BlockFrequencyInfoImpl<BT>::computeIrreducibleMass(
1578 LoopData *OuterLoop, std::list<LoopData>::iterator Insert) {
1579 LLVM_DEBUG(dbgs() << "analyze-irreducible-in-";
1580 if (OuterLoop) dbgs()
1581 << "loop: " << getLoopName(*OuterLoop) << "\n";
1582 else dbgs() << "function\n");
1583
1584 using namespace bfi_detail;
1585
1586 auto addBlockEdges = [&](IrreducibleGraph &G, IrreducibleGraph::IrrNode &Irr,
1587 const LoopData *OuterLoop) {
1588 const BlockT *BB = RPOT[Irr.Node.Index];
1589 for (const auto *Succ : children<const BlockT *>(BB))
1590 G.addEdge(Irr, getNode(Succ), OuterLoop);
1591 };
1592 IrreducibleGraph G(*this, OuterLoop, addBlockEdges);
1593
1594 for (auto &L : analyzeIrreducible(G, OuterLoop, Insert))
1595 computeMassInLoop(L);
1596
1597 if (!OuterLoop)
1598 return;
1599
1600 // Drop the nodes the new packages absorbed.
1601 assert(OuterLoop->Exits.empty() && "unexpected exits before distribution");
1602 assert(OuterLoop->BackedgeMass.isEmpty() &&
1603 "unexpected backedge mass before distribution");
1604 auto O = OuterLoop->Nodes.begin() + 1;
1605 for (auto I = O, E = OuterLoop->Nodes.end(); I != E; ++I)
1606 if (!Working[I->Index].isPackaged())
1607 *O++ = *I;
1608 OuterLoop->Nodes.erase(O, OuterLoop->Nodes.end());
1609}
1610
1611// A helper function that converts a branch probability into weight.
1613 return Prob.getNumerator();
1614}
1615
1616template <class BT>
1617void BlockFrequencyInfoImpl<BT>::propagateMassToSuccessors(
1618 LoopData *OuterLoop, const BlockNode &Node) {
1619 LLVM_DEBUG(dbgs() << " - node: " << getBlockName(Node) << "\n");
1620 // Calculate probability for successors.
1621 Distribution Dist;
1622 if (auto *Loop = Working[Node.Index].getPackagedLoop()) {
1623 assert(Loop != OuterLoop && "Cannot propagate mass in a packaged loop");
1624 addLoopSuccessorsToDist(OuterLoop, *Loop, Dist);
1625 } else {
1626 const BlockT *BB = getBlock(Node);
1627 for (auto It : enumerate(children<const BlockT *>(BB)))
1628 addToDist(
1629 Dist, OuterLoop, Node, getNode(It.value()),
1630 getWeightFromBranchProb(BPI->getEdgeProbability(BB, It.index())));
1631 }
1632
1633 // Distribute mass to successors, saving exit and backedge data in the
1634 // loop header.
1635 distributeMass(Node, OuterLoop, Dist);
1636}
1637
1638template <class BT>
1640 if (!F)
1641 return OS;
1642 OS << "block-frequency-info: " << F->getName() << "\n";
1643 for (const BlockT &BB : *F) {
1644 OS << " - " << bfi_detail::getBlockName(&BB) << ": float = ";
1645 getFloatingBlockFreq(&BB).print(OS, 5)
1646 << ", int = " << getBlockFreq(&BB).getFrequency();
1647 if (std::optional<uint64_t> ProfileCount =
1649 F->getFunction(), getNode(&BB)))
1650 OS << ", count = " << *ProfileCount;
1651 if (std::optional<uint64_t> IrrLoopHeaderWeight =
1652 BB.getIrrLoopHeaderWeight())
1653 OS << ", irr_loop_header_weight = " << *IrrLoopHeaderWeight;
1654 OS << "\n";
1655 }
1656
1657 // Add an extra newline for readability.
1658 OS << "\n";
1659 return OS;
1660}
1661
1662template <class BT>
1665 bool Match = true;
1666 // Gather blocks for numbers so that we can print names and determine whether
1667 // they still exist.
1670 for (const auto &BB : *F)
1671 Blocks[GraphTraits<const BlockT *>::getNumber(&BB)] = &BB;
1672
1673 size_t MinSize = std::min(Nodes.size(), Other.Nodes.size());
1674 for (size_t i = 0; i < MinSize; ++i) {
1675 if (!Blocks[i])
1676 continue; // Block got deleted in the mean time, ignore.
1677 if (Nodes[i].isValid() != Other.Nodes[i].isValid()) {
1678 Match = false;
1679 dbgs() << "Block " << bfi_detail::getBlockName(Blocks[i])
1680 << " existence mismatch.\n";
1681 } else if (Nodes[i].isValid()) {
1682 const auto &Freq = Freqs[Nodes[i].Index];
1683 const auto &OtherFreq = Other.Freqs[Other.Nodes[i].Index];
1684 if (Freq.Integer != OtherFreq.Integer) {
1685 Match = false;
1686 dbgs() << "Freq mismatch: " << bfi_detail::getBlockName(Blocks[i])
1687 << " " << Freq.Integer << " vs " << OtherFreq.Integer << "\n";
1688 }
1689 }
1690 }
1691 // Block with higher numbers must not exist in either state.
1692 for (size_t i = MinSize; i < Nodes.size(); ++i) {
1693 if (Nodes[i].isValid()) {
1694 Match = false;
1695 dbgs() << "Block " << bfi_detail::getBlockName(Blocks[i])
1696 << " existence mismatch.\n";
1697 }
1698 }
1699 for (size_t i = MinSize; i < Other.Nodes.size(); ++i) {
1700 if (Other.Nodes[i].isValid()) {
1701 Match = false;
1702 dbgs() << "Block " << bfi_detail::getBlockName(Blocks[i])
1703 << " existence mismatch.\n";
1704 }
1705 }
1706
1707 if (!Match) {
1708 dbgs() << "This\n";
1709 print(dbgs());
1710 dbgs() << "Other\n";
1711 Other.print(dbgs());
1712 }
1713 assert(Match && "BFI mismatch");
1714}
1715
1716// Graph trait base class for block frequency information graph
1717// viewer.
1718
1720
1721template <class BlockFrequencyInfoT, class BranchProbabilityInfoT>
1724 using NodeRef = typename GTraits::NodeRef;
1725 using EdgeIter = typename GTraits::ChildIteratorType;
1726 using NodeIter = typename GTraits::nodes_iterator;
1727
1729
1732
1733 static StringRef getGraphName(const BlockFrequencyInfoT *G) {
1734 return G->getFunction()->getName();
1735 }
1736
1737 std::string getNodeAttributes(NodeRef Node, const BlockFrequencyInfoT *Graph,
1738 unsigned HotPercentThreshold = 0) {
1739 std::string Result;
1740 if (!HotPercentThreshold)
1741 return Result;
1742
1743 // Compute MaxFrequency on the fly:
1744 if (!MaxFrequency) {
1747 I != E; ++I) {
1748 NodeRef N = *I;
1749 MaxFrequency =
1750 std::max(MaxFrequency, Graph->getBlockFreq(N).getFrequency());
1751 }
1752 }
1753 BlockFrequency Freq = Graph->getBlockFreq(Node);
1754 BlockFrequency HotFreq =
1756 BranchProbability::getBranchProbability(HotPercentThreshold, 100));
1757
1758 if (Freq < HotFreq)
1759 return Result;
1760
1761 raw_string_ostream(Result) << "color=\"red\"";
1762 return Result;
1763 }
1764
1765 std::string getNodeLabel(NodeRef Node, const BlockFrequencyInfoT *Graph,
1766 GVDAGType GType, int layout_order = -1) {
1767 std::string Result;
1768 raw_string_ostream OS(Result);
1769
1770 if (layout_order != -1)
1771 OS << Node->getName() << "[" << layout_order << "] : ";
1772 else
1773 OS << Node->getName() << " : ";
1774 switch (GType) {
1775 case GVDT_Fraction:
1776 OS << printBlockFreq(*Graph, *Node);
1777 break;
1778 case GVDT_Integer:
1779 OS << Graph->getBlockFreq(Node).getFrequency();
1780 break;
1781 case GVDT_Count: {
1782 auto Count = Graph->getBlockProfileCount(Node);
1783 if (Count)
1784 OS << *Count;
1785 else
1786 OS << "Unknown";
1787 break;
1788 }
1789 case GVDT_None:
1790 llvm_unreachable("If we are not supposed to render a graph we should "
1791 "never reach this point.");
1792 }
1793 return Result;
1794 }
1795
1797 const BlockFrequencyInfoT *BFI,
1798 const BranchProbabilityInfoT *BPI,
1799 unsigned HotPercentThreshold = 0) {
1800 std::string Str;
1801 if (!BPI)
1802 return Str;
1803
1804 unsigned SuccIdx = std::distance(succ_begin(Node), EI);
1805 BranchProbability BP = BPI->getEdgeProbability(Node, SuccIdx);
1806 uint32_t N = BP.getNumerator();
1807 uint32_t D = BP.getDenominator();
1808 double Percent = 100.0 * N / D;
1809 raw_string_ostream OS(Str);
1810 OS << format("label=\"%.1f%%\"", Percent);
1811
1812 if (HotPercentThreshold) {
1813 BlockFrequency EFreq = BFI->getBlockFreq(Node) * BP;
1815 BranchProbability(HotPercentThreshold, 100);
1816
1817 if (EFreq >= HotFreq)
1818 OS << ",color=\"red\"";
1819 }
1820 return Str;
1821 }
1822};
1823
1824} // end namespace llvm
1825
1826#undef DEBUG_TYPE
1827
1828#endif // LLVM_ANALYSIS_BLOCKFREQUENCYINFOIMPL_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
uint64_t uint64_t
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
#define X(NUM, ENUM, NAME)
Definition ELF.h:665
This file implements the BitVector class.
static constexpr std::size_t number(BlockVerifier::State S)
static uint64_t scale(uint64_t Num, uint32_t N, uint32_t D)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_ABI
Definition Compiler.h:211
This file defines the DenseMap class.
Find all cycles in a control-flow graph, including irreducible loops.
This file defines the little GraphTraits<X> template class that should be specialized by classes that...
Hexagon Hardware Loops
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
Definition Lint.cpp:540
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
Branch Probability Basic Block static false std::string getBlockName(const MachineBasicBlock *BB)
Helper to print the name of a MBB.
#define P(N)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the SparseBitVector class.
#define LLVM_DEBUG(...)
Definition Debug.h:119
LLVM Basic Block Representation.
Definition BasicBlock.h:62
Base class for BlockFrequencyInfoImpl.
std::vector< WorkingData > Working
Loop data: see initializeLoops().
std::optional< uint64_t > getProfileCountFromFreq(const Function &F, BlockFrequency Freq) const
virtual ~BlockFrequencyInfoImplBase()=default
Virtual destructor.
std::list< LoopData > Loops
Indexed information about loops.
void addToDist(Distribution &Dist, const LoopData *OuterLoop, const BlockNode &Pred, const BlockNode &Succ, uint64_t Weight)
Add an edge to the distribution.
std::optional< uint64_t > getBlockProfileCount(const Function &F, const BlockNode &Node) const
std::string getLoopName(const LoopData &Loop) const
bool TopContainsIrreducible
Has an irreducible SCC outside every loop.
bool isIrrLoopHeader(const BlockNode &Node)
void computeLoopScale(LoopData &Loop)
Compute the loop scale for a loop.
void packageLoop(LoopData &Loop)
Package up a loop.
virtual raw_ostream & print(raw_ostream &OS) const
void finalizeMetrics()
Finalize frequency metrics.
void setBlockFreq(const BlockNode &Node, BlockFrequency Freq)
bool CheckUnknownBlockQueries
-check-bfi-unknown-block-queries of the function's context.
BlockFrequency getBlockFreq(const BlockNode &Node) const
iterator_range< std::list< LoopData >::iterator > analyzeIrreducible(const bfi_detail::IrreducibleGraph &G, LoopData *OuterLoop, std::list< LoopData >::iterator Insert)
Analyze irreducible SCCs.
Scaled64 getFloatingBlockFreq(const BlockNode &Node) const
void distributeMass(const BlockNode &Source, LoopData *OuterLoop, Distribution &Dist)
Distribute mass according to a distribution.
SparseBitVector IsIrrLoopHeader
Whether each block is an irreducible loop header.
void addLoopSuccessorsToDist(const LoopData *OuterLoop, LoopData &Loop, Distribution &Dist)
Add all edges out of a packaged loop to the distribution.
std::vector< FrequencyData > Freqs
Data about each block. This is used downstream.
bool isIrrLoopHeader(const BlockT *BB)
std::optional< uint64_t > getProfileCountFromFreq(const Function &F, BlockFrequency Freq) const
const BranchProbabilityInfoT & getBPI() const
const FunctionT * getFunction() const
void verifyMatch(BlockFrequencyInfoImpl< BT > &Other) const
std::optional< uint64_t > getBlockProfileCount(const Function &F, const BlockT *BB) const
Scaled64 getFloatingBlockFreq(const BlockT *BB) const
void setBlockFreq(const BlockT *BB, BlockFrequency Freq)
void calculate(const FunctionT &F, const BranchProbabilityInfoT &BPI, const CycleInfoT &CI)
raw_ostream & print(raw_ostream &OS) const override
Print the frequencies for the current function.
BlockFrequency getBlockFreq(const BlockT *BB) const
Analysis providing branch probability information.
static LLVM_ABI BranchProbability getBranchProbability(uint64_t Numerator, uint64_t Denominator)
static uint32_t getDenominator()
uint32_t getNumerator() const
Opaque handle to a cycle within a GenericCycleInfo that wraps the cycle's preorder index.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
BlockT * getHeader() const
iterator end() const
iterator begin() const
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
Simple representation of a scaled number.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
typename SuperClass::const_iterator const_iterator
void resize(size_type N)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::string str() const
Get the contents as an std::string.
Definition StringRef.h:222
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM Value Representation.
Definition Value.h:75
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:315
bool operator<(BlockMass X) const
bool operator>(BlockMass X) const
LLVM_ABI raw_ostream & print(raw_ostream &OS) const
bool operator==(BlockMass X) const
BlockMass & operator-=(BlockMass X)
Subtract another mass.
bool operator<=(BlockMass X) const
BlockMass & operator*=(BranchProbability P)
bool operator!=(BlockMass X) const
BlockMass & operator+=(BlockMass X)
Add another mass.
bool operator>=(BlockMass X) const
LLVM_ABI ScaledNumber< uint64_t > toScaled() const
Convert to scaled number.
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an std::string.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
#define UINT64_MAX
Definition DataTypes.h:77
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ Entry
Definition COFF.h:862
std::string getBlockName(const BlockT *BB)
Get the name of a MachineBasicBlock.
BlockMass operator*(BlockMass L, BranchProbability R)
BlockMass operator+(BlockMass L, BlockMass R)
raw_ostream & operator<<(raw_ostream &OS, BlockMass X)
BlockMass operator-(BlockMass L, BlockMass R)
NodeAddr< NodeBase * > Node
Definition RDFGraph.h:381
bool empty() const
Definition BasicBlock.h:101
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI unsigned getIterativeBFIMaxIterationsPerBlock(const LLVMContext &C)
Return -iterative-bfi-max-iterations-per-block.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
uint32_t getWeightFromBranchProb(const BranchProbability Prob)
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2570
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
LLVM_ABI llvm::cl::opt< bool > UseIterativeBFIInference
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
auto post_order(const T &G)
Post-order traversal of a graph.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition Format.h:102
RNSuccIterator< NodeRef, BlockT, RegionT > succ_begin(NodeRef Node)
@ Other
Any other memory.
Definition ModRef.h:68
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
Definition STLExtras.h:2068
constexpr NextUseDistance max(NextUseDistance A, NextUseDistance B)
iterator_range< typename GraphTraits< Inverse< GraphType > >::ChildIteratorType > inverse_children(const typename GraphTraits< GraphType >::NodeRef &G)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
auto make_second_range(ContainerTy &&c)
Given a container of pairs, return a range over the second elements.
Definition STLExtras.h:1425
auto sum_of(R &&Range, E Init=E{0})
Returns the sum of all values in Range with Init initial value.
Definition STLExtras.h:1733
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1933
iterator_range< typename GraphTraits< GraphType >::ChildIteratorType > children(const typename GraphTraits< GraphType >::NodeRef &G)
LLVM_ABI Printable printBlockFreq(const BlockFrequencyInfo &BFI, BlockFrequency Freq)
Print the block frequency Freq relative to the current functions entry frequency.
LLVM_ABI bool shouldCheckBFIUnknownBlockQueries(const LLVMContext &C)
Return -check-bfi-unknown-block-queries.
LLVM_ABI double getIterativeBFIPrecision(const LLVMContext &C)
Return -iterative-bfi-precision.
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
#define N
GraphTraits< BlockFrequencyInfoT * > GTraits
std::string getNodeAttributes(NodeRef Node, const BlockFrequencyInfoT *Graph, unsigned HotPercentThreshold=0)
typename GTraits::nodes_iterator NodeIter
typename GTraits::NodeRef NodeRef
typename GTraits::ChildIteratorType EdgeIter
std::string getNodeLabel(NodeRef Node, const BlockFrequencyInfoT *Graph, GVDAGType GType, int layout_order=-1)
std::string getEdgeAttributes(NodeRef Node, EdgeIter EI, const BlockFrequencyInfoT *BFI, const BranchProbabilityInfoT *BPI, unsigned HotPercentThreshold=0)
BFIDOTGraphTraitsBase(bool isSimple=false)
static StringRef getGraphName(const BlockFrequencyInfoT *G)
Distribution of unscaled probability weight.
void addBackedge(const BlockNode &Node, uint64_t Amount)
WeightList Weights
Individual successor weights.
void addExit(const BlockNode &Node, uint64_t Amount)
void addLocal(const BlockNode &Node, uint64_t Amount)
SmallVector< std::pair< BlockNode, BlockMass >, 4 > ExitMap
ExitMap Exits
Successor edges (and weights).
bool IsPackaged
Whether this has been packaged.
LoopData(LoopData *Parent, const BlockNode &Header)
BlockMass BackedgeMass
Mass that circulates, not exits.
NodeList::const_iterator members_begin() const
NodeList Nodes
Header and the members of the loop.
LoopData(LoopData *Parent, NodeList &&Members)
An irreducible SCC.
iterator_range< NodeList::const_iterator > members() const
Weight(DistType Type, BlockNode TargetNode, uint64_t Amount)
bool isPackaged() const
Has ContainingLoop been packaged up?
BlockMass Mass
Mass distribution from the entry block.
BlockMass & getMass()
The mass slot for Node: its own, or that of the outermost packaged loop it heads.
bool isAPackage() const
Has Loop been packaged up?
LoopData * Loop
The loop this block is inside.
LoopData * getContainingLoop() const
The innermost loop containing Node that Node does not head.
LoopData * getPackagedLoop() const
The outermost loop containing Node that is currently packaged, if any.
BlockNode getResolvedNode() const
Resolve a node to its representative.
DefaultDOTGraphTraits(bool simple=false)
static nodes_iterator nodes_end(const BlockFrequencyInfo *G)
static nodes_iterator nodes_begin(const BlockFrequencyInfo *G)
typename BlockFrequencyInfoT *::UnknownGraphTypeError NodeRef
Definition GraphTraits.h:94
SmallVectorImpl< const IrrNode * >::const_iterator iterator
Graph of irreducible control flow.
IrreducibleGraph(BFIBase &BFI, const BFIBase::LoopData *OuterLoop, BlockEdgesAdder addBlockEdges)
Construct an explicit graph containing irreducible control flow.
LLVM_ABI void addEdge(IrrNode &Irr, const BlockNode &Succ, const BFIBase::LoopData *OuterLoop)
unsigned getIndex(const IrrNode *N) const
The position of N in Nodes, for indexing side tables.
void addEdges(const BlockNode &Node, const BFIBase::LoopData *OuterLoop, BlockEdgesAdder addBlockEdges)
SmallDenseMap< uint32_t, IrrNode *, 4 > Lookup
void initialize(const BFIBase::LoopData *OuterLoop, BlockEdgesAdder addBlockEdges)
LLVM_ABI void addNodesInLoop(const BFIBase::LoopData &OuterLoop)