118 "bbsections-cold-text-prefix",
119 cl::desc(
"The text prefix to use for cold basic block clusters"),
123 "bbsections-detect-source-drift",
124 cl::desc(
"This checks if there is a fdo instr. profile hash "
125 "mismatch for this function"),
137 cl::desc(
"Percentile profile summary cutoff used to "
138 "determine cold blocks. Unused if set to zero."),
142 "mfs-count-threshold",
144 "Minimum number of times a block must be executed to be retained."),
149 cl::desc(
"Splits all EH code and it's descendants by default."),
158 explicit BasicBlockSections(
bool SplitWithPGO =
false)
163 StringRef getPassName()
const override {
164 return "Basic Block Sections Transformation";
167 void getAnalysisUsage(AnalysisUsage &AU)
const override;
181 const bool SplitWithPGO;
186char BasicBlockSections::ID = 0;
188 BasicBlockSections,
"bbsections-prepare",
189 "Prepares for basic block sections, by splitting functions "
190 "into clusters of basic blocks.",
196 "Prepares for basic block sections, by splitting functions "
197 "into clusters of basic blocks.",
207 for (
auto &
MBB : MF) {
208 auto NextMBBI = std::next(
MBB.getIterator());
209 auto *FTMBB = PreLayoutFallThroughs[
MBB.getNumber()];
216 if (FTMBB && (
MBB.isEndSection() || &*NextMBBI != FTMBB))
217 TII->insertUnconditionalBranch(
MBB, FTMBB,
MBB.findBranchDebugLoc());
221 if (
MBB.isEndSection())
230 MBB.updateTerminator(FTMBB);
243 return BBClusterInfos;
244 auto BlockWeights = OptWeightInfo->BlockWeights;
245 auto EdgeWeights = OptWeightInfo->EdgeWeights;
248 if (MF.
size() <= 2) {
249 for (
auto &
MBB : MF) {
250 if (
MBB.isEntryBlock() || BlockWeights[&
MBB] > 0) {
257 std::vector<const MachineBasicBlock *> OrigOrder;
258 OrigOrder.reserve(MF.
size());
265 for (
auto &
MBB : MF) {
268 int NumInsts = std::distance(NonDbgInsts.begin(), NonDbgInsts.end());
269 BlockSizes[
MBB.getNumber()] = 4 * NumInsts;
270 BlockCounts[
MBB.getNumber()] = BlockWeights[&
MBB];
271 OrigOrder.push_back(&
MBB);
275 for (
auto &
MBB : MF) {
276 for (
auto *Succ :
MBB.successors()) {
277 auto EdgeWeight = EdgeWeights[std::make_pair(&
MBB, Succ)];
279 static_cast<uint64_t>(Succ->getNumber()),
285 auto Result = computeExtTspLayout(BlockSizes, BlockCounts, JumpCounts);
287 auto Block = OrigOrder[R];
288 if (
Block->isEntryBlock() || BlockWeights[
Block] > 0)
294 if (!HotMBBs.
empty()) {
295 unsigned CurrentPosition = 0;
296 for (
auto &
MBB : HotMBBs)
297 BBClusterInfos.
push_back({*
MBB->getBBID(), 0, CurrentPosition++});
299 return BBClusterInfos;
324 std::optional<MBBSectionID> EHPadsSectionID;
326 for (
auto &
MBB : MF) {
335 MBB.setSectionID(
MBB.getNumber());
337 auto I = FuncClusterInfo.
find(*
MBB.getBBID());
338 if (
I != FuncClusterInfo.
end()) {
339 MBB.setSectionID(
I->second.ClusterID);
342 *
MBB.getParent()->getSubtarget().getInstrInfo();
344 if (
TII.isMBBSafeToSplitToCold(
MBB)) {
353 if (
MBB.isEHPad() && EHPadsSectionID !=
MBB.getSectionID() &&
359 :
MBB.getSectionID();
368 MBB.setSectionID(*EHPadsSectionID);
376 PreLayoutFallThroughs[
MBB.getNumber()] =
377 MBB.getFallThrough(
false);
381 "Entry block should not be displaced by basic block sections");
397 std::optional<MBBSectionID> CurrentSection;
399 if (
MBB.getFirstNonDebugInstr() ==
MBB.end() ||
400 MBB.getSectionID() == CurrentSection)
402 CurrentSection =
MBB.getSectionID();
406 for (
auto &
MBB : MF) {
407 if (IsFirstNonEmptyBBInSection(
MBB) &&
MBB.isEHPad()) {
409 while (!
MI->isEHLabel())
420 const char MetadataName[] =
"instr_prof_hash_mismatch";
424 for (
const auto &
N : Tuple->operands())
425 if (
N.equalsStr(MetadataName))
438 for (
auto Block : EHBlocks) {
469 if (!SplitWithPGO || skipFunction(MF.
getFunction()))
479 if (!
TII.isFunctionSafeToSplit(MF))
485 getAnalysis<BasicBlockSectionsProfileReaderWrapperPass>()
495void BasicBlockSections::assignColdSectionWithPGO(
MachineFunction &MF) {
500 MachineBlockFrequencyInfo *MBFI =
nullptr;
501 ProfileSummaryInfo *PSI =
nullptr;
502 if (UseProfileData) {
503 MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
504 PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
518 for (
auto &
MBB : MF) {
535 bool HasHotLandingPads =
false;
536 for (
const MachineBasicBlock *LP : LandingPads) {
537 if (!
isColdBlock(*LP, MBFI, PSI) || !
TII.isMBBSafeToSplitToCold(*LP))
538 HasHotLandingPads =
true;
540 if (!HasHotLandingPads) {
541 for (MachineBasicBlock *LP : LandingPads)
553 DenseMap<UniqueBBID, BBClusterInfo> FuncClusterInfo;
560 if (BBSectionsType == BasicBlockSection::List &&
563 if (
auto *BMI = getAnalysisIfAvailable<BasicBlockMatchingAndInference>()) {
566 ClusterInfo = getAnalysis<BasicBlockSectionsProfileReaderWrapperPass>()
567 .getClusterInfoForFunction(MF.
getName());
570 FuncClusterInfo.
try_emplace(BBClusterInfo.BBID, BBClusterInfo);
577 BBSectionsType == BasicBlockSection::None ||
578 (BBSectionsType == BasicBlockSection::List && FuncClusterInfo.
empty());
579 if (UsePGO && !shouldSplitWithPGO(MF))
590 assignColdSectionWithPGO(MF);
596 const MachineBasicBlock &EntryBB = MF.
front();
605 auto MBBSectionOrder = [EntryBBSectionID](
const MBBSectionID &
LHS,
606 const MBBSectionID &
RHS) {
609 if (
LHS == EntryBBSectionID ||
RHS == EntryBBSectionID)
610 return LHS == EntryBBSectionID;
620 auto Comparator = [&](
const MachineBasicBlock &
X,
621 const MachineBasicBlock &
Y) {
622 auto XSectionID =
X.getSectionID();
623 auto YSectionID =
Y.getSectionID();
624 if (XSectionID != YSectionID)
625 return MBBSectionOrder(XSectionID, YSectionID);
627 if (&
X == &EntryBB || &
Y == &EntryBB)
628 return &
X == &EntryBB;
635 if (XSectionID.Type == MBBSectionID::SectionType::Default &&
636 !FuncClusterInfo.
empty()) {
637 auto XI = FuncClusterInfo.
find(*
X.getBBID());
638 auto YI = FuncClusterInfo.
find(*
Y.getBBID());
639 bool XInCluster = XI != FuncClusterInfo.
end();
640 bool YInCluster = YI != FuncClusterInfo.
end();
641 if (XInCluster != YInCluster)
644 return std::tie(XI->second.ClusterID, XI->second.PositionInCluster) <
645 std::tie(YI->second.ClusterID, YI->second.PositionInCluster);
668 auto R1 = handleBBSections(MF);
670 auto R2 = handleBBAddrMap(MF);
674void BasicBlockSections::getAnalysisUsage(AnalysisUsage &AU)
const {
676 AU.
addRequired<BasicBlockSectionsProfileReaderWrapperPass>();
678 AU.
addRequired<MachineBlockFrequencyInfoWrapperPass>();
688 return new BasicBlockSections(SplitWithPGO);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isColdBlock(const MachineBasicBlock &MBB, const MachineBlockFrequencyInfo *MBFI, ProfileSummaryInfo *PSI)
static cl::opt< unsigned > ColdCountThreshold("mfs-count-threshold", cl::desc("Minimum number of times a block must be executed to be retained."), cl::init(1), cl::Hidden)
static void assignSections(MachineFunction &MF, const DenseMap< UniqueBBID, BBClusterInfo > &FuncClusterInfo)
static cl::opt< bool > BBSectionsDetectSourceDrift("bbsections-detect-source-drift", cl::desc("This checks if there is a fdo instr. profile hash " "mismatch for this function"), cl::init(true), cl::Hidden)
static void setDescendantEHBlocksCold(MachineFunction &MF)
setDescendantEHBlocksCold - This splits all EH pads and blocks reachable only by EH pad as cold.
bbsections Prepares for basic block by splitting functions into clusters of basic static false void updateBranches(MachineFunction &MF, const SmallVector< MachineBasicBlock * > &PreLayoutFallThroughs)
static cl::opt< unsigned > PercentileCutoff("mfs-psi-cutoff", cl::desc("Percentile profile summary cutoff used to " "determine cold blocks. Unused if set to zero."), cl::init(999950), cl::Hidden)
static cl::opt< bool > SplitAllEHCode("mfs-split-ehcode", cl::desc("Splits all EH code and it's descendants by default."), cl::init(false), cl::Hidden)
static SmallVector< BBClusterInfo > createBBClusterInfoForFunction(MachineFunction &MF, const BasicBlockMatchingAndInference &BMI)
Declares methods and data structures for code layout algorithms.
const HexagonInstrInfo * TII
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
SmallVector< MachineOperand, 4 > Cond
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
This file defines the SmallVector class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
AnalysisUsage & addUsedIfAvailable()
Add the specified Pass class to the set of analyses used by this pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
std::optional< WeightInfo > getWeightInfo(StringRef FuncName) const
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Implements a dense probed hash-table based set.
bool hasProfileData() const
Return true if the function is annotated with profile data.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this GlobalObject.
bool isEHPad() const
Returns true if the block is a landing pad.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
MBBSectionID getSectionID() const
Returns the section ID of this basic block.
LLVM_ABI bool isEntryBlock() const
Returns true if this is the entry block of the function.
void setSectionID(MBBSectionID V)
Sets the section ID for this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
LLVM_ABI std::optional< uint64_t > getBlockProfileCount(const MachineBasicBlock *MBB) const
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.
void setBBSectionsType(BasicBlockSection V)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
bool hasBBSections() const
Returns true if this function has basic block sections enabled.
Function & getFunction()
Return the LLVM function that this machine code represents.
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
void RenumberBlocks(MachineBasicBlock *MBBFrom=nullptr)
RenumberBlocks - This discards all of the MachineBasicBlock numbers and recomputes them.
const MachineBasicBlock & front() const
void assignBeginEndSections()
Assign IsBeginSection IsEndSection fields for basic blocks in this function.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
Analysis providing profile information.
bool hasCSInstrumentationProfile() const
Returns true if module M has context sensitive instrumentation profile.
bool hasInstrumentationProfile() const
Returns true if module M has instrumentation profile.
bool hasSampleProfile() const
Returns true if module M has sample profile.
LLVM_ABI bool isColdCountNthPercentile(int PercentileCutoff, uint64_t C) const
Returns true if count C is considered cold with regard to a given cold percentile cutoff value.
bool isFunctionHotInCallGraph(const FuncT *F, BFIT &BFI) const
Returns true if F contains hot code.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetInstrInfo - Interface to description of machine instruction set.
virtual void insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const
Insert a noop into the instruction stream at the specified point.
llvm::BasicBlockSection getBBSectionsType() const
If basic blocks should be emitted into their own section, corresponding to -fbasic-block-sections.
FunctionSplittingMode FunctionSplitting
Which functions are eligible for late function splitting.
virtual const TargetInstrInfo * getInstrInfo() const
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI MachineFunctionPass * createBasicBlockSectionsPass(bool SplitWithPGO=false)
createBasicBlockSections Pass - This pass assigns sections to machine basic blocks and is enabled wit...
LLVM_ABI void initializeBasicBlockSectionsPass(PassRegistry &)
static void computeEHOnlyBlocks(FunctionT &F, DenseSet< BlockT * > &EHBlocks)
Compute a list of blocks that are only reachable via EH paths.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
auto instructionsWithoutDebug(IterT It, IterT End, bool SkipPseudoOp=true)
Construct a range iterator which begins at It and moves forwards until End is reached,...
LLVM_ABI bool hasInstrProfHashMismatch(MachineFunction &MF)
This checks if the source of this function has drifted since this binary was profiled previously.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
SmallPtrSet< SUnit *, 8 > ClusterInfo
Keep record of which SUnit are in the same cluster group.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI void avoidZeroOffsetLandingPad(MachineFunction &MF)
LLVM_ABI cl::opt< std::string > BBSectionsColdTextPrefix
function_ref< bool(const MachineBasicBlock &, const MachineBasicBlock &)> MachineBasicBlockComparator
LLVM_ABI void sortBasicBlocksAndUpdateBranches(MachineFunction &MF, MachineBasicBlockComparator MBBCmp)
LLVM_ABI static const MBBSectionID ExceptionSectionID
LLVM_ABI static const MBBSectionID ColdSectionID