1*5fdaaf7fSRong Xu //===-------- MIRSampleProfile.cpp: MIRSampleFDO (For FSAFDO) -------------===//
2*5fdaaf7fSRong Xu //
3*5fdaaf7fSRong Xu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*5fdaaf7fSRong Xu // See https://llvm.org/LICENSE.txt for license information.
5*5fdaaf7fSRong Xu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*5fdaaf7fSRong Xu //
7*5fdaaf7fSRong Xu //===----------------------------------------------------------------------===//
8*5fdaaf7fSRong Xu //
9*5fdaaf7fSRong Xu // This file provides the implementation of the MIRSampleProfile loader, mainly
10*5fdaaf7fSRong Xu // for flow sensitive SampleFDO.
11*5fdaaf7fSRong Xu //
12*5fdaaf7fSRong Xu //===----------------------------------------------------------------------===//
13*5fdaaf7fSRong Xu 
14*5fdaaf7fSRong Xu #include "llvm/CodeGen/MIRSampleProfile.h"
15*5fdaaf7fSRong Xu #include "llvm/ADT/DenseMap.h"
16*5fdaaf7fSRong Xu #include "llvm/ADT/DenseSet.h"
17*5fdaaf7fSRong Xu #include "llvm/Analysis/BlockFrequencyInfoImpl.h"
18*5fdaaf7fSRong Xu #include "llvm/IR/Function.h"
19*5fdaaf7fSRong Xu #include "llvm/Support/CommandLine.h"
20*5fdaaf7fSRong Xu #include "llvm/Support/Debug.h"
21*5fdaaf7fSRong Xu #include "llvm/Support/raw_ostream.h"
22*5fdaaf7fSRong Xu #include "llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h"
23*5fdaaf7fSRong Xu #include "llvm/Transforms/Utils/SampleProfileLoaderBaseUtil.h"
24*5fdaaf7fSRong Xu 
25*5fdaaf7fSRong Xu using namespace llvm;
26*5fdaaf7fSRong Xu using namespace sampleprof;
27*5fdaaf7fSRong Xu using namespace llvm::sampleprofutil;
28*5fdaaf7fSRong Xu using ProfileCount = Function::ProfileCount;
29*5fdaaf7fSRong Xu 
30*5fdaaf7fSRong Xu #define DEBUG_TYPE "fs-profile-loader"
31*5fdaaf7fSRong Xu 
32*5fdaaf7fSRong Xu static cl::opt<bool> ShowFSBranchProb(
33*5fdaaf7fSRong Xu     "show-fs-branchprob", cl::Hidden, cl::init(false),
34*5fdaaf7fSRong Xu     cl::desc("Print setting flow sensitive branch probabilities"));
35*5fdaaf7fSRong Xu static cl::opt<unsigned> FSProfileDebugProbDiffThreshold(
36*5fdaaf7fSRong Xu     "fs-profile-debug-prob-diff-threshold", cl::init(10),
37*5fdaaf7fSRong Xu     cl::desc("Only show debug message if the branch probility is greater than "
38*5fdaaf7fSRong Xu              "this value (in percentage)."));
39*5fdaaf7fSRong Xu 
40*5fdaaf7fSRong Xu static cl::opt<unsigned> FSProfileDebugBWThreshold(
41*5fdaaf7fSRong Xu     "fs-profile-debug-bw-threshold", cl::init(10000),
42*5fdaaf7fSRong Xu     cl::desc("Only show debug message if the source branch weight is greater "
43*5fdaaf7fSRong Xu              " than this value."));
44*5fdaaf7fSRong Xu 
45*5fdaaf7fSRong Xu static cl::opt<bool> ViewBFIBefore("fs-viewbfi-before", cl::Hidden,
46*5fdaaf7fSRong Xu                                    cl::init(false),
47*5fdaaf7fSRong Xu                                    cl::desc("View BFI before MIR loader"));
48*5fdaaf7fSRong Xu static cl::opt<bool> ViewBFIAfter("fs-viewbfi-after", cl::Hidden,
49*5fdaaf7fSRong Xu                                   cl::init(false),
50*5fdaaf7fSRong Xu                                   cl::desc("View BFI after MIR loader"));
51*5fdaaf7fSRong Xu 
52*5fdaaf7fSRong Xu char MIRProfileLoaderPass::ID = 0;
53*5fdaaf7fSRong Xu 
54*5fdaaf7fSRong Xu INITIALIZE_PASS_BEGIN(MIRProfileLoaderPass, DEBUG_TYPE,
55*5fdaaf7fSRong Xu                       "Load MIR Sample Profile",
56*5fdaaf7fSRong Xu                       /* cfg = */ false, /* is_analysis = */ false)
57*5fdaaf7fSRong Xu INITIALIZE_PASS_DEPENDENCY(MachineBlockFrequencyInfo)
58*5fdaaf7fSRong Xu INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
59*5fdaaf7fSRong Xu INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTree)
60*5fdaaf7fSRong Xu INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
61*5fdaaf7fSRong Xu INITIALIZE_PASS_DEPENDENCY(MachineOptimizationRemarkEmitterPass)
62*5fdaaf7fSRong Xu INITIALIZE_PASS_END(MIRProfileLoaderPass, DEBUG_TYPE, "Load MIR Sample Profile",
63*5fdaaf7fSRong Xu                     /* cfg = */ false, /* is_analysis = */ false)
64*5fdaaf7fSRong Xu 
65*5fdaaf7fSRong Xu char &llvm::MIRProfileLoaderPassID = MIRProfileLoaderPass::ID;
66*5fdaaf7fSRong Xu 
67*5fdaaf7fSRong Xu FunctionPass *llvm::createMIRProfileLoaderPass(std::string File,
68*5fdaaf7fSRong Xu                                                std::string RemappingFile,
69*5fdaaf7fSRong Xu                                                FSDiscriminatorPass P) {
70*5fdaaf7fSRong Xu   return new MIRProfileLoaderPass(File, RemappingFile, P);
71*5fdaaf7fSRong Xu }
72*5fdaaf7fSRong Xu 
73*5fdaaf7fSRong Xu namespace llvm {
74*5fdaaf7fSRong Xu 
75*5fdaaf7fSRong Xu // Internal option used to control BFI display only after MBP pass.
76*5fdaaf7fSRong Xu // Defined in CodeGen/MachineBlockFrequencyInfo.cpp:
77*5fdaaf7fSRong Xu // -view-block-layout-with-bfi={none | fraction | integer | count}
78*5fdaaf7fSRong Xu extern cl::opt<GVDAGType> ViewBlockLayoutWithBFI;
79*5fdaaf7fSRong Xu 
80*5fdaaf7fSRong Xu // Command line option to specify the name of the function for CFG dump
81*5fdaaf7fSRong Xu // Defined in Analysis/BlockFrequencyInfo.cpp:  -view-bfi-func-name=
82*5fdaaf7fSRong Xu extern cl::opt<std::string> ViewBlockFreqFuncName;
83*5fdaaf7fSRong Xu 
84*5fdaaf7fSRong Xu namespace afdo_detail {
85*5fdaaf7fSRong Xu template <> struct IRTraits<MachineBasicBlock> {
86*5fdaaf7fSRong Xu   using InstructionT = MachineInstr;
87*5fdaaf7fSRong Xu   using BasicBlockT = MachineBasicBlock;
88*5fdaaf7fSRong Xu   using FunctionT = MachineFunction;
89*5fdaaf7fSRong Xu   using BlockFrequencyInfoT = MachineBlockFrequencyInfo;
90*5fdaaf7fSRong Xu   using LoopT = MachineLoop;
91*5fdaaf7fSRong Xu   using LoopInfoPtrT = MachineLoopInfo *;
92*5fdaaf7fSRong Xu   using DominatorTreePtrT = MachineDominatorTree *;
93*5fdaaf7fSRong Xu   using PostDominatorTreePtrT = MachinePostDominatorTree *;
94*5fdaaf7fSRong Xu   using PostDominatorTreeT = MachinePostDominatorTree;
95*5fdaaf7fSRong Xu   using OptRemarkEmitterT = MachineOptimizationRemarkEmitter;
96*5fdaaf7fSRong Xu   using OptRemarkAnalysisT = MachineOptimizationRemarkAnalysis;
97*5fdaaf7fSRong Xu   using PredRangeT = iterator_range<std::vector<MachineBasicBlock *>::iterator>;
98*5fdaaf7fSRong Xu   using SuccRangeT = iterator_range<std::vector<MachineBasicBlock *>::iterator>;
99*5fdaaf7fSRong Xu   static Function &getFunction(MachineFunction &F) { return F.getFunction(); }
100*5fdaaf7fSRong Xu   static const MachineBasicBlock *getEntryBB(const MachineFunction *F) {
101*5fdaaf7fSRong Xu     return GraphTraits<const MachineFunction *>::getEntryNode(F);
102*5fdaaf7fSRong Xu   }
103*5fdaaf7fSRong Xu   static PredRangeT getPredecessors(MachineBasicBlock *BB) {
104*5fdaaf7fSRong Xu     return BB->predecessors();
105*5fdaaf7fSRong Xu   }
106*5fdaaf7fSRong Xu   static SuccRangeT getSuccessors(MachineBasicBlock *BB) {
107*5fdaaf7fSRong Xu     return BB->successors();
108*5fdaaf7fSRong Xu   }
109*5fdaaf7fSRong Xu };
110*5fdaaf7fSRong Xu } // namespace afdo_detail
111*5fdaaf7fSRong Xu 
112*5fdaaf7fSRong Xu class MIRProfileLoader final
113*5fdaaf7fSRong Xu     : public SampleProfileLoaderBaseImpl<MachineBasicBlock> {
114*5fdaaf7fSRong Xu public:
115*5fdaaf7fSRong Xu   void setInitVals(MachineDominatorTree *MDT, MachinePostDominatorTree *MPDT,
116*5fdaaf7fSRong Xu                    MachineLoopInfo *MLI, MachineBlockFrequencyInfo *MBFI,
117*5fdaaf7fSRong Xu                    MachineOptimizationRemarkEmitter *MORE) {
118*5fdaaf7fSRong Xu     DT = MDT;
119*5fdaaf7fSRong Xu     PDT = MPDT;
120*5fdaaf7fSRong Xu     LI = MLI;
121*5fdaaf7fSRong Xu     BFI = MBFI;
122*5fdaaf7fSRong Xu     ORE = MORE;
123*5fdaaf7fSRong Xu   }
124*5fdaaf7fSRong Xu   void setFSPass(FSDiscriminatorPass Pass) {
125*5fdaaf7fSRong Xu     P = Pass;
126*5fdaaf7fSRong Xu     LowBit = getFSPassBitBegin(P);
127*5fdaaf7fSRong Xu     HighBit = getFSPassBitEnd(P);
128*5fdaaf7fSRong Xu     assert(LowBit < HighBit && "HighBit needs to be greater than Lowbit");
129*5fdaaf7fSRong Xu   }
130*5fdaaf7fSRong Xu 
131*5fdaaf7fSRong Xu   MIRProfileLoader(StringRef Name, StringRef RemapName)
132*5fdaaf7fSRong Xu       : SampleProfileLoaderBaseImpl(std::string(Name), std::string(RemapName)) {
133*5fdaaf7fSRong Xu   }
134*5fdaaf7fSRong Xu 
135*5fdaaf7fSRong Xu   void setBranchProbs(MachineFunction &F);
136*5fdaaf7fSRong Xu   bool runOnFunction(MachineFunction &F);
137*5fdaaf7fSRong Xu   bool doInitialization(Module &M);
138*5fdaaf7fSRong Xu   bool isValid() const { return ProfileIsValid; }
139*5fdaaf7fSRong Xu 
140*5fdaaf7fSRong Xu protected:
141*5fdaaf7fSRong Xu   friend class SampleCoverageTracker;
142*5fdaaf7fSRong Xu 
143*5fdaaf7fSRong Xu   /// Hold the information of the basic block frequency.
144*5fdaaf7fSRong Xu   MachineBlockFrequencyInfo *BFI;
145*5fdaaf7fSRong Xu 
146*5fdaaf7fSRong Xu   /// PassNum is the sequence number this pass is called, start from 1.
147*5fdaaf7fSRong Xu   FSDiscriminatorPass P;
148*5fdaaf7fSRong Xu 
149*5fdaaf7fSRong Xu   // LowBit in the FS discriminator used by this instance. Note the number is
150*5fdaaf7fSRong Xu   // 0-based. Base discrimnator use bit 0 to bit 11.
151*5fdaaf7fSRong Xu   unsigned LowBit;
152*5fdaaf7fSRong Xu   // HighwBit in the FS discriminator used by this instance. Note the number
153*5fdaaf7fSRong Xu   // is 0-based.
154*5fdaaf7fSRong Xu   unsigned HighBit;
155*5fdaaf7fSRong Xu 
156*5fdaaf7fSRong Xu   bool ProfileIsValid = true;
157*5fdaaf7fSRong Xu };
158*5fdaaf7fSRong Xu 
159*5fdaaf7fSRong Xu template <>
160*5fdaaf7fSRong Xu void SampleProfileLoaderBaseImpl<
161*5fdaaf7fSRong Xu     MachineBasicBlock>::computeDominanceAndLoopInfo(MachineFunction &F) {}
162*5fdaaf7fSRong Xu 
163*5fdaaf7fSRong Xu void MIRProfileLoader::setBranchProbs(MachineFunction &F) {
164*5fdaaf7fSRong Xu   LLVM_DEBUG(dbgs() << "\nPropagation complete. Setting branch probs\n");
165*5fdaaf7fSRong Xu   for (auto &BI : F) {
166*5fdaaf7fSRong Xu     MachineBasicBlock *BB = &BI;
167*5fdaaf7fSRong Xu     if (BB->succ_size() < 2)
168*5fdaaf7fSRong Xu       continue;
169*5fdaaf7fSRong Xu     const MachineBasicBlock *EC = EquivalenceClass[BB];
170*5fdaaf7fSRong Xu     uint64_t BBWeight = BlockWeights[EC];
171*5fdaaf7fSRong Xu     uint64_t SumEdgeWeight = 0;
172*5fdaaf7fSRong Xu     for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(),
173*5fdaaf7fSRong Xu                                           SE = BB->succ_end();
174*5fdaaf7fSRong Xu          SI != SE; ++SI) {
175*5fdaaf7fSRong Xu       MachineBasicBlock *Succ = *SI;
176*5fdaaf7fSRong Xu       Edge E = std::make_pair(BB, Succ);
177*5fdaaf7fSRong Xu       SumEdgeWeight += EdgeWeights[E];
178*5fdaaf7fSRong Xu     }
179*5fdaaf7fSRong Xu 
180*5fdaaf7fSRong Xu     if (BBWeight != SumEdgeWeight) {
181*5fdaaf7fSRong Xu       LLVM_DEBUG(dbgs() << "BBweight is not equal to SumEdgeWeight: BBWWeight="
182*5fdaaf7fSRong Xu                         << BBWeight << " SumEdgeWeight= " << SumEdgeWeight
183*5fdaaf7fSRong Xu                         << "\n");
184*5fdaaf7fSRong Xu       BBWeight = SumEdgeWeight;
185*5fdaaf7fSRong Xu     }
186*5fdaaf7fSRong Xu     if (BBWeight == 0) {
187*5fdaaf7fSRong Xu       LLVM_DEBUG(dbgs() << "SKIPPED. All branch weights are zero.\n");
188*5fdaaf7fSRong Xu       continue;
189*5fdaaf7fSRong Xu     }
190*5fdaaf7fSRong Xu 
191*5fdaaf7fSRong Xu #ifndef NDEBUG
192*5fdaaf7fSRong Xu     uint64_t BBWeightOrig = BBWeight;
193*5fdaaf7fSRong Xu #endif
194*5fdaaf7fSRong Xu     uint32_t MaxWeight = std::numeric_limits<uint32_t>::max();
195*5fdaaf7fSRong Xu     uint32_t Factor = 1;
196*5fdaaf7fSRong Xu     if (BBWeight > MaxWeight) {
197*5fdaaf7fSRong Xu       Factor = BBWeight / MaxWeight + 1;
198*5fdaaf7fSRong Xu       BBWeight /= Factor;
199*5fdaaf7fSRong Xu       LLVM_DEBUG(dbgs() << "Scaling weights by " << Factor << "\n");
200*5fdaaf7fSRong Xu     }
201*5fdaaf7fSRong Xu 
202*5fdaaf7fSRong Xu     for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(),
203*5fdaaf7fSRong Xu                                           SE = BB->succ_end();
204*5fdaaf7fSRong Xu          SI != SE; ++SI) {
205*5fdaaf7fSRong Xu       MachineBasicBlock *Succ = *SI;
206*5fdaaf7fSRong Xu       Edge E = std::make_pair(BB, Succ);
207*5fdaaf7fSRong Xu       uint64_t EdgeWeight = EdgeWeights[E];
208*5fdaaf7fSRong Xu       EdgeWeight /= Factor;
209*5fdaaf7fSRong Xu 
210*5fdaaf7fSRong Xu       assert(BBWeight >= EdgeWeight &&
211*5fdaaf7fSRong Xu              "BBweight is larger than EdgeWeight -- should not happen.\n");
212*5fdaaf7fSRong Xu 
213*5fdaaf7fSRong Xu       BranchProbability OldProb = BFI->getMBPI()->getEdgeProbability(BB, SI);
214*5fdaaf7fSRong Xu       BranchProbability NewProb(EdgeWeight, BBWeight);
215*5fdaaf7fSRong Xu       if (OldProb == NewProb)
216*5fdaaf7fSRong Xu         continue;
217*5fdaaf7fSRong Xu       BB->setSuccProbability(SI, NewProb);
218*5fdaaf7fSRong Xu #ifndef NDEBUG
219*5fdaaf7fSRong Xu       if (!ShowFSBranchProb)
220*5fdaaf7fSRong Xu         continue;
221*5fdaaf7fSRong Xu       bool Show = false;
222*5fdaaf7fSRong Xu       BranchProbability Diff;
223*5fdaaf7fSRong Xu       if (OldProb > NewProb)
224*5fdaaf7fSRong Xu         Diff = OldProb - NewProb;
225*5fdaaf7fSRong Xu       else
226*5fdaaf7fSRong Xu         Diff = NewProb - OldProb;
227*5fdaaf7fSRong Xu       Show = (Diff >= BranchProbability(FSProfileDebugProbDiffThreshold, 100));
228*5fdaaf7fSRong Xu       Show &= (BBWeightOrig >= FSProfileDebugBWThreshold);
229*5fdaaf7fSRong Xu 
230*5fdaaf7fSRong Xu       auto DIL = BB->findBranchDebugLoc();
231*5fdaaf7fSRong Xu       auto SuccDIL = Succ->findBranchDebugLoc();
232*5fdaaf7fSRong Xu       if (Show) {
233*5fdaaf7fSRong Xu         dbgs() << "Set branch fs prob: MBB (" << BB->getNumber() << " -> "
234*5fdaaf7fSRong Xu                << Succ->getNumber() << "): ";
235*5fdaaf7fSRong Xu         if (DIL)
236*5fdaaf7fSRong Xu           dbgs() << DIL->getFilename() << ":" << DIL->getLine() << ":"
237*5fdaaf7fSRong Xu                  << DIL->getColumn();
238*5fdaaf7fSRong Xu         if (SuccDIL)
239*5fdaaf7fSRong Xu           dbgs() << "-->" << SuccDIL->getFilename() << ":" << SuccDIL->getLine()
240*5fdaaf7fSRong Xu                  << ":" << SuccDIL->getColumn();
241*5fdaaf7fSRong Xu         dbgs() << " W=" << BBWeightOrig << "  " << OldProb << " --> " << NewProb
242*5fdaaf7fSRong Xu                << "\n";
243*5fdaaf7fSRong Xu       }
244*5fdaaf7fSRong Xu #endif
245*5fdaaf7fSRong Xu     }
246*5fdaaf7fSRong Xu   }
247*5fdaaf7fSRong Xu }
248*5fdaaf7fSRong Xu 
249*5fdaaf7fSRong Xu bool MIRProfileLoader::doInitialization(Module &M) {
250*5fdaaf7fSRong Xu   auto &Ctx = M.getContext();
251*5fdaaf7fSRong Xu 
252*5fdaaf7fSRong Xu   auto ReaderOrErr = sampleprof::SampleProfileReader::create(Filename, Ctx, P,
253*5fdaaf7fSRong Xu                                                              RemappingFilename);
254*5fdaaf7fSRong Xu   if (std::error_code EC = ReaderOrErr.getError()) {
255*5fdaaf7fSRong Xu     std::string Msg = "Could not open profile: " + EC.message();
256*5fdaaf7fSRong Xu     Ctx.diagnose(DiagnosticInfoSampleProfile(Filename, Msg));
257*5fdaaf7fSRong Xu     return false;
258*5fdaaf7fSRong Xu   }
259*5fdaaf7fSRong Xu 
260*5fdaaf7fSRong Xu   Reader = std::move(ReaderOrErr.get());
261*5fdaaf7fSRong Xu   Reader->setModule(&M);
262*5fdaaf7fSRong Xu   ProfileIsValid = (Reader->read() == sampleprof_error::success);
263*5fdaaf7fSRong Xu   Reader->getSummary();
264*5fdaaf7fSRong Xu 
265*5fdaaf7fSRong Xu   return true;
266*5fdaaf7fSRong Xu }
267*5fdaaf7fSRong Xu 
268*5fdaaf7fSRong Xu bool MIRProfileLoader::runOnFunction(MachineFunction &MF) {
269*5fdaaf7fSRong Xu   Function &Func = MF.getFunction();
270*5fdaaf7fSRong Xu   clearFunctionData(false);
271*5fdaaf7fSRong Xu   Samples = Reader->getSamplesFor(Func);
272*5fdaaf7fSRong Xu   if (!Samples || Samples->empty())
273*5fdaaf7fSRong Xu     return false;
274*5fdaaf7fSRong Xu 
275*5fdaaf7fSRong Xu   if (getFunctionLoc(MF) == 0)
276*5fdaaf7fSRong Xu     return false;
277*5fdaaf7fSRong Xu 
278*5fdaaf7fSRong Xu   DenseSet<GlobalValue::GUID> InlinedGUIDs;
279*5fdaaf7fSRong Xu   bool Changed = computeAndPropagateWeights(MF, InlinedGUIDs);
280*5fdaaf7fSRong Xu 
281*5fdaaf7fSRong Xu   // Set the new BPI, BFI.
282*5fdaaf7fSRong Xu   setBranchProbs(MF);
283*5fdaaf7fSRong Xu 
284*5fdaaf7fSRong Xu   return Changed;
285*5fdaaf7fSRong Xu }
286*5fdaaf7fSRong Xu 
287*5fdaaf7fSRong Xu } // namespace llvm
288*5fdaaf7fSRong Xu 
289*5fdaaf7fSRong Xu bool MIRProfileLoaderPass::runOnMachineFunction(MachineFunction &MF) {
290*5fdaaf7fSRong Xu   if (!MIRSampleLoader->isValid())
291*5fdaaf7fSRong Xu     return false;
292*5fdaaf7fSRong Xu 
293*5fdaaf7fSRong Xu   LLVM_DEBUG(dbgs() << "MIRProfileLoader pass working on Func: "
294*5fdaaf7fSRong Xu                     << MF.getFunction().getName() << "\n");
295*5fdaaf7fSRong Xu   MBFI = &getAnalysis<MachineBlockFrequencyInfo>();
296*5fdaaf7fSRong Xu   MIRSampleLoader->setInitVals(
297*5fdaaf7fSRong Xu       &getAnalysis<MachineDominatorTree>(),
298*5fdaaf7fSRong Xu       &getAnalysis<MachinePostDominatorTree>(), &getAnalysis<MachineLoopInfo>(),
299*5fdaaf7fSRong Xu       MBFI, &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE());
300*5fdaaf7fSRong Xu 
301*5fdaaf7fSRong Xu   MF.RenumberBlocks();
302*5fdaaf7fSRong Xu   if (ViewBFIBefore && ViewBlockLayoutWithBFI != GVDT_None &&
303*5fdaaf7fSRong Xu       (ViewBlockFreqFuncName.empty() ||
304*5fdaaf7fSRong Xu        MF.getFunction().getName().equals(ViewBlockFreqFuncName))) {
305*5fdaaf7fSRong Xu     MBFI->view("MIR_Prof_loader_b." + MF.getName(), false);
306*5fdaaf7fSRong Xu   }
307*5fdaaf7fSRong Xu 
308*5fdaaf7fSRong Xu   bool Changed = MIRSampleLoader->runOnFunction(MF);
309*5fdaaf7fSRong Xu 
310*5fdaaf7fSRong Xu   if (ViewBFIAfter && ViewBlockLayoutWithBFI != GVDT_None &&
311*5fdaaf7fSRong Xu       (ViewBlockFreqFuncName.empty() ||
312*5fdaaf7fSRong Xu        MF.getFunction().getName().equals(ViewBlockFreqFuncName))) {
313*5fdaaf7fSRong Xu     MBFI->view("MIR_prof_loader_a." + MF.getName(), false);
314*5fdaaf7fSRong Xu   }
315*5fdaaf7fSRong Xu 
316*5fdaaf7fSRong Xu   return Changed;
317*5fdaaf7fSRong Xu }
318*5fdaaf7fSRong Xu 
319*5fdaaf7fSRong Xu bool MIRProfileLoaderPass::doInitialization(Module &M) {
320*5fdaaf7fSRong Xu   LLVM_DEBUG(dbgs() << "MIRProfileLoader pass working on Module " << M.getName()
321*5fdaaf7fSRong Xu                     << "\n");
322*5fdaaf7fSRong Xu 
323*5fdaaf7fSRong Xu   MIRSampleLoader->setFSPass(P);
324*5fdaaf7fSRong Xu   return MIRSampleLoader->doInitialization(M);
325*5fdaaf7fSRong Xu }
326*5fdaaf7fSRong Xu 
327*5fdaaf7fSRong Xu void MIRProfileLoaderPass::getAnalysisUsage(AnalysisUsage &AU) const {
328*5fdaaf7fSRong Xu   AU.setPreservesAll();
329*5fdaaf7fSRong Xu   AU.addRequired<MachineBlockFrequencyInfo>();
330*5fdaaf7fSRong Xu   AU.addRequired<MachineDominatorTree>();
331*5fdaaf7fSRong Xu   AU.addRequired<MachinePostDominatorTree>();
332*5fdaaf7fSRong Xu   AU.addRequiredTransitive<MachineLoopInfo>();
333*5fdaaf7fSRong Xu   AU.addRequired<MachineOptimizationRemarkEmitterPass>();
334*5fdaaf7fSRong Xu   MachineFunctionPass::getAnalysisUsage(AU);
335*5fdaaf7fSRong Xu }
336