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 if (
MBB->getBBID()) {
298 BBClusterInfos.
push_back({*(
MBB->getBBID()), 0, CurrentPosition++});
302 return BBClusterInfos;
327 std::optional<MBBSectionID> EHPadsSectionID;
329 for (
auto &
MBB : MF) {
338 MBB.setSectionID(
MBB.getNumber());
340 auto I = FuncClusterInfo.
find(*
MBB.getBBID());
341 if (
I != FuncClusterInfo.
end()) {
342 MBB.setSectionID(
I->second.ClusterID);
345 *
MBB.getParent()->getSubtarget().getInstrInfo();
347 if (
TII.isMBBSafeToSplitToCold(
MBB)) {
356 if (
MBB.isEHPad() && EHPadsSectionID !=
MBB.getSectionID() &&
362 :
MBB.getSectionID();
371 MBB.setSectionID(*EHPadsSectionID);
379 PreLayoutFallThroughs[
MBB.getNumber()] =
380 MBB.getFallThrough(
false);
384 "Entry block should not be displaced by basic block sections");
400 std::optional<MBBSectionID> CurrentSection;
402 if (
MBB.empty() ||
MBB.getSectionID() == CurrentSection)
404 CurrentSection =
MBB.getSectionID();
408 for (
auto &
MBB : MF) {
409 if (IsFirstNonEmptyBBInSection(
MBB) &&
MBB.isEHPad()) {
411 while (!
MI->isEHLabel())
422 const char MetadataName[] =
"instr_prof_hash_mismatch";
426 for (
const auto &
N : Tuple->operands())
427 if (
N.equalsStr(MetadataName))
440 for (
auto Block : EHBlocks) {
471 if (!SplitWithPGO || skipFunction(MF.
getFunction()))
481 if (!
TII.isFunctionSafeToSplit(MF))
487 getAnalysis<BasicBlockSectionsProfileReaderWrapperPass>()
497void BasicBlockSections::assignColdSectionWithPGO(
MachineFunction &MF) {
502 MachineBlockFrequencyInfo *MBFI =
nullptr;
503 ProfileSummaryInfo *PSI =
nullptr;
504 if (UseProfileData) {
505 MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
506 PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
520 for (
auto &
MBB : MF) {
537 bool HasHotLandingPads =
false;
538 for (
const MachineBasicBlock *LP : LandingPads) {
539 if (!
isColdBlock(*LP, MBFI, PSI) || !
TII.isMBBSafeToSplitToCold(*LP))
540 HasHotLandingPads =
true;
542 if (!HasHotLandingPads) {
543 for (MachineBasicBlock *LP : LandingPads)
555 DenseMap<UniqueBBID, BBClusterInfo> FuncClusterInfo;
562 if (BBSectionsType == BasicBlockSection::List &&
565 if (
auto *BMI = getAnalysisIfAvailable<BasicBlockMatchingAndInference>()) {
568 ClusterInfo = getAnalysis<BasicBlockSectionsProfileReaderWrapperPass>()
569 .getClusterInfoForFunction(MF.
getName());
572 FuncClusterInfo.
try_emplace(BBClusterInfo.BBID, BBClusterInfo);
579 BBSectionsType == BasicBlockSection::None ||
580 (BBSectionsType == BasicBlockSection::List && FuncClusterInfo.
empty());
581 if (UsePGO && !shouldSplitWithPGO(MF))
592 assignColdSectionWithPGO(MF);
598 const MachineBasicBlock &EntryBB = MF.
front();
607 auto MBBSectionOrder = [EntryBBSectionID](
const MBBSectionID &
LHS,
608 const MBBSectionID &
RHS) {
611 if (
LHS == EntryBBSectionID ||
RHS == EntryBBSectionID)
612 return LHS == EntryBBSectionID;
622 auto Comparator = [&](
const MachineBasicBlock &
X,
623 const MachineBasicBlock &
Y) {
624 auto XSectionID =
X.getSectionID();
625 auto YSectionID =
Y.getSectionID();
626 if (XSectionID != YSectionID)
627 return MBBSectionOrder(XSectionID, YSectionID);
629 if (&
X == &EntryBB || &
Y == &EntryBB)
630 return &
X == &EntryBB;
637 if (XSectionID.Type == MBBSectionID::SectionType::Default &&
638 !FuncClusterInfo.
empty()) {
639 auto XI = FuncClusterInfo.
find(*
X.getBBID());
640 auto YI = FuncClusterInfo.
find(*
Y.getBBID());
641 bool XInCluster = XI != FuncClusterInfo.
end();
642 bool YInCluster = YI != FuncClusterInfo.
end();
643 if (XInCluster != YInCluster)
646 return std::tie(XI->second.ClusterID, XI->second.PositionInCluster) <
647 std::tie(YI->second.ClusterID, YI->second.PositionInCluster);
670 auto R1 = handleBBSections(MF);
672 auto R2 = handleBBAddrMap(MF);
676void BasicBlockSections::getAnalysisUsage(AnalysisUsage &AU)
const {
678 AU.
addRequired<BasicBlockSectionsProfileReaderWrapperPass>();
680 AU.
addRequired<MachineBlockFrequencyInfoWrapperPass>();
690 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)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
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