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