1//===-------- MIRSampleProfile.cpp: MIRSampleFDO (For FSAFDO) -------------===// 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 7//===----------------------------------------------------------------------===// 9// This file provides the implementation of the MIRSampleProfile loader, mainly 10// for flow sensitive SampleFDO. 12//===----------------------------------------------------------------------===// 38using namespacesampleprof;
42#define DEBUG_TYPE "fs-profile-loader" 46cl::desc(
"Print setting flow sensitive branch probabilities"));
48"fs-profile-debug-prob-diff-threshold",
cl::init(10),
50"Only show debug message if the branch probability is greater than " 51"this value (in percentage)."));
54"fs-profile-debug-bw-threshold",
cl::init(10000),
55cl::desc(
"Only show debug message if the source branch weight is greater " 60cl::desc(
"View BFI before MIR loader"));
63cl::desc(
"View BFI after MIR loader"));
71"Load MIR Sample Profile",
72/* cfg = */false,
/* is_analysis = */false)
92// Internal option used to control BFI display only after MBP pass. 93// Defined in CodeGen/MachineBlockFrequencyInfo.cpp: 94// -view-block-layout-with-bfi={none | fraction | integer | count} 97// Command line option to specify the name of the function for CFG dump 98// Defined in Analysis/BlockFrequencyInfo.cpp: -view-bfi-func-name= 102if (
MI.isPseudoProbe()) {
104 Probe.
Id =
MI.getOperand(1).getImm();
105 Probe.
Type =
MI.getOperand(2).getImm();
106 Probe.
Attr =
MI.getOperand(3).getImm();
113// Ignore callsite probes since they do not have FS discriminators. 117namespaceafdo_detail {
145}
// namespace afdo_detail 179 /// Hold the information of the basic block frequency. 182 /// PassNum is the sequence number this pass is called, start from 1. 185// LowBit in the FS discriminator used by this instance. Note the number is 186// 0-based. Base discrimnator use bit 0 to bit 11. 188// HighwBit in the FS discriminator used by this instance. Note the number 197return std::error_code();
207LLVM_DEBUG(
dbgs() <<
"\nPropagation complete. Setting branch probs\n");
216EdgeE = std::make_pair(BB, Succ);
220if (BBWeight != SumEdgeWeight) {
221LLVM_DEBUG(
dbgs() <<
"BBweight is not equal to SumEdgeWeight: BBWWeight=" 222 << BBWeight <<
" SumEdgeWeight= " << SumEdgeWeight
224 BBWeight = SumEdgeWeight;
234uint32_t MaxWeight = std::numeric_limits<uint32_t>::max();
236if (BBWeight > MaxWeight) {
237 Factor = BBWeight / MaxWeight + 1;
246EdgeE = std::make_pair(BB, Succ);
248 EdgeWeight /= Factor;
250assert(BBWeight >= EdgeWeight &&
251"BBweight is larger than EdgeWeight -- should not happen.\n");
255if (OldProb == NewProb)
263if (OldProb > NewProb)
264 Diff = OldProb - NewProb;
266 Diff = NewProb - OldProb;
273dbgs() <<
"Set branch fs prob: MBB (" << BB->
getNumber() <<
" -> " 276dbgs() << DIL->getFilename() <<
":" << DIL->getLine() <<
":" 279dbgs() <<
"-->" << SuccDIL->getFilename() <<
":" << SuccDIL->getLine()
280 <<
":" << SuccDIL->getColumn();
281dbgs() <<
" W=" << BBWeightOrig <<
" " << OldProb <<
" --> " << NewProb
290auto &Ctx = M.getContext();
294if (std::error_code EC = ReaderOrErr.getError()) {
295 std::string Msg =
"Could not open profile: " + EC.message();
300Reader = std::move(ReaderOrErr.get());
304// Load pseudo probe descriptors for probe-based function samples. 305if (
Reader->profileIsProbeBased()) {
316// Do not load non-FS profiles. A line or probe can get a zero-valued 317// discriminator at certain pass which could result in accidentally loading 318// the corresponding base counter in the non-FS profile, while a non-zero 319// discriminator would end up getting zero samples. This could in turn undo 320// the sample distribution effort done by previous BFI maintenance and the 321// probe distribution factor work for pseudo probes. 322if (!
Reader->profileIsFS())
342// Set the new BPI, BFI. 358 MIRSampleLoader = std::make_unique<MIRProfileLoader>(
359 FileName, RemappingFileName, std::move(VFS));
360assert(LowBit < HighBit &&
"HighBit needs to be greater than Lowbit");
364if (!MIRSampleLoader->isValid())
369 MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
370auto *MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
372 &getAnalysis<MachinePostDominatorTreeWrapperPass>().getPostDomTree();
375 MDT->updateBlockNumbers();
376 MPDT->updateBlockNumbers();
378 MIRSampleLoader->setInitVals(
379 MDT, MPDT, &getAnalysis<MachineLoopInfoWrapperPass>().getLI(), MBFI,
380 &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE());
385 MBFI->
view(
"MIR_Prof_loader_b." + MF.
getName(),
false);
388bool Changed = MIRSampleLoader->runOnFunction(MF);
391 *&getAnalysis<MachineLoopInfoWrapperPass>().getLI());
396 MBFI->
view(
"MIR_prof_loader_a." + MF.
getName(),
false);
402bool MIRProfileLoaderPass::doInitialization(
Module &M) {
403LLVM_DEBUG(
dbgs() <<
"MIRProfileLoader pass working on Module " <<
M.getName()
406 MIRSampleLoader->setFSPass(
P);
407return MIRSampleLoader->doInitialization(M);
410void MIRProfileLoaderPass::getAnalysisUsage(
AnalysisUsage &AU)
const{
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
static cl::opt< bool > ShowFSBranchProb("show-fs-branchprob", cl::Hidden, cl::init(false), cl::desc("Print setting flow sensitive branch probabilities"))
static cl::opt< bool > ViewBFIAfter("fs-viewbfi-after", cl::Hidden, cl::init(false), cl::desc("View BFI after MIR loader"))
static cl::opt< unsigned > FSProfileDebugBWThreshold("fs-profile-debug-bw-threshold", cl::init(10000), cl::desc("Only show debug message if the source branch weight is greater " " than this value."))
static cl::opt< unsigned > FSProfileDebugProbDiffThreshold("fs-profile-debug-prob-diff-threshold", cl::init(10), cl::desc("Only show debug message if the branch probability is greater than " "this value (in percentage)."))
static cl::opt< bool > ViewBFIBefore("fs-viewbfi-before", cl::Hidden, cl::init(false), cl::desc("View BFI before MIR loader"))
===- MachineOptimizationRemarkEmitter.h - Opt Diagnostics -*- C++ -*-—===//
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file provides the interface for the sampled PGO profile loader base implementation.
This file provides the utility functions for the sampled PGO loader base implementation.
Defines the virtual file system interface vfs::FileSystem.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
AnalysisUsage & addRequiredTransitive()
Implements a dense probed hash-table based set.
Diagnostic information for the sample profiler.
Represents either an error or a value T.
FunctionPass class - This class is used to implement most global optimizations.
Class to represent profile counts.
A smart pointer to a reference-counted object that inherits from RefCountedBase or ThreadSafeRefCount...
MIRProfileLoaderPass(std::string FileName="", std::string RemappingFileName="", FSDiscriminatorPass P=FSDiscriminatorPass::Pass1, IntrusiveRefCntPtr< vfs::FileSystem > FS=nullptr)
FS bits will only use the '1' bits in the Mask.
MIRProfileLoader(StringRef Name, StringRef RemapName, IntrusiveRefCntPtr< vfs::FileSystem > FS)
void setBranchProbs(MachineFunction &F)
ErrorOr< uint64_t > getInstWeight(const MachineInstr &MI) override
bool runOnFunction(MachineFunction &F)
MachineBlockFrequencyInfo * BFI
Hold the information of the basic block frequency.
FSDiscriminatorPass P
PassNum is the sequence number this pass is called, start from 1.
bool doInitialization(Module &M)
void setInitVals(MachineDominatorTree *MDT, MachinePostDominatorTree *MPDT, MachineLoopInfo *MLI, MachineBlockFrequencyInfo *MBFI, MachineOptimizationRemarkEmitter *MORE)
void setFSPass(FSDiscriminatorPass Pass)
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
void setSuccProbability(succ_iterator I, BranchProbability Prob)
Set successor probability of a given iterator.
succ_iterator succ_begin()
unsigned succ_size() const
SmallVectorImpl< MachineBasicBlock * >::iterator succ_iterator
DebugLoc findBranchDebugLoc()
Find and return the merged DebugLoc of the branch instructions of the block.
iterator_range< succ_iterator > successors()
iterator_range< pred_iterator > predecessors()
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
void view(const Twine &Name, bool isSimple=true) const
Pop up a ghostview window with the current block frequency propagation rendered using dot.
const MachineBranchProbabilityInfo * getMBPI() const
void calculate(const MachineFunction &F, const MachineBranchProbabilityInfo &MBPI, const MachineLoopInfo &MLI)
calculate - compute block frequency info for the given function.
BranchProbability getEdgeProbability(const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
Function & getFunction()
Return the LLVM function that this machine code represents.
void RenumberBlocks(MachineBasicBlock *MBBFrom=nullptr)
RenumberBlocks - This discards all of the MachineBasicBlock numbers and recomputes them.
Representation of each machine instruction.
Diagnostic information for optimization analysis remarks.
The optimization diagnostic interface.
MachinePostDominatorTree - an analysis pass wrapper for DominatorTree used to compute the post-domina...
A Module instance is used to store all the information related to an LLVM module.
Pass interface - Implemented by all 'passes'.
bool computeAndPropagateWeights(FunctionT &F, const DenseSet< GlobalValue::GUID > &InlinedGUIDs)
Generate branch weight metadata for all branches in F.
void computeDominanceAndLoopInfo(FunctionT &F)
IntrusiveRefCntPtr< vfs::FileSystem > FS
VirtualFileSystem to load profile files from.
EdgeWeightMap EdgeWeights
Map edges to their computed weights.
OptRemarkEmitterT * ORE
Optimization Remark Emitter used to emit diagnostic remarks.
unsigned getFunctionLoc(FunctionT &Func)
Get the line number for the function header.
ErrorOr< uint64_t > getInstWeightImpl(const InstructionT &Inst)
EquivalenceClassMap EquivalenceClass
Equivalence classes for block weights.
std::unique_ptr< SampleProfileReader > Reader
Profile reader object.
DominatorTreePtrT DT
Dominance, post-dominance and loop information.
std::unique_ptr< PseudoProbeManager > ProbeManager
std::string Filename
Name of the profile file to load.
PostDominatorTreePtrT PDT
virtual ErrorOr< uint64_t > getProbeWeight(const InstructionT &Inst)
std::string RemappingFilename
Name of the profile remapping file to load.
FunctionSamples * Samples
Samples collected for the body of this function.
std::pair< const BasicBlockT *, const BasicBlockT * > Edge
void clearFunctionData(bool ResetDT=true)
Clear all the per-function data used to load samples and propagate weights.
BlockWeightMap BlockWeights
Map basic blocks to their computed weights.
StringRef - Represent a constant reference to a string, i.e.
StringRef getName() const
Return a constant reference to the value's name.
A range adaptor for a pair of iterators.
static bool ProfileIsProbeBased
static ErrorOr< std::unique_ptr< SampleProfileReader > > create(StringRef Filename, LLVMContext &C, vfs::FileSystem &FS, FSDiscriminatorPass P=FSDiscriminatorPass::Base, StringRef RemapFilename="")
Create a sample profile reader appropriate to the file format.
initializer< Ty > init(const Ty &Val)
IntrusiveRefCntPtr< FileSystem > getRealFileSystem()
Gets an vfs::FileSystem for the 'real' file system, as seen by the operating system.
This is an optimization pass for GlobalISel generic memory operations.
static unsigned getFSPassBitBegin(sampleprof::FSDiscriminatorPass P)
char & MIRProfileLoaderPassID
This pass reads flow sensitive profile.
static unsigned getFSPassBitEnd(sampleprof::FSDiscriminatorPass P)
cl::opt< std::string > ViewBlockFreqFuncName("view-bfi-func-name", cl::Hidden, cl::desc("The option to specify " "the name of the function " "whose CFG will be displayed."))
std::optional< PseudoProbe > extractProbe(const Instruction &Inst)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
cl::opt< GVDAGType > ViewBlockLayoutWithBFI("view-block-layout-with-bfi", cl::Hidden, cl::desc("Pop up a window to show a dag displaying MBP layout and associated " "block frequencies of the CFG."), cl::values(clEnumValN(GVDT_None, "none", "do not display graphs."), clEnumValN(GVDT_Fraction, "fraction", "display a graph using the " "fractional block frequency representation."), clEnumValN(GVDT_Integer, "integer", "display a graph using the raw " "integer fractional block frequency representation."), clEnumValN(GVDT_Count, "count", "display a graph using the real " "profile count if available.")))
cl::opt< bool > ImprovedFSDiscriminator("improved-fs-discriminator", cl::Hidden, cl::init(false), cl::desc("New FS discriminators encoding (incompatible with the original " "encoding)"))
FunctionPass * createMIRProfileLoaderPass(std::string File, std::string RemappingFile, sampleprof::FSDiscriminatorPass P, IntrusiveRefCntPtr< vfs::FileSystem > FS)
Read Flow Sensitive Profile.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Implement std::hash so that hash_code can be used in STL containers.
static PredRangeT getPredecessors(MachineBasicBlock *BB)
static SuccRangeT getSuccessors(MachineBasicBlock *BB)
static const MachineBasicBlock * getEntryBB(const MachineFunction *F)
static Function & getFunction(MachineFunction &F)