xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/MIRSampleProfile.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
1349cc55cSDimitry Andric //===-------- MIRSampleProfile.cpp: MIRSampleFDO (For FSAFDO) -------------===//
2349cc55cSDimitry Andric //
3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6349cc55cSDimitry Andric //
7349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
8349cc55cSDimitry Andric //
9349cc55cSDimitry Andric // This file provides the implementation of the MIRSampleProfile loader, mainly
10349cc55cSDimitry Andric // for flow sensitive SampleFDO.
11349cc55cSDimitry Andric //
12349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
13349cc55cSDimitry Andric 
14349cc55cSDimitry Andric #include "llvm/CodeGen/MIRSampleProfile.h"
15349cc55cSDimitry Andric #include "llvm/ADT/DenseMap.h"
16349cc55cSDimitry Andric #include "llvm/ADT/DenseSet.h"
17349cc55cSDimitry Andric #include "llvm/Analysis/BlockFrequencyInfoImpl.h"
18*81ad6265SDimitry Andric #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
19*81ad6265SDimitry Andric #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
20*81ad6265SDimitry Andric #include "llvm/CodeGen/MachineDominators.h"
21*81ad6265SDimitry Andric #include "llvm/CodeGen/MachineLoopInfo.h"
22*81ad6265SDimitry Andric #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
23*81ad6265SDimitry Andric #include "llvm/CodeGen/MachinePostDominators.h"
24*81ad6265SDimitry Andric #include "llvm/CodeGen/Passes.h"
25349cc55cSDimitry Andric #include "llvm/IR/Function.h"
26*81ad6265SDimitry Andric #include "llvm/InitializePasses.h"
27349cc55cSDimitry Andric #include "llvm/Support/CommandLine.h"
28349cc55cSDimitry Andric #include "llvm/Support/Debug.h"
29349cc55cSDimitry Andric #include "llvm/Support/raw_ostream.h"
30349cc55cSDimitry Andric #include "llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h"
31349cc55cSDimitry Andric #include "llvm/Transforms/Utils/SampleProfileLoaderBaseUtil.h"
32349cc55cSDimitry Andric 
33349cc55cSDimitry Andric using namespace llvm;
34349cc55cSDimitry Andric using namespace sampleprof;
35349cc55cSDimitry Andric using namespace llvm::sampleprofutil;
36349cc55cSDimitry Andric using ProfileCount = Function::ProfileCount;
37349cc55cSDimitry Andric 
38349cc55cSDimitry Andric #define DEBUG_TYPE "fs-profile-loader"
39349cc55cSDimitry Andric 
40349cc55cSDimitry Andric static cl::opt<bool> ShowFSBranchProb(
41349cc55cSDimitry Andric     "show-fs-branchprob", cl::Hidden, cl::init(false),
42349cc55cSDimitry Andric     cl::desc("Print setting flow sensitive branch probabilities"));
43349cc55cSDimitry Andric static cl::opt<unsigned> FSProfileDebugProbDiffThreshold(
44349cc55cSDimitry Andric     "fs-profile-debug-prob-diff-threshold", cl::init(10),
45349cc55cSDimitry Andric     cl::desc("Only show debug message if the branch probility is greater than "
46349cc55cSDimitry Andric              "this value (in percentage)."));
47349cc55cSDimitry Andric 
48349cc55cSDimitry Andric static cl::opt<unsigned> FSProfileDebugBWThreshold(
49349cc55cSDimitry Andric     "fs-profile-debug-bw-threshold", cl::init(10000),
50349cc55cSDimitry Andric     cl::desc("Only show debug message if the source branch weight is greater "
51349cc55cSDimitry Andric              " than this value."));
52349cc55cSDimitry Andric 
53349cc55cSDimitry Andric static cl::opt<bool> ViewBFIBefore("fs-viewbfi-before", cl::Hidden,
54349cc55cSDimitry Andric                                    cl::init(false),
55349cc55cSDimitry Andric                                    cl::desc("View BFI before MIR loader"));
56349cc55cSDimitry Andric static cl::opt<bool> ViewBFIAfter("fs-viewbfi-after", cl::Hidden,
57349cc55cSDimitry Andric                                   cl::init(false),
58349cc55cSDimitry Andric                                   cl::desc("View BFI after MIR loader"));
59349cc55cSDimitry Andric 
60349cc55cSDimitry Andric char MIRProfileLoaderPass::ID = 0;
61349cc55cSDimitry Andric 
62349cc55cSDimitry Andric INITIALIZE_PASS_BEGIN(MIRProfileLoaderPass, DEBUG_TYPE,
63349cc55cSDimitry Andric                       "Load MIR Sample Profile",
64349cc55cSDimitry Andric                       /* cfg = */ false, /* is_analysis = */ false)
65349cc55cSDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineBlockFrequencyInfo)
66349cc55cSDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
67349cc55cSDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTree)
68349cc55cSDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
69349cc55cSDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineOptimizationRemarkEmitterPass)
70349cc55cSDimitry Andric INITIALIZE_PASS_END(MIRProfileLoaderPass, DEBUG_TYPE, "Load MIR Sample Profile",
71349cc55cSDimitry Andric                     /* cfg = */ false, /* is_analysis = */ false)
72349cc55cSDimitry Andric 
73349cc55cSDimitry Andric char &llvm::MIRProfileLoaderPassID = MIRProfileLoaderPass::ID;
74349cc55cSDimitry Andric 
75349cc55cSDimitry Andric FunctionPass *llvm::createMIRProfileLoaderPass(std::string File,
76349cc55cSDimitry Andric                                                std::string RemappingFile,
77349cc55cSDimitry Andric                                                FSDiscriminatorPass P) {
78349cc55cSDimitry Andric   return new MIRProfileLoaderPass(File, RemappingFile, P);
79349cc55cSDimitry Andric }
80349cc55cSDimitry Andric 
81349cc55cSDimitry Andric namespace llvm {
82349cc55cSDimitry Andric 
83349cc55cSDimitry Andric // Internal option used to control BFI display only after MBP pass.
84349cc55cSDimitry Andric // Defined in CodeGen/MachineBlockFrequencyInfo.cpp:
85349cc55cSDimitry Andric // -view-block-layout-with-bfi={none | fraction | integer | count}
86349cc55cSDimitry Andric extern cl::opt<GVDAGType> ViewBlockLayoutWithBFI;
87349cc55cSDimitry Andric 
88349cc55cSDimitry Andric // Command line option to specify the name of the function for CFG dump
89349cc55cSDimitry Andric // Defined in Analysis/BlockFrequencyInfo.cpp:  -view-bfi-func-name=
90349cc55cSDimitry Andric extern cl::opt<std::string> ViewBlockFreqFuncName;
91349cc55cSDimitry Andric 
92349cc55cSDimitry Andric namespace afdo_detail {
93349cc55cSDimitry Andric template <> struct IRTraits<MachineBasicBlock> {
94349cc55cSDimitry Andric   using InstructionT = MachineInstr;
95349cc55cSDimitry Andric   using BasicBlockT = MachineBasicBlock;
96349cc55cSDimitry Andric   using FunctionT = MachineFunction;
97349cc55cSDimitry Andric   using BlockFrequencyInfoT = MachineBlockFrequencyInfo;
98349cc55cSDimitry Andric   using LoopT = MachineLoop;
99349cc55cSDimitry Andric   using LoopInfoPtrT = MachineLoopInfo *;
100349cc55cSDimitry Andric   using DominatorTreePtrT = MachineDominatorTree *;
101349cc55cSDimitry Andric   using PostDominatorTreePtrT = MachinePostDominatorTree *;
102349cc55cSDimitry Andric   using PostDominatorTreeT = MachinePostDominatorTree;
103349cc55cSDimitry Andric   using OptRemarkEmitterT = MachineOptimizationRemarkEmitter;
104349cc55cSDimitry Andric   using OptRemarkAnalysisT = MachineOptimizationRemarkAnalysis;
105349cc55cSDimitry Andric   using PredRangeT = iterator_range<std::vector<MachineBasicBlock *>::iterator>;
106349cc55cSDimitry Andric   using SuccRangeT = iterator_range<std::vector<MachineBasicBlock *>::iterator>;
107349cc55cSDimitry Andric   static Function &getFunction(MachineFunction &F) { return F.getFunction(); }
108349cc55cSDimitry Andric   static const MachineBasicBlock *getEntryBB(const MachineFunction *F) {
109349cc55cSDimitry Andric     return GraphTraits<const MachineFunction *>::getEntryNode(F);
110349cc55cSDimitry Andric   }
111349cc55cSDimitry Andric   static PredRangeT getPredecessors(MachineBasicBlock *BB) {
112349cc55cSDimitry Andric     return BB->predecessors();
113349cc55cSDimitry Andric   }
114349cc55cSDimitry Andric   static SuccRangeT getSuccessors(MachineBasicBlock *BB) {
115349cc55cSDimitry Andric     return BB->successors();
116349cc55cSDimitry Andric   }
117349cc55cSDimitry Andric };
118349cc55cSDimitry Andric } // namespace afdo_detail
119349cc55cSDimitry Andric 
120349cc55cSDimitry Andric class MIRProfileLoader final
121349cc55cSDimitry Andric     : public SampleProfileLoaderBaseImpl<MachineBasicBlock> {
122349cc55cSDimitry Andric public:
123349cc55cSDimitry Andric   void setInitVals(MachineDominatorTree *MDT, MachinePostDominatorTree *MPDT,
124349cc55cSDimitry Andric                    MachineLoopInfo *MLI, MachineBlockFrequencyInfo *MBFI,
125349cc55cSDimitry Andric                    MachineOptimizationRemarkEmitter *MORE) {
126349cc55cSDimitry Andric     DT = MDT;
127349cc55cSDimitry Andric     PDT = MPDT;
128349cc55cSDimitry Andric     LI = MLI;
129349cc55cSDimitry Andric     BFI = MBFI;
130349cc55cSDimitry Andric     ORE = MORE;
131349cc55cSDimitry Andric   }
132349cc55cSDimitry Andric   void setFSPass(FSDiscriminatorPass Pass) {
133349cc55cSDimitry Andric     P = Pass;
134349cc55cSDimitry Andric     LowBit = getFSPassBitBegin(P);
135349cc55cSDimitry Andric     HighBit = getFSPassBitEnd(P);
136349cc55cSDimitry Andric     assert(LowBit < HighBit && "HighBit needs to be greater than Lowbit");
137349cc55cSDimitry Andric   }
138349cc55cSDimitry Andric 
139349cc55cSDimitry Andric   MIRProfileLoader(StringRef Name, StringRef RemapName)
140349cc55cSDimitry Andric       : SampleProfileLoaderBaseImpl(std::string(Name), std::string(RemapName)) {
141349cc55cSDimitry Andric   }
142349cc55cSDimitry Andric 
143349cc55cSDimitry Andric   void setBranchProbs(MachineFunction &F);
144349cc55cSDimitry Andric   bool runOnFunction(MachineFunction &F);
145349cc55cSDimitry Andric   bool doInitialization(Module &M);
146349cc55cSDimitry Andric   bool isValid() const { return ProfileIsValid; }
147349cc55cSDimitry Andric 
148349cc55cSDimitry Andric protected:
149349cc55cSDimitry Andric   friend class SampleCoverageTracker;
150349cc55cSDimitry Andric 
151349cc55cSDimitry Andric   /// Hold the information of the basic block frequency.
152349cc55cSDimitry Andric   MachineBlockFrequencyInfo *BFI;
153349cc55cSDimitry Andric 
154349cc55cSDimitry Andric   /// PassNum is the sequence number this pass is called, start from 1.
155349cc55cSDimitry Andric   FSDiscriminatorPass P;
156349cc55cSDimitry Andric 
157349cc55cSDimitry Andric   // LowBit in the FS discriminator used by this instance. Note the number is
158349cc55cSDimitry Andric   // 0-based. Base discrimnator use bit 0 to bit 11.
159349cc55cSDimitry Andric   unsigned LowBit;
160349cc55cSDimitry Andric   // HighwBit in the FS discriminator used by this instance. Note the number
161349cc55cSDimitry Andric   // is 0-based.
162349cc55cSDimitry Andric   unsigned HighBit;
163349cc55cSDimitry Andric 
164349cc55cSDimitry Andric   bool ProfileIsValid = true;
165349cc55cSDimitry Andric };
166349cc55cSDimitry Andric 
167349cc55cSDimitry Andric template <>
168349cc55cSDimitry Andric void SampleProfileLoaderBaseImpl<
169349cc55cSDimitry Andric     MachineBasicBlock>::computeDominanceAndLoopInfo(MachineFunction &F) {}
170349cc55cSDimitry Andric 
171349cc55cSDimitry Andric void MIRProfileLoader::setBranchProbs(MachineFunction &F) {
172349cc55cSDimitry Andric   LLVM_DEBUG(dbgs() << "\nPropagation complete. Setting branch probs\n");
173349cc55cSDimitry Andric   for (auto &BI : F) {
174349cc55cSDimitry Andric     MachineBasicBlock *BB = &BI;
175349cc55cSDimitry Andric     if (BB->succ_size() < 2)
176349cc55cSDimitry Andric       continue;
177349cc55cSDimitry Andric     const MachineBasicBlock *EC = EquivalenceClass[BB];
178349cc55cSDimitry Andric     uint64_t BBWeight = BlockWeights[EC];
179349cc55cSDimitry Andric     uint64_t SumEdgeWeight = 0;
180349cc55cSDimitry Andric     for (MachineBasicBlock *Succ : BB->successors()) {
181349cc55cSDimitry Andric       Edge E = std::make_pair(BB, Succ);
182349cc55cSDimitry Andric       SumEdgeWeight += EdgeWeights[E];
183349cc55cSDimitry Andric     }
184349cc55cSDimitry Andric 
185349cc55cSDimitry Andric     if (BBWeight != SumEdgeWeight) {
186349cc55cSDimitry Andric       LLVM_DEBUG(dbgs() << "BBweight is not equal to SumEdgeWeight: BBWWeight="
187349cc55cSDimitry Andric                         << BBWeight << " SumEdgeWeight= " << SumEdgeWeight
188349cc55cSDimitry Andric                         << "\n");
189349cc55cSDimitry Andric       BBWeight = SumEdgeWeight;
190349cc55cSDimitry Andric     }
191349cc55cSDimitry Andric     if (BBWeight == 0) {
192349cc55cSDimitry Andric       LLVM_DEBUG(dbgs() << "SKIPPED. All branch weights are zero.\n");
193349cc55cSDimitry Andric       continue;
194349cc55cSDimitry Andric     }
195349cc55cSDimitry Andric 
196349cc55cSDimitry Andric #ifndef NDEBUG
197349cc55cSDimitry Andric     uint64_t BBWeightOrig = BBWeight;
198349cc55cSDimitry Andric #endif
199349cc55cSDimitry Andric     uint32_t MaxWeight = std::numeric_limits<uint32_t>::max();
200349cc55cSDimitry Andric     uint32_t Factor = 1;
201349cc55cSDimitry Andric     if (BBWeight > MaxWeight) {
202349cc55cSDimitry Andric       Factor = BBWeight / MaxWeight + 1;
203349cc55cSDimitry Andric       BBWeight /= Factor;
204349cc55cSDimitry Andric       LLVM_DEBUG(dbgs() << "Scaling weights by " << Factor << "\n");
205349cc55cSDimitry Andric     }
206349cc55cSDimitry Andric 
207349cc55cSDimitry Andric     for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(),
208349cc55cSDimitry Andric                                           SE = BB->succ_end();
209349cc55cSDimitry Andric          SI != SE; ++SI) {
210349cc55cSDimitry Andric       MachineBasicBlock *Succ = *SI;
211349cc55cSDimitry Andric       Edge E = std::make_pair(BB, Succ);
212349cc55cSDimitry Andric       uint64_t EdgeWeight = EdgeWeights[E];
213349cc55cSDimitry Andric       EdgeWeight /= Factor;
214349cc55cSDimitry Andric 
215349cc55cSDimitry Andric       assert(BBWeight >= EdgeWeight &&
216349cc55cSDimitry Andric              "BBweight is larger than EdgeWeight -- should not happen.\n");
217349cc55cSDimitry Andric 
218349cc55cSDimitry Andric       BranchProbability OldProb = BFI->getMBPI()->getEdgeProbability(BB, SI);
219349cc55cSDimitry Andric       BranchProbability NewProb(EdgeWeight, BBWeight);
220349cc55cSDimitry Andric       if (OldProb == NewProb)
221349cc55cSDimitry Andric         continue;
222349cc55cSDimitry Andric       BB->setSuccProbability(SI, NewProb);
223349cc55cSDimitry Andric #ifndef NDEBUG
224349cc55cSDimitry Andric       if (!ShowFSBranchProb)
225349cc55cSDimitry Andric         continue;
226349cc55cSDimitry Andric       bool Show = false;
227349cc55cSDimitry Andric       BranchProbability Diff;
228349cc55cSDimitry Andric       if (OldProb > NewProb)
229349cc55cSDimitry Andric         Diff = OldProb - NewProb;
230349cc55cSDimitry Andric       else
231349cc55cSDimitry Andric         Diff = NewProb - OldProb;
232349cc55cSDimitry Andric       Show = (Diff >= BranchProbability(FSProfileDebugProbDiffThreshold, 100));
233349cc55cSDimitry Andric       Show &= (BBWeightOrig >= FSProfileDebugBWThreshold);
234349cc55cSDimitry Andric 
235349cc55cSDimitry Andric       auto DIL = BB->findBranchDebugLoc();
236349cc55cSDimitry Andric       auto SuccDIL = Succ->findBranchDebugLoc();
237349cc55cSDimitry Andric       if (Show) {
238349cc55cSDimitry Andric         dbgs() << "Set branch fs prob: MBB (" << BB->getNumber() << " -> "
239349cc55cSDimitry Andric                << Succ->getNumber() << "): ";
240349cc55cSDimitry Andric         if (DIL)
241349cc55cSDimitry Andric           dbgs() << DIL->getFilename() << ":" << DIL->getLine() << ":"
242349cc55cSDimitry Andric                  << DIL->getColumn();
243349cc55cSDimitry Andric         if (SuccDIL)
244349cc55cSDimitry Andric           dbgs() << "-->" << SuccDIL->getFilename() << ":" << SuccDIL->getLine()
245349cc55cSDimitry Andric                  << ":" << SuccDIL->getColumn();
246349cc55cSDimitry Andric         dbgs() << " W=" << BBWeightOrig << "  " << OldProb << " --> " << NewProb
247349cc55cSDimitry Andric                << "\n";
248349cc55cSDimitry Andric       }
249349cc55cSDimitry Andric #endif
250349cc55cSDimitry Andric     }
251349cc55cSDimitry Andric   }
252349cc55cSDimitry Andric }
253349cc55cSDimitry Andric 
254349cc55cSDimitry Andric bool MIRProfileLoader::doInitialization(Module &M) {
255349cc55cSDimitry Andric   auto &Ctx = M.getContext();
256349cc55cSDimitry Andric 
257349cc55cSDimitry Andric   auto ReaderOrErr = sampleprof::SampleProfileReader::create(Filename, Ctx, P,
258349cc55cSDimitry Andric                                                              RemappingFilename);
259349cc55cSDimitry Andric   if (std::error_code EC = ReaderOrErr.getError()) {
260349cc55cSDimitry Andric     std::string Msg = "Could not open profile: " + EC.message();
261349cc55cSDimitry Andric     Ctx.diagnose(DiagnosticInfoSampleProfile(Filename, Msg));
262349cc55cSDimitry Andric     return false;
263349cc55cSDimitry Andric   }
264349cc55cSDimitry Andric 
265349cc55cSDimitry Andric   Reader = std::move(ReaderOrErr.get());
266349cc55cSDimitry Andric   Reader->setModule(&M);
267349cc55cSDimitry Andric   ProfileIsValid = (Reader->read() == sampleprof_error::success);
268349cc55cSDimitry Andric   Reader->getSummary();
269349cc55cSDimitry Andric 
270349cc55cSDimitry Andric   return true;
271349cc55cSDimitry Andric }
272349cc55cSDimitry Andric 
273349cc55cSDimitry Andric bool MIRProfileLoader::runOnFunction(MachineFunction &MF) {
274349cc55cSDimitry Andric   Function &Func = MF.getFunction();
275349cc55cSDimitry Andric   clearFunctionData(false);
276349cc55cSDimitry Andric   Samples = Reader->getSamplesFor(Func);
277349cc55cSDimitry Andric   if (!Samples || Samples->empty())
278349cc55cSDimitry Andric     return false;
279349cc55cSDimitry Andric 
280349cc55cSDimitry Andric   if (getFunctionLoc(MF) == 0)
281349cc55cSDimitry Andric     return false;
282349cc55cSDimitry Andric 
283349cc55cSDimitry Andric   DenseSet<GlobalValue::GUID> InlinedGUIDs;
284349cc55cSDimitry Andric   bool Changed = computeAndPropagateWeights(MF, InlinedGUIDs);
285349cc55cSDimitry Andric 
286349cc55cSDimitry Andric   // Set the new BPI, BFI.
287349cc55cSDimitry Andric   setBranchProbs(MF);
288349cc55cSDimitry Andric 
289349cc55cSDimitry Andric   return Changed;
290349cc55cSDimitry Andric }
291349cc55cSDimitry Andric 
292349cc55cSDimitry Andric } // namespace llvm
293349cc55cSDimitry Andric 
294349cc55cSDimitry Andric MIRProfileLoaderPass::MIRProfileLoaderPass(std::string FileName,
295349cc55cSDimitry Andric                                            std::string RemappingFileName,
296349cc55cSDimitry Andric                                            FSDiscriminatorPass P)
297349cc55cSDimitry Andric     : MachineFunctionPass(ID), ProfileFileName(FileName), P(P),
298349cc55cSDimitry Andric       MIRSampleLoader(
299349cc55cSDimitry Andric           std::make_unique<MIRProfileLoader>(FileName, RemappingFileName)) {
300349cc55cSDimitry Andric   LowBit = getFSPassBitBegin(P);
301349cc55cSDimitry Andric   HighBit = getFSPassBitEnd(P);
302349cc55cSDimitry Andric   assert(LowBit < HighBit && "HighBit needs to be greater than Lowbit");
303349cc55cSDimitry Andric }
304349cc55cSDimitry Andric 
305349cc55cSDimitry Andric bool MIRProfileLoaderPass::runOnMachineFunction(MachineFunction &MF) {
306349cc55cSDimitry Andric   if (!MIRSampleLoader->isValid())
307349cc55cSDimitry Andric     return false;
308349cc55cSDimitry Andric 
309349cc55cSDimitry Andric   LLVM_DEBUG(dbgs() << "MIRProfileLoader pass working on Func: "
310349cc55cSDimitry Andric                     << MF.getFunction().getName() << "\n");
311349cc55cSDimitry Andric   MBFI = &getAnalysis<MachineBlockFrequencyInfo>();
312349cc55cSDimitry Andric   MIRSampleLoader->setInitVals(
313349cc55cSDimitry Andric       &getAnalysis<MachineDominatorTree>(),
314349cc55cSDimitry Andric       &getAnalysis<MachinePostDominatorTree>(), &getAnalysis<MachineLoopInfo>(),
315349cc55cSDimitry Andric       MBFI, &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE());
316349cc55cSDimitry Andric 
317349cc55cSDimitry Andric   MF.RenumberBlocks();
318349cc55cSDimitry Andric   if (ViewBFIBefore && ViewBlockLayoutWithBFI != GVDT_None &&
319349cc55cSDimitry Andric       (ViewBlockFreqFuncName.empty() ||
320349cc55cSDimitry Andric        MF.getFunction().getName().equals(ViewBlockFreqFuncName))) {
321349cc55cSDimitry Andric     MBFI->view("MIR_Prof_loader_b." + MF.getName(), false);
322349cc55cSDimitry Andric   }
323349cc55cSDimitry Andric 
324349cc55cSDimitry Andric   bool Changed = MIRSampleLoader->runOnFunction(MF);
3254824e7fdSDimitry Andric   if (Changed)
3264824e7fdSDimitry Andric     MBFI->calculate(MF, *MBFI->getMBPI(), *&getAnalysis<MachineLoopInfo>());
327349cc55cSDimitry Andric 
328349cc55cSDimitry Andric   if (ViewBFIAfter && ViewBlockLayoutWithBFI != GVDT_None &&
329349cc55cSDimitry Andric       (ViewBlockFreqFuncName.empty() ||
330349cc55cSDimitry Andric        MF.getFunction().getName().equals(ViewBlockFreqFuncName))) {
331349cc55cSDimitry Andric     MBFI->view("MIR_prof_loader_a." + MF.getName(), false);
332349cc55cSDimitry Andric   }
333349cc55cSDimitry Andric 
334349cc55cSDimitry Andric   return Changed;
335349cc55cSDimitry Andric }
336349cc55cSDimitry Andric 
337349cc55cSDimitry Andric bool MIRProfileLoaderPass::doInitialization(Module &M) {
338349cc55cSDimitry Andric   LLVM_DEBUG(dbgs() << "MIRProfileLoader pass working on Module " << M.getName()
339349cc55cSDimitry Andric                     << "\n");
340349cc55cSDimitry Andric 
341349cc55cSDimitry Andric   MIRSampleLoader->setFSPass(P);
342349cc55cSDimitry Andric   return MIRSampleLoader->doInitialization(M);
343349cc55cSDimitry Andric }
344349cc55cSDimitry Andric 
345349cc55cSDimitry Andric void MIRProfileLoaderPass::getAnalysisUsage(AnalysisUsage &AU) const {
346349cc55cSDimitry Andric   AU.setPreservesAll();
347349cc55cSDimitry Andric   AU.addRequired<MachineBlockFrequencyInfo>();
348349cc55cSDimitry Andric   AU.addRequired<MachineDominatorTree>();
349349cc55cSDimitry Andric   AU.addRequired<MachinePostDominatorTree>();
350349cc55cSDimitry Andric   AU.addRequiredTransitive<MachineLoopInfo>();
351349cc55cSDimitry Andric   AU.addRequired<MachineOptimizationRemarkEmitterPass>();
352349cc55cSDimitry Andric   MachineFunctionPass::getAnalysisUsage(AU);
353349cc55cSDimitry Andric }
354