xref: /llvm-project/llvm/lib/CodeGen/MIRSampleProfile.cpp (revision 67efbd0bf1b2df8a479e09eb2be7db4c3c892f2c)
15fdaaf7fSRong Xu //===-------- MIRSampleProfile.cpp: MIRSampleFDO (For FSAFDO) -------------===//
25fdaaf7fSRong Xu //
35fdaaf7fSRong Xu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45fdaaf7fSRong Xu // See https://llvm.org/LICENSE.txt for license information.
55fdaaf7fSRong Xu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65fdaaf7fSRong Xu //
75fdaaf7fSRong Xu //===----------------------------------------------------------------------===//
85fdaaf7fSRong Xu //
95fdaaf7fSRong Xu // This file provides the implementation of the MIRSampleProfile loader, mainly
105fdaaf7fSRong Xu // for flow sensitive SampleFDO.
115fdaaf7fSRong Xu //
125fdaaf7fSRong Xu //===----------------------------------------------------------------------===//
135fdaaf7fSRong Xu 
145fdaaf7fSRong Xu #include "llvm/CodeGen/MIRSampleProfile.h"
155fdaaf7fSRong Xu #include "llvm/ADT/DenseMap.h"
165fdaaf7fSRong Xu #include "llvm/ADT/DenseSet.h"
175fdaaf7fSRong Xu #include "llvm/Analysis/BlockFrequencyInfoImpl.h"
18989f1c72Sserge-sans-paille #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
19989f1c72Sserge-sans-paille #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
20989f1c72Sserge-sans-paille #include "llvm/CodeGen/MachineDominators.h"
21b7d9322bSHongtao Yu #include "llvm/CodeGen/MachineInstr.h"
22989f1c72Sserge-sans-paille #include "llvm/CodeGen/MachineLoopInfo.h"
23989f1c72Sserge-sans-paille #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
24989f1c72Sserge-sans-paille #include "llvm/CodeGen/MachinePostDominators.h"
25989f1c72Sserge-sans-paille #include "llvm/CodeGen/Passes.h"
265fdaaf7fSRong Xu #include "llvm/IR/Function.h"
27b7d9322bSHongtao Yu #include "llvm/IR/PseudoProbe.h"
28989f1c72Sserge-sans-paille #include "llvm/InitializePasses.h"
295fdaaf7fSRong Xu #include "llvm/Support/CommandLine.h"
305fdaaf7fSRong Xu #include "llvm/Support/Debug.h"
31516e3017SSteven Wu #include "llvm/Support/VirtualFileSystem.h"
325fdaaf7fSRong Xu #include "llvm/Support/raw_ostream.h"
335fdaaf7fSRong Xu #include "llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h"
345fdaaf7fSRong Xu #include "llvm/Transforms/Utils/SampleProfileLoaderBaseUtil.h"
35b7d9322bSHongtao Yu #include <optional>
365fdaaf7fSRong Xu 
375fdaaf7fSRong Xu using namespace llvm;
385fdaaf7fSRong Xu using namespace sampleprof;
395fdaaf7fSRong Xu using namespace llvm::sampleprofutil;
405fdaaf7fSRong Xu using ProfileCount = Function::ProfileCount;
415fdaaf7fSRong Xu 
425fdaaf7fSRong Xu #define DEBUG_TYPE "fs-profile-loader"
435fdaaf7fSRong Xu 
445fdaaf7fSRong Xu static cl::opt<bool> ShowFSBranchProb(
455fdaaf7fSRong Xu     "show-fs-branchprob", cl::Hidden, cl::init(false),
465fdaaf7fSRong Xu     cl::desc("Print setting flow sensitive branch probabilities"));
475fdaaf7fSRong Xu static cl::opt<unsigned> FSProfileDebugProbDiffThreshold(
485fdaaf7fSRong Xu     "fs-profile-debug-prob-diff-threshold", cl::init(10),
49*67efbd0bSRyan Mansfield     cl::desc(
50*67efbd0bSRyan Mansfield         "Only show debug message if the branch probability is greater than "
515fdaaf7fSRong Xu         "this value (in percentage)."));
525fdaaf7fSRong Xu 
535fdaaf7fSRong Xu static cl::opt<unsigned> FSProfileDebugBWThreshold(
545fdaaf7fSRong Xu     "fs-profile-debug-bw-threshold", cl::init(10000),
555fdaaf7fSRong Xu     cl::desc("Only show debug message if the source branch weight is greater "
565fdaaf7fSRong Xu              " than this value."));
575fdaaf7fSRong Xu 
585fdaaf7fSRong Xu static cl::opt<bool> ViewBFIBefore("fs-viewbfi-before", cl::Hidden,
595fdaaf7fSRong Xu                                    cl::init(false),
605fdaaf7fSRong Xu                                    cl::desc("View BFI before MIR loader"));
615fdaaf7fSRong Xu static cl::opt<bool> ViewBFIAfter("fs-viewbfi-after", cl::Hidden,
625fdaaf7fSRong Xu                                   cl::init(false),
635fdaaf7fSRong Xu                                   cl::desc("View BFI after MIR loader"));
645fdaaf7fSRong Xu 
652d854dd3SFangrui Song namespace llvm {
66ebe09e2aSRong Xu extern cl::opt<bool> ImprovedFSDiscriminator;
672d854dd3SFangrui Song }
685fdaaf7fSRong Xu char MIRProfileLoaderPass::ID = 0;
695fdaaf7fSRong Xu 
705fdaaf7fSRong Xu INITIALIZE_PASS_BEGIN(MIRProfileLoaderPass, DEBUG_TYPE,
715fdaaf7fSRong Xu                       "Load MIR Sample Profile",
725fdaaf7fSRong Xu                       /* cfg = */ false, /* is_analysis = */ false)
7309989996Spaperchalice INITIALIZE_PASS_DEPENDENCY(MachineBlockFrequencyInfoWrapperPass)
74837dc542Spaperchalice INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
754b24c2dfSpaperchalice INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTreeWrapperPass)
7679d0de2aSpaperchalice INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
775fdaaf7fSRong Xu INITIALIZE_PASS_DEPENDENCY(MachineOptimizationRemarkEmitterPass)
785fdaaf7fSRong Xu INITIALIZE_PASS_END(MIRProfileLoaderPass, DEBUG_TYPE, "Load MIR Sample Profile",
795fdaaf7fSRong Xu                     /* cfg = */ false, /* is_analysis = */ false)
805fdaaf7fSRong Xu 
815fdaaf7fSRong Xu char &llvm::MIRProfileLoaderPassID = MIRProfileLoaderPass::ID;
825fdaaf7fSRong Xu 
83516e3017SSteven Wu FunctionPass *
84516e3017SSteven Wu llvm::createMIRProfileLoaderPass(std::string File, std::string RemappingFile,
85516e3017SSteven Wu                                  FSDiscriminatorPass P,
86516e3017SSteven Wu                                  IntrusiveRefCntPtr<vfs::FileSystem> FS) {
87516e3017SSteven Wu   return new MIRProfileLoaderPass(File, RemappingFile, P, std::move(FS));
885fdaaf7fSRong Xu }
895fdaaf7fSRong Xu 
905fdaaf7fSRong Xu namespace llvm {
915fdaaf7fSRong Xu 
925fdaaf7fSRong Xu // Internal option used to control BFI display only after MBP pass.
935fdaaf7fSRong Xu // Defined in CodeGen/MachineBlockFrequencyInfo.cpp:
945fdaaf7fSRong Xu // -view-block-layout-with-bfi={none | fraction | integer | count}
955fdaaf7fSRong Xu extern cl::opt<GVDAGType> ViewBlockLayoutWithBFI;
965fdaaf7fSRong Xu 
975fdaaf7fSRong Xu // Command line option to specify the name of the function for CFG dump
985fdaaf7fSRong Xu // Defined in Analysis/BlockFrequencyInfo.cpp:  -view-bfi-func-name=
995fdaaf7fSRong Xu extern cl::opt<std::string> ViewBlockFreqFuncName;
1005fdaaf7fSRong Xu 
101b7d9322bSHongtao Yu std::optional<PseudoProbe> extractProbe(const MachineInstr &MI) {
102b7d9322bSHongtao Yu   if (MI.isPseudoProbe()) {
103b7d9322bSHongtao Yu     PseudoProbe Probe;
104b7d9322bSHongtao Yu     Probe.Id = MI.getOperand(1).getImm();
105b7d9322bSHongtao Yu     Probe.Type = MI.getOperand(2).getImm();
106b7d9322bSHongtao Yu     Probe.Attr = MI.getOperand(3).getImm();
107b7d9322bSHongtao Yu     Probe.Factor = 1;
108b7d9322bSHongtao Yu     DILocation *DebugLoc = MI.getDebugLoc();
109b7d9322bSHongtao Yu     Probe.Discriminator = DebugLoc ? DebugLoc->getDiscriminator() : 0;
110b7d9322bSHongtao Yu     return Probe;
111b7d9322bSHongtao Yu   }
112b7d9322bSHongtao Yu 
113b7d9322bSHongtao Yu   // Ignore callsite probes since they do not have FS discriminators.
114b7d9322bSHongtao Yu   return std::nullopt;
115b7d9322bSHongtao Yu }
116b7d9322bSHongtao Yu 
1175fdaaf7fSRong Xu namespace afdo_detail {
1185fdaaf7fSRong Xu template <> struct IRTraits<MachineBasicBlock> {
1195fdaaf7fSRong Xu   using InstructionT = MachineInstr;
1205fdaaf7fSRong Xu   using BasicBlockT = MachineBasicBlock;
1215fdaaf7fSRong Xu   using FunctionT = MachineFunction;
1225fdaaf7fSRong Xu   using BlockFrequencyInfoT = MachineBlockFrequencyInfo;
1235fdaaf7fSRong Xu   using LoopT = MachineLoop;
1245fdaaf7fSRong Xu   using LoopInfoPtrT = MachineLoopInfo *;
1255fdaaf7fSRong Xu   using DominatorTreePtrT = MachineDominatorTree *;
1265fdaaf7fSRong Xu   using PostDominatorTreePtrT = MachinePostDominatorTree *;
1275fdaaf7fSRong Xu   using PostDominatorTreeT = MachinePostDominatorTree;
1285fdaaf7fSRong Xu   using OptRemarkEmitterT = MachineOptimizationRemarkEmitter;
1295fdaaf7fSRong Xu   using OptRemarkAnalysisT = MachineOptimizationRemarkAnalysis;
1304c23c1b9SAlexis Engelke   using PredRangeT =
1314c23c1b9SAlexis Engelke       iterator_range<SmallVectorImpl<MachineBasicBlock *>::iterator>;
1324c23c1b9SAlexis Engelke   using SuccRangeT =
1334c23c1b9SAlexis Engelke       iterator_range<SmallVectorImpl<MachineBasicBlock *>::iterator>;
1345fdaaf7fSRong Xu   static Function &getFunction(MachineFunction &F) { return F.getFunction(); }
1355fdaaf7fSRong Xu   static const MachineBasicBlock *getEntryBB(const MachineFunction *F) {
1365fdaaf7fSRong Xu     return GraphTraits<const MachineFunction *>::getEntryNode(F);
1375fdaaf7fSRong Xu   }
1385fdaaf7fSRong Xu   static PredRangeT getPredecessors(MachineBasicBlock *BB) {
1395fdaaf7fSRong Xu     return BB->predecessors();
1405fdaaf7fSRong Xu   }
1415fdaaf7fSRong Xu   static SuccRangeT getSuccessors(MachineBasicBlock *BB) {
1425fdaaf7fSRong Xu     return BB->successors();
1435fdaaf7fSRong Xu   }
1445fdaaf7fSRong Xu };
1455fdaaf7fSRong Xu } // namespace afdo_detail
1465fdaaf7fSRong Xu 
1475fdaaf7fSRong Xu class MIRProfileLoader final
148b244a4c4SAmir Ayupov     : public SampleProfileLoaderBaseImpl<MachineFunction> {
1495fdaaf7fSRong Xu public:
1505fdaaf7fSRong Xu   void setInitVals(MachineDominatorTree *MDT, MachinePostDominatorTree *MPDT,
1515fdaaf7fSRong Xu                    MachineLoopInfo *MLI, MachineBlockFrequencyInfo *MBFI,
1525fdaaf7fSRong Xu                    MachineOptimizationRemarkEmitter *MORE) {
1535fdaaf7fSRong Xu     DT = MDT;
1545fdaaf7fSRong Xu     PDT = MPDT;
1555fdaaf7fSRong Xu     LI = MLI;
1565fdaaf7fSRong Xu     BFI = MBFI;
1575fdaaf7fSRong Xu     ORE = MORE;
1585fdaaf7fSRong Xu   }
1595fdaaf7fSRong Xu   void setFSPass(FSDiscriminatorPass Pass) {
1605fdaaf7fSRong Xu     P = Pass;
1615fdaaf7fSRong Xu     LowBit = getFSPassBitBegin(P);
1625fdaaf7fSRong Xu     HighBit = getFSPassBitEnd(P);
1635fdaaf7fSRong Xu     assert(LowBit < HighBit && "HighBit needs to be greater than Lowbit");
1645fdaaf7fSRong Xu   }
1655fdaaf7fSRong Xu 
166516e3017SSteven Wu   MIRProfileLoader(StringRef Name, StringRef RemapName,
167516e3017SSteven Wu                    IntrusiveRefCntPtr<vfs::FileSystem> FS)
168516e3017SSteven Wu       : SampleProfileLoaderBaseImpl(std::string(Name), std::string(RemapName),
169516e3017SSteven Wu                                     std::move(FS)) {}
1705fdaaf7fSRong Xu 
1715fdaaf7fSRong Xu   void setBranchProbs(MachineFunction &F);
1725fdaaf7fSRong Xu   bool runOnFunction(MachineFunction &F);
1735fdaaf7fSRong Xu   bool doInitialization(Module &M);
1745fdaaf7fSRong Xu   bool isValid() const { return ProfileIsValid; }
1755fdaaf7fSRong Xu 
1765fdaaf7fSRong Xu protected:
1775fdaaf7fSRong Xu   friend class SampleCoverageTracker;
1785fdaaf7fSRong Xu 
1795fdaaf7fSRong Xu   /// Hold the information of the basic block frequency.
1805fdaaf7fSRong Xu   MachineBlockFrequencyInfo *BFI;
1815fdaaf7fSRong Xu 
1825fdaaf7fSRong Xu   /// PassNum is the sequence number this pass is called, start from 1.
1835fdaaf7fSRong Xu   FSDiscriminatorPass P;
1845fdaaf7fSRong Xu 
1855fdaaf7fSRong Xu   // LowBit in the FS discriminator used by this instance. Note the number is
1865fdaaf7fSRong Xu   // 0-based. Base discrimnator use bit 0 to bit 11.
1875fdaaf7fSRong Xu   unsigned LowBit;
1885fdaaf7fSRong Xu   // HighwBit in the FS discriminator used by this instance. Note the number
1895fdaaf7fSRong Xu   // is 0-based.
1905fdaaf7fSRong Xu   unsigned HighBit;
1915fdaaf7fSRong Xu 
1925fdaaf7fSRong Xu   bool ProfileIsValid = true;
193ebe09e2aSRong Xu   ErrorOr<uint64_t> getInstWeight(const MachineInstr &MI) override {
194b7d9322bSHongtao Yu     if (FunctionSamples::ProfileIsProbeBased)
195b7d9322bSHongtao Yu       return getProbeWeight(MI);
196ebe09e2aSRong Xu     if (ImprovedFSDiscriminator && MI.isMetaInstruction())
197ebe09e2aSRong Xu       return std::error_code();
198ebe09e2aSRong Xu     return getInstWeightImpl(MI);
199ebe09e2aSRong Xu   }
2005fdaaf7fSRong Xu };
2015fdaaf7fSRong Xu 
2025fdaaf7fSRong Xu template <>
203b244a4c4SAmir Ayupov void SampleProfileLoaderBaseImpl<MachineFunction>::computeDominanceAndLoopInfo(
204b244a4c4SAmir Ayupov     MachineFunction &F) {}
2055fdaaf7fSRong Xu 
2065fdaaf7fSRong Xu void MIRProfileLoader::setBranchProbs(MachineFunction &F) {
2075fdaaf7fSRong Xu   LLVM_DEBUG(dbgs() << "\nPropagation complete. Setting branch probs\n");
2085fdaaf7fSRong Xu   for (auto &BI : F) {
2095fdaaf7fSRong Xu     MachineBasicBlock *BB = &BI;
2105fdaaf7fSRong Xu     if (BB->succ_size() < 2)
2115fdaaf7fSRong Xu       continue;
2125fdaaf7fSRong Xu     const MachineBasicBlock *EC = EquivalenceClass[BB];
2135fdaaf7fSRong Xu     uint64_t BBWeight = BlockWeights[EC];
2145fdaaf7fSRong Xu     uint64_t SumEdgeWeight = 0;
215cba40c4eSKazu Hirata     for (MachineBasicBlock *Succ : BB->successors()) {
2165fdaaf7fSRong Xu       Edge E = std::make_pair(BB, Succ);
2175fdaaf7fSRong Xu       SumEdgeWeight += EdgeWeights[E];
2185fdaaf7fSRong Xu     }
2195fdaaf7fSRong Xu 
2205fdaaf7fSRong Xu     if (BBWeight != SumEdgeWeight) {
2215fdaaf7fSRong Xu       LLVM_DEBUG(dbgs() << "BBweight is not equal to SumEdgeWeight: BBWWeight="
2225fdaaf7fSRong Xu                         << BBWeight << " SumEdgeWeight= " << SumEdgeWeight
2235fdaaf7fSRong Xu                         << "\n");
2245fdaaf7fSRong Xu       BBWeight = SumEdgeWeight;
2255fdaaf7fSRong Xu     }
2265fdaaf7fSRong Xu     if (BBWeight == 0) {
2275fdaaf7fSRong Xu       LLVM_DEBUG(dbgs() << "SKIPPED. All branch weights are zero.\n");
2285fdaaf7fSRong Xu       continue;
2295fdaaf7fSRong Xu     }
2305fdaaf7fSRong Xu 
2315fdaaf7fSRong Xu #ifndef NDEBUG
2325fdaaf7fSRong Xu     uint64_t BBWeightOrig = BBWeight;
2335fdaaf7fSRong Xu #endif
2345fdaaf7fSRong Xu     uint32_t MaxWeight = std::numeric_limits<uint32_t>::max();
2355fdaaf7fSRong Xu     uint32_t Factor = 1;
2365fdaaf7fSRong Xu     if (BBWeight > MaxWeight) {
2375fdaaf7fSRong Xu       Factor = BBWeight / MaxWeight + 1;
2385fdaaf7fSRong Xu       BBWeight /= Factor;
2395fdaaf7fSRong Xu       LLVM_DEBUG(dbgs() << "Scaling weights by " << Factor << "\n");
2405fdaaf7fSRong Xu     }
2415fdaaf7fSRong Xu 
2425fdaaf7fSRong Xu     for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(),
2435fdaaf7fSRong Xu                                           SE = BB->succ_end();
2445fdaaf7fSRong Xu          SI != SE; ++SI) {
2455fdaaf7fSRong Xu       MachineBasicBlock *Succ = *SI;
2465fdaaf7fSRong Xu       Edge E = std::make_pair(BB, Succ);
2475fdaaf7fSRong Xu       uint64_t EdgeWeight = EdgeWeights[E];
2485fdaaf7fSRong Xu       EdgeWeight /= Factor;
2495fdaaf7fSRong Xu 
2505fdaaf7fSRong Xu       assert(BBWeight >= EdgeWeight &&
2515fdaaf7fSRong Xu              "BBweight is larger than EdgeWeight -- should not happen.\n");
2525fdaaf7fSRong Xu 
2535fdaaf7fSRong Xu       BranchProbability OldProb = BFI->getMBPI()->getEdgeProbability(BB, SI);
2545fdaaf7fSRong Xu       BranchProbability NewProb(EdgeWeight, BBWeight);
2555fdaaf7fSRong Xu       if (OldProb == NewProb)
2565fdaaf7fSRong Xu         continue;
2575fdaaf7fSRong Xu       BB->setSuccProbability(SI, NewProb);
2585fdaaf7fSRong Xu #ifndef NDEBUG
2595fdaaf7fSRong Xu       if (!ShowFSBranchProb)
2605fdaaf7fSRong Xu         continue;
2615fdaaf7fSRong Xu       bool Show = false;
2625fdaaf7fSRong Xu       BranchProbability Diff;
2635fdaaf7fSRong Xu       if (OldProb > NewProb)
2645fdaaf7fSRong Xu         Diff = OldProb - NewProb;
2655fdaaf7fSRong Xu       else
2665fdaaf7fSRong Xu         Diff = NewProb - OldProb;
2675fdaaf7fSRong Xu       Show = (Diff >= BranchProbability(FSProfileDebugProbDiffThreshold, 100));
2685fdaaf7fSRong Xu       Show &= (BBWeightOrig >= FSProfileDebugBWThreshold);
2695fdaaf7fSRong Xu 
2705fdaaf7fSRong Xu       auto DIL = BB->findBranchDebugLoc();
2715fdaaf7fSRong Xu       auto SuccDIL = Succ->findBranchDebugLoc();
2725fdaaf7fSRong Xu       if (Show) {
2735fdaaf7fSRong Xu         dbgs() << "Set branch fs prob: MBB (" << BB->getNumber() << " -> "
2745fdaaf7fSRong Xu                << Succ->getNumber() << "): ";
2755fdaaf7fSRong Xu         if (DIL)
2765fdaaf7fSRong Xu           dbgs() << DIL->getFilename() << ":" << DIL->getLine() << ":"
2775fdaaf7fSRong Xu                  << DIL->getColumn();
2785fdaaf7fSRong Xu         if (SuccDIL)
2795fdaaf7fSRong Xu           dbgs() << "-->" << SuccDIL->getFilename() << ":" << SuccDIL->getLine()
2805fdaaf7fSRong Xu                  << ":" << SuccDIL->getColumn();
2815fdaaf7fSRong Xu         dbgs() << " W=" << BBWeightOrig << "  " << OldProb << " --> " << NewProb
2825fdaaf7fSRong Xu                << "\n";
2835fdaaf7fSRong Xu       }
2845fdaaf7fSRong Xu #endif
2855fdaaf7fSRong Xu     }
2865fdaaf7fSRong Xu   }
2875fdaaf7fSRong Xu }
2885fdaaf7fSRong Xu 
2895fdaaf7fSRong Xu bool MIRProfileLoader::doInitialization(Module &M) {
2905fdaaf7fSRong Xu   auto &Ctx = M.getContext();
2915fdaaf7fSRong Xu 
292516e3017SSteven Wu   auto ReaderOrErr = sampleprof::SampleProfileReader::create(
293516e3017SSteven Wu       Filename, Ctx, *FS, P, RemappingFilename);
2945fdaaf7fSRong Xu   if (std::error_code EC = ReaderOrErr.getError()) {
2955fdaaf7fSRong Xu     std::string Msg = "Could not open profile: " + EC.message();
2965fdaaf7fSRong Xu     Ctx.diagnose(DiagnosticInfoSampleProfile(Filename, Msg));
2975fdaaf7fSRong Xu     return false;
2985fdaaf7fSRong Xu   }
2995fdaaf7fSRong Xu 
3005fdaaf7fSRong Xu   Reader = std::move(ReaderOrErr.get());
3015fdaaf7fSRong Xu   Reader->setModule(&M);
3025fdaaf7fSRong Xu   ProfileIsValid = (Reader->read() == sampleprof_error::success);
3035fdaaf7fSRong Xu 
304b7d9322bSHongtao Yu   // Load pseudo probe descriptors for probe-based function samples.
305b7d9322bSHongtao Yu   if (Reader->profileIsProbeBased()) {
306b7d9322bSHongtao Yu     ProbeManager = std::make_unique<PseudoProbeManager>(M);
307b7d9322bSHongtao Yu     if (!ProbeManager->moduleIsProbed(M)) {
308b7d9322bSHongtao Yu       return false;
309b7d9322bSHongtao Yu     }
310b7d9322bSHongtao Yu   }
311b7d9322bSHongtao Yu 
3125fdaaf7fSRong Xu   return true;
3135fdaaf7fSRong Xu }
3145fdaaf7fSRong Xu 
3155fdaaf7fSRong Xu bool MIRProfileLoader::runOnFunction(MachineFunction &MF) {
316958a3d8eSHongtao Yu   // Do not load non-FS profiles. A line or probe can get a zero-valued
317958a3d8eSHongtao Yu   // discriminator at certain pass which could result in accidentally loading
318958a3d8eSHongtao Yu   // the corresponding base counter in the non-FS profile, while a non-zero
319958a3d8eSHongtao Yu   // discriminator would end up getting zero samples. This could in turn undo
320958a3d8eSHongtao Yu   // the sample distribution effort done by previous BFI maintenance and the
321958a3d8eSHongtao Yu   // probe distribution factor work for pseudo probes.
322958a3d8eSHongtao Yu   if (!Reader->profileIsFS())
323958a3d8eSHongtao Yu     return false;
324958a3d8eSHongtao Yu 
3255fdaaf7fSRong Xu   Function &Func = MF.getFunction();
3265fdaaf7fSRong Xu   clearFunctionData(false);
3275fdaaf7fSRong Xu   Samples = Reader->getSamplesFor(Func);
3285fdaaf7fSRong Xu   if (!Samples || Samples->empty())
3295fdaaf7fSRong Xu     return false;
3305fdaaf7fSRong Xu 
331b7d9322bSHongtao Yu   if (FunctionSamples::ProfileIsProbeBased) {
332b7d9322bSHongtao Yu     if (!ProbeManager->profileIsValid(MF.getFunction(), *Samples))
333b7d9322bSHongtao Yu       return false;
334b7d9322bSHongtao Yu   } else {
3355fdaaf7fSRong Xu     if (getFunctionLoc(MF) == 0)
3365fdaaf7fSRong Xu       return false;
337b7d9322bSHongtao Yu   }
3385fdaaf7fSRong Xu 
3395fdaaf7fSRong Xu   DenseSet<GlobalValue::GUID> InlinedGUIDs;
3405fdaaf7fSRong Xu   bool Changed = computeAndPropagateWeights(MF, InlinedGUIDs);
3415fdaaf7fSRong Xu 
3425fdaaf7fSRong Xu   // Set the new BPI, BFI.
3435fdaaf7fSRong Xu   setBranchProbs(MF);
3445fdaaf7fSRong Xu 
3455fdaaf7fSRong Xu   return Changed;
3465fdaaf7fSRong Xu }
3475fdaaf7fSRong Xu 
3485fdaaf7fSRong Xu } // namespace llvm
3495fdaaf7fSRong Xu 
350516e3017SSteven Wu MIRProfileLoaderPass::MIRProfileLoaderPass(
351516e3017SSteven Wu     std::string FileName, std::string RemappingFileName, FSDiscriminatorPass P,
352516e3017SSteven Wu     IntrusiveRefCntPtr<vfs::FileSystem> FS)
353516e3017SSteven Wu     : MachineFunctionPass(ID), ProfileFileName(FileName), P(P) {
3541e586bccSAdrian Prantl   LowBit = getFSPassBitBegin(P);
3551e586bccSAdrian Prantl   HighBit = getFSPassBitEnd(P);
356516e3017SSteven Wu 
357516e3017SSteven Wu   auto VFS = FS ? std::move(FS) : vfs::getRealFileSystem();
358516e3017SSteven Wu   MIRSampleLoader = std::make_unique<MIRProfileLoader>(
359516e3017SSteven Wu       FileName, RemappingFileName, std::move(VFS));
3601e586bccSAdrian Prantl   assert(LowBit < HighBit && "HighBit needs to be greater than Lowbit");
3611e586bccSAdrian Prantl }
3621e586bccSAdrian Prantl 
3635fdaaf7fSRong Xu bool MIRProfileLoaderPass::runOnMachineFunction(MachineFunction &MF) {
3645fdaaf7fSRong Xu   if (!MIRSampleLoader->isValid())
3655fdaaf7fSRong Xu     return false;
3665fdaaf7fSRong Xu 
3675fdaaf7fSRong Xu   LLVM_DEBUG(dbgs() << "MIRProfileLoader pass working on Func: "
3685fdaaf7fSRong Xu                     << MF.getFunction().getName() << "\n");
36909989996Spaperchalice   MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
370d871b2e0SAlexis Engelke   auto *MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
371d871b2e0SAlexis Engelke   auto *MPDT =
372d871b2e0SAlexis Engelke       &getAnalysis<MachinePostDominatorTreeWrapperPass>().getPostDomTree();
3735fdaaf7fSRong Xu 
3745fdaaf7fSRong Xu   MF.RenumberBlocks();
375d871b2e0SAlexis Engelke   MDT->updateBlockNumbers();
376d871b2e0SAlexis Engelke   MPDT->updateBlockNumbers();
377d871b2e0SAlexis Engelke 
378d871b2e0SAlexis Engelke   MIRSampleLoader->setInitVals(
379d871b2e0SAlexis Engelke       MDT, MPDT, &getAnalysis<MachineLoopInfoWrapperPass>().getLI(), MBFI,
380d871b2e0SAlexis Engelke       &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE());
381d871b2e0SAlexis Engelke 
3825fdaaf7fSRong Xu   if (ViewBFIBefore && ViewBlockLayoutWithBFI != GVDT_None &&
3835fdaaf7fSRong Xu       (ViewBlockFreqFuncName.empty() ||
384026a29e8SKazu Hirata        MF.getFunction().getName() == ViewBlockFreqFuncName)) {
3855fdaaf7fSRong Xu     MBFI->view("MIR_Prof_loader_b." + MF.getName(), false);
3865fdaaf7fSRong Xu   }
3875fdaaf7fSRong Xu 
3885fdaaf7fSRong Xu   bool Changed = MIRSampleLoader->runOnFunction(MF);
389bf113849SRong Xu   if (Changed)
39079d0de2aSpaperchalice     MBFI->calculate(MF, *MBFI->getMBPI(),
39179d0de2aSpaperchalice                     *&getAnalysis<MachineLoopInfoWrapperPass>().getLI());
3925fdaaf7fSRong Xu 
3935fdaaf7fSRong Xu   if (ViewBFIAfter && ViewBlockLayoutWithBFI != GVDT_None &&
3945fdaaf7fSRong Xu       (ViewBlockFreqFuncName.empty() ||
395026a29e8SKazu Hirata        MF.getFunction().getName() == ViewBlockFreqFuncName)) {
3965fdaaf7fSRong Xu     MBFI->view("MIR_prof_loader_a." + MF.getName(), false);
3975fdaaf7fSRong Xu   }
3985fdaaf7fSRong Xu 
3995fdaaf7fSRong Xu   return Changed;
4005fdaaf7fSRong Xu }
4015fdaaf7fSRong Xu 
4025fdaaf7fSRong Xu bool MIRProfileLoaderPass::doInitialization(Module &M) {
4035fdaaf7fSRong Xu   LLVM_DEBUG(dbgs() << "MIRProfileLoader pass working on Module " << M.getName()
4045fdaaf7fSRong Xu                     << "\n");
4055fdaaf7fSRong Xu 
4065fdaaf7fSRong Xu   MIRSampleLoader->setFSPass(P);
4075fdaaf7fSRong Xu   return MIRSampleLoader->doInitialization(M);
4085fdaaf7fSRong Xu }
4095fdaaf7fSRong Xu 
4105fdaaf7fSRong Xu void MIRProfileLoaderPass::getAnalysisUsage(AnalysisUsage &AU) const {
4115fdaaf7fSRong Xu   AU.setPreservesAll();
41209989996Spaperchalice   AU.addRequired<MachineBlockFrequencyInfoWrapperPass>();
413837dc542Spaperchalice   AU.addRequired<MachineDominatorTreeWrapperPass>();
4144b24c2dfSpaperchalice   AU.addRequired<MachinePostDominatorTreeWrapperPass>();
41579d0de2aSpaperchalice   AU.addRequiredTransitive<MachineLoopInfoWrapperPass>();
4165fdaaf7fSRong Xu   AU.addRequired<MachineOptimizationRemarkEmitterPass>();
4175fdaaf7fSRong Xu   MachineFunctionPass::getAnalysisUsage(AU);
4185fdaaf7fSRong Xu }
419