LLVM 17.0.0git
SampleProfileLoaderBaseImpl.h
Go to the documentation of this file.
1////===- SampleProfileLoadBaseImpl.h - Profile loader base impl --*- 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/// \file
10/// This file provides the interface for the sampled PGO profile loader base
11/// implementation.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_TRANSFORMS_UTILS_SAMPLEPROFILELOADERBASEIMPL_H
16#define LLVM_TRANSFORMS_UTILS_SAMPLEPROFILELOADERBASEIMPL_H
17
18#include "llvm/ADT/ArrayRef.h"
19#include "llvm/ADT/DenseMap.h"
20#include "llvm/ADT/DenseSet.h"
23#include "llvm/ADT/SmallSet.h"
28#include "llvm/IR/BasicBlock.h"
29#include "llvm/IR/CFG.h"
31#include "llvm/IR/DebugLoc.h"
32#include "llvm/IR/Dominators.h"
33#include "llvm/IR/Function.h"
34#include "llvm/IR/Instruction.h"
36#include "llvm/IR/Module.h"
37#include "llvm/IR/PseudoProbe.h"
45
46namespace llvm {
47using namespace sampleprof;
48using namespace sampleprofutil;
50
51namespace vfs {
52class FileSystem;
53} // namespace vfs
54
55#define DEBUG_TYPE "sample-profile-impl"
56
57namespace afdo_detail {
58
59template <typename BlockT> struct IRTraits;
60template <> struct IRTraits<BasicBlock> {
65 using LoopT = Loop;
66 using LoopInfoPtrT = std::unique_ptr<LoopInfo>;
67 using DominatorTreePtrT = std::unique_ptr<DominatorTree>;
69 using PostDominatorTreePtrT = std::unique_ptr<PostDominatorTree>;
74 static Function &getFunction(Function &F) { return F; }
75 static const BasicBlock *getEntryBB(const Function *F) {
76 return &F->getEntryBlock();
77 }
79 static succ_range getSuccessors(BasicBlock *BB) { return successors(BB); }
80};
81
82} // end namespace afdo_detail
83
84// This class serves sample counts correlation for SampleProfileLoader by
85// analyzing pseudo probes and their function descriptors injected by
86// SampleProfileProber.
89
90 const PseudoProbeDescriptor *getDesc(const Function &F) const {
91 auto I = GUIDToProbeDescMap.find(
93 return I == GUIDToProbeDescMap.end() ? nullptr : &I->second;
94 }
95
96public:
99 M.getNamedMetadata(PseudoProbeDescMetadataName)) {
100 for (const auto *Operand : FuncInfo->operands()) {
101 const auto *MD = cast<MDNode>(Operand);
102 auto GUID = mdconst::dyn_extract<ConstantInt>(MD->getOperand(0))
103 ->getZExtValue();
104 auto Hash = mdconst::dyn_extract<ConstantInt>(MD->getOperand(1))
105 ->getZExtValue();
106 GUIDToProbeDescMap.try_emplace(GUID, PseudoProbeDescriptor(GUID, Hash));
107 }
108 }
109 }
110
111 bool moduleIsProbed(const Module &M) const {
112 return M.getNamedMetadata(PseudoProbeDescMetadataName);
113 }
114
115 bool profileIsValid(const Function &F, const FunctionSamples &Samples) const {
116 const auto *Desc = getDesc(F);
117 if (!Desc) {
118 LLVM_DEBUG(dbgs() << "Probe descriptor missing for Function "
119 << F.getName() << "\n");
120 return false;
121 }
122 if (Desc->getFunctionHash() != Samples.getFunctionHash()) {
123 LLVM_DEBUG(dbgs() << "Hash mismatch for Function " << F.getName()
124 << "\n");
125 return false;
126 }
127 return true;
128 }
129};
130
131
132
133extern cl::opt<bool> SampleProfileUseProfi;
134
135template <typename FT> class SampleProfileLoaderBaseImpl {
136public:
137 SampleProfileLoaderBaseImpl(std::string Name, std::string RemapName,
139 : Filename(Name), RemappingFilename(RemapName), FS(std::move(FS)) {}
140 void dump() { Reader->dump(); }
141
143 using BT = typename std::remove_pointer<NodeRef>::type;
163
167 using Edge = std::pair<const BasicBlockT *, const BasicBlockT *>;
171
172protected:
175
178 }
181 }
184 }
187 }
188
189 unsigned getFunctionLoc(FunctionT &Func);
196 virtual const FunctionSamples *
204 ArrayRef<BasicBlockT *> Descendants,
205 PostDominatorTreeT *DomTree);
208 BlockWeightMap &SampleBlockWeights,
210 uint64_t visitEdge(Edge E, unsigned *NumUnknownEdges, Edge *UnknownEdge);
212 bool propagateThroughEdges(FunctionT &F, bool UpdateBlockCount);
213 void clearFunctionData(bool ResetDT = true);
215 bool
217 const DenseSet<GlobalValue::GUID> &InlinedGUIDs);
219 const DenseSet<GlobalValue::GUID> &InlinedGUIDs);
220 void
222 const DenseSet<GlobalValue::GUID> &InlinedGUIDs);
224
225 /// Map basic blocks to their computed weights.
226 ///
227 /// The weight of a basic block is defined to be the maximum
228 /// of all the instruction weights in that block.
230
231 /// Map edges to their computed weights.
232 ///
233 /// Edge weights are computed by propagating basic block weights in
234 /// SampleProfile::propagateWeights.
236
237 /// Set of visited blocks during propagation.
239
240 /// Set of visited edges during propagation.
242
243 /// Equivalence classes for block weights.
244 ///
245 /// Two blocks BB1 and BB2 are in the same equivalence class if they
246 /// dominate and post-dominate each other, and they are in the same loop
247 /// nest. When this happens, the two blocks are guaranteed to execute
248 /// the same number of times.
250
251 /// Dominance, post-dominance and loop information.
255
256 /// Predecessors for each basic block in the CFG.
258
259 /// Successors for each basic block in the CFG.
261
262 /// Profile coverage tracker.
264
265 /// Profile reader object.
266 std::unique_ptr<SampleProfileReader> Reader;
267
268 // A pseudo probe helper to correlate the imported sample counts.
269 std::unique_ptr<PseudoProbeManager> ProbeManager;
270
271 /// Samples collected for the body of this function.
273
274 /// Name of the profile file to load.
275 std::string Filename;
276
277 /// Name of the profile remapping file to load.
278 std::string RemappingFilename;
279
280 /// VirtualFileSystem to load profile files from.
282
283 /// Profile Summary Info computed from sample profile.
285
286 /// Optimization Remark Emitter used to emit diagnostic remarks.
288};
289
290/// Clear all the per-function data used to load samples and propagate weights.
291template <typename BT>
293 BlockWeights.clear();
294 EdgeWeights.clear();
295 VisitedBlocks.clear();
296 VisitedEdges.clear();
297 EquivalenceClass.clear();
298 if (ResetDT) {
299 DT = nullptr;
300 PDT = nullptr;
301 LI = nullptr;
302 }
303 Predecessors.clear();
304 Successors.clear();
305 CoverageTracker.clear();
306}
307
308#ifndef NDEBUG
309/// Print the weight of edge \p E on stream \p OS.
310///
311/// \param OS Stream to emit the output to.
312/// \param E Edge to print.
313template <typename BT>
315 OS << "weight[" << E.first->getName() << "->" << E.second->getName()
316 << "]: " << EdgeWeights[E] << "\n";
317}
318
319/// Print the equivalence class of block \p BB on stream \p OS.
320///
321/// \param OS Stream to emit the output to.
322/// \param BB Block to print.
323template <typename BT>
325 raw_ostream &OS, const BasicBlockT *BB) {
326 const BasicBlockT *Equiv = EquivalenceClass[BB];
327 OS << "equivalence[" << BB->getName()
328 << "]: " << ((Equiv) ? EquivalenceClass[BB]->getName() : "NONE") << "\n";
329}
330
331/// Print the weight of block \p BB on stream \p OS.
332///
333/// \param OS Stream to emit the output to.
334/// \param BB Block to print.
335template <typename BT>
337 raw_ostream &OS, const BasicBlockT *BB) const {
338 const auto &I = BlockWeights.find(BB);
339 uint64_t W = (I == BlockWeights.end() ? 0 : I->second);
340 OS << "weight[" << BB->getName() << "]: " << W << "\n";
341}
342#endif
343
344/// Get the weight for an instruction.
345///
346/// The "weight" of an instruction \p Inst is the number of samples
347/// collected on that instruction at runtime. To retrieve it, we
348/// need to compute the line number of \p Inst relative to the start of its
349/// function. We use HeaderLineno to compute the offset. We then
350/// look up the samples collected for \p Inst using BodySamples.
351///
352/// \param Inst Instruction to query.
353///
354/// \returns the weight of \p Inst.
355template <typename BT>
359 return getProbeWeight(Inst);
360 return getInstWeightImpl(Inst);
361}
362
363template <typename BT>
366 const FunctionSamples *FS = findFunctionSamples(Inst);
367 if (!FS)
368 return std::error_code();
369
370 const DebugLoc &DLoc = Inst.getDebugLoc();
371 if (!DLoc)
372 return std::error_code();
373
374 const DILocation *DIL = DLoc;
375 uint32_t LineOffset = FunctionSamples::getOffset(DIL);
376 uint32_t Discriminator;
378 Discriminator = DIL->getDiscriminator();
379 else
380 Discriminator = DIL->getBaseDiscriminator();
381
382 ErrorOr<uint64_t> R = FS->findSamplesAt(LineOffset, Discriminator);
383 if (R) {
384 bool FirstMark =
385 CoverageTracker.markSamplesUsed(FS, LineOffset, Discriminator, R.get());
386 if (FirstMark) {
387 ORE->emit([&]() {
388 OptRemarkAnalysisT Remark(DEBUG_TYPE, "AppliedSamples", &Inst);
389 Remark << "Applied " << ore::NV("NumSamples", *R);
390 Remark << " samples from profile (offset: ";
391 Remark << ore::NV("LineOffset", LineOffset);
392 if (Discriminator) {
393 Remark << ".";
394 Remark << ore::NV("Discriminator", Discriminator);
395 }
396 Remark << ")";
397 return Remark;
398 });
399 }
400 LLVM_DEBUG(dbgs() << " " << DLoc.getLine() << "." << Discriminator << ":"
401 << Inst << " (line offset: " << LineOffset << "."
402 << Discriminator << " - weight: " << R.get() << ")\n");
403 }
404 return R;
405}
406
407// Here use error_code to represent: 1) The dangling probe. 2) Ignore the weight
408// of non-probe instruction. So if all instructions of the BB give error_code,
409// tell the inference algorithm to infer the BB weight.
410template <typename BT>
414 "Profile is not pseudo probe based");
415 std::optional<PseudoProbe> Probe = extractProbe(Inst);
416 // Ignore the non-probe instruction. If none of the instruction in the BB is
417 // probe, we choose to infer the BB's weight.
418 if (!Probe)
419 return std::error_code();
420
421 const FunctionSamples *FS = findFunctionSamples(Inst);
422 // If none of the instruction has FunctionSample, we choose to return zero
423 // value sample to indicate the BB is cold. This could happen when the
424 // instruction is from inlinee and no profile data is found.
425 // FIXME: This should not be affected by the source drift issue as 1) if the
426 // newly added function is top-level inliner, it won't match the CFG checksum
427 // in the function profile or 2) if it's the inlinee, the inlinee should have
428 // a profile, otherwise it wouldn't be inlined. For non-probe based profile,
429 // we can improve it by adding a switch for profile-sample-block-accurate for
430 // block level counts in the future.
431 if (!FS)
432 return 0;
433
434 auto R = FS->findSamplesAt(Probe->Id, Probe->Discriminator);
435 if (R) {
436 uint64_t Samples = R.get() * Probe->Factor;
437 bool FirstMark = CoverageTracker.markSamplesUsed(FS, Probe->Id, 0, Samples);
438 if (FirstMark) {
439 ORE->emit([&]() {
440 OptRemarkAnalysisT Remark(DEBUG_TYPE, "AppliedSamples", &Inst);
441 Remark << "Applied " << ore::NV("NumSamples", Samples);
442 Remark << " samples from profile (ProbeId=";
443 Remark << ore::NV("ProbeId", Probe->Id);
444 if (Probe->Discriminator) {
445 Remark << ".";
446 Remark << ore::NV("Discriminator", Probe->Discriminator);
447 }
448 Remark << ", Factor=";
449 Remark << ore::NV("Factor", Probe->Factor);
450 Remark << ", OriginalSamples=";
451 Remark << ore::NV("OriginalSamples", R.get());
452 Remark << ")";
453 return Remark;
454 });
455 }
456 LLVM_DEBUG({dbgs() << " " << Probe->Id;
457 if (Probe->Discriminator)
458 dbgs() << "." << Probe->Discriminator;
459 dbgs() << ":" << Inst << " - weight: " << R.get()
460 << " - factor: " << format("%0.2f", Probe->Factor) << ")\n";});
461 return Samples;
462 }
463 return R;
464}
465
466/// Compute the weight of a basic block.
467///
468/// The weight of basic block \p BB is the maximum weight of all the
469/// instructions in BB.
470///
471/// \param BB The basic block to query.
472///
473/// \returns the weight for \p BB.
474template <typename BT>
477 uint64_t Max = 0;
478 bool HasWeight = false;
479 for (auto &I : *BB) {
480 const ErrorOr<uint64_t> &R = getInstWeight(I);
481 if (R) {
482 Max = std::max(Max, R.get());
483 HasWeight = true;
484 }
485 }
486 return HasWeight ? ErrorOr<uint64_t>(Max) : std::error_code();
487}
488
489/// Compute and store the weights of every basic block.
490///
491/// This populates the BlockWeights map by computing
492/// the weights of every basic block in the CFG.
493///
494/// \param F The function to query.
495template <typename BT>
497 bool Changed = false;
498 LLVM_DEBUG(dbgs() << "Block weights\n");
499 for (const auto &BB : F) {
500 ErrorOr<uint64_t> Weight = getBlockWeight(&BB);
501 if (Weight) {
502 BlockWeights[&BB] = Weight.get();
503 VisitedBlocks.insert(&BB);
504 Changed = true;
505 }
506 LLVM_DEBUG(printBlockWeight(dbgs(), &BB));
507 }
508
509 return Changed;
510}
511
512/// Get the FunctionSamples for an instruction.
513///
514/// The FunctionSamples of an instruction \p Inst is the inlined instance
515/// in which that instruction is coming from. We traverse the inline stack
516/// of that instruction, and match it with the tree nodes in the profile.
517///
518/// \param Inst Instruction to query.
519///
520/// \returns the FunctionSamples pointer to the inlined instance.
521template <typename BT>
523 const InstructionT &Inst) const {
524 const DILocation *DIL = Inst.getDebugLoc();
525 if (!DIL)
526 return Samples;
527
528 auto it = DILocation2SampleMap.try_emplace(DIL, nullptr);
529 if (it.second) {
530 it.first->second = Samples->findFunctionSamples(DIL, Reader->getRemapper());
531 }
532 return it.first->second;
533}
534
535/// Find equivalence classes for the given block.
536///
537/// This finds all the blocks that are guaranteed to execute the same
538/// number of times as \p BB1. To do this, it traverses all the
539/// descendants of \p BB1 in the dominator or post-dominator tree.
540///
541/// A block BB2 will be in the same equivalence class as \p BB1 if
542/// the following holds:
543///
544/// 1- \p BB1 is a descendant of BB2 in the opposite tree. So, if BB2
545/// is a descendant of \p BB1 in the dominator tree, then BB2 should
546/// dominate BB1 in the post-dominator tree.
547///
548/// 2- Both BB2 and \p BB1 must be in the same loop.
549///
550/// For every block BB2 that meets those two requirements, we set BB2's
551/// equivalence class to \p BB1.
552///
553/// \param BB1 Block to check.
554/// \param Descendants Descendants of \p BB1 in either the dom or pdom tree.
555/// \param DomTree Opposite dominator tree. If \p Descendants is filled
556/// with blocks from \p BB1's dominator tree, then
557/// this is the post-dominator tree, and vice versa.
558template <typename BT>
560 BasicBlockT *BB1, ArrayRef<BasicBlockT *> Descendants,
561 PostDominatorTreeT *DomTree) {
562 const BasicBlockT *EC = EquivalenceClass[BB1];
563 uint64_t Weight = BlockWeights[EC];
564 for (const auto *BB2 : Descendants) {
565 bool IsDomParent = DomTree->dominates(BB2, BB1);
566 bool IsInSameLoop = LI->getLoopFor(BB1) == LI->getLoopFor(BB2);
567 if (BB1 != BB2 && IsDomParent && IsInSameLoop) {
568 EquivalenceClass[BB2] = EC;
569 // If BB2 is visited, then the entire EC should be marked as visited.
570 if (VisitedBlocks.count(BB2)) {
571 VisitedBlocks.insert(EC);
572 }
573
574 // If BB2 is heavier than BB1, make BB2 have the same weight
575 // as BB1.
576 //
577 // Note that we don't worry about the opposite situation here
578 // (when BB2 is lighter than BB1). We will deal with this
579 // during the propagation phase. Right now, we just want to
580 // make sure that BB1 has the largest weight of all the
581 // members of its equivalence set.
582 Weight = std::max(Weight, BlockWeights[BB2]);
583 }
584 }
585 const BasicBlockT *EntryBB = getEntryBB(EC->getParent());
586 if (EC == EntryBB) {
587 BlockWeights[EC] = Samples->getHeadSamples() + 1;
588 } else {
589 BlockWeights[EC] = Weight;
590 }
591}
592
593/// Find equivalence classes.
594///
595/// Since samples may be missing from blocks, we can fill in the gaps by setting
596/// the weights of all the blocks in the same equivalence class to the same
597/// weight. To compute the concept of equivalence, we use dominance and loop
598/// information. Two blocks B1 and B2 are in the same equivalence class if B1
599/// dominates B2, B2 post-dominates B1 and both are in the same loop.
600///
601/// \param F The function to query.
602template <typename BT>
605 LLVM_DEBUG(dbgs() << "\nBlock equivalence classes\n");
606 // Find equivalence sets based on dominance and post-dominance information.
607 for (auto &BB : F) {
608 BasicBlockT *BB1 = &BB;
609
610 // Compute BB1's equivalence class once.
611 if (EquivalenceClass.count(BB1)) {
612 LLVM_DEBUG(printBlockEquivalence(dbgs(), BB1));
613 continue;
614 }
615
616 // By default, blocks are in their own equivalence class.
617 EquivalenceClass[BB1] = BB1;
618
619 // Traverse all the blocks dominated by BB1. We are looking for
620 // every basic block BB2 such that:
621 //
622 // 1- BB1 dominates BB2.
623 // 2- BB2 post-dominates BB1.
624 // 3- BB1 and BB2 are in the same loop nest.
625 //
626 // If all those conditions hold, it means that BB2 is executed
627 // as many times as BB1, so they are placed in the same equivalence
628 // class by making BB2's equivalence class be BB1.
629 DominatedBBs.clear();
630 DT->getDescendants(BB1, DominatedBBs);
631 findEquivalencesFor(BB1, DominatedBBs, &*PDT);
632
633 LLVM_DEBUG(printBlockEquivalence(dbgs(), BB1));
634 }
635
636 // Assign weights to equivalence classes.
637 //
638 // All the basic blocks in the same equivalence class will execute
639 // the same number of times. Since we know that the head block in
640 // each equivalence class has the largest weight, assign that weight
641 // to all the blocks in that equivalence class.
643 dbgs() << "\nAssign the same weight to all blocks in the same class\n");
644 for (auto &BI : F) {
645 const BasicBlockT *BB = &BI;
646 const BasicBlockT *EquivBB = EquivalenceClass[BB];
647 if (BB != EquivBB)
648 BlockWeights[BB] = BlockWeights[EquivBB];
649 LLVM_DEBUG(printBlockWeight(dbgs(), BB));
650 }
651}
652
653/// Visit the given edge to decide if it has a valid weight.
654///
655/// If \p E has not been visited before, we copy to \p UnknownEdge
656/// and increment the count of unknown edges.
657///
658/// \param E Edge to visit.
659/// \param NumUnknownEdges Current number of unknown edges.
660/// \param UnknownEdge Set if E has not been visited before.
661///
662/// \returns E's weight, if known. Otherwise, return 0.
663template <typename BT>
665 unsigned *NumUnknownEdges,
666 Edge *UnknownEdge) {
667 if (!VisitedEdges.count(E)) {
668 (*NumUnknownEdges)++;
669 *UnknownEdge = E;
670 return 0;
671 }
672
673 return EdgeWeights[E];
674}
675
676/// Propagate weights through incoming/outgoing edges.
677///
678/// If the weight of a basic block is known, and there is only one edge
679/// with an unknown weight, we can calculate the weight of that edge.
680///
681/// Similarly, if all the edges have a known count, we can calculate the
682/// count of the basic block, if needed.
683///
684/// \param F Function to process.
685/// \param UpdateBlockCount Whether we should update basic block counts that
686/// has already been annotated.
687///
688/// \returns True if new weights were assigned to edges or blocks.
689template <typename BT>
691 FunctionT &F, bool UpdateBlockCount) {
692 bool Changed = false;
693 LLVM_DEBUG(dbgs() << "\nPropagation through edges\n");
694 for (const auto &BI : F) {
695 const BasicBlockT *BB = &BI;
696 const BasicBlockT *EC = EquivalenceClass[BB];
697
698 // Visit all the predecessor and successor edges to determine
699 // which ones have a weight assigned already. Note that it doesn't
700 // matter that we only keep track of a single unknown edge. The
701 // only case we are interested in handling is when only a single
702 // edge is unknown (see setEdgeOrBlockWeight).
703 for (unsigned i = 0; i < 2; i++) {
704 uint64_t TotalWeight = 0;
705 unsigned NumUnknownEdges = 0, NumTotalEdges = 0;
706 Edge UnknownEdge, SelfReferentialEdge, SingleEdge;
707
708 if (i == 0) {
709 // First, visit all predecessor edges.
710 NumTotalEdges = Predecessors[BB].size();
711 for (auto *Pred : Predecessors[BB]) {
712 Edge E = std::make_pair(Pred, BB);
713 TotalWeight += visitEdge(E, &NumUnknownEdges, &UnknownEdge);
714 if (E.first == E.second)
715 SelfReferentialEdge = E;
716 }
717 if (NumTotalEdges == 1) {
718 SingleEdge = std::make_pair(Predecessors[BB][0], BB);
719 }
720 } else {
721 // On the second round, visit all successor edges.
722 NumTotalEdges = Successors[BB].size();
723 for (auto *Succ : Successors[BB]) {
724 Edge E = std::make_pair(BB, Succ);
725 TotalWeight += visitEdge(E, &NumUnknownEdges, &UnknownEdge);
726 }
727 if (NumTotalEdges == 1) {
728 SingleEdge = std::make_pair(BB, Successors[BB][0]);
729 }
730 }
731
732 // After visiting all the edges, there are three cases that we
733 // can handle immediately:
734 //
735 // - All the edge weights are known (i.e., NumUnknownEdges == 0).
736 // In this case, we simply check that the sum of all the edges
737 // is the same as BB's weight. If not, we change BB's weight
738 // to match. Additionally, if BB had not been visited before,
739 // we mark it visited.
740 //
741 // - Only one edge is unknown and BB has already been visited.
742 // In this case, we can compute the weight of the edge by
743 // subtracting the total block weight from all the known
744 // edge weights. If the edges weight more than BB, then the
745 // edge of the last remaining edge is set to zero.
746 //
747 // - There exists a self-referential edge and the weight of BB is
748 // known. In this case, this edge can be based on BB's weight.
749 // We add up all the other known edges and set the weight on
750 // the self-referential edge as we did in the previous case.
751 //
752 // In any other case, we must continue iterating. Eventually,
753 // all edges will get a weight, or iteration will stop when
754 // it reaches SampleProfileMaxPropagateIterations.
755 if (NumUnknownEdges <= 1) {
756 uint64_t &BBWeight = BlockWeights[EC];
757 if (NumUnknownEdges == 0) {
758 if (!VisitedBlocks.count(EC)) {
759 // If we already know the weight of all edges, the weight of the
760 // basic block can be computed. It should be no larger than the sum
761 // of all edge weights.
762 if (TotalWeight > BBWeight) {
763 BBWeight = TotalWeight;
764 Changed = true;
765 LLVM_DEBUG(dbgs() << "All edge weights for " << BB->getName()
766 << " known. Set weight for block: ";
767 printBlockWeight(dbgs(), BB););
768 }
769 } else if (NumTotalEdges == 1 &&
770 EdgeWeights[SingleEdge] < BlockWeights[EC]) {
771 // If there is only one edge for the visited basic block, use the
772 // block weight to adjust edge weight if edge weight is smaller.
773 EdgeWeights[SingleEdge] = BlockWeights[EC];
774 Changed = true;
775 }
776 } else if (NumUnknownEdges == 1 && VisitedBlocks.count(EC)) {
777 // If there is a single unknown edge and the block has been
778 // visited, then we can compute E's weight.
779 if (BBWeight >= TotalWeight)
780 EdgeWeights[UnknownEdge] = BBWeight - TotalWeight;
781 else
782 EdgeWeights[UnknownEdge] = 0;
783 const BasicBlockT *OtherEC;
784 if (i == 0)
785 OtherEC = EquivalenceClass[UnknownEdge.first];
786 else
787 OtherEC = EquivalenceClass[UnknownEdge.second];
788 // Edge weights should never exceed the BB weights it connects.
789 if (VisitedBlocks.count(OtherEC) &&
790 EdgeWeights[UnknownEdge] > BlockWeights[OtherEC])
791 EdgeWeights[UnknownEdge] = BlockWeights[OtherEC];
792 VisitedEdges.insert(UnknownEdge);
793 Changed = true;
794 LLVM_DEBUG(dbgs() << "Set weight for edge: ";
795 printEdgeWeight(dbgs(), UnknownEdge));
796 }
797 } else if (VisitedBlocks.count(EC) && BlockWeights[EC] == 0) {
798 // If a block Weights 0, all its in/out edges should weight 0.
799 if (i == 0) {
800 for (auto *Pred : Predecessors[BB]) {
801 Edge E = std::make_pair(Pred, BB);
802 EdgeWeights[E] = 0;
803 VisitedEdges.insert(E);
804 }
805 } else {
806 for (auto *Succ : Successors[BB]) {
807 Edge E = std::make_pair(BB, Succ);
808 EdgeWeights[E] = 0;
809 VisitedEdges.insert(E);
810 }
811 }
812 } else if (SelfReferentialEdge.first && VisitedBlocks.count(EC)) {
813 uint64_t &BBWeight = BlockWeights[BB];
814 // We have a self-referential edge and the weight of BB is known.
815 if (BBWeight >= TotalWeight)
816 EdgeWeights[SelfReferentialEdge] = BBWeight - TotalWeight;
817 else
818 EdgeWeights[SelfReferentialEdge] = 0;
819 VisitedEdges.insert(SelfReferentialEdge);
820 Changed = true;
821 LLVM_DEBUG(dbgs() << "Set self-referential edge weight to: ";
822 printEdgeWeight(dbgs(), SelfReferentialEdge));
823 }
824 if (UpdateBlockCount && !VisitedBlocks.count(EC) && TotalWeight > 0) {
825 BlockWeights[EC] = TotalWeight;
826 VisitedBlocks.insert(EC);
827 Changed = true;
828 }
829 }
830 }
831
832 return Changed;
833}
834
835/// Build in/out edge lists for each basic block in the CFG.
836///
837/// We are interested in unique edges. If a block B1 has multiple
838/// edges to another block B2, we only add a single B1->B2 edge.
839template <typename BT>
841 for (auto &BI : F) {
842 BasicBlockT *B1 = &BI;
843
844 // Add predecessors for B1.
846 if (!Predecessors[B1].empty())
847 llvm_unreachable("Found a stale predecessors list in a basic block.");
848 for (auto *B2 : getPredecessors(B1))
849 if (Visited.insert(B2).second)
850 Predecessors[B1].push_back(B2);
851
852 // Add successors for B1.
853 Visited.clear();
854 if (!Successors[B1].empty())
855 llvm_unreachable("Found a stale successors list in a basic block.");
856 for (auto *B2 : getSuccessors(B1))
857 if (Visited.insert(B2).second)
858 Successors[B1].push_back(B2);
859 }
860}
861
862/// Propagate weights into edges
863///
864/// The following rules are applied to every block BB in the CFG:
865///
866/// - If BB has a single predecessor/successor, then the weight
867/// of that edge is the weight of the block.
868///
869/// - If all incoming or outgoing edges are known except one, and the
870/// weight of the block is already known, the weight of the unknown
871/// edge will be the weight of the block minus the sum of all the known
872/// edges. If the sum of all the known edges is larger than BB's weight,
873/// we set the unknown edge weight to zero.
874///
875/// - If there is a self-referential edge, and the weight of the block is
876/// known, the weight for that edge is set to the weight of the block
877/// minus the weight of the other incoming edges to that block (if
878/// known).
879template <typename BT>
881 // Flow-based profile inference is only usable with BasicBlock instantiation
882 // of SampleProfileLoaderBaseImpl.
884 // Prepare block sample counts for inference.
885 BlockWeightMap SampleBlockWeights;
886 for (const auto &BI : F) {
887 ErrorOr<uint64_t> Weight = getBlockWeight(&BI);
888 if (Weight)
889 SampleBlockWeights[&BI] = Weight.get();
890 }
891 // Fill in BlockWeights and EdgeWeights using an inference algorithm.
892 applyProfi(F, Successors, SampleBlockWeights, BlockWeights, EdgeWeights);
893 } else {
894 bool Changed = true;
895 unsigned I = 0;
896
897 // If BB weight is larger than its corresponding loop's header BB weight,
898 // use the BB weight to replace the loop header BB weight.
899 for (auto &BI : F) {
900 BasicBlockT *BB = &BI;
901 LoopT *L = LI->getLoopFor(BB);
902 if (!L) {
903 continue;
904 }
905 BasicBlockT *Header = L->getHeader();
906 if (Header && BlockWeights[BB] > BlockWeights[Header]) {
907 BlockWeights[Header] = BlockWeights[BB];
908 }
909 }
910
911 // Propagate until we converge or we go past the iteration limit.
912 while (Changed && I++ < SampleProfileMaxPropagateIterations) {
913 Changed = propagateThroughEdges(F, false);
914 }
915
916 // The first propagation propagates BB counts from annotated BBs to unknown
917 // BBs. The 2nd propagation pass resets edges weights, and use all BB
918 // weights to propagate edge weights.
919 VisitedEdges.clear();
920 Changed = true;
921 while (Changed && I++ < SampleProfileMaxPropagateIterations) {
922 Changed = propagateThroughEdges(F, false);
923 }
924
925 // The 3rd propagation pass allows adjust annotated BB weights that are
926 // obviously wrong.
927 Changed = true;
928 while (Changed && I++ < SampleProfileMaxPropagateIterations) {
929 Changed = propagateThroughEdges(F, true);
930 }
931 }
932}
933
934template <typename FT>
936 FunctionT &F, BlockEdgeMap &Successors, BlockWeightMap &SampleBlockWeights,
937 BlockWeightMap &BlockWeights, EdgeWeightMap &EdgeWeights) {
938 auto Infer = SampleProfileInference<FT>(F, Successors, SampleBlockWeights);
939 Infer.apply(BlockWeights, EdgeWeights);
940}
941
942/// Generate branch weight metadata for all branches in \p F.
943///
944/// Branch weights are computed out of instruction samples using a
945/// propagation heuristic. Propagation proceeds in 3 phases:
946///
947/// 1- Assignment of block weights. All the basic blocks in the function
948/// are initial assigned the same weight as their most frequently
949/// executed instruction.
950///
951/// 2- Creation of equivalence classes. Since samples may be missing from
952/// blocks, we can fill in the gaps by setting the weights of all the
953/// blocks in the same equivalence class to the same weight. To compute
954/// the concept of equivalence, we use dominance and loop information.
955/// Two blocks B1 and B2 are in the same equivalence class if B1
956/// dominates B2, B2 post-dominates B1 and both are in the same loop.
957///
958/// 3- Propagation of block weights into edges. This uses a simple
959/// propagation heuristic. The following rules are applied to every
960/// block BB in the CFG:
961///
962/// - If BB has a single predecessor/successor, then the weight
963/// of that edge is the weight of the block.
964///
965/// - If all the edges are known except one, and the weight of the
966/// block is already known, the weight of the unknown edge will
967/// be the weight of the block minus the sum of all the known
968/// edges. If the sum of all the known edges is larger than BB's weight,
969/// we set the unknown edge weight to zero.
970///
971/// - If there is a self-referential edge, and the weight of the block is
972/// known, the weight for that edge is set to the weight of the block
973/// minus the weight of the other incoming edges to that block (if
974/// known).
975///
976/// Since this propagation is not guaranteed to finalize for every CFG, we
977/// only allow it to proceed for a limited number of iterations (controlled
978/// by -sample-profile-max-propagate-iterations).
979///
980/// FIXME: Try to replace this propagation heuristic with a scheme
981/// that is guaranteed to finalize. A work-list approach similar to
982/// the standard value propagation algorithm used by SSA-CCP might
983/// work here.
984///
985/// \param F The function to query.
986///
987/// \returns true if \p F was modified. Returns false, otherwise.
988template <typename BT>
990 FunctionT &F, const DenseSet<GlobalValue::GUID> &InlinedGUIDs) {
991 bool Changed = (InlinedGUIDs.size() != 0);
992
993 // Compute basic block weights.
994 Changed |= computeBlockWeights(F);
995
996 if (Changed) {
997 // Initialize propagation.
998 initWeightPropagation(F, InlinedGUIDs);
999
1000 // Propagate weights to all edges.
1001 propagateWeights(F);
1002
1003 // Post-process propagated weights.
1004 finalizeWeightPropagation(F, InlinedGUIDs);
1005 }
1006
1007 return Changed;
1008}
1009
1010template <typename BT>
1012 FunctionT &F, const DenseSet<GlobalValue::GUID> &InlinedGUIDs) {
1013 // Add an entry count to the function using the samples gathered at the
1014 // function entry.
1015 // Sets the GUIDs that are inlined in the profiled binary. This is used
1016 // for ThinLink to make correct liveness analysis, and also make the IR
1017 // match the profiled binary before annotation.
1019 ProfileCount(Samples->getHeadSamples() + 1, Function::PCT_Real),
1020 &InlinedGUIDs);
1021
1022 if (!SampleProfileUseProfi) {
1023 // Compute dominance and loop info needed for propagation.
1024 computeDominanceAndLoopInfo(F);
1025
1026 // Find equivalence classes.
1027 findEquivalenceClasses(F);
1028 }
1029
1030 // Before propagation starts, build, for each block, a list of
1031 // unique predecessors and successors. This is necessary to handle
1032 // identical edges in multiway branches. Since we visit all blocks and all
1033 // edges of the CFG, it is cleaner to build these lists once at the start
1034 // of the pass.
1035 buildEdges(F);
1036}
1037
1038template <typename BT>
1040 FunctionT &F, const DenseSet<GlobalValue::GUID> &InlinedGUIDs) {
1041 // If we utilize a flow-based count inference, then we trust the computed
1042 // counts and set the entry count as computed by the algorithm. This is
1043 // primarily done to sync the counts produced by profi and BFI inference,
1044 // which uses the entry count for mass propagation.
1045 // If profi produces a zero-value for the entry count, we fallback to
1046 // Samples->getHeadSamples() + 1 to avoid functions with zero count.
1048 const BasicBlockT *EntryBB = getEntryBB(&F);
1049 ErrorOr<uint64_t> EntryWeight = getBlockWeight(EntryBB);
1050 if (BlockWeights[EntryBB] > 0) {
1052 ProfileCount(BlockWeights[EntryBB], Function::PCT_Real),
1053 &InlinedGUIDs);
1054 }
1055 }
1056}
1057
1058template <typename BT>
1060 // If coverage checking was requested, compute it now.
1061 const Function &Func = getFunction(F);
1063 unsigned Used = CoverageTracker.countUsedRecords(Samples, PSI);
1064 unsigned Total = CoverageTracker.countBodyRecords(Samples, PSI);
1065 unsigned Coverage = CoverageTracker.computeCoverage(Used, Total);
1066 if (Coverage < SampleProfileRecordCoverage) {
1067 Func.getContext().diagnose(DiagnosticInfoSampleProfile(
1068 Func.getSubprogram()->getFilename(), getFunctionLoc(F),
1069 Twine(Used) + " of " + Twine(Total) + " available profile records (" +
1070 Twine(Coverage) + "%) were applied",
1071 DS_Warning));
1072 }
1073 }
1074
1076 uint64_t Used = CoverageTracker.getTotalUsedSamples();
1077 uint64_t Total = CoverageTracker.countBodySamples(Samples, PSI);
1078 unsigned Coverage = CoverageTracker.computeCoverage(Used, Total);
1079 if (Coverage < SampleProfileSampleCoverage) {
1080 Func.getContext().diagnose(DiagnosticInfoSampleProfile(
1081 Func.getSubprogram()->getFilename(), getFunctionLoc(F),
1082 Twine(Used) + " of " + Twine(Total) + " available profile samples (" +
1083 Twine(Coverage) + "%) were applied",
1084 DS_Warning));
1085 }
1086 }
1087}
1088
1089/// Get the line number for the function header.
1090///
1091/// This looks up function \p F in the current compilation unit and
1092/// retrieves the line number where the function is defined. This is
1093/// line 0 for all the samples read from the profile file. Every line
1094/// number is relative to this line.
1095///
1096/// \param F Function object to query.
1097///
1098/// \returns the line number where \p F is defined. If it returns 0,
1099/// it means that there is no debug information available for \p F.
1100template <typename BT>
1102 const Function &Func = getFunction(F);
1103 if (DISubprogram *S = Func.getSubprogram())
1104 return S->getLine();
1105
1107 return 0;
1108
1109 // If the start of \p F is missing, emit a diagnostic to inform the user
1110 // about the missed opportunity.
1111 Func.getContext().diagnose(DiagnosticInfoSampleProfile(
1112 "No debug information found in function " + Func.getName() +
1113 ": Function profile not used",
1114 DS_Warning));
1115 return 0;
1116}
1117
1118#undef DEBUG_TYPE
1119
1120} // namespace llvm
1121#endif // LLVM_TRANSFORMS_UTILS_SAMPLEPROFILELOADERBASEIMPL_H
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_DEBUG(X)
Definition: Debug.h:101
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
std::string Name
static Function * getFunction(Constant *C)
Definition: Evaluator.cpp:236
#define DEBUG_TYPE
This file defines a set of templates that efficiently compute a dominator tree over a generic graph.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
This file defines the RefCountedBase, ThreadSafeRefCountedBase, and IntrusiveRefCntPtr classes.
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
typename CallsiteContextGraph< DerivedCCG, FuncTy, CallTy >::FuncInfo FuncInfo
Module.h This file contains the declarations for the Module class.
static StringRef getName(Value *V)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file provides the interface for the profile inference algorithm, profi.
This file provides the utility functions for the sampled PGO loader base implementation.
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
LLVM Basic Block Representation.
Definition: BasicBlock.h:56
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Debug location.
unsigned getBaseDiscriminator() const
Returns the base discriminator stored in the discriminator.
Subprogram description.
A debug info location.
Definition: DebugLoc.h:33
unsigned getLine() const
Definition: DebugLoc.cpp:24
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:155
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&... Args)
Definition: DenseMap.h:235
iterator end()
Definition: DenseMap.h:84
Implements a dense probed hash-table based set.
Definition: DenseSet.h:271
Diagnostic information for the sample profiler.
Represents either an error or a value T.
Definition: ErrorOr.h:56
reference get()
Definition: ErrorOr.h:149
Class to represent profile counts.
Definition: Function.h:252
void setEntryCount(ProfileCount Count, const DenseSet< GlobalValue::GUID > *Imports=nullptr)
Set the entry count for this function.
Definition: Function.cpp:2025
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
Definition: GlobalValue.h:591
A smart pointer to a reference-counted object that inherits from RefCountedBase or ThreadSafeRefCount...
Represents a single loop in the control flow graph.
Definition: LoopInfo.h:47
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
A tuple of MDNodes.
Definition: Metadata.h:1604
Diagnostic information for optimization analysis remarks.
The optimization diagnostic interface.
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
Analysis providing profile information.
bool moduleIsProbed(const Module &M) const
bool profileIsValid(const Function &F, const FunctionSamples &Samples) const
Sample profile inference pass.
typename std::remove_pointer< NodeRef >::type BT
bool computeAndPropagateWeights(FunctionT &F, const DenseSet< GlobalValue::GUID > &InlinedGUIDs)
Generate branch weight metadata for all branches in F.
void computeDominanceAndLoopInfo(FunctionT &F)
typename afdo_detail::IRTraits< BT >::BasicBlockT BasicBlockT
IntrusiveRefCntPtr< vfs::FileSystem > FS
VirtualFileSystem to load profile files from.
typename afdo_detail::IRTraits< BT >::OptRemarkAnalysisT OptRemarkAnalysisT
typename afdo_detail::IRTraits< BT >::SuccRangeT SuccRangeT
EdgeWeightMap EdgeWeights
Map edges to their computed weights.
SmallSet< Edge, 32 > VisitedEdges
Set of visited edges during propagation.
OptRemarkEmitterT * ORE
Optimization Remark Emitter used to emit diagnostic remarks.
const BasicBlockT * getEntryBB(const FunctionT *F)
ErrorOr< uint64_t > getBlockWeight(const BasicBlockT *BB)
Compute the weight of a basic block.
unsigned getFunctionLoc(FunctionT &Func)
Get the line number for the function header.
ErrorOr< uint64_t > getInstWeightImpl(const InstructionT &Inst)
virtual ErrorOr< uint64_t > getInstWeight(const InstructionT &Inst)
Get the weight for an instruction.
SmallPtrSet< const BasicBlockT *, 32 > VisitedBlocks
Set of visited blocks during propagation.
EquivalenceClassMap EquivalenceClass
Equivalence classes for block weights.
typename afdo_detail::IRTraits< BT >::DominatorTreePtrT DominatorTreePtrT
SampleCoverageTracker CoverageTracker
Profile coverage tracker.
typename afdo_detail::IRTraits< BT >::LoopT LoopT
typename GraphTraits< FT * >::NodeRef NodeRef
std::unique_ptr< SampleProfileReader > Reader
Profile reader object.
typename afdo_detail::IRTraits< BT >::OptRemarkEmitterT OptRemarkEmitterT
void printBlockWeight(raw_ostream &OS, const BasicBlockT *BB) const
Print the weight of block BB on stream OS.
DominatorTreePtrT DT
Dominance, post-dominance and loop information.
void printBlockEquivalence(raw_ostream &OS, const BasicBlockT *BB)
Print the equivalence class of block BB on stream OS.
SampleProfileLoaderBaseImpl(std::string Name, std::string RemapName, IntrusiveRefCntPtr< vfs::FileSystem > FS)
std::unique_ptr< PseudoProbeManager > ProbeManager
typename afdo_detail::IRTraits< BT >::LoopInfoPtrT LoopInfoPtrT
std::string Filename
Name of the profile file to load.
bool propagateThroughEdges(FunctionT &F, bool UpdateBlockCount)
Propagate weights through incoming/outgoing edges.
typename afdo_detail::IRTraits< BT >::InstructionT InstructionT
uint64_t visitEdge(Edge E, unsigned *NumUnknownEdges, Edge *UnknownEdge)
Visit the given edge to decide if it has a valid weight.
typename afdo_detail::IRTraits< BT >::PostDominatorTreePtrT PostDominatorTreePtrT
void initWeightPropagation(FunctionT &F, const DenseSet< GlobalValue::GUID > &InlinedGUIDs)
BlockEdgeMap Predecessors
Predecessors for each basic block in the CFG.
void finalizeWeightPropagation(FunctionT &F, const DenseSet< GlobalValue::GUID > &InlinedGUIDs)
bool computeBlockWeights(FunctionT &F)
Compute and store the weights of every basic block.
virtual const FunctionSamples * findFunctionSamples(const InstructionT &I) const
Get the FunctionSamples for an instruction.
typename afdo_detail::IRTraits< BT >::PostDominatorTreeT PostDominatorTreeT
virtual ErrorOr< uint64_t > getProbeWeight(const InstructionT &Inst)
std::string RemappingFilename
Name of the profile remapping file to load.
typename afdo_detail::IRTraits< BT >::PredRangeT PredRangeT
void applyProfi(FunctionT &F, BlockEdgeMap &Successors, BlockWeightMap &SampleBlockWeights, BlockWeightMap &BlockWeights, EdgeWeightMap &EdgeWeights)
typename afdo_detail::IRTraits< BT >::BlockFrequencyInfoT BlockFrequencyInfoT
BlockEdgeMap Successors
Successors for each basic block in the CFG.
FunctionSamples * Samples
Samples collected for the body of this function.
void findEquivalenceClasses(FunctionT &F)
Find equivalence classes.
std::pair< const BasicBlockT *, const BasicBlockT * > Edge
ProfileSummaryInfo * PSI
Profile Summary Info computed from sample profile.
void clearFunctionData(bool ResetDT=true)
Clear all the per-function data used to load samples and propagate weights.
DenseMap< const DILocation *, const FunctionSamples * > DILocation2SampleMap
void buildEdges(FunctionT &F)
Build in/out edge lists for each basic block in the CFG.
void findEquivalencesFor(BasicBlockT *BB1, ArrayRef< BasicBlockT * > Descendants, PostDominatorTreeT *DomTree)
Find equivalence classes for the given block.
void printEdgeWeight(raw_ostream &OS, Edge E)
Print the weight of edge E on stream OS.
typename afdo_detail::IRTraits< BT >::FunctionT FunctionT
BlockWeightMap BlockWeights
Map basic blocks to their computed weights.
void propagateWeights(FunctionT &F)
Propagate weights into edges.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:365
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:450
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:135
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
size_type size() const
Definition: DenseSet.h:81
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:52
Representation of the samples collected for a function.
Definition: SampleProf.h:734
static StringRef getCanonicalFnName(const Function &F)
Return the canonical name for a function, taking into account suffix elision policy attributes.
Definition: SampleProf.h:1066
static unsigned getOffset(const DILocation *DIL)
Returns the line offset to the start line of the subprogram.
Definition: SampleProf.cpp:216
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
Function::ProfileCount ProfileCount
auto successors(const MachineBasicBlock *BB)
cl::opt< unsigned > SampleProfileSampleCoverage
cl::opt< unsigned > SampleProfileRecordCoverage
cl::opt< unsigned > SampleProfileMaxPropagateIterations
cl::opt< bool > SampleProfileUseProfi
cl::opt< bool > EnableFSDiscriminator
std::optional< PseudoProbe > extractProbe(const Instruction &Inst)
Definition: PseudoProbe.cpp:56
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
iterator_range< succ_iterator > succ_range
Definition: CFG.h:244
cl::opt< bool > NoWarnSampleUnused
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
iterator_range< pred_iterator > pred_range
Definition: CFG.h:107
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:1946
@ DS_Warning
auto predecessors(const MachineBasicBlock *BB)
constexpr const char * PseudoProbeDescMetadataName
Definition: PseudoProbe.h:26
Definition: BitVector.h:858
typename GraphType::UnknownGraphTypeError NodeRef
Definition: GraphTraits.h:80
std::unique_ptr< PostDominatorTree > PostDominatorTreePtrT
static pred_range getPredecessors(BasicBlock *BB)
static succ_range getSuccessors(BasicBlock *BB)
std::unique_ptr< DominatorTree > DominatorTreePtrT
static const BasicBlock * getEntryBB(const Function *F)