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