LLVM 22.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"
29#include "llvm/IR/BasicBlock.h"
30#include "llvm/IR/CFG.h"
32#include "llvm/IR/DebugLoc.h"
33#include "llvm/IR/Dominators.h"
34#include "llvm/IR/Function.h"
35#include "llvm/IR/Instruction.h"
37#include "llvm/IR/Module.h"
38#include "llvm/IR/PseudoProbe.h"
46
47namespace llvm {
48using namespace sampleprof;
49using namespace sampleprofutil;
51
52namespace vfs {
53class FileSystem;
54} // namespace vfs
55
56#define DEBUG_TYPE "sample-profile-impl"
57
58namespace afdo_detail {
59
60template <typename BlockT> struct IRTraits;
61template <> struct IRTraits<BasicBlock> {
66 using LoopT = Loop;
67 using LoopInfoPtrT = std::unique_ptr<LoopInfo>;
68 using DominatorTreePtrT = std::unique_ptr<DominatorTree>;
70 using PostDominatorTreePtrT = std::unique_ptr<PostDominatorTree>;
75 static Function &getFunction(Function &F) { return F; }
76 static const BasicBlock *getEntryBB(const Function *F) {
77 return &F->getEntryBlock();
78 }
80 static succ_range getSuccessors(BasicBlock *BB) { return successors(BB); }
81};
82
83} // end namespace afdo_detail
84
85// This class serves sample counts correlation for SampleProfileLoader by
86// analyzing pseudo probes and their function descriptors injected by
87// SampleProfileProber.
90
91public:
93 if (NamedMDNode *FuncInfo =
94 M.getNamedMetadata(PseudoProbeDescMetadataName)) {
95 for (const auto *Operand : FuncInfo->operands()) {
96 const auto *MD = cast<MDNode>(Operand);
97 auto GUID = mdconst::dyn_extract<ConstantInt>(MD->getOperand(0))
98 ->getZExtValue();
99 auto Hash = mdconst::dyn_extract<ConstantInt>(MD->getOperand(1))
100 ->getZExtValue();
101 GUIDToProbeDescMap.try_emplace(GUID, PseudoProbeDescriptor(GUID, Hash));
102 }
103 }
104 }
105
107 auto I = GUIDToProbeDescMap.find(GUID);
108 return I == GUIDToProbeDescMap.end() ? nullptr : &I->second;
109 }
110
111 const PseudoProbeDescriptor *getDesc(StringRef FProfileName) const {
113 }
114
118 }
119
121 const FunctionSamples &Samples) const {
122 return FuncDesc.getFunctionHash() != Samples.getFunctionHash();
123 }
124
125 bool moduleIsProbed(const Module &M) const {
126 return M.getNamedMetadata(PseudoProbeDescMetadataName);
127 }
128
129 bool profileIsValid(const Function &F, const FunctionSamples &Samples) const {
130 const auto *Desc = getDesc(F);
131 bool IsAvailableExternallyLinkage =
133 // Always check the function attribute to determine checksum mismatch for
134 // `available_externally` functions even if their desc are available. This
135 // is because the desc is computed based on the original internal function
136 // and it's substituted by the `available_externally` function during link
137 // time. However, when unstable IR or ODR violation issue occurs, the
138 // definitions of the same function across different translation units could
139 // be different and result in different checksums. So we should use the
140 // state from the new (available_externally) function, which is saved in its
141 // attribute.
142 // TODO: If the function's profile only exists as nested inlinee profile in
143 // a different module, we don't have the attr mismatch state(unknown), we
144 // need to fix it later.
145 if (IsAvailableExternallyLinkage || !Desc)
146 return !F.hasFnAttribute("profile-checksum-mismatch");
147
148 return Desc && !profileIsHashMismatched(*Desc, Samples);
149 }
150};
151
152
153
155
156static inline bool skipProfileForFunction(const Function &F) {
157 return F.isDeclaration() || !F.hasFnAttribute("use-sample-profile");
158}
159
160static inline void
162 std::vector<Function *> &FunctionOrderList) {
163 CG.buildRefSCCs();
165 for (LazyCallGraph::SCC &C : RC) {
166 for (LazyCallGraph::Node &N : C) {
167 Function &F = N.getFunction();
169 FunctionOrderList.push_back(&F);
170 }
171 }
172 }
173 std::reverse(FunctionOrderList.begin(), FunctionOrderList.end());
174}
175
176template <typename FT> class SampleProfileLoaderBaseImpl {
177public:
178 SampleProfileLoaderBaseImpl(std::string Name, std::string RemapName,
180 : Filename(Name), RemappingFilename(RemapName), FS(std::move(FS)) {}
181 void dump() { Reader->dump(); }
182
184 using BT = std::remove_pointer_t<NodeRef>;
204
208 using Edge = std::pair<const BasicBlockT *, const BasicBlockT *>;
212
213protected:
216
219 }
222 }
225 }
228 }
229
230 unsigned getFunctionLoc(FunctionT &Func);
237 virtual const FunctionSamples *
245 ArrayRef<BasicBlockT *> Descendants,
246 PostDominatorTreeT *DomTree);
249 BlockWeightMap &SampleBlockWeights,
251 uint64_t visitEdge(Edge E, unsigned *NumUnknownEdges, Edge *UnknownEdge);
253 bool propagateThroughEdges(FunctionT &F, bool UpdateBlockCount);
254 void clearFunctionData(bool ResetDT = true);
256 bool
258 const DenseSet<GlobalValue::GUID> &InlinedGUIDs);
260 const DenseSet<GlobalValue::GUID> &InlinedGUIDs);
261 void
263 const DenseSet<GlobalValue::GUID> &InlinedGUIDs);
265
266 /// Map basic blocks to their computed weights.
267 ///
268 /// The weight of a basic block is defined to be the maximum
269 /// of all the instruction weights in that block.
271
272 /// Map edges to their computed weights.
273 ///
274 /// Edge weights are computed by propagating basic block weights in
275 /// SampleProfile::propagateWeights.
277
278 /// Set of visited blocks during propagation.
280
281 /// Set of visited edges during propagation.
283
284 /// Equivalence classes for block weights.
285 ///
286 /// Two blocks BB1 and BB2 are in the same equivalence class if they
287 /// dominate and post-dominate each other, and they are in the same loop
288 /// nest. When this happens, the two blocks are guaranteed to execute
289 /// the same number of times.
291
292 /// Dominance, post-dominance and loop information.
296
297 /// Predecessors for each basic block in the CFG.
299
300 /// Successors for each basic block in the CFG.
302
303 /// Profile coverage tracker.
305
306 /// Profile reader object.
307 std::unique_ptr<SampleProfileReader> Reader;
308
309 /// Synthetic samples created by duplicating the samples of inlined functions
310 /// from the original profile as if they were top level sample profiles.
311 /// Use std::map because insertion may happen while its content is referenced.
312 std::map<SampleContext, FunctionSamples> OutlineFunctionSamples;
313
314 // A pseudo probe helper to correlate the imported sample counts.
315 std::unique_ptr<PseudoProbeManager> ProbeManager;
316
317 /// Samples collected for the body of this function.
319
320 /// Name of the profile file to load.
321 std::string Filename;
322
323 /// Name of the profile remapping file to load.
324 std::string RemappingFilename;
325
326 /// VirtualFileSystem to load profile files from.
328
329 /// Profile Summary Info computed from sample profile.
331
332 /// Optimization Remark Emitter used to emit diagnostic remarks.
334};
335
336/// Clear all the per-function data used to load samples and propagate weights.
337template <typename BT>
339 BlockWeights.clear();
340 EdgeWeights.clear();
341 VisitedBlocks.clear();
342 VisitedEdges.clear();
343 EquivalenceClass.clear();
344 if (ResetDT) {
345 DT = nullptr;
346 PDT = nullptr;
347 LI = nullptr;
348 }
349 Predecessors.clear();
350 Successors.clear();
351 CoverageTracker.clear();
352}
353
354#ifndef NDEBUG
355/// Print the weight of edge \p E on stream \p OS.
356///
357/// \param OS Stream to emit the output to.
358/// \param E Edge to print.
359template <typename BT>
361 OS << "weight[" << E.first->getName() << "->" << E.second->getName()
362 << "]: " << EdgeWeights[E] << "\n";
363}
364
365/// Print the equivalence class of block \p BB on stream \p OS.
366///
367/// \param OS Stream to emit the output to.
368/// \param BB Block to print.
369template <typename BT>
371 raw_ostream &OS, const BasicBlockT *BB) {
372 const BasicBlockT *Equiv = EquivalenceClass[BB];
373 OS << "equivalence[" << BB->getName()
374 << "]: " << ((Equiv) ? EquivalenceClass[BB]->getName() : "NONE") << "\n";
375}
376
377/// Print the weight of block \p BB on stream \p OS.
378///
379/// \param OS Stream to emit the output to.
380/// \param BB Block to print.
381template <typename BT>
383 raw_ostream &OS, const BasicBlockT *BB) const {
384 const auto &I = BlockWeights.find(BB);
385 uint64_t W = (I == BlockWeights.end() ? 0 : I->second);
386 OS << "weight[" << BB->getName() << "]: " << W << "\n";
387}
388#endif
389
390/// Get the weight for an instruction.
391///
392/// The "weight" of an instruction \p Inst is the number of samples
393/// collected on that instruction at runtime. To retrieve it, we
394/// need to compute the line number of \p Inst relative to the start of its
395/// function. We use HeaderLineno to compute the offset. We then
396/// look up the samples collected for \p Inst using BodySamples.
397///
398/// \param Inst Instruction to query.
399///
400/// \returns the weight of \p Inst.
401template <typename BT>
405 return getProbeWeight(Inst);
406 return getInstWeightImpl(Inst);
407}
408
409template <typename BT>
412 const FunctionSamples *FS = findFunctionSamples(Inst);
413 if (!FS)
414 return std::error_code();
415
416 const DebugLoc &DLoc = Inst.getDebugLoc();
417 if (!DLoc)
418 return std::error_code();
419
420 const DILocation *DIL = DLoc;
421 uint32_t LineOffset = FunctionSamples::getOffset(DIL);
422 uint32_t Discriminator;
424 Discriminator = DIL->getDiscriminator();
425 else
426 Discriminator = DIL->getBaseDiscriminator();
427
428 ErrorOr<uint64_t> R = FS->findSamplesAt(LineOffset, Discriminator);
429 if (R) {
430 bool FirstMark =
431 CoverageTracker.markSamplesUsed(FS, LineOffset, Discriminator, R.get());
432 if (FirstMark) {
433 ORE->emit([&]() {
434 OptRemarkAnalysisT Remark(DEBUG_TYPE, "AppliedSamples", &Inst);
435 Remark << "Applied " << ore::NV("NumSamples", *R);
436 Remark << " samples from profile (offset: ";
437 Remark << ore::NV("LineOffset", LineOffset);
438 if (Discriminator) {
439 Remark << ".";
440 Remark << ore::NV("Discriminator", Discriminator);
441 }
442 Remark << ")";
443 return Remark;
444 });
445 }
446 LLVM_DEBUG(dbgs() << " " << DLoc.getLine() << "." << Discriminator << ":"
447 << Inst << " (line offset: " << LineOffset << "."
448 << Discriminator << " - weight: " << R.get() << ")\n");
449 }
450 return R;
451}
452
453template <typename BT>
457 "Profile is not pseudo probe based");
458 std::optional<PseudoProbe> Probe = extractProbe(Inst);
459 // Ignore the non-probe instruction. If none of the instruction in the BB is
460 // probe, we choose to infer the BB's weight.
461 if (!Probe)
462 return std::error_code();
463
464 const FunctionSamples *FS = findFunctionSamples(Inst);
465 if (!FS) {
466 // If we can't find the function samples for a probe, it could be due to the
467 // probe is later optimized away or the inlining context is mismatced. We
468 // treat it as unknown, leaving it to profile inference instead of forcing a
469 // zero count.
470 return std::error_code();
471 }
472
473 auto R = FS->findSamplesAt(Probe->Id, Probe->Discriminator);
474 if (R) {
475 uint64_t Samples = R.get() * Probe->Factor;
476 bool FirstMark = CoverageTracker.markSamplesUsed(FS, Probe->Id, 0, Samples);
477 if (FirstMark) {
478 ORE->emit([&]() {
479 OptRemarkAnalysisT Remark(DEBUG_TYPE, "AppliedSamples", &Inst);
480 Remark << "Applied " << ore::NV("NumSamples", Samples);
481 Remark << " samples from profile (ProbeId=";
482 Remark << ore::NV("ProbeId", Probe->Id);
483 if (Probe->Discriminator) {
484 Remark << ".";
485 Remark << ore::NV("Discriminator", Probe->Discriminator);
486 }
487 Remark << ", Factor=";
488 Remark << ore::NV("Factor", Probe->Factor);
489 Remark << ", OriginalSamples=";
490 Remark << ore::NV("OriginalSamples", R.get());
491 Remark << ")";
492 return Remark;
493 });
494 }
495 LLVM_DEBUG({dbgs() << " " << Probe->Id;
496 if (Probe->Discriminator)
497 dbgs() << "." << Probe->Discriminator;
498 dbgs() << ":" << Inst << " - weight: " << R.get()
499 << " - factor: " << format("%0.2f", Probe->Factor) << ")\n";});
500 return Samples;
501 }
502 return R;
503}
504
505/// Compute the weight of a basic block.
506///
507/// The weight of basic block \p BB is the maximum weight of all the
508/// instructions in BB.
509///
510/// \param BB The basic block to query.
511///
512/// \returns the weight for \p BB.
513template <typename BT>
516 uint64_t Max = 0;
517 bool HasWeight = false;
518 for (auto &I : *BB) {
519 const ErrorOr<uint64_t> &R = getInstWeight(I);
520 if (R) {
521 Max = std::max(Max, R.get());
522 HasWeight = true;
523 }
524 }
525 return HasWeight ? ErrorOr<uint64_t>(Max) : std::error_code();
526}
527
528/// Compute and store the weights of every basic block.
529///
530/// This populates the BlockWeights map by computing
531/// the weights of every basic block in the CFG.
532///
533/// \param F The function to query.
534template <typename BT>
536 bool Changed = false;
537 LLVM_DEBUG(dbgs() << "Block weights\n");
538 for (const auto &BB : F) {
539 ErrorOr<uint64_t> Weight = getBlockWeight(&BB);
540 if (Weight) {
541 BlockWeights[&BB] = Weight.get();
542 VisitedBlocks.insert(&BB);
543 Changed = true;
544 }
545 LLVM_DEBUG(printBlockWeight(dbgs(), &BB));
546 }
547
548 return Changed;
549}
550
551/// Get the FunctionSamples for an instruction.
552///
553/// The FunctionSamples of an instruction \p Inst is the inlined instance
554/// in which that instruction is coming from. We traverse the inline stack
555/// of that instruction, and match it with the tree nodes in the profile.
556///
557/// \param Inst Instruction to query.
558///
559/// \returns the FunctionSamples pointer to the inlined instance.
560template <typename BT>
562 const InstructionT &Inst) const {
563 const DILocation *DIL = Inst.getDebugLoc();
564 if (!DIL)
565 return Samples;
566
567 auto it = DILocation2SampleMap.try_emplace(DIL, nullptr);
568 if (it.second) {
569 it.first->second = Samples->findFunctionSamples(DIL, Reader->getRemapper());
570 }
571 return it.first->second;
572}
573
574/// Find equivalence classes for the given block.
575///
576/// This finds all the blocks that are guaranteed to execute the same
577/// number of times as \p BB1. To do this, it traverses all the
578/// descendants of \p BB1 in the dominator or post-dominator tree.
579///
580/// A block BB2 will be in the same equivalence class as \p BB1 if
581/// the following holds:
582///
583/// 1- \p BB1 is a descendant of BB2 in the opposite tree. So, if BB2
584/// is a descendant of \p BB1 in the dominator tree, then BB2 should
585/// dominate BB1 in the post-dominator tree.
586///
587/// 2- Both BB2 and \p BB1 must be in the same loop.
588///
589/// For every block BB2 that meets those two requirements, we set BB2's
590/// equivalence class to \p BB1.
591///
592/// \param BB1 Block to check.
593/// \param Descendants Descendants of \p BB1 in either the dom or pdom tree.
594/// \param DomTree Opposite dominator tree. If \p Descendants is filled
595/// with blocks from \p BB1's dominator tree, then
596/// this is the post-dominator tree, and vice versa.
597template <typename BT>
599 BasicBlockT *BB1, ArrayRef<BasicBlockT *> Descendants,
600 PostDominatorTreeT *DomTree) {
601 const BasicBlockT *EC = EquivalenceClass[BB1];
602 uint64_t Weight = BlockWeights[EC];
603 for (const auto *BB2 : Descendants) {
604 bool IsDomParent = DomTree->dominates(BB2, BB1);
605 bool IsInSameLoop = LI->getLoopFor(BB1) == LI->getLoopFor(BB2);
606 if (BB1 != BB2 && IsDomParent && IsInSameLoop) {
607 EquivalenceClass[BB2] = EC;
608 // If BB2 is visited, then the entire EC should be marked as visited.
609 if (VisitedBlocks.count(BB2)) {
610 VisitedBlocks.insert(EC);
611 }
612
613 // If BB2 is heavier than BB1, make BB2 have the same weight
614 // as BB1.
615 //
616 // Note that we don't worry about the opposite situation here
617 // (when BB2 is lighter than BB1). We will deal with this
618 // during the propagation phase. Right now, we just want to
619 // make sure that BB1 has the largest weight of all the
620 // members of its equivalence set.
621 Weight = std::max(Weight, BlockWeights[BB2]);
622 }
623 }
624 const BasicBlockT *EntryBB = getEntryBB(EC->getParent());
625 if (EC == EntryBB) {
626 BlockWeights[EC] = Samples->getHeadSamples() + 1;
627 } else {
628 BlockWeights[EC] = Weight;
629 }
630}
631
632/// Find equivalence classes.
633///
634/// Since samples may be missing from blocks, we can fill in the gaps by setting
635/// the weights of all the blocks in the same equivalence class to the same
636/// weight. To compute the concept of equivalence, we use dominance and loop
637/// information. Two blocks B1 and B2 are in the same equivalence class if B1
638/// dominates B2, B2 post-dominates B1 and both are in the same loop.
639///
640/// \param F The function to query.
641template <typename BT>
644 LLVM_DEBUG(dbgs() << "\nBlock equivalence classes\n");
645 // Find equivalence sets based on dominance and post-dominance information.
646 for (auto &BB : F) {
647 BasicBlockT *BB1 = &BB;
648
649 // Compute BB1's equivalence class once.
650 // By default, blocks are in their own equivalence class.
651 auto [It, Inserted] = EquivalenceClass.try_emplace(BB1, BB1);
652 if (!Inserted) {
653 LLVM_DEBUG(printBlockEquivalence(dbgs(), BB1));
654 continue;
655 }
656
657 // Traverse all the blocks dominated by BB1. We are looking for
658 // every basic block BB2 such that:
659 //
660 // 1- BB1 dominates BB2.
661 // 2- BB2 post-dominates BB1.
662 // 3- BB1 and BB2 are in the same loop nest.
663 //
664 // If all those conditions hold, it means that BB2 is executed
665 // as many times as BB1, so they are placed in the same equivalence
666 // class by making BB2's equivalence class be BB1.
667 DominatedBBs.clear();
668 DT->getDescendants(BB1, DominatedBBs);
669 findEquivalencesFor(BB1, DominatedBBs, &*PDT);
670
671 LLVM_DEBUG(printBlockEquivalence(dbgs(), BB1));
672 }
673
674 // Assign weights to equivalence classes.
675 //
676 // All the basic blocks in the same equivalence class will execute
677 // the same number of times. Since we know that the head block in
678 // each equivalence class has the largest weight, assign that weight
679 // to all the blocks in that equivalence class.
681 dbgs() << "\nAssign the same weight to all blocks in the same class\n");
682 for (auto &BI : F) {
683 const BasicBlockT *BB = &BI;
684 const BasicBlockT *EquivBB = EquivalenceClass[BB];
685 if (BB != EquivBB)
686 BlockWeights[BB] = BlockWeights[EquivBB];
687 LLVM_DEBUG(printBlockWeight(dbgs(), BB));
688 }
689}
690
691/// Visit the given edge to decide if it has a valid weight.
692///
693/// If \p E has not been visited before, we copy to \p UnknownEdge
694/// and increment the count of unknown edges.
695///
696/// \param E Edge to visit.
697/// \param NumUnknownEdges Current number of unknown edges.
698/// \param UnknownEdge Set if E has not been visited before.
699///
700/// \returns E's weight, if known. Otherwise, return 0.
701template <typename BT>
703 unsigned *NumUnknownEdges,
704 Edge *UnknownEdge) {
705 if (!VisitedEdges.count(E)) {
706 (*NumUnknownEdges)++;
707 *UnknownEdge = E;
708 return 0;
709 }
710
711 return EdgeWeights[E];
712}
713
714/// Propagate weights through incoming/outgoing edges.
715///
716/// If the weight of a basic block is known, and there is only one edge
717/// with an unknown weight, we can calculate the weight of that edge.
718///
719/// Similarly, if all the edges have a known count, we can calculate the
720/// count of the basic block, if needed.
721///
722/// \param F Function to process.
723/// \param UpdateBlockCount Whether we should update basic block counts that
724/// has already been annotated.
725///
726/// \returns True if new weights were assigned to edges or blocks.
727template <typename BT>
729 FunctionT &F, bool UpdateBlockCount) {
730 bool Changed = false;
731 LLVM_DEBUG(dbgs() << "\nPropagation through edges\n");
732 for (const auto &BI : F) {
733 const BasicBlockT *BB = &BI;
734 const BasicBlockT *EC = EquivalenceClass[BB];
735
736 // Visit all the predecessor and successor edges to determine
737 // which ones have a weight assigned already. Note that it doesn't
738 // matter that we only keep track of a single unknown edge. The
739 // only case we are interested in handling is when only a single
740 // edge is unknown (see setEdgeOrBlockWeight).
741 for (unsigned i = 0; i < 2; i++) {
742 uint64_t TotalWeight = 0;
743 unsigned NumUnknownEdges = 0, NumTotalEdges = 0;
744 Edge UnknownEdge, SelfReferentialEdge, SingleEdge;
745
746 if (i == 0) {
747 // First, visit all predecessor edges.
748 auto &Preds = Predecessors[BB];
749 NumTotalEdges = Preds.size();
750 for (auto *Pred : Preds) {
751 Edge E = std::make_pair(Pred, BB);
752 TotalWeight += visitEdge(E, &NumUnknownEdges, &UnknownEdge);
753 if (E.first == E.second)
754 SelfReferentialEdge = E;
755 }
756 if (NumTotalEdges == 1) {
757 SingleEdge = std::make_pair(Predecessors[BB][0], BB);
758 }
759 } else {
760 // On the second round, visit all successor edges.
761 auto &Succs = Successors[BB];
762 NumTotalEdges = Succs.size();
763 for (auto *Succ : Succs) {
764 Edge E = std::make_pair(BB, Succ);
765 TotalWeight += visitEdge(E, &NumUnknownEdges, &UnknownEdge);
766 }
767 if (NumTotalEdges == 1) {
768 SingleEdge = std::make_pair(BB, Successors[BB][0]);
769 }
770 }
771
772 // After visiting all the edges, there are three cases that we
773 // can handle immediately:
774 //
775 // - All the edge weights are known (i.e., NumUnknownEdges == 0).
776 // In this case, we simply check that the sum of all the edges
777 // is the same as BB's weight. If not, we change BB's weight
778 // to match. Additionally, if BB had not been visited before,
779 // we mark it visited.
780 //
781 // - Only one edge is unknown and BB has already been visited.
782 // In this case, we can compute the weight of the edge by
783 // subtracting the total block weight from all the known
784 // edge weights. If the edges weight more than BB, then the
785 // edge of the last remaining edge is set to zero.
786 //
787 // - There exists a self-referential edge and the weight of BB is
788 // known. In this case, this edge can be based on BB's weight.
789 // We add up all the other known edges and set the weight on
790 // the self-referential edge as we did in the previous case.
791 //
792 // In any other case, we must continue iterating. Eventually,
793 // all edges will get a weight, or iteration will stop when
794 // it reaches SampleProfileMaxPropagateIterations.
795 if (NumUnknownEdges <= 1) {
796 uint64_t &BBWeight = BlockWeights[EC];
797 if (NumUnknownEdges == 0) {
798 if (!VisitedBlocks.count(EC)) {
799 // If we already know the weight of all edges, the weight of the
800 // basic block can be computed. It should be no larger than the sum
801 // of all edge weights.
802 if (TotalWeight > BBWeight) {
803 BBWeight = TotalWeight;
804 Changed = true;
805 LLVM_DEBUG(dbgs() << "All edge weights for " << BB->getName()
806 << " known. Set weight for block: ";
807 printBlockWeight(dbgs(), BB););
808 }
809 } else if (NumTotalEdges == 1 &&
810 EdgeWeights[SingleEdge] < BlockWeights[EC]) {
811 // If there is only one edge for the visited basic block, use the
812 // block weight to adjust edge weight if edge weight is smaller.
813 EdgeWeights[SingleEdge] = BlockWeights[EC];
814 Changed = true;
815 }
816 } else if (NumUnknownEdges == 1 && VisitedBlocks.count(EC)) {
817 // If there is a single unknown edge and the block has been
818 // visited, then we can compute E's weight.
819 if (BBWeight >= TotalWeight)
820 EdgeWeights[UnknownEdge] = BBWeight - TotalWeight;
821 else
822 EdgeWeights[UnknownEdge] = 0;
823 const BasicBlockT *OtherEC;
824 if (i == 0)
825 OtherEC = EquivalenceClass[UnknownEdge.first];
826 else
827 OtherEC = EquivalenceClass[UnknownEdge.second];
828 // Edge weights should never exceed the BB weights it connects.
829 if (VisitedBlocks.count(OtherEC) &&
830 EdgeWeights[UnknownEdge] > BlockWeights[OtherEC])
831 EdgeWeights[UnknownEdge] = BlockWeights[OtherEC];
832 VisitedEdges.insert(UnknownEdge);
833 Changed = true;
834 LLVM_DEBUG(dbgs() << "Set weight for edge: ";
835 printEdgeWeight(dbgs(), UnknownEdge));
836 }
837 } else if (VisitedBlocks.count(EC) && BlockWeights[EC] == 0) {
838 // If a block Weights 0, all its in/out edges should weight 0.
839 if (i == 0) {
840 for (auto *Pred : Predecessors[BB]) {
841 Edge E = std::make_pair(Pred, BB);
842 EdgeWeights[E] = 0;
843 VisitedEdges.insert(E);
844 }
845 } else {
846 for (auto *Succ : Successors[BB]) {
847 Edge E = std::make_pair(BB, Succ);
848 EdgeWeights[E] = 0;
849 VisitedEdges.insert(E);
850 }
851 }
852 } else if (SelfReferentialEdge.first && VisitedBlocks.count(EC)) {
853 uint64_t &BBWeight = BlockWeights[BB];
854 // We have a self-referential edge and the weight of BB is known.
855 if (BBWeight >= TotalWeight)
856 EdgeWeights[SelfReferentialEdge] = BBWeight - TotalWeight;
857 else
858 EdgeWeights[SelfReferentialEdge] = 0;
859 VisitedEdges.insert(SelfReferentialEdge);
860 Changed = true;
861 LLVM_DEBUG(dbgs() << "Set self-referential edge weight to: ";
862 printEdgeWeight(dbgs(), SelfReferentialEdge));
863 }
864 if (UpdateBlockCount && TotalWeight > 0 &&
865 VisitedBlocks.insert(EC).second) {
866 BlockWeights[EC] = TotalWeight;
867 Changed = true;
868 }
869 }
870 }
871
872 return Changed;
873}
874
875/// Build in/out edge lists for each basic block in the CFG.
876///
877/// We are interested in unique edges. If a block B1 has multiple
878/// edges to another block B2, we only add a single B1->B2 edge.
879template <typename BT>
881 for (auto &BI : F) {
882 BasicBlockT *B1 = &BI;
883
884 // Add predecessors for B1.
886 auto &Preds = Predecessors[B1];
887 if (!Preds.empty())
888 llvm_unreachable("Found a stale predecessors list in a basic block.");
889 for (auto *B2 : getPredecessors(B1))
890 if (Visited.insert(B2).second)
891 Preds.push_back(B2);
892
893 // Add successors for B1.
894 Visited.clear();
895 auto &Succs = Successors[B1];
896 if (!Succs.empty())
897 llvm_unreachable("Found a stale successors list in a basic block.");
898 for (auto *B2 : getSuccessors(B1))
899 if (Visited.insert(B2).second)
900 Succs.push_back(B2);
901 }
902}
903
904/// Propagate weights into edges
905///
906/// The following rules are applied to every block BB in the CFG:
907///
908/// - If BB has a single predecessor/successor, then the weight
909/// of that edge is the weight of the block.
910///
911/// - If all incoming or outgoing edges are known except one, and the
912/// weight of the block is already known, the weight of the unknown
913/// edge will be the weight of the block minus the sum of all the known
914/// edges. If the sum of all the known edges is larger than BB's weight,
915/// we set the unknown edge weight to zero.
916///
917/// - If there is a self-referential edge, and the weight of the block is
918/// known, the weight for that edge is set to the weight of the block
919/// minus the weight of the other incoming edges to that block (if
920/// known).
921template <typename BT>
923 // Flow-based profile inference is only usable with BasicBlock instantiation
924 // of SampleProfileLoaderBaseImpl.
926 // Prepare block sample counts for inference.
927 BlockWeightMap SampleBlockWeights;
928 for (const auto &BI : F) {
929 ErrorOr<uint64_t> Weight = getBlockWeight(&BI);
930 if (Weight)
931 SampleBlockWeights[&BI] = Weight.get();
932 }
933 // Fill in BlockWeights and EdgeWeights using an inference algorithm.
934 applyProfi(F, Successors, SampleBlockWeights, BlockWeights, EdgeWeights);
935 } else {
936 bool Changed = true;
937 unsigned I = 0;
938
939 // If BB weight is larger than its corresponding loop's header BB weight,
940 // use the BB weight to replace the loop header BB weight.
941 for (auto &BI : F) {
942 BasicBlockT *BB = &BI;
943 LoopT *L = LI->getLoopFor(BB);
944 if (!L) {
945 continue;
946 }
947 BasicBlockT *Header = L->getHeader();
948 if (Header && BlockWeights[BB] > BlockWeights[Header]) {
949 BlockWeights[Header] = BlockWeights[BB];
950 }
951 }
952
953 // Propagate until we converge or we go past the iteration limit.
954 while (Changed && I++ < SampleProfileMaxPropagateIterations) {
955 Changed = propagateThroughEdges(F, false);
956 }
957
958 // The first propagation propagates BB counts from annotated BBs to unknown
959 // BBs. The 2nd propagation pass resets edges weights, and use all BB
960 // weights to propagate edge weights.
961 VisitedEdges.clear();
962 Changed = true;
963 while (Changed && I++ < SampleProfileMaxPropagateIterations) {
964 Changed = propagateThroughEdges(F, false);
965 }
966
967 // The 3rd propagation pass allows adjust annotated BB weights that are
968 // obviously wrong.
969 Changed = true;
970 while (Changed && I++ < SampleProfileMaxPropagateIterations) {
971 Changed = propagateThroughEdges(F, true);
972 }
973 }
974}
975
976template <typename FT>
978 FunctionT &F, BlockEdgeMap &Successors, BlockWeightMap &SampleBlockWeights,
979 BlockWeightMap &BlockWeights, EdgeWeightMap &EdgeWeights) {
980 auto Infer = SampleProfileInference<FT>(F, Successors, SampleBlockWeights);
981 Infer.apply(BlockWeights, EdgeWeights);
982}
983
984/// Generate branch weight metadata for all branches in \p F.
985///
986/// Branch weights are computed out of instruction samples using a
987/// propagation heuristic. Propagation proceeds in 3 phases:
988///
989/// 1- Assignment of block weights. All the basic blocks in the function
990/// are initial assigned the same weight as their most frequently
991/// executed instruction.
992///
993/// 2- Creation of equivalence classes. Since samples may be missing from
994/// blocks, we can fill in the gaps by setting the weights of all the
995/// blocks in the same equivalence class to the same weight. To compute
996/// the concept of equivalence, we use dominance and loop information.
997/// Two blocks B1 and B2 are in the same equivalence class if B1
998/// dominates B2, B2 post-dominates B1 and both are in the same loop.
999///
1000/// 3- Propagation of block weights into edges. This uses a simple
1001/// propagation heuristic. The following rules are applied to every
1002/// block BB in the CFG:
1003///
1004/// - If BB has a single predecessor/successor, then the weight
1005/// of that edge is the weight of the block.
1006///
1007/// - If all the edges are known except one, and the weight of the
1008/// block is already known, the weight of the unknown edge will
1009/// be the weight of the block minus the sum of all the known
1010/// edges. If the sum of all the known edges is larger than BB's weight,
1011/// we set the unknown edge weight to zero.
1012///
1013/// - If there is a self-referential edge, and the weight of the block is
1014/// known, the weight for that edge is set to the weight of the block
1015/// minus the weight of the other incoming edges to that block (if
1016/// known).
1017///
1018/// Since this propagation is not guaranteed to finalize for every CFG, we
1019/// only allow it to proceed for a limited number of iterations (controlled
1020/// by -sample-profile-max-propagate-iterations).
1021///
1022/// FIXME: Try to replace this propagation heuristic with a scheme
1023/// that is guaranteed to finalize. A work-list approach similar to
1024/// the standard value propagation algorithm used by SSA-CCP might
1025/// work here.
1026///
1027/// \param F The function to query.
1028///
1029/// \returns true if \p F was modified. Returns false, otherwise.
1030template <typename BT>
1032 FunctionT &F, const DenseSet<GlobalValue::GUID> &InlinedGUIDs) {
1033 bool Changed = (InlinedGUIDs.size() != 0);
1034
1035 // Compute basic block weights.
1036 Changed |= computeBlockWeights(F);
1037
1038 if (Changed) {
1039 // Initialize propagation.
1040 initWeightPropagation(F, InlinedGUIDs);
1041
1042 // Propagate weights to all edges.
1043 propagateWeights(F);
1044
1045 // Post-process propagated weights.
1046 finalizeWeightPropagation(F, InlinedGUIDs);
1047 }
1048
1049 return Changed;
1050}
1051
1052template <typename BT>
1054 FunctionT &F, const DenseSet<GlobalValue::GUID> &InlinedGUIDs) {
1055 // Add an entry count to the function using the samples gathered at the
1056 // function entry.
1057 // Sets the GUIDs that are inlined in the profiled binary. This is used
1058 // for ThinLink to make correct liveness analysis, and also make the IR
1059 // match the profiled binary before annotation.
1061 ProfileCount(Samples->getHeadSamples() + 1, Function::PCT_Real),
1062 &InlinedGUIDs);
1063
1064 if (!SampleProfileUseProfi) {
1065 // Compute dominance and loop info needed for propagation.
1066 computeDominanceAndLoopInfo(F);
1067
1068 // Find equivalence classes.
1069 findEquivalenceClasses(F);
1070 }
1071
1072 // Before propagation starts, build, for each block, a list of
1073 // unique predecessors and successors. This is necessary to handle
1074 // identical edges in multiway branches. Since we visit all blocks and all
1075 // edges of the CFG, it is cleaner to build these lists once at the start
1076 // of the pass.
1077 buildEdges(F);
1078}
1079
1080template <typename BT>
1082 FunctionT &F, const DenseSet<GlobalValue::GUID> &InlinedGUIDs) {
1083 // If we utilize a flow-based count inference, then we trust the computed
1084 // counts and set the entry count as computed by the algorithm. This is
1085 // primarily done to sync the counts produced by profi and BFI inference,
1086 // which uses the entry count for mass propagation.
1087 // If profi produces a zero-value for the entry count, we fallback to
1088 // Samples->getHeadSamples() + 1 to avoid functions with zero count.
1090 const BasicBlockT *EntryBB = getEntryBB(&F);
1091 ErrorOr<uint64_t> EntryWeight = getBlockWeight(EntryBB);
1092 if (BlockWeights[EntryBB] > 0) {
1094 ProfileCount(BlockWeights[EntryBB], Function::PCT_Real),
1095 &InlinedGUIDs);
1096 }
1097 }
1098}
1099
1100template <typename BT>
1102 // If coverage checking was requested, compute it now.
1103 const Function &Func = getFunction(F);
1105 unsigned Used = CoverageTracker.countUsedRecords(Samples, PSI);
1106 unsigned Total = CoverageTracker.countBodyRecords(Samples, PSI);
1107 unsigned Coverage = CoverageTracker.computeCoverage(Used, Total);
1108 if (Coverage < SampleProfileRecordCoverage) {
1109 Func.getContext().diagnose(DiagnosticInfoSampleProfile(
1110 Func.getSubprogram()->getFilename(), getFunctionLoc(F),
1111 Twine(Used) + " of " + Twine(Total) + " available profile records (" +
1112 Twine(Coverage) + "%) were applied",
1113 DS_Warning));
1114 }
1115 }
1116
1118 uint64_t Used = CoverageTracker.getTotalUsedSamples();
1119 uint64_t Total = CoverageTracker.countBodySamples(Samples, PSI);
1120 unsigned Coverage = CoverageTracker.computeCoverage(Used, Total);
1121 if (Coverage < SampleProfileSampleCoverage) {
1122 Func.getContext().diagnose(DiagnosticInfoSampleProfile(
1123 Func.getSubprogram()->getFilename(), getFunctionLoc(F),
1124 Twine(Used) + " of " + Twine(Total) + " available profile samples (" +
1125 Twine(Coverage) + "%) were applied",
1126 DS_Warning));
1127 }
1128 }
1129}
1130
1131/// Get the line number for the function header.
1132///
1133/// This looks up function \p F in the current compilation unit and
1134/// retrieves the line number where the function is defined. This is
1135/// line 0 for all the samples read from the profile file. Every line
1136/// number is relative to this line.
1137///
1138/// \param F Function object to query.
1139///
1140/// \returns the line number where \p F is defined. If it returns 0,
1141/// it means that there is no debug information available for \p F.
1142template <typename BT>
1144 const Function &Func = getFunction(F);
1145 if (DISubprogram *S = Func.getSubprogram())
1146 return S->getLine();
1147
1149 return 0;
1150
1151 // If the start of \p F is missing, emit a diagnostic to inform the user
1152 // about the missed opportunity.
1153 Func.getContext().diagnose(DiagnosticInfoSampleProfile(
1154 "No debug information found in function " + Func.getName() +
1155 ": Function profile not used",
1156 DS_Warning));
1157 return 0;
1158}
1159
1160#undef DEBUG_TYPE
1161
1162} // namespace llvm
1163#endif // LLVM_TRANSFORMS_UTILS_SAMPLEPROFILELOADERBASEIMPL_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
std::string Name
#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...
Module.h This file contains the declarations for the Module class.
This file defines the RefCountedBase, ThreadSafeRefCountedBase, and IntrusiveRefCntPtr classes.
Implements a lazy call graph analysis and related passes for the new pass manager.
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
static StringRef getName(Value *V)
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.
#define LLVM_DEBUG(...)
Definition: Debug.h:119
static Function * getFunction(FunctionType *Ty, const Twine &Name, Module *M)
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:62
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. Uses SubclassData1.
A debug info location.
Definition: DebugLoc.h:124
LLVM_ABI unsigned getLine() const
Definition: DebugLoc.cpp:54
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:177
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition: DenseMap.h:245
iterator end()
Definition: DenseMap.h:87
Implements a dense probed hash-table based set.
Definition: DenseSet.h:263
Diagnostic information for the sample profiler.
void getDescendants(NodeT *R, SmallVectorImpl< NodeT * > &Result) const
Get all nodes dominated by R, including R itself.
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:297
void setEntryCount(ProfileCount Count, const DenseSet< GlobalValue::GUID > *Imports=nullptr)
Set the entry count for this function.
Definition: Function.cpp:1099
static LLVM_ABI GUID getGUIDAssumingExternalLinkage(StringRef GlobalName)
Return a 64-bit global unique ID constructed from the name of a global symbol.
Definition: Globals.cpp:77
static bool isAvailableExternallyLinkage(LinkageTypes Linkage)
Definition: GlobalValue.h:381
A smart pointer to a reference-counted object that inherits from RefCountedBase or ThreadSafeRefCount...
A node in the call graph.
A RefSCC of the call graph.
An SCC of the call graph.
A lazily constructed view of the call graph of a module.
LLVM_ABI void buildRefSCCs()
iterator_range< postorder_ref_scc_iterator > postorder_ref_sccs()
Represents a single loop in the control flow graph.
Definition: LoopInfo.h:40
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
A tuple of MDNodes.
Definition: Metadata.h:1753
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.
uint64_t getFunctionHash() const
Definition: PseudoProbe.h:115
const PseudoProbeDescriptor * getDesc(StringRef FProfileName) const
bool profileIsHashMismatched(const PseudoProbeDescriptor &FuncDesc, const FunctionSamples &Samples) const
const PseudoProbeDescriptor * getDesc(const Function &F) const
bool moduleIsProbed(const Module &M) const
bool profileIsValid(const Function &F, const FunctionSamples &Samples) const
const PseudoProbeDescriptor * getDesc(uint64_t GUID) const
Sample profile inference pass.
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.
std::map< SampleContext, FunctionSamples > OutlineFunctionSamples
Synthetic samples created by duplicating the samples of inlined functions from the original profile a...
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.
std::remove_pointer_t< NodeRef > BT
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:401
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:541
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:134
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:82
size_type size() const
Definition: DenseSet.h:87
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
Representation of the samples collected for a function.
Definition: SampleProf.h:757
static LLVM_ABI bool ProfileIsProbeBased
Definition: SampleProf.h:1198
static StringRef getCanonicalFnName(const Function &F)
Return the canonical name for a function, taking into account suffix elision policy attributes.
Definition: SampleProf.h:1102
static LLVM_ABI unsigned getOffset(const DILocation *DIL)
Returns the line offset to the start line of the subprogram.
Definition: SampleProf.cpp:245
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
template class LLVM_TEMPLATE_ABI opt< bool >
Definition: CommandLine.cpp:79
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
static void buildTopDownFuncOrder(LazyCallGraph &CG, std::vector< Function * > &FunctionOrderList)
cl::opt< unsigned > SampleProfileRecordCoverage
cl::opt< unsigned > SampleProfileMaxPropagateIterations
cl::opt< bool > SampleProfileUseProfi
LLVM_ABI cl::opt< bool > EnableFSDiscriminator
LLVM_ABI std::optional< PseudoProbe > extractProbe(const Instruction &Inst)
Definition: PseudoProbe.cpp:56
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
iterator_range< succ_iterator > succ_range
Definition: CFG.h:245
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:126
iterator_range< pred_iterator > pred_range
Definition: CFG.h:108
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:1886
@ DS_Warning
static bool skipProfileForFunction(const Function &F)
auto predecessors(const MachineBasicBlock *BB)
constexpr const char * PseudoProbeDescMetadataName
Definition: PseudoProbe.h:26
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:856
#define N
Description of the encoding of one expression Op.
typename GraphType::UnknownGraphTypeError NodeRef
Definition: GraphTraits.h:95
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)