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