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