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