xref: /openbsd-src/gnu/llvm/llvm/lib/CodeGen/BasicBlockSections.cpp (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
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