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"
19#include "llvm/ADT/DenseSet.h"
23#include "llvm/ADT/STLExtras.h"
27#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 <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 {
225
226 LoopData *Parent; ///< The parent loop.
227 bool IsPackaged = false; ///< Whether this has been packaged.
228 // Has an irreducible SCC in its own nodes; sub-loops package theirs first.
230 // Headers are Nodes[0, NumHeaders), sorted. For an irreducible loop, the
231 // SCC's entries and the nodes a retreating edge from a non-entry reaches.
233 ExitMap Exits; ///< Successor edges (and weights).
234 NodeList Nodes; ///< Header and the members of the loop.
235 HeaderMassList BackedgeMass; ///< Mass returned to each loop header.
238
240 : Parent(Parent), Nodes(1, Header), BackedgeMass(1) {}
241
242 template <class It>
243 LoopData(LoopData *Parent, It FirstHeader, It LastHeader)
244 : Parent(Parent), Nodes(FirstHeader, LastHeader) {
245 NumHeaders = Nodes.size();
246 BackedgeMass.resize(NumHeaders);
247 }
248
249 template <class It1, class It2>
250 LoopData(LoopData *Parent, It1 FirstHeader, It1 LastHeader, It2 FirstOther,
251 It2 LastOther)
252 : Parent(Parent), Nodes(FirstHeader, LastHeader) {
253 NumHeaders = Nodes.size();
254 Nodes.insert(Nodes.end(), FirstOther, LastOther);
255 BackedgeMass.resize(NumHeaders);
256 }
257
258 bool isHeader(const BlockNode &Node) const {
259 if (isIrreducible())
260 return std::binary_search(Nodes.begin(), Nodes.begin() + NumHeaders,
261 Node);
262 return Node == Nodes[0];
263 }
264
265 BlockNode getHeader() const { return Nodes[0]; }
266 bool isIrreducible() const { return NumHeaders > 1; }
267
269 assert(isHeader(B) && "this is only valid on loop header blocks");
270 if (isIrreducible())
271 return std::lower_bound(Nodes.begin(), Nodes.begin() + NumHeaders, B) -
272 Nodes.begin();
273 return 0;
274 }
275
277 return Nodes.begin() + NumHeaders;
278 }
279
284 };
285
286 /// Index of loop information.
287 struct WorkingData {
288 BlockNode Node; ///< This node.
289 LoopData *Loop = nullptr; ///< The loop this block is inside.
290 BlockMass Mass; ///< Mass distribution from the entry block.
291
293
294 bool isLoopHeader() const { return Loop && Loop->isHeader(Node); }
295
296 /// The innermost loop containing Node that Node does not head.
297 ///
298 /// A block can head several nested loops: createIrreducibleLoop() reuses
299 /// an SCC's entry blocks as the irreducible loop's headers.
301 LoopData *L = Loop;
302 while (L && L->isHeader(Node))
303 L = L->Parent;
304 return L;
305 }
306
307 /// Resolve a node to its representative.
308 ///
309 /// Get the node currently representing Node, which could be a containing
310 /// loop.
311 ///
312 /// This function should only be called when distributing mass. As long as
313 /// there are no irreducible edges to Node, then it will have complexity
314 /// O(1) in this context.
315 ///
316 /// In general, the complexity is O(L), where L is the number of loop
317 /// headers Node has been packaged into. Since this method is called in
318 /// the context of distributing mass, L will be the number of loop headers
319 /// an early exit edge jumps out of.
321 auto *L = getPackagedLoop();
322 return L ? L->getHeader() : Node;
323 }
324
325 /// The outermost loop containing Node that is currently packaged, if any.
326 ///
327 /// Packaging is transient state: this answers what represents Node at the
328 /// level being processed, not where Node sits in the loop nest.
330 if (!Loop || !Loop->IsPackaged)
331 return nullptr;
332 auto *L = Loop;
333 while (L->Parent && L->Parent->IsPackaged)
334 L = L->Parent;
335 return L;
336 }
337
338 /// The mass slot for Node: its own, or that of the outermost packaged
339 /// loop it heads.
341 BlockMass *M = &Mass;
342 for (LoopData *L = Loop; L && L->IsPackaged && L->isHeader(Node);
343 L = L->Parent)
344 M = &L->Mass;
345 return *M;
346 }
347
348 /// Has ContainingLoop been packaged up?
349 bool isPackaged() const { return getResolvedNode() != Node; }
350
351 /// Has Loop been packaged up?
352 bool isAPackage() const { return isLoopHeader() && Loop->IsPackaged; }
353 };
354
355 /// Unscaled probability weight.
356 ///
357 /// Probability weight for an edge in the graph (including the
358 /// successor/target node).
359 ///
360 /// All edges in the original function are 32-bit. However, exit edges from
361 /// loop packages are taken from 64-bit exit masses, so we need 64-bits of
362 /// space in general.
363 ///
364 /// In addition to the raw weight amount, Weight stores the type of the edge
365 /// in the current context (i.e., the context of the loop being processed).
366 /// Is this a local edge within the loop, an exit from the loop, or a
367 /// backedge to the loop header?
378
379 /// Distribution of unscaled probability weight.
380 ///
381 /// Distribution of unscaled probability weight to a set of successors.
382 ///
383 /// This class collates the successor edge weights for later processing.
384 ///
385 /// \a DidOverflow indicates whether \a Total did overflow while adding to
386 /// the distribution. It should never overflow twice.
389
390 WeightList Weights; ///< Individual successor weights.
391 uint64_t Total = 0; ///< Sum of all weights.
392 bool DidOverflow = false; ///< Whether \a Total did overflow.
393
394 Distribution() = default;
395
396 void addLocal(const BlockNode &Node, uint64_t Amount) {
397 add(Node, Amount, Weight::Local);
398 }
399
400 void addExit(const BlockNode &Node, uint64_t Amount) {
401 add(Node, Amount, Weight::Exit);
402 }
403
404 void addBackedge(const BlockNode &Node, uint64_t Amount) {
405 add(Node, Amount, Weight::Backedge);
406 }
407
408 /// Normalize the distribution.
409 ///
410 /// Combines multiple edges to the same \a Weight::TargetNode and scales
411 /// down so that \a Total fits into 32-bits.
412 ///
413 /// This is linear in the size of \a Weights. For the vast majority of
414 /// cases, adjacent edge weights are combined by sorting WeightList and
415 /// combining adjacent weights. However, for very large edge lists an
416 /// auxiliary hash table is used.
417 LLVM_ABI void normalize();
418
419 private:
420 LLVM_ABI void add(const BlockNode &Node, uint64_t Amount,
422 };
423
424 /// Data about each block. This is used downstream.
425 std::vector<FrequencyData> Freqs;
426
427 /// Whether each block is an irreducible loop header.
428 /// This is used downstream.
430
431 /// Loop data: see initializeLoops().
432 std::vector<WorkingData> Working;
433
434 /// Indexed information about loops.
435 std::list<LoopData> Loops;
436
437 /// Has an irreducible SCC outside every loop.
439
440 /// Virtual destructor.
441 ///
442 /// Need a virtual destructor to mask the compiler warning about
443 /// getBlockName().
444 virtual ~BlockFrequencyInfoImplBase() = default;
445
446 /// Add all edges out of a packaged loop to the distribution.
447 ///
448 /// Adds all edges from LocalLoopHead to Dist. Calls addToDist() to add each
449 /// successor edge.
450 void addLoopSuccessorsToDist(const LoopData *OuterLoop, LoopData &Loop,
451 Distribution &Dist);
452
453 /// Add an edge to the distribution.
454 ///
455 /// Adds an edge to Succ to Dist. If \c LoopHead.isValid(), then whether the
456 /// edge is local/exit/backedge is in the context of LoopHead. Otherwise,
457 /// every edge should be a local edge (since all the loops are packaged up).
458 void addToDist(Distribution &Dist, const LoopData *OuterLoop,
459 const BlockNode &Pred, const BlockNode &Succ, uint64_t Weight);
460
461 /// Analyze irreducible SCCs.
462 ///
463 /// Separate irreducible SCCs from \c G, which is an explicit graph of \c
464 /// OuterLoop (or the top-level function, if \c OuterLoop is \c nullptr).
465 /// Insert them into \a Loops before \c Insert.
466 ///
467 /// \return the \c LoopData nodes representing the irreducible SCCs.
470 std::list<LoopData>::iterator Insert);
471
472 /// Distribute mass according to a distribution.
473 ///
474 /// Distributes the mass in Source according to Dist. If LoopHead.isValid(),
475 /// backedges and exits are stored in its entry in Loops.
476 ///
477 /// Mass is distributed in parallel from two copies of the source mass.
478 void distributeMass(const BlockNode &Source, LoopData *OuterLoop,
479 Distribution &Dist);
480
481 /// Compute the loop scale for a loop.
483
484 /// Adjust the mass of all headers in an irreducible loop.
485 ///
486 /// Initially, irreducible loops are assumed to distribute their mass
487 /// equally among its headers. This can lead to wrong frequency estimates
488 /// since some headers may be executed more frequently than others.
489 ///
490 /// This adjusts header mass distribution so it matches the weights of
491 /// the backedges going into each of the loop headers.
493
495
496 /// Package up a loop.
498
499 /// Unwrap loops.
500 void unwrapLoops();
501
502 /// Finalize frequency metrics.
503 ///
504 /// Calculates final frequencies and cleans up no-longer-needed data
505 /// structures.
506 void finalizeMetrics();
507
508 /// Clear all memory.
509 void clear();
510
511 virtual std::string getBlockName(const BlockNode &Node) const;
512 std::string getLoopName(const LoopData &Loop) const;
513
514 virtual raw_ostream &print(raw_ostream &OS) const { return OS; }
515 void dump() const { print(dbgs()); }
516
517 Scaled64 getFloatingBlockFreq(const BlockNode &Node) const;
518
519 BlockFrequency getBlockFreq(const BlockNode &Node) const;
520 std::optional<uint64_t> getBlockProfileCount(const Function &F,
521 const BlockNode &Node) const;
522 std::optional<uint64_t> getProfileCountFromFreq(const Function &F,
523 BlockFrequency Freq) const;
524 bool isIrrLoopHeader(const BlockNode &Node);
525
526 void setBlockFreq(const BlockNode &Node, BlockFrequency Freq);
527
529 assert(!Freqs.empty());
530 return BlockFrequency(Freqs[0].Integer);
531 }
532};
533
534namespace bfi_detail {
535
536template <class BlockT> struct TypeMap {};
549
550/// Get the name of a MachineBasicBlock.
551///
552/// Get the name of a MachineBasicBlock. It's templated so that including from
553/// CodeGen is unnecessary (that would be a layering issue).
554///
555/// This is used mainly for debug output. The name is similar to
556/// MachineBasicBlock::getFullName(), but skips the name of the function.
557template <class BlockT> std::string getBlockName(const BlockT *BB) {
558 assert(BB && "Unexpected nullptr");
559 auto MachineName = "BB" + Twine(BB->getNumber());
560 if (BB->getBasicBlock())
561 return (MachineName + "[" + BB->getName() + "]").str();
562 return MachineName.str();
563}
564/// Get the name of a BasicBlock.
565template <> inline std::string getBlockName(const BasicBlock *BB) {
566 assert(BB && "Unexpected nullptr");
567 return BB->getName().str();
568}
569
570/// Graph of irreducible control flow.
571///
572/// This graph is used for determining the SCCs in a loop (or top-level
573/// function) that has irreducible control flow.
574///
575/// During the block frequency algorithm, the local graphs are defined in a
576/// light-weight way, deferring to the \a BasicBlock or \a MachineBasicBlock
577/// graphs for most edges, but getting others from \a LoopData::ExitMap. The
578/// latter only has successor information.
579///
580/// \a IrreducibleGraph makes this graph explicit. It's in a form that can use
581/// \a GraphTraits (so that \a analyzeIrreducible() can use \a scc_iterator),
582/// and it explicitly lists predecessors and successors. The initialization
583/// that relies on \c MachineBasicBlock is defined in the header.
586
588
602 const IrrNode *StartIrr = nullptr;
603 std::vector<IrrNode> Nodes;
605
606 /// The position of \p N in \a Nodes, for indexing side tables.
607 unsigned getIndex(const IrrNode *N) const { return N - Nodes.data(); }
608
609 /// Construct an explicit graph containing irreducible control flow.
610 ///
611 /// Construct an explicit graph of the control flow in \c OuterLoop (or the
612 /// top-level function, if \c OuterLoop is \c nullptr). Uses \c
613 /// addBlockEdges to add block successors that have not been packaged into
614 /// loops.
615 ///
616 /// \a BlockFrequencyInfoImpl::computeIrreducibleMass() is the only expected
617 /// user of this.
618 template <class BlockEdgesAdder>
620 BlockEdgesAdder addBlockEdges) : BFI(BFI) {
621 initialize(OuterLoop, addBlockEdges);
622 }
623
624 template <class BlockEdgesAdder>
625 void initialize(const BFIBase::LoopData *OuterLoop,
626 BlockEdgesAdder addBlockEdges);
627 LLVM_ABI void addNodesInLoop(const BFIBase::LoopData &OuterLoop);
629
630 void addNode(const BlockNode &Node) {
631 Nodes.emplace_back(Node);
632 assert(BFI.Working[Node.Index].getMass().isEmpty() &&
633 "mass distributed before the region was packaged");
634 }
635
636 LLVM_ABI void indexNodes();
637 template <class BlockEdgesAdder>
638 void addEdges(const BlockNode &Node, const BFIBase::LoopData *OuterLoop,
639 BlockEdgesAdder addBlockEdges);
640 LLVM_ABI void addEdge(IrrNode &Irr, const BlockNode &Succ,
641 const BFIBase::LoopData *OuterLoop);
642};
643
644template <class BlockEdgesAdder>
646 BlockEdgesAdder addBlockEdges) {
647 if (OuterLoop) {
648 addNodesInLoop(*OuterLoop);
649 for (auto N : OuterLoop->Nodes)
650 addEdges(N, OuterLoop, addBlockEdges);
651 } else {
653 for (uint32_t Index = 0; Index < BFI.Working.size(); ++Index)
654 addEdges(Index, OuterLoop, addBlockEdges);
655 }
656 StartIrr = Lookup[Start.Index];
657}
658
659template <class BlockEdgesAdder>
661 const BFIBase::LoopData *OuterLoop,
662 BlockEdgesAdder addBlockEdges) {
663 auto L = Lookup.find(Node.Index);
664 if (L == Lookup.end())
665 return;
666 IrrNode &Irr = *L->second;
667 const auto &Working = BFI.Working[Node.Index];
668
669 if (Working.isAPackage())
670 for (const auto &I : Working.Loop->Exits)
671 addEdge(Irr, I.first, OuterLoop);
672 else
673 addBlockEdges(*this, Irr, OuterLoop);
674}
675
676} // end namespace bfi_detail
677
678/// Shared implementation for block frequency analysis.
679///
680/// This is a shared implementation of BlockFrequencyInfo and
681/// MachineBlockFrequencyInfo, and calculates the relative frequencies of
682/// blocks.
683///
684/// LoopInfo defines a loop as a "non-trivial" SCC dominated by a single block,
685/// which is called the header. A given loop, L, can have sub-loops, which are
686/// loops within the subgraph of L that exclude its header. (A "trivial" SCC
687/// consists of a single block that does not have a self-edge.)
688///
689/// In addition to loops, this algorithm has limited support for irreducible
690/// SCCs, which are SCCs with multiple entry blocks. Irreducible SCCs are
691/// found from CycleInfo before any mass is distributed, and modelled as loops
692/// with multiple headers.
693///
694/// The headers of irreducible sub-SCCs consist of its entry blocks and all
695/// nodes that are targets of a backedge within it (excluding backedges within
696/// true sub-loops). Block frequency calculations act as if a block is
697/// inserted that intercepts all the edges to the headers. All backedges and
698/// entries point to this block. Its successors are the headers, which split
699/// the frequency evenly.
700///
701/// This algorithm leverages BlockMass and ScaledNumber to maintain precision,
702/// separates mass distribution from loop scaling, and dithers to eliminate
703/// probability mass loss.
704///
705/// The implementation is split between BlockFrequencyInfoImpl, which knows the
706/// type of graph being modelled (BasicBlock vs. MachineBasicBlock), and
707/// BlockFrequencyInfoImplBase, which doesn't. The base class uses \a
708/// BlockNode, a wrapper around a uint32_t. BlockNode is numbered from 0 in
709/// reverse-post order. This gives two advantages: it's easy to compare the
710/// relative ordering of two nodes, and maps keyed on BlockT can be represented
711/// by vectors.
712///
713/// This algorithm is O(V+E), unless there is irreducible control flow, in
714/// which case it's O(V*E) in the worst case.
715///
716/// These are the main stages:
717///
718/// 0. Reverse post-order traversal (\a initializeRPOT()).
719///
720/// Run a single post-order traversal and save it (in reverse) in RPOT.
721/// All other stages make use of this ordering. Save a lookup from BlockT
722/// to BlockNode (the index into RPOT) in Nodes.
723///
724/// 1. Loop initialization (\a initializeLoops()).
725///
726/// Translate LoopInfo/MachineLoopInfo into a form suitable for the rest of
727/// the algorithm. In particular, store the immediate members of each loop
728/// in reverse post-order.
729///
730/// 2. Calculate mass and scale in loops (\a computeMassInLoops()).
731///
732/// For each loop (bottom-up), distribute mass through the DAG resulting
733/// from ignoring backedges and treating sub-loops as a single pseudo-node.
734/// Track the backedge mass distributed to the loop header, and use it to
735/// calculate the loop scale (number of loop iterations). Immediate
736/// members that represent sub-loops will already have been visited and
737/// packaged into a pseudo-node.
738///
739/// Distributing mass in a loop is a reverse-post-order traversal through
740/// the loop. Start by assigning full mass to the Loop header. For each
741/// node in the loop:
742///
743/// - Fetch and categorize the weight distribution for its successors.
744/// If this is a packaged-subloop, the weight distribution is stored
745/// in \a LoopData::Exits. Otherwise, fetch it from
746/// BranchProbabilityInfo.
747///
748/// - Each successor is categorized as \a Weight::Local, a local edge
749/// within the current loop, \a Weight::Backedge, a backedge to the
750/// loop header, or \a Weight::Exit, any successor outside the loop.
751/// The weight, the successor, and its category are stored in \a
752/// Distribution. There can be multiple edges to each successor.
753/// \a computeIrreducibleMass() has packaged up every irreducible SCC
754/// by this point, so no backedge here targets a non-header.
755///
756/// - Normalize the distribution: scale weights down so that their sum
757/// is 32-bits, and coalesce multiple edges to the same node.
758///
759/// - Distribute the mass accordingly, dithering to minimize mass loss,
760/// as described in \a distributeMass().
761///
762/// In the case of irreducible loops, instead of a single loop header,
763/// there will be several. The computation of backedge masses is similar
764/// but instead of having a single backedge mass, there will be one
765/// backedge per loop header. In these cases, each backedge will carry
766/// a mass proportional to the edge weights along the corresponding
767/// path.
768///
769/// At the end of propagation, the full mass assigned to the loop will be
770/// distributed among the loop headers proportionally according to the
771/// mass flowing through their backedges.
772///
773/// Finally, calculate the loop scale from the accumulated backedge mass.
774///
775/// 3. Distribute mass in the function (\a computeMassInFunction()).
776///
777/// Finally, distribute mass through the DAG resulting from packaging all
778/// loops in the function. This uses the same algorithm as distributing
779/// mass in a loop, except that there are no exit or backedge edges.
780///
781/// 4. Unpackage loops (\a unwrapLoops()).
782///
783/// Initialize each block's frequency to a floating point representation of
784/// its mass.
785///
786/// Visit loops top-down, scaling the frequencies of its immediate members
787/// by the loop's pseudo-node's frequency.
788///
789/// 5. Convert frequencies to a 64-bit range (\a finalizeMetrics()).
790///
791/// Using the min and max frequencies as a guide, translate floating point
792/// frequencies to an appropriate range in uint64_t.
793///
794/// It has some known flaws.
795///
796/// - The model of irreducible control flow is a rough approximation.
797///
798/// Modelling irreducible control flow exactly involves setting up and
799/// solving a group of infinite geometric series. Such precision is
800/// unlikely to be worthwhile, since most of our algorithms give up on
801/// irreducible control flow anyway.
802///
803/// Nevertheless, we might find that we need to get closer. Here's a sort
804/// of TODO list for the model with diminishing returns, to be completed as
805/// necessary.
806///
807/// - The headers for the \a LoopData representing an irreducible SCC
808/// include non-entry blocks. When these extra blocks exist, they
809/// indicate a self-contained irreducible sub-SCC. We could treat them
810/// as sub-loops, rather than arbitrarily shoving the problematic
811/// blocks into the headers of the main irreducible SCC.
812///
813/// - Entry frequencies are assumed to be evenly split between the
814/// headers of a given irreducible SCC, which is the only option if we
815/// need to compute mass in the SCC before its parent loop. Instead,
816/// we could partially compute mass in the parent loop, and stop when
817/// we get to the SCC. Here, we have the correct ratio of entry
818/// masses, which we can use to adjust their relative frequencies.
819/// Compute mass in the SCC, and then continue propagation in the
820/// parent.
821///
822/// - We can propagate mass iteratively through the SCC, for some fixed
823/// number of iterations. Each iteration starts by assigning the entry
824/// blocks their backedge mass from the prior iteration. The final
825/// mass for each block (and each exit, and the total backedge mass
826/// used for computing loop scale) is the sum of all iterations.
827/// (Running this until fixed point would "solve" the geometric
828/// series by simulation.)
830 using BlockT = typename bfi_detail::TypeMap<BT>::BlockT;
831 using FunctionT = typename bfi_detail::TypeMap<BT>::FunctionT;
832 using BranchProbabilityInfoT =
834 using CycleInfoT = typename bfi_detail::TypeMap<BT>::CycleInfoT;
835 using Successor = GraphTraits<const BlockT *>;
836 using Predecessor = GraphTraits<Inverse<const BlockT *>>;
837
838 const BranchProbabilityInfoT *BPI = nullptr;
839 const CycleInfoT *CI = nullptr;
840 const FunctionT *F = nullptr;
841
842 // All blocks in reverse postorder.
843 std::vector<const BlockT *> RPOT;
844 /// Map from block number to number on RPOT/Freqs.
846 unsigned BlockNumberEpoch;
847
848 BlockNode getNode(const BlockT *BB) const {
849 assert(BlockNumberEpoch ==
851 unsigned BlockNumber = GraphTraits<const BlockT *>::getNumber(BB);
852 return BlockNumber < Nodes.size() ? Nodes[BlockNumber] : BlockNode();
853 }
854
855 const BlockT *getBlock(const BlockNode &Node) const {
856 assert(Node.Index < RPOT.size());
857 return RPOT[Node.Index];
858 }
859
860 /// Save a reverse post-order traversal of all the nodes.
861 void initializeRPOT();
862
863 /// Initialize loop data.
864 ///
865 /// Build up \a Loops using \a LoopInfo. \a LoopInfo gives us a mapping from
866 /// each block to the deepest loop it's in, but we need the inverse. For each
867 /// loop, we store in reverse post-order its "immediate" members, defined as
868 /// the header, the headers of immediate sub-loops, and all other blocks in
869 /// the loop that are not in sub-loops.
870 void initializeLoops();
871
872 /// Propagate to a block's successors.
873 ///
874 /// In the context of distributing mass through \c OuterLoop, divide the mass
875 /// currently assigned to \c Node between its successors.
876 void propagateMassToSuccessors(LoopData *OuterLoop, const BlockNode &Node);
877
878 /// Compute mass in a particular loop.
879 ///
880 /// Assign mass to \c Loop's header, and then for each block in \c Loop in
881 /// reverse post-order, distribute mass to its successors. Only visits nodes
882 /// that have not been packaged into sub-loops.
883 ///
884 /// \pre \a computeMassInLoop() has been called for each subloop of \c Loop,
885 /// and \a computeIrreducibleMass() for \c Loop if it contains irreducible
886 /// control flow.
887 void computeMassInLoop(LoopData &Loop);
888
889 /// Distribute mass in a multi-header loop, seeding the headers from
890 /// irr_loop_header_weight metadata and marking them in IsIrrLoopHeader.
891 void computeMassInIrreducibleLoop(LoopData &Loop);
892
893 /// Compute mass in (and package up) irreducible SCCs.
894 ///
895 /// Find the irreducible SCCs in \c OuterLoop, add them to \a Loops (in front
896 /// of \c Insert), and call \a computeMassInLoop() on each of them.
897 ///
898 /// If \c OuterLoop is \c nullptr, it refers to the top-level function.
899 ///
900 /// \pre \a computeMassInLoop() has been called for each subloop of \c
901 /// OuterLoop.
902 /// \pre \c OuterLoop has irreducible SCCs.
903 void computeIrreducibleMass(LoopData *OuterLoop,
904 std::list<LoopData>::iterator Insert);
905
906 /// Compute mass in all loops.
907 ///
908 /// For each loop bottom-up, call \a computeMassInLoop(), packaging
909 /// irreducible SCCs first via \a computeIrreducibleMass() where \a
910 /// initializeLoops() found them.
911 void computeMassInLoops();
912
913 /// Compute mass in the top-level function.
914 ///
915 /// Package up any top-level irreducible SCCs, assign mass to the entry
916 /// block, and then for each block in reverse post-order, distribute mass to
917 /// its successors. Skips nodes that have been packaged into loops.
918 ///
919 /// \pre \a computeMassInLoops() has been called.
920 void computeMassInFunction();
921
922 std::string getBlockName(const BlockNode &Node) const override {
923 return bfi_detail::getBlockName(getBlock(Node));
924 }
925
926 /// The current implementation for computing relative block frequencies does
927 /// not handle correctly control-flow graphs containing irreducible loops. To
928 /// resolve the problem, we apply a post-processing step, which iteratively
929 /// updates block frequencies based on the frequencies of their predesessors.
930 /// This corresponds to finding the stationary point of the Markov chain by
931 /// an iterative method aka "PageRank computation".
932 /// The algorithm takes at most O(|E| * IterativeBFIMaxIterations) steps but
933 /// typically converges faster.
934 ///
935 /// Decide whether we want to apply iterative inference for a given function.
936 bool needIterativeInference() const;
937
938 /// Apply an iterative post-processing to infer correct counts for irr loops.
939 void applyIterativeInference();
940
941 using ProbMatrixType = std::vector<std::vector<std::pair<size_t, Scaled64>>>;
942
943 /// Run iterative inference for a probability matrix and initial frequencies.
944 void iterativeInference(const ProbMatrixType &ProbMatrix,
945 const BitVector &Blocks,
946 std::vector<Scaled64> &Freq) const;
947
948 /// Find all blocks to apply inference on, that is, reachable from the entry
949 /// and backward reachable from exits along edges with positive probability.
950 void findReachableBlocks(BitVector &Blocks) const;
951
952 /// Build a matrix of probabilities with transitions (edges) between the
953 /// blocks: ProbMatrix[I] holds pairs (J, P), where Pr[J -> I | J] = P
954 void initTransitionProbabilities(const BitVector &Blocks,
955 ProbMatrixType &ProbMatrix) const;
956
957#ifndef NDEBUG
958 /// Compute the discrepancy between current block frequencies and the
959 /// probability matrix.
960 Scaled64 discrepancy(const ProbMatrixType &ProbMatrix,
961 const std::vector<Scaled64> &Freq) const;
962#endif
963
964public:
966
967 const FunctionT *getFunction() const { return F; }
968
969 void calculate(const FunctionT &F, const BranchProbabilityInfoT &BPI,
970 const CycleInfoT &CI);
971
973
974 BlockFrequency getBlockFreq(const BlockT *BB) const {
976 }
977
978 std::optional<uint64_t> getBlockProfileCount(const Function &F,
979 const BlockT *BB) const {
981 }
982
983 std::optional<uint64_t> getProfileCountFromFreq(const Function &F,
984 BlockFrequency Freq) const {
986 }
987
988 bool isIrrLoopHeader(const BlockT *BB) {
990 }
991
992 void setBlockFreq(const BlockT *BB, BlockFrequency Freq);
993
994 Scaled64 getFloatingBlockFreq(const BlockT *BB) const {
996 }
997
998 const BranchProbabilityInfoT &getBPI() const { return *BPI; }
999
1000 /// Print the frequencies for the current function.
1001 ///
1002 /// Prints the frequencies for the blocks in the current function.
1003 ///
1004 /// Blocks are printed in the natural iteration order of the function, rather
1005 /// than reverse post-order. This provides two advantages: writing -analyze
1006 /// tests is easier (since blocks come out in source order), and even
1007 /// unreachable blocks are printed.
1008 ///
1009 /// \a BlockFrequencyInfoImplBase::print() only knows reverse post-order, so
1010 /// we need to override it here.
1011 raw_ostream &print(raw_ostream &OS) const override;
1012
1014
1016};
1017
1018template <class BT>
1020 const BranchProbabilityInfoT &BPI,
1021 const CycleInfoT &CI) {
1022 // Save the parameters.
1023 this->BPI = &BPI;
1024 this->CI = &CI;
1025 this->F = &F;
1026
1027 // Clean up left-over data structures.
1029 RPOT.clear();
1030 Nodes.clear();
1031
1032 LLVM_DEBUG(dbgs() << "\nblock-frequency: " << F.getName()
1033 << "\n================="
1034 << std::string(F.getName().size(), '=') << "\n");
1035
1036 // Mass flows over a DAG: loops are packaged into pseudo-nodes, and backedges
1037 // accumulate as loop mass instead of being followed.
1038
1039 // Number blocks in reverse post-order; BlockNode comparisons use it.
1040 initializeRPOT();
1041 // Group blocks into the loops BFI represents, marking irreducible regions.
1042 initializeLoops();
1043
1044 // Deepest loop first, so each is packaged before its parent needs it.
1045 computeMassInLoops();
1046 computeMassInFunction();
1047 // Unpackage, scaling members by the loop's iterations and package mass.
1048 unwrapLoops();
1049 // Apply a post-processing step improving computed frequencies for functions
1050 // with irreducible loops.
1051 if (needIterativeInference())
1052 applyIterativeInference();
1054
1056 // To detect BFI queries for unknown blocks, add entries for unreachable
1057 // blocks, if any. This is to distinguish between known/existing unreachable
1058 // blocks and unknown blocks.
1059 for (const BlockT &BB : F)
1060 if (!getNode(&BB).isValid())
1062 }
1063
1064 RPOT.clear();
1065}
1066
1067template <class BT>
1069 BlockFrequency Freq) {
1071 unsigned BlockNumber = GraphTraits<const BlockT *>::getNumber(BB);
1072 if (Nodes.size() <= BlockNumber)
1074 BlockNode &Node = Nodes[BlockNumber];
1075 if (!Node.isValid()) {
1076 // If BB is a newly added block after BFI is done, we need to create a new
1077 // BlockNode for it assigned with a new index. The index can be determined
1078 // by the size of Freqs.
1079 Node = BlockNode(Freqs.size());
1080 Freqs.emplace_back();
1081 }
1083}
1084
1085template <class BT> void BlockFrequencyInfoImpl<BT>::initializeRPOT() {
1086 const BlockT *Entry = &F->front();
1087 RPOT.reserve(F->size());
1088 for (const BlockT *BB : post_order(Entry))
1089 RPOT.emplace_back(BB);
1090 std::reverse(RPOT.begin(), RPOT.end());
1091
1092 assert(RPOT.size() - 1 <= BlockNode::getMaxIndex() &&
1093 "More nodes in function than Block Frequency Info supports");
1094
1095 LLVM_DEBUG(dbgs() << "reverse-post-order-traversal\n");
1098 for (auto [Idx, Block] : enumerate(RPOT)) {
1099 BlockNode Node = BlockNode(Idx);
1100 LLVM_DEBUG(dbgs() << " - " << Idx << ": " << getBlockName(Node) << "\n");
1102 }
1103
1104 Working.reserve(RPOT.size());
1105 for (size_t Index = 0; Index < RPOT.size(); ++Index)
1106 Working.emplace_back(Index);
1107 Freqs.resize(RPOT.size());
1108}
1109
1110template <class BT> void BlockFrequencyInfoImpl<BT>::initializeLoops() {
1111 LLVM_DEBUG(dbgs() << "loop-detection\n");
1112
1113 LLVM_DEBUG(CI->print(dbgs()));
1114
1115 // Whether \p C describes a loop for BFI. An entry of a cycle an edge
1116 // re-enters heads a loop the forest does not represent, because the cycle
1117 // absorbed it; which entry that is depends on the order the search found
1118 // them in. Represent none of them, so that equal entries stay equal, and
1119 // leave the region to the packaging computeIrreducibleMass does.
1120 auto hasLoop = [&](CycleRef C) {
1121 if (!CI->isReducible(C))
1122 return false;
1123 for (CycleRef A = CI->getParentCycle(C); A; A = CI->getParentCycle(A))
1124 if (!CI->isReducible(A) && CI->isEntry(A, CI->getHeader(C)))
1125 return false;
1126 return true;
1127 };
1128
1129 // Visit loops top down and assign them an index.
1130 std::deque<std::pair<CycleRef, LoopData *>> Q;
1131 for (CycleRef C : CI->toplevel_cycles())
1132 Q.emplace_back(C, nullptr);
1133 if (Q.empty())
1134 return; // Early exit if there are no cycles.
1135 while (!Q.empty()) {
1136 CycleRef Cycle = Q.front().first;
1137 LoopData *Parent = Q.front().second;
1138 Q.pop_front();
1139
1140 if (hasLoop(Cycle)) {
1141 BlockNode Header = getNode(CI->getHeader(Cycle));
1142 Loops.emplace_back(Parent, Header);
1143
1144 Working[Header.Index].Loop = &Loops.back();
1145 LLVM_DEBUG(dbgs() << " - loop = " << getBlockName(Header) << "\n");
1146 Parent = &Loops.back();
1147 } else if (!CI->isReducible(Cycle)) {
1148 // No LoopData yet; ask computeIrreducibleMass to package the SCC
1149 // that contains this cycle.
1150 if (Parent)
1151 Parent->ContainsIrreducible = true;
1152 else
1153 TopContainsIrreducible = true;
1154 }
1155
1156 for (CycleRef C : CI->children(Cycle))
1157 Q.emplace_back(C, Parent);
1158 }
1159
1160 // Visit nodes in reverse post-order and add them to their deepest containing
1161 // loop.
1162 for (size_t Index = 0; Index < RPOT.size(); ++Index) {
1163 // Loop headers have already been mostly mapped.
1164 if (Working[Index].isLoopHeader()) {
1165 LoopData *ContainingLoop = Working[Index].getContainingLoop();
1166 if (ContainingLoop)
1167 ContainingLoop->Nodes.push_back(Index);
1168 continue;
1169 }
1170
1171 CycleRef Cycle = CI->getCycle(RPOT[Index]);
1172 while (Cycle && !hasLoop(Cycle))
1173 Cycle = CI->getParentCycle(Cycle);
1174 if (!Cycle)
1175 continue;
1176
1177 // Add this node to its containing loop's member list.
1178 BlockNode Header = getNode(CI->getHeader(Cycle));
1179 assert(Header.isValid());
1180 const auto &HeaderData = Working[Header.Index];
1181 assert(HeaderData.isLoopHeader());
1182
1183 Working[Index].Loop = HeaderData.Loop;
1184 HeaderData.Loop->Nodes.push_back(Index);
1185 LLVM_DEBUG(dbgs() << " - loop = " << getBlockName(Header)
1186 << ": member = " << getBlockName(Index) << "\n");
1187 }
1188}
1189
1190template <class BT> void BlockFrequencyInfoImpl<BT>::computeMassInLoops() {
1191 // Visit loops with the deepest first, and the top-level loops last.
1192 // computeIrreducibleMass inserts each new loop immediately after *L.
1193 for (auto L = Loops.end(), B = Loops.begin(); L != B;) {
1194 --L;
1195 if (L->ContainsIrreducible)
1196 computeIrreducibleMass(&*L, std::next(L));
1197 computeMassInLoop(*L);
1198 }
1199}
1200
1201template <class BT>
1202void BlockFrequencyInfoImpl<BT>::computeMassInLoop(LoopData &Loop) {
1203 LLVM_DEBUG(dbgs() << "compute-mass-in-loop: " << getLoopName(Loop) << "\n");
1204
1205 if (Loop.isIrreducible()) {
1206 LLVM_DEBUG(dbgs() << "isIrreducible = true\n");
1207 computeMassInIrreducibleLoop(Loop);
1208 } else {
1209 Working[Loop.getHeader().Index].getMass() = BlockMass::getFull();
1210 propagateMassToSuccessors(&Loop, Loop.getHeader());
1211 for (const BlockNode &M : Loop.members())
1212 propagateMassToSuccessors(&Loop, M);
1213 }
1214
1215 computeLoopScale(Loop);
1216 packageLoop(Loop);
1217}
1218
1219template <class BT>
1220void BlockFrequencyInfoImpl<BT>::computeMassInIrreducibleLoop(LoopData &Loop) {
1221 Distribution Dist;
1222 unsigned NumHeadersWithWeight = 0;
1223 std::optional<uint64_t> MinHeaderWeight;
1224 DenseSet<uint32_t> HeadersWithoutWeight;
1225 HeadersWithoutWeight.reserve(Loop.NumHeaders);
1226 for (uint32_t H = 0; H < Loop.NumHeaders; ++H) {
1227 auto &HeaderNode = Loop.Nodes[H];
1228 const BlockT *Block = getBlock(HeaderNode);
1229 IsIrrLoopHeader.set(Loop.Nodes[H].Index);
1230 std::optional<uint64_t> HeaderWeight = Block->getIrrLoopHeaderWeight();
1231 if (!HeaderWeight) {
1232 LLVM_DEBUG(dbgs() << "Missing irr loop header metadata on "
1233 << getBlockName(HeaderNode) << "\n");
1234 HeadersWithoutWeight.insert(H);
1235 continue;
1236 }
1237 LLVM_DEBUG(dbgs() << getBlockName(HeaderNode)
1238 << " has irr loop header weight " << *HeaderWeight
1239 << "\n");
1240 NumHeadersWithWeight++;
1241 uint64_t HeaderWeightValue = *HeaderWeight;
1242 if (!MinHeaderWeight || HeaderWeightValue < MinHeaderWeight)
1243 MinHeaderWeight = HeaderWeightValue;
1244 if (HeaderWeightValue) {
1245 Dist.addLocal(HeaderNode, HeaderWeightValue);
1246 }
1247 }
1248 // As a heuristic, if some headers don't have a weight, give them the
1249 // minimum weight seen (not to disrupt the existing trends too much by
1250 // using a weight that's in the general range of the other headers' weights,
1251 // and the minimum seems to perform better than the average.)
1252 // FIXME: better update in the passes that drop the header weight.
1253 // If no headers have a weight, give them even weight (use weight 1).
1254 if (!MinHeaderWeight)
1255 MinHeaderWeight = 1;
1256 for (uint32_t H : HeadersWithoutWeight) {
1257 auto &HeaderNode = Loop.Nodes[H];
1258 assert(!getBlock(HeaderNode)->getIrrLoopHeaderWeight() &&
1259 "Shouldn't have a weight metadata");
1260 uint64_t MinWeight = *MinHeaderWeight;
1261 LLVM_DEBUG(dbgs() << "Giving weight " << MinWeight << " to "
1262 << getBlockName(HeaderNode) << "\n");
1263 if (MinWeight)
1264 Dist.addLocal(HeaderNode, MinWeight);
1265 }
1266 distributeIrrLoopHeaderMass(Dist);
1267 // Seeded headers are ordered first. Any retreating edge from a non-header
1268 // targets a header.
1269 for (const BlockNode &M : Loop.Nodes)
1270 propagateMassToSuccessors(&Loop, M);
1271 if (NumHeadersWithWeight == 0)
1272 // No headers have a metadata. Adjust header mass.
1273 adjustLoopHeaderMass(Loop);
1274}
1275
1276template <class BT> void BlockFrequencyInfoImpl<BT>::computeMassInFunction() {
1277 if (TopContainsIrreducible)
1278 computeIrreducibleMass(nullptr, Loops.begin());
1279
1280 LLVM_DEBUG(dbgs() << "compute-mass-in-function\n");
1281 assert(!Working.empty() && "no blocks in function");
1282 assert(!Working[0].isLoopHeader() && "entry block is a loop header");
1283
1284 Working[0].getMass() = BlockMass::getFull();
1285 for (size_t i = 0, n = RPOT.size(); i != n; ++i) {
1286 // Check for nodes that have been packaged.
1287 if (Working[i].isPackaged())
1288 continue;
1289
1290 propagateMassToSuccessors(nullptr, BlockNode(i));
1291 }
1292}
1293
1294template <class BT>
1295bool BlockFrequencyInfoImpl<BT>::needIterativeInference() const {
1297 return false;
1298 if (!F->getFunction().hasProfileData())
1299 return false;
1300 // Apply iterative inference only if the function contains irreducible loops;
1301 // otherwise, computed block frequencies are reasonably correct.
1302 for (auto L = Loops.rbegin(), E = Loops.rend(); L != E; ++L) {
1303 if (L->isIrreducible())
1304 return true;
1305 }
1306 return false;
1307}
1308
1309template <class BT> void BlockFrequencyInfoImpl<BT>::applyIterativeInference() {
1310 // Extract blocks for processing: a block is considered for inference iff it
1311 // can be reached from the entry by edges with a positive probability.
1312 // Non-processed blocks are assigned with the zero frequency and are ignored
1313 // in the computation
1314 BitVector ReachableBlocks;
1315 findReachableBlocks(ReachableBlocks);
1316 if (ReachableBlocks.none())
1317 return;
1318
1319 // Extract initial frequencies for the reachable blocks
1320 auto Freq = std::vector<Scaled64>(ReachableBlocks.size());
1321 Scaled64 SumFreq;
1322 for (const BlockT &BB : *F) {
1324 if (!ReachableBlocks[Number])
1325 continue;
1326 Freq[Number] = getFloatingBlockFreq(&BB);
1327 SumFreq += Freq[Number];
1328 }
1329 assert(!SumFreq.isZero() && "empty initial block frequencies");
1330
1331 LLVM_DEBUG(dbgs() << "Applying iterative inference for " << F->getName()
1332 << " with " << ReachableBlocks.count() << " blocks\n");
1333
1334 // Normalizing frequencies so they sum up to 1.0
1335 for (auto &Value : Freq) {
1336 Value /= SumFreq;
1337 }
1338
1339 // Setting up edge probabilities using sparse matrix representation:
1340 // ProbMatrix[I] holds a vector of pairs (J, P) where Pr[J -> I | J] = P
1341 ProbMatrixType ProbMatrix;
1342 initTransitionProbabilities(ReachableBlocks, ProbMatrix);
1343
1344 // Run the propagation
1345 iterativeInference(ProbMatrix, ReachableBlocks, Freq);
1346
1347 // Assign computed frequency values
1348 for (const BlockT &BB : *F) {
1349 auto Node = getNode(&BB);
1350 if (!Node.isValid())
1351 continue;
1353 Freqs[Node.Index].Scaled =
1354 ReachableBlocks[Number] ? Freq[Number] : Scaled64::getZero();
1355 }
1356}
1357
1358template <class BT>
1359void BlockFrequencyInfoImpl<BT>::iterativeInference(
1360 const ProbMatrixType &ProbMatrix, const BitVector &Blocks,
1361 std::vector<Scaled64> &Freq) const {
1363 "incorrectly specified precision");
1364 // Convert double precision to Scaled64
1365 const auto Precision =
1366 Scaled64::getInverse(static_cast<uint64_t>(1.0 / IterativeBFIPrecision));
1367 const size_t MaxIterations =
1368 IterativeBFIMaxIterationsPerBlock * Blocks.count();
1369
1370#ifndef NDEBUG
1371 LLVM_DEBUG(dbgs() << " Initial discrepancy = "
1372 << discrepancy(ProbMatrix, Freq).toString() << "\n");
1373#endif
1374
1375 // Successors[I] holds unique sucessors of the I-th block
1376 auto Successors = std::vector<std::vector<size_t>>(Freq.size());
1377 for (size_t I = 0; I < Freq.size(); I++) {
1378 for (const auto &Jump : ProbMatrix[I]) {
1379 Successors[Jump.first].push_back(I);
1380 }
1381 }
1382
1383 // To speedup computation, we maintain a set of "active" blocks whose
1384 // frequencies need to be updated based on the incoming edges.
1385 // The set is dynamic and changes after every update. Initially all blocks
1386 // with a positive frequency are active
1387 auto IsActive = BitVector(Freq.size(), false);
1388 std::queue<size_t> ActiveSet;
1389 for (unsigned I : Blocks.set_bits()) {
1390 if (Freq[I] > 0) {
1391 ActiveSet.push(I);
1392 IsActive[I] = true;
1393 }
1394 }
1395
1396 // Iterate over the blocks propagating frequencies
1397 size_t It = 0;
1398 while (It++ < MaxIterations && !ActiveSet.empty()) {
1399 size_t I = ActiveSet.front();
1400 ActiveSet.pop();
1401 IsActive[I] = false;
1402
1403 // Compute a new frequency for the block: NewFreq := Freq \times ProbMatrix.
1404 // A special care is taken for self-edges that needs to be scaled by
1405 // (1.0 - SelfProb), where SelfProb is the sum of probabilities on the edges
1406 Scaled64 NewFreq;
1407 Scaled64 OneMinusSelfProb = Scaled64::getOne();
1408 for (const auto &Jump : ProbMatrix[I]) {
1409 if (Jump.first == I) {
1410 OneMinusSelfProb -= Jump.second;
1411 } else {
1412 NewFreq += Freq[Jump.first] * Jump.second;
1413 }
1414 }
1415 if (OneMinusSelfProb != Scaled64::getOne())
1416 NewFreq /= OneMinusSelfProb;
1417
1418 // If the block's frequency has changed enough, then
1419 // make sure the block and its successors are in the active set
1420 auto Change = Freq[I] >= NewFreq ? Freq[I] - NewFreq : NewFreq - Freq[I];
1421 if (Change > Precision) {
1422 ActiveSet.push(I);
1423 IsActive[I] = true;
1424 for (size_t Succ : Successors[I]) {
1425 if (!IsActive[Succ]) {
1426 ActiveSet.push(Succ);
1427 IsActive[Succ] = true;
1428 }
1429 }
1430 }
1431
1432 // Update the frequency for the block
1433 Freq[I] = NewFreq;
1434 }
1435
1436 LLVM_DEBUG(dbgs() << " Completed " << It << " inference iterations"
1437 << format(" (%0.0f per block)", double(It) / Freq.size())
1438 << "\n");
1439#ifndef NDEBUG
1440 LLVM_DEBUG(dbgs() << " Final discrepancy = "
1441 << discrepancy(ProbMatrix, Freq).toString() << "\n");
1442#endif
1443}
1444
1445template <class BT>
1446void BlockFrequencyInfoImpl<BT>::findReachableBlocks(BitVector &Blocks) const {
1447 unsigned MaxNumber = GraphTraits<const FunctionT *>::getMaxNumber(F);
1448 auto number = [](const BlockT *BB) {
1450 };
1451
1452 // Find all blocks to apply inference on, that is, reachable from the entry
1453 // along edges with non-zero probablities
1454 std::queue<const BlockT *> Queue;
1455 BitVector Reachable(MaxNumber);
1456 const BlockT *Entry = &F->front();
1457 Queue.push(Entry);
1458 Reachable.set(number(Entry));
1459 while (!Queue.empty()) {
1460 const BlockT *SrcBB = Queue.front();
1461 Queue.pop();
1462 for (auto It : enumerate(children<const BlockT *>(SrcBB))) {
1463 auto EP = BPI->getEdgeProbability(SrcBB, It.index());
1464 if (EP.isZero())
1465 continue;
1466 unsigned Number = number(It.value());
1467 if (!Reachable.test(Number)) {
1468 Reachable.set(Number);
1469 Queue.push(It.value());
1470 }
1471 }
1472 }
1473
1474 // Find all blocks to apply inference on, that is, backward reachable from
1475 // the entry along (backward) edges with non-zero probablities
1476 BitVector InverseReachable(MaxNumber);
1477 for (const BlockT &BB : *F) {
1478 // An exit block is a block without any successors
1479 bool HasSucc = !llvm::children<const BlockT *>(&BB).empty();
1480 if (!HasSucc && Reachable.test(number(&BB))) {
1481 Queue.push(&BB);
1482 InverseReachable.set(number(&BB));
1483 }
1484 }
1485 while (!Queue.empty()) {
1486 const BlockT *SrcBB = Queue.front();
1487 Queue.pop();
1488 for (const BlockT *DstBB : inverse_children<const BlockT *>(SrcBB)) {
1489 auto EP = BPI->getEdgeProbability(DstBB, SrcBB);
1490 if (EP.isZero())
1491 continue;
1492 unsigned Number = number(DstBB);
1493 if (!InverseReachable.test(Number)) {
1494 InverseReachable.set(Number);
1495 Queue.push(DstBB);
1496 }
1497 }
1498 }
1499
1500 // Collect the result
1501 Reachable &= InverseReachable;
1502 Blocks = std::move(Reachable);
1503}
1504
1505template <class BT>
1506void BlockFrequencyInfoImpl<BT>::initTransitionProbabilities(
1507 const BitVector &Blocks, ProbMatrixType &ProbMatrix) const {
1508 const size_t NumBlocks = Blocks.size();
1509 auto Succs = std::vector<std::vector<std::pair<size_t, Scaled64>>>(NumBlocks);
1510 auto SumProb = std::vector<Scaled64>(NumBlocks);
1511
1512 // Find unique successors and corresponding probabilities for every block
1513 for (const BlockT &BB : *F) {
1515 if (!Blocks[Src])
1516 continue;
1518 for (auto It : enumerate(children<const BlockT *>(&BB))) {
1519 const BlockT *SI = It.value();
1521 // Ignore cold blocks
1522 if (!Blocks[Dst])
1523 continue;
1524 // Ignore parallel edges between BB and SI blocks
1525 if (!UniqueSuccs.insert(SI).second)
1526 continue;
1527 // Ignore jumps with zero probability
1528 auto EP = BPI->getEdgeProbability(&BB, It.index());
1529 if (EP.isZero())
1530 continue;
1531
1532 auto EdgeProb =
1533 Scaled64::getFraction(EP.getNumerator(), EP.getDenominator());
1534 Succs[Src].push_back(std::make_pair(Dst, EdgeProb));
1535 SumProb[Src] += EdgeProb;
1536 }
1537 }
1538
1539 // Add transitions for every jump with positive branch probability
1540 ProbMatrix = ProbMatrixType(NumBlocks);
1541 for (size_t Src = 0; Src < NumBlocks; Src++) {
1542 // Ignore blocks w/o successors
1543 if (Succs[Src].empty())
1544 continue;
1545
1546 assert(!SumProb[Src].isZero() && "Zero sum probability of non-exit block");
1547 for (auto &Jump : Succs[Src]) {
1548 size_t Dst = Jump.first;
1549 Scaled64 Prob = Jump.second;
1550 ProbMatrix[Dst].push_back(std::make_pair(Src, Prob / SumProb[Src]));
1551 }
1552 }
1553
1554 // Add transitions from sinks to the source
1555 size_t EntryIdx = GraphTraits<const BlockT *>::getNumber(&F->front());
1556 for (size_t Src = 0; Src < NumBlocks; Src++) {
1557 if (Blocks[Src] && Succs[Src].empty()) {
1558 ProbMatrix[EntryIdx].push_back(std::make_pair(Src, Scaled64::getOne()));
1559 }
1560 }
1561}
1562
1563#ifndef NDEBUG
1564template <class BT>
1565BlockFrequencyInfoImplBase::Scaled64 BlockFrequencyInfoImpl<BT>::discrepancy(
1566 const ProbMatrixType &ProbMatrix, const std::vector<Scaled64> &Freq) const {
1567 size_t EntryIdx = GraphTraits<const BlockT *>::getNumber(&F->front());
1568 assert(Freq[EntryIdx] > 0 &&
1569 "Incorrectly computed frequency of the entry block");
1570 Scaled64 Discrepancy;
1571 for (size_t I = 0; I < ProbMatrix.size(); I++) {
1572 Scaled64 Sum;
1573 for (const auto &Jump : ProbMatrix[I]) {
1574 Sum += Freq[Jump.first] * Jump.second;
1575 }
1576 Discrepancy += Freq[I] >= Sum ? Freq[I] - Sum : Sum - Freq[I];
1577 }
1578 // Normalizing by the frequency of the entry block
1579 return Discrepancy / Freq[EntryIdx];
1580}
1581#endif
1582
1583template <class BT>
1584void BlockFrequencyInfoImpl<BT>::computeIrreducibleMass(
1585 LoopData *OuterLoop, std::list<LoopData>::iterator Insert) {
1586 LLVM_DEBUG(dbgs() << "analyze-irreducible-in-";
1587 if (OuterLoop) dbgs()
1588 << "loop: " << getLoopName(*OuterLoop) << "\n";
1589 else dbgs() << "function\n");
1590
1591 using namespace bfi_detail;
1592
1593 auto addBlockEdges = [&](IrreducibleGraph &G, IrreducibleGraph::IrrNode &Irr,
1594 const LoopData *OuterLoop) {
1595 const BlockT *BB = RPOT[Irr.Node.Index];
1596 for (const auto *Succ : children<const BlockT *>(BB))
1597 G.addEdge(Irr, getNode(Succ), OuterLoop);
1598 };
1599 IrreducibleGraph G(*this, OuterLoop, addBlockEdges);
1600
1601 for (auto &L : analyzeIrreducible(G, OuterLoop, Insert))
1602 computeMassInLoop(L);
1603
1604 if (!OuterLoop)
1605 return;
1606
1607 // Drop the nodes the new packages absorbed.
1608 assert(OuterLoop->Exits.empty() && "unexpected exits before distribution");
1609 assert(llvm::all_of(OuterLoop->BackedgeMass,
1610 [](BlockMass M) { return M.isEmpty(); }) &&
1611 "unexpected backedge mass before distribution");
1612 auto O = OuterLoop->Nodes.begin() + 1;
1613 for (auto I = O, E = OuterLoop->Nodes.end(); I != E; ++I)
1614 if (!Working[I->Index].isPackaged())
1615 *O++ = *I;
1616 OuterLoop->Nodes.erase(O, OuterLoop->Nodes.end());
1617}
1618
1619// A helper function that converts a branch probability into weight.
1621 return Prob.getNumerator();
1622}
1623
1624template <class BT>
1625void BlockFrequencyInfoImpl<BT>::propagateMassToSuccessors(
1626 LoopData *OuterLoop, const BlockNode &Node) {
1627 LLVM_DEBUG(dbgs() << " - node: " << getBlockName(Node) << "\n");
1628 // Calculate probability for successors.
1629 Distribution Dist;
1630 if (auto *Loop = Working[Node.Index].getPackagedLoop()) {
1631 assert(Loop != OuterLoop && "Cannot propagate mass in a packaged loop");
1632 addLoopSuccessorsToDist(OuterLoop, *Loop, Dist);
1633 } else {
1634 const BlockT *BB = getBlock(Node);
1635 for (auto It : enumerate(children<const BlockT *>(BB)))
1636 addToDist(
1637 Dist, OuterLoop, Node, getNode(It.value()),
1638 getWeightFromBranchProb(BPI->getEdgeProbability(BB, It.index())));
1639 }
1640
1641 // Distribute mass to successors, saving exit and backedge data in the
1642 // loop header.
1643 distributeMass(Node, OuterLoop, Dist);
1644}
1645
1646template <class BT>
1648 if (!F)
1649 return OS;
1650 OS << "block-frequency-info: " << F->getName() << "\n";
1651 for (const BlockT &BB : *F) {
1652 OS << " - " << bfi_detail::getBlockName(&BB) << ": float = ";
1653 getFloatingBlockFreq(&BB).print(OS, 5)
1654 << ", int = " << getBlockFreq(&BB).getFrequency();
1655 if (std::optional<uint64_t> ProfileCount =
1657 F->getFunction(), getNode(&BB)))
1658 OS << ", count = " << *ProfileCount;
1659 if (std::optional<uint64_t> IrrLoopHeaderWeight =
1660 BB.getIrrLoopHeaderWeight())
1661 OS << ", irr_loop_header_weight = " << *IrrLoopHeaderWeight;
1662 OS << "\n";
1663 }
1664
1665 // Add an extra newline for readability.
1666 OS << "\n";
1667 return OS;
1668}
1669
1670template <class BT>
1673 bool Match = true;
1674 // Gather blocks for numbers so that we can print names and determine whether
1675 // they still exist.
1678 for (const auto &BB : *F)
1679 Blocks[GraphTraits<const BlockT *>::getNumber(&BB)] = &BB;
1680
1681 size_t MinSize = std::min(Nodes.size(), Other.Nodes.size());
1682 for (size_t i = 0; i < MinSize; ++i) {
1683 if (!Blocks[i])
1684 continue; // Block got deleted in the mean time, ignore.
1685 if (Nodes[i].isValid() != Other.Nodes[i].isValid()) {
1686 Match = false;
1687 dbgs() << "Block " << bfi_detail::getBlockName(Blocks[i])
1688 << " existence mismatch.\n";
1689 } else if (Nodes[i].isValid()) {
1690 const auto &Freq = Freqs[Nodes[i].Index];
1691 const auto &OtherFreq = Other.Freqs[Other.Nodes[i].Index];
1692 if (Freq.Integer != OtherFreq.Integer) {
1693 Match = false;
1694 dbgs() << "Freq mismatch: " << bfi_detail::getBlockName(Blocks[i])
1695 << " " << Freq.Integer << " vs " << OtherFreq.Integer << "\n";
1696 }
1697 }
1698 }
1699 // Block with higher numbers must not exist in either state.
1700 for (size_t i = MinSize; i < Nodes.size(); ++i) {
1701 if (Nodes[i].isValid()) {
1702 Match = false;
1703 dbgs() << "Block " << bfi_detail::getBlockName(Blocks[i])
1704 << " existence mismatch.\n";
1705 }
1706 }
1707 for (size_t i = MinSize; i < Other.Nodes.size(); ++i) {
1708 if (Other.Nodes[i].isValid()) {
1709 Match = false;
1710 dbgs() << "Block " << bfi_detail::getBlockName(Blocks[i])
1711 << " existence mismatch.\n";
1712 }
1713 }
1714
1715 if (!Match) {
1716 dbgs() << "This\n";
1717 print(dbgs());
1718 dbgs() << "Other\n";
1719 Other.print(dbgs());
1720 }
1721 assert(Match && "BFI mismatch");
1722}
1723
1724// Graph trait base class for block frequency information graph
1725// viewer.
1726
1728
1729template <class BlockFrequencyInfoT, class BranchProbabilityInfoT>
1732 using NodeRef = typename GTraits::NodeRef;
1733 using EdgeIter = typename GTraits::ChildIteratorType;
1734 using NodeIter = typename GTraits::nodes_iterator;
1735
1737
1740
1741 static StringRef getGraphName(const BlockFrequencyInfoT *G) {
1742 return G->getFunction()->getName();
1743 }
1744
1745 std::string getNodeAttributes(NodeRef Node, const BlockFrequencyInfoT *Graph,
1746 unsigned HotPercentThreshold = 0) {
1747 std::string Result;
1748 if (!HotPercentThreshold)
1749 return Result;
1750
1751 // Compute MaxFrequency on the fly:
1752 if (!MaxFrequency) {
1753 for (NodeIter I = GTraits::nodes_begin(Graph),
1754 E = GTraits::nodes_end(Graph);
1755 I != E; ++I) {
1756 NodeRef N = *I;
1757 MaxFrequency =
1758 std::max(MaxFrequency, Graph->getBlockFreq(N).getFrequency());
1759 }
1760 }
1761 BlockFrequency Freq = Graph->getBlockFreq(Node);
1762 BlockFrequency HotFreq =
1764 BranchProbability::getBranchProbability(HotPercentThreshold, 100));
1765
1766 if (Freq < HotFreq)
1767 return Result;
1768
1769 raw_string_ostream(Result) << "color=\"red\"";
1770 return Result;
1771 }
1772
1773 std::string getNodeLabel(NodeRef Node, const BlockFrequencyInfoT *Graph,
1774 GVDAGType GType, int layout_order = -1) {
1775 std::string Result;
1776 raw_string_ostream OS(Result);
1777
1778 if (layout_order != -1)
1779 OS << Node->getName() << "[" << layout_order << "] : ";
1780 else
1781 OS << Node->getName() << " : ";
1782 switch (GType) {
1783 case GVDT_Fraction:
1784 OS << printBlockFreq(*Graph, *Node);
1785 break;
1786 case GVDT_Integer:
1787 OS << Graph->getBlockFreq(Node).getFrequency();
1788 break;
1789 case GVDT_Count: {
1790 auto Count = Graph->getBlockProfileCount(Node);
1791 if (Count)
1792 OS << *Count;
1793 else
1794 OS << "Unknown";
1795 break;
1796 }
1797 case GVDT_None:
1798 llvm_unreachable("If we are not supposed to render a graph we should "
1799 "never reach this point.");
1800 }
1801 return Result;
1802 }
1803
1805 const BlockFrequencyInfoT *BFI,
1806 const BranchProbabilityInfoT *BPI,
1807 unsigned HotPercentThreshold = 0) {
1808 std::string Str;
1809 if (!BPI)
1810 return Str;
1811
1812 unsigned SuccIdx = std::distance(succ_begin(Node), EI);
1813 BranchProbability BP = BPI->getEdgeProbability(Node, SuccIdx);
1814 uint32_t N = BP.getNumerator();
1815 uint32_t D = BP.getDenominator();
1816 double Percent = 100.0 * N / D;
1817 raw_string_ostream OS(Str);
1818 OS << format("label=\"%.1f%%\"", Percent);
1819
1820 if (HotPercentThreshold) {
1821 BlockFrequency EFreq = BFI->getBlockFreq(Node) * BP;
1823 BranchProbability(HotPercentThreshold, 100);
1824
1825 if (EFreq >= HotFreq)
1826 OS << ",color=\"red\"";
1827 }
1828 return Str;
1829 }
1830};
1831
1832} // end namespace llvm
1833
1834#undef DEBUG_TYPE
1835
1836#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)
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 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.
This file defines the DenseSet and SmallDenseSet classes.
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
#define H(x, y, z)
Definition MD5.cpp:56
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
void distributeIrrLoopHeaderMass(Distribution &Dist)
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.
void adjustLoopHeaderMass(LoopData &Loop)
Adjust the mass of all headers in an irreducible loop.
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.
Implements a dense probed hash-table based set.
Definition DenseSet.h:281
BlockT * getHeader() 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.
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.
void reserve(size_t Size)
Grow the DenseSet so that it can contain at least NumEntries items before resizing again.
Definition DenseSet.h:93
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 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.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1739
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:94
LLVM_ABI llvm::cl::opt< bool > CheckBFIUnknownBlockQueries
RNSuccIterator< NodeRef, BlockT, RegionT > succ_begin(NodeRef Node)
@ Other
Any other memory.
Definition ModRef.h:68
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)
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
LoopData(LoopData *Parent, It1 FirstHeader, It1 LastHeader, It2 FirstOther, It2 LastOther)
ExitMap Exits
Successor edges (and weights).
bool IsPackaged
Whether this has been packaged.
LoopData(LoopData *Parent, It FirstHeader, It LastHeader)
LoopData(LoopData *Parent, const BlockNode &Header)
NodeList::const_iterator members_begin() const
NodeList Nodes
Header and the members of the loop.
HeaderMassList BackedgeMass
Mass returned to each loop header.
HeaderMassList::difference_type getHeaderIndex(const BlockNode &B)
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)