173471bf0Spatrick //===-- BasicBlockSections.cpp ---=========--------------------------------===//
273471bf0Spatrick //
373471bf0Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
473471bf0Spatrick // See https://llvm.org/LICENSE.txt for license information.
573471bf0Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
673471bf0Spatrick //
773471bf0Spatrick //===----------------------------------------------------------------------===//
873471bf0Spatrick //
973471bf0Spatrick // BasicBlockSections implementation.
1073471bf0Spatrick //
1173471bf0Spatrick // The purpose of this pass is to assign sections to basic blocks when
1273471bf0Spatrick // -fbasic-block-sections= option is used. Further, with profile information
1373471bf0Spatrick // only the subset of basic blocks with profiles are placed in separate sections
1473471bf0Spatrick // and the rest are grouped in a cold section. The exception handling blocks are
1573471bf0Spatrick // treated specially to ensure they are all in one seciton.
1673471bf0Spatrick //
1773471bf0Spatrick // Basic Block Sections
1873471bf0Spatrick // ====================
1973471bf0Spatrick //
2073471bf0Spatrick // With option, -fbasic-block-sections=list, every function may be split into
2173471bf0Spatrick // clusters of basic blocks. Every cluster will be emitted into a separate
2273471bf0Spatrick // section with its basic blocks sequenced in the given order. To get the
2373471bf0Spatrick // optimized performance, the clusters must form an optimal BB layout for the
24*d415bd75Srobert // function. We insert a symbol at the beginning of every cluster's section to
25*d415bd75Srobert // allow the linker to reorder the sections in any arbitrary sequence. A global
26*d415bd75Srobert // order of these sections would encapsulate the function layout.
27*d415bd75Srobert // For example, consider the following clusters for a function foo (consisting
28*d415bd75Srobert // of 6 basic blocks 0, 1, ..., 5).
29*d415bd75Srobert //
30*d415bd75Srobert // 0 2
31*d415bd75Srobert // 1 3 5
32*d415bd75Srobert //
33*d415bd75Srobert // * Basic blocks 0 and 2 are placed in one section with symbol `foo`
34*d415bd75Srobert // referencing the beginning of this section.
35*d415bd75Srobert // * Basic blocks 1, 3, 5 are placed in a separate section. A new symbol
36*d415bd75Srobert // `foo.__part.1` will reference the beginning of this section.
37*d415bd75Srobert // * Basic block 4 (note that it is not referenced in the list) is placed in
38*d415bd75Srobert // one section, and a new symbol `foo.cold` will point to it.
3973471bf0Spatrick //
4073471bf0Spatrick // There are a couple of challenges to be addressed:
4173471bf0Spatrick //
4273471bf0Spatrick // 1. The last basic block of every cluster should not have any implicit
4373471bf0Spatrick // fallthrough to its next basic block, as it can be reordered by the linker.
4473471bf0Spatrick // The compiler should make these fallthroughs explicit by adding
4573471bf0Spatrick // unconditional jumps..
4673471bf0Spatrick //
4773471bf0Spatrick // 2. All inter-cluster branch targets would now need to be resolved by the
4873471bf0Spatrick // linker as they cannot be calculated during compile time. This is done
4973471bf0Spatrick // using static relocations. Further, the compiler tries to use short branch
5073471bf0Spatrick // instructions on some ISAs for small branch offsets. This is not possible
5173471bf0Spatrick // for inter-cluster branches as the offset is not determined at compile
5273471bf0Spatrick // time, and therefore, long branch instructions have to be used for those.
5373471bf0Spatrick //
5473471bf0Spatrick // 3. Debug Information (DebugInfo) and Call Frame Information (CFI) emission
5573471bf0Spatrick // needs special handling with basic block sections. DebugInfo needs to be
5673471bf0Spatrick // emitted with more relocations as basic block sections can break a
5773471bf0Spatrick // function into potentially several disjoint pieces, and CFI needs to be
5873471bf0Spatrick // emitted per cluster. This also bloats the object file and binary sizes.
5973471bf0Spatrick //
6073471bf0Spatrick // Basic Block Labels
6173471bf0Spatrick // ==================
6273471bf0Spatrick //
63*d415bd75Srobert // With -fbasic-block-sections=labels, we encode the offsets of BB addresses of
6473471bf0Spatrick // every function into the .llvm_bb_addr_map section. Along with the function
6573471bf0Spatrick // symbols, this allows for mapping of virtual addresses in PMU profiles back to
6673471bf0Spatrick // the corresponding basic blocks. This logic is implemented in AsmPrinter. This
6773471bf0Spatrick // pass only assigns the BBSectionType of every function to ``labels``.
6873471bf0Spatrick //
6973471bf0Spatrick //===----------------------------------------------------------------------===//
7073471bf0Spatrick
7173471bf0Spatrick #include "llvm/ADT/SmallVector.h"
7273471bf0Spatrick #include "llvm/ADT/StringRef.h"
7373471bf0Spatrick #include "llvm/CodeGen/BasicBlockSectionUtils.h"
74*d415bd75Srobert #include "llvm/CodeGen/BasicBlockSectionsProfileReader.h"
7573471bf0Spatrick #include "llvm/CodeGen/MachineFunction.h"
7673471bf0Spatrick #include "llvm/CodeGen/MachineFunctionPass.h"
7773471bf0Spatrick #include "llvm/CodeGen/Passes.h"
7873471bf0Spatrick #include "llvm/CodeGen/TargetInstrInfo.h"
7973471bf0Spatrick #include "llvm/InitializePasses.h"
8073471bf0Spatrick #include "llvm/Target/TargetMachine.h"
81*d415bd75Srobert #include <optional>
8273471bf0Spatrick
8373471bf0Spatrick using namespace llvm;
8473471bf0Spatrick
8573471bf0Spatrick // Placing the cold clusters in a separate section mitigates against poor
8673471bf0Spatrick // profiles and allows optimizations such as hugepage mapping to be applied at a
8773471bf0Spatrick // section granularity. Defaults to ".text.split." which is recognized by lld
8873471bf0Spatrick // via the `-z keep-text-section-prefix` flag.
8973471bf0Spatrick cl::opt<std::string> llvm::BBSectionsColdTextPrefix(
9073471bf0Spatrick "bbsections-cold-text-prefix",
9173471bf0Spatrick cl::desc("The text prefix to use for cold basic block clusters"),
9273471bf0Spatrick cl::init(".text.split."), cl::Hidden);
9373471bf0Spatrick
9473471bf0Spatrick cl::opt<bool> BBSectionsDetectSourceDrift(
9573471bf0Spatrick "bbsections-detect-source-drift",
9673471bf0Spatrick cl::desc("This checks if there is a fdo instr. profile hash "
9773471bf0Spatrick "mismatch for this function"),
9873471bf0Spatrick cl::init(true), cl::Hidden);
9973471bf0Spatrick
10073471bf0Spatrick namespace {
10173471bf0Spatrick
10273471bf0Spatrick class BasicBlockSections : public MachineFunctionPass {
10373471bf0Spatrick public:
10473471bf0Spatrick static char ID;
10573471bf0Spatrick
106*d415bd75Srobert BasicBlockSectionsProfileReader *BBSectionsProfileReader = nullptr;
10773471bf0Spatrick
BasicBlockSections()10873471bf0Spatrick BasicBlockSections() : MachineFunctionPass(ID) {
10973471bf0Spatrick initializeBasicBlockSectionsPass(*PassRegistry::getPassRegistry());
11073471bf0Spatrick }
11173471bf0Spatrick
getPassName() const11273471bf0Spatrick StringRef getPassName() const override {
11373471bf0Spatrick return "Basic Block Sections Analysis";
11473471bf0Spatrick }
11573471bf0Spatrick
11673471bf0Spatrick void getAnalysisUsage(AnalysisUsage &AU) const override;
11773471bf0Spatrick
11873471bf0Spatrick /// Identify basic blocks that need separate sections and prepare to emit them
11973471bf0Spatrick /// accordingly.
12073471bf0Spatrick bool runOnMachineFunction(MachineFunction &MF) override;
12173471bf0Spatrick };
12273471bf0Spatrick
12373471bf0Spatrick } // end anonymous namespace
12473471bf0Spatrick
12573471bf0Spatrick char BasicBlockSections::ID = 0;
12673471bf0Spatrick INITIALIZE_PASS(BasicBlockSections, "bbsections-prepare",
12773471bf0Spatrick "Prepares for basic block sections, by splitting functions "
12873471bf0Spatrick "into clusters of basic blocks.",
12973471bf0Spatrick false, false)
13073471bf0Spatrick
13173471bf0Spatrick // This function updates and optimizes the branching instructions of every basic
13273471bf0Spatrick // block in a given function to account for changes in the layout.
133*d415bd75Srobert static void
updateBranches(MachineFunction & MF,const SmallVector<MachineBasicBlock * > & PreLayoutFallThroughs)134*d415bd75Srobert updateBranches(MachineFunction &MF,
135*d415bd75Srobert const SmallVector<MachineBasicBlock *> &PreLayoutFallThroughs) {
13673471bf0Spatrick const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
13773471bf0Spatrick SmallVector<MachineOperand, 4> Cond;
13873471bf0Spatrick for (auto &MBB : MF) {
13973471bf0Spatrick auto NextMBBI = std::next(MBB.getIterator());
14073471bf0Spatrick auto *FTMBB = PreLayoutFallThroughs[MBB.getNumber()];
14173471bf0Spatrick // If this block had a fallthrough before we need an explicit unconditional
14273471bf0Spatrick // branch to that block if either
14373471bf0Spatrick // 1- the block ends a section, which means its next block may be
14473471bf0Spatrick // reorderd by the linker, or
14573471bf0Spatrick // 2- the fallthrough block is not adjacent to the block in the new
14673471bf0Spatrick // order.
14773471bf0Spatrick if (FTMBB && (MBB.isEndSection() || &*NextMBBI != FTMBB))
14873471bf0Spatrick TII->insertUnconditionalBranch(MBB, FTMBB, MBB.findBranchDebugLoc());
14973471bf0Spatrick
15073471bf0Spatrick // We do not optimize branches for machine basic blocks ending sections, as
15173471bf0Spatrick // their adjacent block might be reordered by the linker.
15273471bf0Spatrick if (MBB.isEndSection())
15373471bf0Spatrick continue;
15473471bf0Spatrick
15573471bf0Spatrick // It might be possible to optimize branches by flipping the branch
15673471bf0Spatrick // condition.
15773471bf0Spatrick Cond.clear();
15873471bf0Spatrick MachineBasicBlock *TBB = nullptr, *FBB = nullptr; // For analyzeBranch.
15973471bf0Spatrick if (TII->analyzeBranch(MBB, TBB, FBB, Cond))
16073471bf0Spatrick continue;
16173471bf0Spatrick MBB.updateTerminator(FTMBB);
16273471bf0Spatrick }
16373471bf0Spatrick }
16473471bf0Spatrick
16573471bf0Spatrick // This function provides the BBCluster information associated with a function.
16673471bf0Spatrick // Returns true if a valid association exists and false otherwise.
getBBClusterInfoForFunction(const MachineFunction & MF,BasicBlockSectionsProfileReader * BBSectionsProfileReader,DenseMap<unsigned,BBClusterInfo> & V)167*d415bd75Srobert bool getBBClusterInfoForFunction(
168*d415bd75Srobert const MachineFunction &MF,
169*d415bd75Srobert BasicBlockSectionsProfileReader *BBSectionsProfileReader,
170*d415bd75Srobert DenseMap<unsigned, BBClusterInfo> &V) {
17173471bf0Spatrick
17273471bf0Spatrick // Find the assoicated cluster information.
173*d415bd75Srobert std::pair<bool, SmallVector<BBClusterInfo, 4>> P =
174*d415bd75Srobert BBSectionsProfileReader->getBBClusterInfoForFunction(MF.getName());
175*d415bd75Srobert if (!P.first)
17673471bf0Spatrick return false;
17773471bf0Spatrick
178*d415bd75Srobert if (P.second.empty()) {
17973471bf0Spatrick // This indicates that sections are desired for all basic blocks of this
18073471bf0Spatrick // function. We clear the BBClusterInfo vector to denote this.
18173471bf0Spatrick V.clear();
18273471bf0Spatrick return true;
18373471bf0Spatrick }
18473471bf0Spatrick
185*d415bd75Srobert for (const BBClusterInfo &BBCI : P.second)
186*d415bd75Srobert V[BBCI.BBID] = BBCI;
18773471bf0Spatrick return true;
18873471bf0Spatrick }
18973471bf0Spatrick
19073471bf0Spatrick // This function sorts basic blocks according to the cluster's information.
19173471bf0Spatrick // All explicitly specified clusters of basic blocks will be ordered
19273471bf0Spatrick // accordingly. All non-specified BBs go into a separate "Cold" section.
19373471bf0Spatrick // Additionally, if exception handling landing pads end up in more than one
19473471bf0Spatrick // clusters, they are moved into a single "Exception" section. Eventually,
19573471bf0Spatrick // clusters are ordered in increasing order of their IDs, with the "Exception"
19673471bf0Spatrick // and "Cold" succeeding all other clusters.
197*d415bd75Srobert // FuncBBClusterInfo represent the cluster information for basic blocks. It
198*d415bd75Srobert // maps from BBID of basic blocks to their cluster information. If this is
199*d415bd75Srobert // empty, it means unique sections for all basic blocks in the function.
20073471bf0Spatrick static void
assignSections(MachineFunction & MF,const DenseMap<unsigned,BBClusterInfo> & FuncBBClusterInfo)20173471bf0Spatrick assignSections(MachineFunction &MF,
202*d415bd75Srobert const DenseMap<unsigned, BBClusterInfo> &FuncBBClusterInfo) {
20373471bf0Spatrick assert(MF.hasBBSections() && "BB Sections is not set for function.");
20473471bf0Spatrick // This variable stores the section ID of the cluster containing eh_pads (if
20573471bf0Spatrick // all eh_pads are one cluster). If more than one cluster contain eh_pads, we
20673471bf0Spatrick // set it equal to ExceptionSectionID.
207*d415bd75Srobert std::optional<MBBSectionID> EHPadsSectionID;
20873471bf0Spatrick
20973471bf0Spatrick for (auto &MBB : MF) {
21073471bf0Spatrick // With the 'all' option, every basic block is placed in a unique section.
21173471bf0Spatrick // With the 'list' option, every basic block is placed in a section
21273471bf0Spatrick // associated with its cluster, unless we want individual unique sections
21373471bf0Spatrick // for every basic block in this function (if FuncBBClusterInfo is empty).
21473471bf0Spatrick if (MF.getTarget().getBBSectionsType() == llvm::BasicBlockSection::All ||
21573471bf0Spatrick FuncBBClusterInfo.empty()) {
21673471bf0Spatrick // If unique sections are desired for all basic blocks of the function, we
217*d415bd75Srobert // set every basic block's section ID equal to its original position in
218*d415bd75Srobert // the layout (which is equal to its number). This ensures that basic
219*d415bd75Srobert // blocks are ordered canonically.
220*d415bd75Srobert MBB.setSectionID(MBB.getNumber());
221*d415bd75Srobert } else {
222*d415bd75Srobert // TODO: Replace `getBBIDOrNumber` with `getBBID` once version 1 is
223*d415bd75Srobert // deprecated.
224*d415bd75Srobert auto I = FuncBBClusterInfo.find(MBB.getBBIDOrNumber());
225*d415bd75Srobert if (I != FuncBBClusterInfo.end()) {
226*d415bd75Srobert MBB.setSectionID(I->second.ClusterID);
227*d415bd75Srobert } else {
22873471bf0Spatrick // BB goes into the special cold section if it is not specified in the
22973471bf0Spatrick // cluster info map.
23073471bf0Spatrick MBB.setSectionID(MBBSectionID::ColdSectionID);
23173471bf0Spatrick }
232*d415bd75Srobert }
23373471bf0Spatrick
23473471bf0Spatrick if (MBB.isEHPad() && EHPadsSectionID != MBB.getSectionID() &&
23573471bf0Spatrick EHPadsSectionID != MBBSectionID::ExceptionSectionID) {
23673471bf0Spatrick // If we already have one cluster containing eh_pads, this must be updated
23773471bf0Spatrick // to ExceptionSectionID. Otherwise, we set it equal to the current
23873471bf0Spatrick // section ID.
239*d415bd75Srobert EHPadsSectionID = EHPadsSectionID ? MBBSectionID::ExceptionSectionID
24073471bf0Spatrick : MBB.getSectionID();
24173471bf0Spatrick }
24273471bf0Spatrick }
24373471bf0Spatrick
24473471bf0Spatrick // If EHPads are in more than one section, this places all of them in the
24573471bf0Spatrick // special exception section.
24673471bf0Spatrick if (EHPadsSectionID == MBBSectionID::ExceptionSectionID)
24773471bf0Spatrick for (auto &MBB : MF)
24873471bf0Spatrick if (MBB.isEHPad())
249*d415bd75Srobert MBB.setSectionID(*EHPadsSectionID);
25073471bf0Spatrick }
25173471bf0Spatrick
sortBasicBlocksAndUpdateBranches(MachineFunction & MF,MachineBasicBlockComparator MBBCmp)25273471bf0Spatrick void llvm::sortBasicBlocksAndUpdateBranches(
25373471bf0Spatrick MachineFunction &MF, MachineBasicBlockComparator MBBCmp) {
254*d415bd75Srobert [[maybe_unused]] const MachineBasicBlock *EntryBlock = &MF.front();
255*d415bd75Srobert SmallVector<MachineBasicBlock *> PreLayoutFallThroughs(MF.getNumBlockIDs());
25673471bf0Spatrick for (auto &MBB : MF)
25773471bf0Spatrick PreLayoutFallThroughs[MBB.getNumber()] = MBB.getFallThrough();
25873471bf0Spatrick
25973471bf0Spatrick MF.sort(MBBCmp);
260*d415bd75Srobert assert(&MF.front() == EntryBlock &&
261*d415bd75Srobert "Entry block should not be displaced by basic block sections");
26273471bf0Spatrick
26373471bf0Spatrick // Set IsBeginSection and IsEndSection according to the assigned section IDs.
26473471bf0Spatrick MF.assignBeginEndSections();
26573471bf0Spatrick
26673471bf0Spatrick // After reordering basic blocks, we must update basic block branches to
26773471bf0Spatrick // insert explicit fallthrough branches when required and optimize branches
26873471bf0Spatrick // when possible.
26973471bf0Spatrick updateBranches(MF, PreLayoutFallThroughs);
27073471bf0Spatrick }
27173471bf0Spatrick
27273471bf0Spatrick // If the exception section begins with a landing pad, that landing pad will
27373471bf0Spatrick // assume a zero offset (relative to @LPStart) in the LSDA. However, a value of
27473471bf0Spatrick // zero implies "no landing pad." This function inserts a NOP just before the EH
275*d415bd75Srobert // pad label to ensure a nonzero offset.
avoidZeroOffsetLandingPad(MachineFunction & MF)276*d415bd75Srobert void llvm::avoidZeroOffsetLandingPad(MachineFunction &MF) {
27773471bf0Spatrick for (auto &MBB : MF) {
27873471bf0Spatrick if (MBB.isBeginSection() && MBB.isEHPad()) {
27973471bf0Spatrick MachineBasicBlock::iterator MI = MBB.begin();
28073471bf0Spatrick while (!MI->isEHLabel())
28173471bf0Spatrick ++MI;
28273471bf0Spatrick MCInst Nop = MF.getSubtarget().getInstrInfo()->getNop();
28373471bf0Spatrick BuildMI(MBB, MI, DebugLoc(),
28473471bf0Spatrick MF.getSubtarget().getInstrInfo()->get(Nop.getOpcode()));
28573471bf0Spatrick }
28673471bf0Spatrick }
28773471bf0Spatrick }
28873471bf0Spatrick
28973471bf0Spatrick // This checks if the source of this function has drifted since this binary was
29073471bf0Spatrick // profiled previously. For now, we are piggy backing on what PGO does to
29173471bf0Spatrick // detect this with instrumented profiles. PGO emits an hash of the IR and
29273471bf0Spatrick // checks if the hash has changed. Advanced basic block layout is usually done
29373471bf0Spatrick // on top of PGO optimized binaries and hence this check works well in practice.
hasInstrProfHashMismatch(MachineFunction & MF)29473471bf0Spatrick static bool hasInstrProfHashMismatch(MachineFunction &MF) {
29573471bf0Spatrick if (!BBSectionsDetectSourceDrift)
29673471bf0Spatrick return false;
29773471bf0Spatrick
29873471bf0Spatrick const char MetadataName[] = "instr_prof_hash_mismatch";
29973471bf0Spatrick auto *Existing = MF.getFunction().getMetadata(LLVMContext::MD_annotation);
30073471bf0Spatrick if (Existing) {
30173471bf0Spatrick MDTuple *Tuple = cast<MDTuple>(Existing);
302*d415bd75Srobert for (const auto &N : Tuple->operands())
30373471bf0Spatrick if (cast<MDString>(N.get())->getString() == MetadataName)
30473471bf0Spatrick return true;
30573471bf0Spatrick }
30673471bf0Spatrick
30773471bf0Spatrick return false;
30873471bf0Spatrick }
30973471bf0Spatrick
runOnMachineFunction(MachineFunction & MF)31073471bf0Spatrick bool BasicBlockSections::runOnMachineFunction(MachineFunction &MF) {
31173471bf0Spatrick auto BBSectionsType = MF.getTarget().getBBSectionsType();
31273471bf0Spatrick assert(BBSectionsType != BasicBlockSection::None &&
31373471bf0Spatrick "BB Sections not enabled!");
31473471bf0Spatrick
31573471bf0Spatrick // Check for source drift. If the source has changed since the profiles
31673471bf0Spatrick // were obtained, optimizing basic blocks might be sub-optimal.
31773471bf0Spatrick // This only applies to BasicBlockSection::List as it creates
31873471bf0Spatrick // clusters of basic blocks using basic block ids. Source drift can
31973471bf0Spatrick // invalidate these groupings leading to sub-optimal code generation with
32073471bf0Spatrick // regards to performance.
32173471bf0Spatrick if (BBSectionsType == BasicBlockSection::List &&
32273471bf0Spatrick hasInstrProfHashMismatch(MF))
32373471bf0Spatrick return true;
324*d415bd75Srobert // Renumber blocks before sorting them. This is useful during sorting,
325*d415bd75Srobert // basic blocks in the same section will retain the default order.
326*d415bd75Srobert // This renumbering should also be done for basic block labels to match the
327*d415bd75Srobert // profiles with the correct blocks.
328*d415bd75Srobert // For LLVM_BB_ADDR_MAP versions 2 and higher, this renumbering serves
329*d415bd75Srobert // the different purpose of accessing the original layout positions and
330*d415bd75Srobert // finding the original fallthroughs.
331*d415bd75Srobert // TODO: Change the above comment accordingly when version 1 is deprecated.
33273471bf0Spatrick MF.RenumberBlocks();
33373471bf0Spatrick
33473471bf0Spatrick if (BBSectionsType == BasicBlockSection::Labels) {
33573471bf0Spatrick MF.setBBSectionsType(BBSectionsType);
33673471bf0Spatrick return true;
33773471bf0Spatrick }
33873471bf0Spatrick
339*d415bd75Srobert BBSectionsProfileReader = &getAnalysis<BasicBlockSectionsProfileReader>();
340*d415bd75Srobert
341*d415bd75Srobert // Map from BBID of blocks to their cluster information.
342*d415bd75Srobert DenseMap<unsigned, BBClusterInfo> FuncBBClusterInfo;
34373471bf0Spatrick if (BBSectionsType == BasicBlockSection::List &&
344*d415bd75Srobert !getBBClusterInfoForFunction(MF, BBSectionsProfileReader,
34573471bf0Spatrick FuncBBClusterInfo))
34673471bf0Spatrick return true;
34773471bf0Spatrick MF.setBBSectionsType(BBSectionsType);
34873471bf0Spatrick assignSections(MF, FuncBBClusterInfo);
34973471bf0Spatrick
35073471bf0Spatrick // We make sure that the cluster including the entry basic block precedes all
35173471bf0Spatrick // other clusters.
35273471bf0Spatrick auto EntryBBSectionID = MF.front().getSectionID();
35373471bf0Spatrick
35473471bf0Spatrick // Helper function for ordering BB sections as follows:
35573471bf0Spatrick // * Entry section (section including the entry block).
35673471bf0Spatrick // * Regular sections (in increasing order of their Number).
35773471bf0Spatrick // ...
35873471bf0Spatrick // * Exception section
35973471bf0Spatrick // * Cold section
36073471bf0Spatrick auto MBBSectionOrder = [EntryBBSectionID](const MBBSectionID &LHS,
36173471bf0Spatrick const MBBSectionID &RHS) {
36273471bf0Spatrick // We make sure that the section containing the entry block precedes all the
36373471bf0Spatrick // other sections.
36473471bf0Spatrick if (LHS == EntryBBSectionID || RHS == EntryBBSectionID)
36573471bf0Spatrick return LHS == EntryBBSectionID;
36673471bf0Spatrick return LHS.Type == RHS.Type ? LHS.Number < RHS.Number : LHS.Type < RHS.Type;
36773471bf0Spatrick };
36873471bf0Spatrick
36973471bf0Spatrick // We sort all basic blocks to make sure the basic blocks of every cluster are
37073471bf0Spatrick // contiguous and ordered accordingly. Furthermore, clusters are ordered in
37173471bf0Spatrick // increasing order of their section IDs, with the exception and the
37273471bf0Spatrick // cold section placed at the end of the function.
37373471bf0Spatrick auto Comparator = [&](const MachineBasicBlock &X,
37473471bf0Spatrick const MachineBasicBlock &Y) {
37573471bf0Spatrick auto XSectionID = X.getSectionID();
37673471bf0Spatrick auto YSectionID = Y.getSectionID();
37773471bf0Spatrick if (XSectionID != YSectionID)
37873471bf0Spatrick return MBBSectionOrder(XSectionID, YSectionID);
37973471bf0Spatrick // If the two basic block are in the same section, the order is decided by
38073471bf0Spatrick // their position within the section.
38173471bf0Spatrick if (XSectionID.Type == MBBSectionID::SectionType::Default)
382*d415bd75Srobert return FuncBBClusterInfo.lookup(X.getBBIDOrNumber()).PositionInCluster <
383*d415bd75Srobert FuncBBClusterInfo.lookup(Y.getBBIDOrNumber()).PositionInCluster;
38473471bf0Spatrick return X.getNumber() < Y.getNumber();
38573471bf0Spatrick };
38673471bf0Spatrick
38773471bf0Spatrick sortBasicBlocksAndUpdateBranches(MF, Comparator);
38873471bf0Spatrick avoidZeroOffsetLandingPad(MF);
38973471bf0Spatrick return true;
39073471bf0Spatrick }
39173471bf0Spatrick
getAnalysisUsage(AnalysisUsage & AU) const39273471bf0Spatrick void BasicBlockSections::getAnalysisUsage(AnalysisUsage &AU) const {
39373471bf0Spatrick AU.setPreservesAll();
394*d415bd75Srobert AU.addRequired<BasicBlockSectionsProfileReader>();
39573471bf0Spatrick MachineFunctionPass::getAnalysisUsage(AU);
39673471bf0Spatrick }
39773471bf0Spatrick
createBasicBlockSectionsPass()398*d415bd75Srobert MachineFunctionPass *llvm::createBasicBlockSectionsPass() {
399*d415bd75Srobert return new BasicBlockSections();
40073471bf0Spatrick }
401