1e8d8bef9SDimitry Andric //===-- BasicBlockSections.cpp ---=========--------------------------------===// 2e8d8bef9SDimitry Andric // 3e8d8bef9SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4e8d8bef9SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5e8d8bef9SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e8d8bef9SDimitry Andric // 7e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===// 8e8d8bef9SDimitry Andric // 9e8d8bef9SDimitry Andric // BasicBlockSections implementation. 10e8d8bef9SDimitry Andric // 11e8d8bef9SDimitry Andric // The purpose of this pass is to assign sections to basic blocks when 12e8d8bef9SDimitry Andric // -fbasic-block-sections= option is used. Further, with profile information 13e8d8bef9SDimitry Andric // only the subset of basic blocks with profiles are placed in separate sections 14e8d8bef9SDimitry Andric // and the rest are grouped in a cold section. The exception handling blocks are 15e8d8bef9SDimitry Andric // treated specially to ensure they are all in one seciton. 16e8d8bef9SDimitry Andric // 17e8d8bef9SDimitry Andric // Basic Block Sections 18e8d8bef9SDimitry Andric // ==================== 19e8d8bef9SDimitry Andric // 20e8d8bef9SDimitry Andric // With option, -fbasic-block-sections=list, every function may be split into 21e8d8bef9SDimitry Andric // clusters of basic blocks. Every cluster will be emitted into a separate 22e8d8bef9SDimitry Andric // section with its basic blocks sequenced in the given order. To get the 23e8d8bef9SDimitry Andric // optimized performance, the clusters must form an optimal BB layout for the 24349cc55cSDimitry Andric // function. We insert a symbol at the beginning of every cluster's section to 25349cc55cSDimitry Andric // allow the linker to reorder the sections in any arbitrary sequence. A global 26349cc55cSDimitry Andric // order of these sections would encapsulate the function layout. 27349cc55cSDimitry Andric // For example, consider the following clusters for a function foo (consisting 28349cc55cSDimitry Andric // of 6 basic blocks 0, 1, ..., 5). 29349cc55cSDimitry Andric // 30349cc55cSDimitry Andric // 0 2 31349cc55cSDimitry Andric // 1 3 5 32349cc55cSDimitry Andric // 33349cc55cSDimitry Andric // * Basic blocks 0 and 2 are placed in one section with symbol `foo` 34349cc55cSDimitry Andric // referencing the beginning of this section. 35349cc55cSDimitry Andric // * Basic blocks 1, 3, 5 are placed in a separate section. A new symbol 36349cc55cSDimitry Andric // `foo.__part.1` will reference the beginning of this section. 37349cc55cSDimitry Andric // * Basic block 4 (note that it is not referenced in the list) is placed in 38349cc55cSDimitry Andric // one section, and a new symbol `foo.cold` will point to it. 39e8d8bef9SDimitry Andric // 40e8d8bef9SDimitry Andric // There are a couple of challenges to be addressed: 41e8d8bef9SDimitry Andric // 42e8d8bef9SDimitry Andric // 1. The last basic block of every cluster should not have any implicit 43e8d8bef9SDimitry Andric // fallthrough to its next basic block, as it can be reordered by the linker. 44e8d8bef9SDimitry Andric // The compiler should make these fallthroughs explicit by adding 45e8d8bef9SDimitry Andric // unconditional jumps.. 46e8d8bef9SDimitry Andric // 47e8d8bef9SDimitry Andric // 2. All inter-cluster branch targets would now need to be resolved by the 48e8d8bef9SDimitry Andric // linker as they cannot be calculated during compile time. This is done 49e8d8bef9SDimitry Andric // using static relocations. Further, the compiler tries to use short branch 50e8d8bef9SDimitry Andric // instructions on some ISAs for small branch offsets. This is not possible 51e8d8bef9SDimitry Andric // for inter-cluster branches as the offset is not determined at compile 52e8d8bef9SDimitry Andric // time, and therefore, long branch instructions have to be used for those. 53e8d8bef9SDimitry Andric // 54e8d8bef9SDimitry Andric // 3. Debug Information (DebugInfo) and Call Frame Information (CFI) emission 55e8d8bef9SDimitry Andric // needs special handling with basic block sections. DebugInfo needs to be 56e8d8bef9SDimitry Andric // emitted with more relocations as basic block sections can break a 57e8d8bef9SDimitry Andric // function into potentially several disjoint pieces, and CFI needs to be 58e8d8bef9SDimitry Andric // emitted per cluster. This also bloats the object file and binary sizes. 59e8d8bef9SDimitry Andric // 60e8d8bef9SDimitry Andric // Basic Block Labels 61e8d8bef9SDimitry Andric // ================== 62e8d8bef9SDimitry Andric // 6381ad6265SDimitry Andric // With -fbasic-block-sections=labels, we encode the offsets of BB addresses of 64e8d8bef9SDimitry Andric // every function into the .llvm_bb_addr_map section. Along with the function 65e8d8bef9SDimitry Andric // symbols, this allows for mapping of virtual addresses in PMU profiles back to 66e8d8bef9SDimitry Andric // the corresponding basic blocks. This logic is implemented in AsmPrinter. This 67e8d8bef9SDimitry Andric // pass only assigns the BBSectionType of every function to ``labels``. 68e8d8bef9SDimitry Andric // 69e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===// 70e8d8bef9SDimitry Andric 71e8d8bef9SDimitry Andric #include "llvm/ADT/SmallVector.h" 72e8d8bef9SDimitry Andric #include "llvm/ADT/StringRef.h" 73e8d8bef9SDimitry Andric #include "llvm/CodeGen/BasicBlockSectionUtils.h" 74bdd1243dSDimitry Andric #include "llvm/CodeGen/BasicBlockSectionsProfileReader.h" 75e8d8bef9SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 76e8d8bef9SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 77e8d8bef9SDimitry Andric #include "llvm/CodeGen/Passes.h" 78e8d8bef9SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 79e8d8bef9SDimitry Andric #include "llvm/InitializePasses.h" 80e8d8bef9SDimitry Andric #include "llvm/Target/TargetMachine.h" 81bdd1243dSDimitry Andric #include <optional> 82e8d8bef9SDimitry Andric 83e8d8bef9SDimitry Andric using namespace llvm; 84e8d8bef9SDimitry Andric 85e8d8bef9SDimitry Andric // Placing the cold clusters in a separate section mitigates against poor 86e8d8bef9SDimitry Andric // profiles and allows optimizations such as hugepage mapping to be applied at a 87e8d8bef9SDimitry Andric // section granularity. Defaults to ".text.split." which is recognized by lld 88e8d8bef9SDimitry Andric // via the `-z keep-text-section-prefix` flag. 89e8d8bef9SDimitry Andric cl::opt<std::string> llvm::BBSectionsColdTextPrefix( 90e8d8bef9SDimitry Andric "bbsections-cold-text-prefix", 91e8d8bef9SDimitry Andric cl::desc("The text prefix to use for cold basic block clusters"), 92e8d8bef9SDimitry Andric cl::init(".text.split."), cl::Hidden); 93e8d8bef9SDimitry Andric 9406c3fb27SDimitry Andric static cl::opt<bool> BBSectionsDetectSourceDrift( 95fe6060f1SDimitry Andric "bbsections-detect-source-drift", 96fe6060f1SDimitry Andric cl::desc("This checks if there is a fdo instr. profile hash " 97fe6060f1SDimitry Andric "mismatch for this function"), 98fe6060f1SDimitry Andric cl::init(true), cl::Hidden); 99fe6060f1SDimitry Andric 100e8d8bef9SDimitry Andric namespace { 101e8d8bef9SDimitry Andric 102e8d8bef9SDimitry Andric class BasicBlockSections : public MachineFunctionPass { 103e8d8bef9SDimitry Andric public: 104e8d8bef9SDimitry Andric static char ID; 105e8d8bef9SDimitry Andric 10681ad6265SDimitry Andric BasicBlockSectionsProfileReader *BBSectionsProfileReader = nullptr; 107e8d8bef9SDimitry Andric 108e8d8bef9SDimitry Andric BasicBlockSections() : MachineFunctionPass(ID) { 109e8d8bef9SDimitry Andric initializeBasicBlockSectionsPass(*PassRegistry::getPassRegistry()); 110e8d8bef9SDimitry Andric } 111e8d8bef9SDimitry Andric 112e8d8bef9SDimitry Andric StringRef getPassName() const override { 113e8d8bef9SDimitry Andric return "Basic Block Sections Analysis"; 114e8d8bef9SDimitry Andric } 115e8d8bef9SDimitry Andric 116e8d8bef9SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override; 117e8d8bef9SDimitry Andric 118e8d8bef9SDimitry Andric /// Identify basic blocks that need separate sections and prepare to emit them 119e8d8bef9SDimitry Andric /// accordingly. 120e8d8bef9SDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override; 121e8d8bef9SDimitry Andric }; 122e8d8bef9SDimitry Andric 123e8d8bef9SDimitry Andric } // end anonymous namespace 124e8d8bef9SDimitry Andric 125e8d8bef9SDimitry Andric char BasicBlockSections::ID = 0; 12606c3fb27SDimitry Andric INITIALIZE_PASS_BEGIN( 12706c3fb27SDimitry Andric BasicBlockSections, "bbsections-prepare", 12806c3fb27SDimitry Andric "Prepares for basic block sections, by splitting functions " 12906c3fb27SDimitry Andric "into clusters of basic blocks.", 13006c3fb27SDimitry Andric false, false) 13106c3fb27SDimitry Andric INITIALIZE_PASS_DEPENDENCY(BasicBlockSectionsProfileReader) 13206c3fb27SDimitry Andric INITIALIZE_PASS_END(BasicBlockSections, "bbsections-prepare", 133e8d8bef9SDimitry Andric "Prepares for basic block sections, by splitting functions " 134e8d8bef9SDimitry Andric "into clusters of basic blocks.", 135e8d8bef9SDimitry Andric false, false) 136e8d8bef9SDimitry Andric 137e8d8bef9SDimitry Andric // This function updates and optimizes the branching instructions of every basic 138e8d8bef9SDimitry Andric // block in a given function to account for changes in the layout. 139bdd1243dSDimitry Andric static void 140bdd1243dSDimitry Andric updateBranches(MachineFunction &MF, 141bdd1243dSDimitry Andric const SmallVector<MachineBasicBlock *> &PreLayoutFallThroughs) { 142e8d8bef9SDimitry Andric const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); 143e8d8bef9SDimitry Andric SmallVector<MachineOperand, 4> Cond; 144e8d8bef9SDimitry Andric for (auto &MBB : MF) { 145e8d8bef9SDimitry Andric auto NextMBBI = std::next(MBB.getIterator()); 146e8d8bef9SDimitry Andric auto *FTMBB = PreLayoutFallThroughs[MBB.getNumber()]; 147e8d8bef9SDimitry Andric // If this block had a fallthrough before we need an explicit unconditional 148e8d8bef9SDimitry Andric // branch to that block if either 149e8d8bef9SDimitry Andric // 1- the block ends a section, which means its next block may be 150e8d8bef9SDimitry Andric // reorderd by the linker, or 151e8d8bef9SDimitry Andric // 2- the fallthrough block is not adjacent to the block in the new 152e8d8bef9SDimitry Andric // order. 153e8d8bef9SDimitry Andric if (FTMBB && (MBB.isEndSection() || &*NextMBBI != FTMBB)) 154e8d8bef9SDimitry Andric TII->insertUnconditionalBranch(MBB, FTMBB, MBB.findBranchDebugLoc()); 155e8d8bef9SDimitry Andric 156e8d8bef9SDimitry Andric // We do not optimize branches for machine basic blocks ending sections, as 157e8d8bef9SDimitry Andric // their adjacent block might be reordered by the linker. 158e8d8bef9SDimitry Andric if (MBB.isEndSection()) 159e8d8bef9SDimitry Andric continue; 160e8d8bef9SDimitry Andric 161e8d8bef9SDimitry Andric // It might be possible to optimize branches by flipping the branch 162e8d8bef9SDimitry Andric // condition. 163e8d8bef9SDimitry Andric Cond.clear(); 164e8d8bef9SDimitry Andric MachineBasicBlock *TBB = nullptr, *FBB = nullptr; // For analyzeBranch. 165e8d8bef9SDimitry Andric if (TII->analyzeBranch(MBB, TBB, FBB, Cond)) 166e8d8bef9SDimitry Andric continue; 167e8d8bef9SDimitry Andric MBB.updateTerminator(FTMBB); 168e8d8bef9SDimitry Andric } 169e8d8bef9SDimitry Andric } 170e8d8bef9SDimitry Andric 171e8d8bef9SDimitry Andric // This function sorts basic blocks according to the cluster's information. 172e8d8bef9SDimitry Andric // All explicitly specified clusters of basic blocks will be ordered 173e8d8bef9SDimitry Andric // accordingly. All non-specified BBs go into a separate "Cold" section. 174e8d8bef9SDimitry Andric // Additionally, if exception handling landing pads end up in more than one 175e8d8bef9SDimitry Andric // clusters, they are moved into a single "Exception" section. Eventually, 176e8d8bef9SDimitry Andric // clusters are ordered in increasing order of their IDs, with the "Exception" 177e8d8bef9SDimitry Andric // and "Cold" succeeding all other clusters. 178*5f757f3fSDimitry Andric // FuncClusterInfo represents the cluster information for basic blocks. It 179bdd1243dSDimitry Andric // maps from BBID of basic blocks to their cluster information. If this is 180bdd1243dSDimitry Andric // empty, it means unique sections for all basic blocks in the function. 181e8d8bef9SDimitry Andric static void 182e8d8bef9SDimitry Andric assignSections(MachineFunction &MF, 183*5f757f3fSDimitry Andric const DenseMap<UniqueBBID, BBClusterInfo> &FuncClusterInfo) { 184e8d8bef9SDimitry Andric assert(MF.hasBBSections() && "BB Sections is not set for function."); 185e8d8bef9SDimitry Andric // This variable stores the section ID of the cluster containing eh_pads (if 186e8d8bef9SDimitry Andric // all eh_pads are one cluster). If more than one cluster contain eh_pads, we 187e8d8bef9SDimitry Andric // set it equal to ExceptionSectionID. 188bdd1243dSDimitry Andric std::optional<MBBSectionID> EHPadsSectionID; 189e8d8bef9SDimitry Andric 190e8d8bef9SDimitry Andric for (auto &MBB : MF) { 191e8d8bef9SDimitry Andric // With the 'all' option, every basic block is placed in a unique section. 192e8d8bef9SDimitry Andric // With the 'list' option, every basic block is placed in a section 193e8d8bef9SDimitry Andric // associated with its cluster, unless we want individual unique sections 194*5f757f3fSDimitry Andric // for every basic block in this function (if FuncClusterInfo is empty). 195e8d8bef9SDimitry Andric if (MF.getTarget().getBBSectionsType() == llvm::BasicBlockSection::All || 196*5f757f3fSDimitry Andric FuncClusterInfo.empty()) { 197e8d8bef9SDimitry Andric // If unique sections are desired for all basic blocks of the function, we 198bdd1243dSDimitry Andric // set every basic block's section ID equal to its original position in 199bdd1243dSDimitry Andric // the layout (which is equal to its number). This ensures that basic 200bdd1243dSDimitry Andric // blocks are ordered canonically. 201bdd1243dSDimitry Andric MBB.setSectionID(MBB.getNumber()); 202bdd1243dSDimitry Andric } else { 203*5f757f3fSDimitry Andric auto I = FuncClusterInfo.find(*MBB.getBBID()); 204*5f757f3fSDimitry Andric if (I != FuncClusterInfo.end()) { 205bdd1243dSDimitry Andric MBB.setSectionID(I->second.ClusterID); 206bdd1243dSDimitry Andric } else { 207e8d8bef9SDimitry Andric // BB goes into the special cold section if it is not specified in the 208e8d8bef9SDimitry Andric // cluster info map. 209e8d8bef9SDimitry Andric MBB.setSectionID(MBBSectionID::ColdSectionID); 210e8d8bef9SDimitry Andric } 211bdd1243dSDimitry Andric } 212e8d8bef9SDimitry Andric 213e8d8bef9SDimitry Andric if (MBB.isEHPad() && EHPadsSectionID != MBB.getSectionID() && 214e8d8bef9SDimitry Andric EHPadsSectionID != MBBSectionID::ExceptionSectionID) { 215e8d8bef9SDimitry Andric // If we already have one cluster containing eh_pads, this must be updated 216e8d8bef9SDimitry Andric // to ExceptionSectionID. Otherwise, we set it equal to the current 217e8d8bef9SDimitry Andric // section ID. 21881ad6265SDimitry Andric EHPadsSectionID = EHPadsSectionID ? MBBSectionID::ExceptionSectionID 219e8d8bef9SDimitry Andric : MBB.getSectionID(); 220e8d8bef9SDimitry Andric } 221e8d8bef9SDimitry Andric } 222e8d8bef9SDimitry Andric 223e8d8bef9SDimitry Andric // If EHPads are in more than one section, this places all of them in the 224e8d8bef9SDimitry Andric // special exception section. 225e8d8bef9SDimitry Andric if (EHPadsSectionID == MBBSectionID::ExceptionSectionID) 226e8d8bef9SDimitry Andric for (auto &MBB : MF) 227e8d8bef9SDimitry Andric if (MBB.isEHPad()) 22881ad6265SDimitry Andric MBB.setSectionID(*EHPadsSectionID); 229e8d8bef9SDimitry Andric } 230e8d8bef9SDimitry Andric 231e8d8bef9SDimitry Andric void llvm::sortBasicBlocksAndUpdateBranches( 232e8d8bef9SDimitry Andric MachineFunction &MF, MachineBasicBlockComparator MBBCmp) { 233bdd1243dSDimitry Andric [[maybe_unused]] const MachineBasicBlock *EntryBlock = &MF.front(); 234bdd1243dSDimitry Andric SmallVector<MachineBasicBlock *> PreLayoutFallThroughs(MF.getNumBlockIDs()); 235e8d8bef9SDimitry Andric for (auto &MBB : MF) 236*5f757f3fSDimitry Andric PreLayoutFallThroughs[MBB.getNumber()] = 237*5f757f3fSDimitry Andric MBB.getFallThrough(/*JumpToFallThrough=*/false); 238e8d8bef9SDimitry Andric 239e8d8bef9SDimitry Andric MF.sort(MBBCmp); 240bdd1243dSDimitry Andric assert(&MF.front() == EntryBlock && 241bdd1243dSDimitry Andric "Entry block should not be displaced by basic block sections"); 242e8d8bef9SDimitry Andric 243e8d8bef9SDimitry Andric // Set IsBeginSection and IsEndSection according to the assigned section IDs. 244e8d8bef9SDimitry Andric MF.assignBeginEndSections(); 245e8d8bef9SDimitry Andric 246e8d8bef9SDimitry Andric // After reordering basic blocks, we must update basic block branches to 247e8d8bef9SDimitry Andric // insert explicit fallthrough branches when required and optimize branches 248e8d8bef9SDimitry Andric // when possible. 249e8d8bef9SDimitry Andric updateBranches(MF, PreLayoutFallThroughs); 250e8d8bef9SDimitry Andric } 251e8d8bef9SDimitry Andric 252e8d8bef9SDimitry Andric // If the exception section begins with a landing pad, that landing pad will 253e8d8bef9SDimitry Andric // assume a zero offset (relative to @LPStart) in the LSDA. However, a value of 254e8d8bef9SDimitry Andric // zero implies "no landing pad." This function inserts a NOP just before the EH 255fcaf7f86SDimitry Andric // pad label to ensure a nonzero offset. 256fcaf7f86SDimitry Andric void llvm::avoidZeroOffsetLandingPad(MachineFunction &MF) { 257e8d8bef9SDimitry Andric for (auto &MBB : MF) { 258e8d8bef9SDimitry Andric if (MBB.isBeginSection() && MBB.isEHPad()) { 259e8d8bef9SDimitry Andric MachineBasicBlock::iterator MI = MBB.begin(); 260e8d8bef9SDimitry Andric while (!MI->isEHLabel()) 261e8d8bef9SDimitry Andric ++MI; 262*5f757f3fSDimitry Andric MF.getSubtarget().getInstrInfo()->insertNoop(MBB, MI); 263e8d8bef9SDimitry Andric } 264e8d8bef9SDimitry Andric } 265e8d8bef9SDimitry Andric } 266e8d8bef9SDimitry Andric 267*5f757f3fSDimitry Andric bool llvm::hasInstrProfHashMismatch(MachineFunction &MF) { 268fe6060f1SDimitry Andric if (!BBSectionsDetectSourceDrift) 269fe6060f1SDimitry Andric return false; 270fe6060f1SDimitry Andric 271fe6060f1SDimitry Andric const char MetadataName[] = "instr_prof_hash_mismatch"; 272fe6060f1SDimitry Andric auto *Existing = MF.getFunction().getMetadata(LLVMContext::MD_annotation); 273fe6060f1SDimitry Andric if (Existing) { 274fe6060f1SDimitry Andric MDTuple *Tuple = cast<MDTuple>(Existing); 275fcaf7f86SDimitry Andric for (const auto &N : Tuple->operands()) 27606c3fb27SDimitry Andric if (N.equalsStr(MetadataName)) 277fe6060f1SDimitry Andric return true; 278fe6060f1SDimitry Andric } 279fe6060f1SDimitry Andric 280fe6060f1SDimitry Andric return false; 281fe6060f1SDimitry Andric } 282fe6060f1SDimitry Andric 283e8d8bef9SDimitry Andric bool BasicBlockSections::runOnMachineFunction(MachineFunction &MF) { 284e8d8bef9SDimitry Andric auto BBSectionsType = MF.getTarget().getBBSectionsType(); 285e8d8bef9SDimitry Andric assert(BBSectionsType != BasicBlockSection::None && 286e8d8bef9SDimitry Andric "BB Sections not enabled!"); 287fe6060f1SDimitry Andric 288fe6060f1SDimitry Andric // Check for source drift. If the source has changed since the profiles 289fe6060f1SDimitry Andric // were obtained, optimizing basic blocks might be sub-optimal. 290fe6060f1SDimitry Andric // This only applies to BasicBlockSection::List as it creates 291fe6060f1SDimitry Andric // clusters of basic blocks using basic block ids. Source drift can 292fe6060f1SDimitry Andric // invalidate these groupings leading to sub-optimal code generation with 293fe6060f1SDimitry Andric // regards to performance. 294fe6060f1SDimitry Andric if (BBSectionsType == BasicBlockSection::List && 295fe6060f1SDimitry Andric hasInstrProfHashMismatch(MF)) 296*5f757f3fSDimitry Andric return false; 297*5f757f3fSDimitry Andric // Renumber blocks before sorting them. This is useful for accessing the 298*5f757f3fSDimitry Andric // original layout positions and finding the original fallthroughs. 299e8d8bef9SDimitry Andric MF.RenumberBlocks(); 300e8d8bef9SDimitry Andric 301e8d8bef9SDimitry Andric if (BBSectionsType == BasicBlockSection::Labels) { 302e8d8bef9SDimitry Andric MF.setBBSectionsType(BBSectionsType); 303*5f757f3fSDimitry Andric return false; 304e8d8bef9SDimitry Andric } 305e8d8bef9SDimitry Andric 306*5f757f3fSDimitry Andric DenseMap<UniqueBBID, BBClusterInfo> FuncClusterInfo; 307*5f757f3fSDimitry Andric if (BBSectionsType == BasicBlockSection::List) { 308*5f757f3fSDimitry Andric auto [HasProfile, ClusterInfo] = 309*5f757f3fSDimitry Andric getAnalysis<BasicBlockSectionsProfileReader>() 310*5f757f3fSDimitry Andric .getClusterInfoForFunction(MF.getName()); 311*5f757f3fSDimitry Andric if (!HasProfile) 312*5f757f3fSDimitry Andric return false; 313*5f757f3fSDimitry Andric for (auto &BBClusterInfo : ClusterInfo) { 314*5f757f3fSDimitry Andric FuncClusterInfo.try_emplace(BBClusterInfo.BBID, BBClusterInfo); 315*5f757f3fSDimitry Andric } 316*5f757f3fSDimitry Andric } 31781ad6265SDimitry Andric 318e8d8bef9SDimitry Andric MF.setBBSectionsType(BBSectionsType); 319*5f757f3fSDimitry Andric assignSections(MF, FuncClusterInfo); 320e8d8bef9SDimitry Andric 321e8d8bef9SDimitry Andric // We make sure that the cluster including the entry basic block precedes all 322e8d8bef9SDimitry Andric // other clusters. 323e8d8bef9SDimitry Andric auto EntryBBSectionID = MF.front().getSectionID(); 324e8d8bef9SDimitry Andric 325e8d8bef9SDimitry Andric // Helper function for ordering BB sections as follows: 326e8d8bef9SDimitry Andric // * Entry section (section including the entry block). 327e8d8bef9SDimitry Andric // * Regular sections (in increasing order of their Number). 328e8d8bef9SDimitry Andric // ... 329e8d8bef9SDimitry Andric // * Exception section 330e8d8bef9SDimitry Andric // * Cold section 331e8d8bef9SDimitry Andric auto MBBSectionOrder = [EntryBBSectionID](const MBBSectionID &LHS, 332e8d8bef9SDimitry Andric const MBBSectionID &RHS) { 333e8d8bef9SDimitry Andric // We make sure that the section containing the entry block precedes all the 334e8d8bef9SDimitry Andric // other sections. 335e8d8bef9SDimitry Andric if (LHS == EntryBBSectionID || RHS == EntryBBSectionID) 336e8d8bef9SDimitry Andric return LHS == EntryBBSectionID; 337e8d8bef9SDimitry Andric return LHS.Type == RHS.Type ? LHS.Number < RHS.Number : LHS.Type < RHS.Type; 338e8d8bef9SDimitry Andric }; 339e8d8bef9SDimitry Andric 340e8d8bef9SDimitry Andric // We sort all basic blocks to make sure the basic blocks of every cluster are 341e8d8bef9SDimitry Andric // contiguous and ordered accordingly. Furthermore, clusters are ordered in 342e8d8bef9SDimitry Andric // increasing order of their section IDs, with the exception and the 343e8d8bef9SDimitry Andric // cold section placed at the end of the function. 344e8d8bef9SDimitry Andric auto Comparator = [&](const MachineBasicBlock &X, 345e8d8bef9SDimitry Andric const MachineBasicBlock &Y) { 346e8d8bef9SDimitry Andric auto XSectionID = X.getSectionID(); 347e8d8bef9SDimitry Andric auto YSectionID = Y.getSectionID(); 348e8d8bef9SDimitry Andric if (XSectionID != YSectionID) 349e8d8bef9SDimitry Andric return MBBSectionOrder(XSectionID, YSectionID); 350e8d8bef9SDimitry Andric // If the two basic block are in the same section, the order is decided by 351e8d8bef9SDimitry Andric // their position within the section. 352e8d8bef9SDimitry Andric if (XSectionID.Type == MBBSectionID::SectionType::Default) 353*5f757f3fSDimitry Andric return FuncClusterInfo.lookup(*X.getBBID()).PositionInCluster < 354*5f757f3fSDimitry Andric FuncClusterInfo.lookup(*Y.getBBID()).PositionInCluster; 355e8d8bef9SDimitry Andric return X.getNumber() < Y.getNumber(); 356e8d8bef9SDimitry Andric }; 357e8d8bef9SDimitry Andric 358e8d8bef9SDimitry Andric sortBasicBlocksAndUpdateBranches(MF, Comparator); 359e8d8bef9SDimitry Andric avoidZeroOffsetLandingPad(MF); 360e8d8bef9SDimitry Andric return true; 361e8d8bef9SDimitry Andric } 362e8d8bef9SDimitry Andric 363e8d8bef9SDimitry Andric void BasicBlockSections::getAnalysisUsage(AnalysisUsage &AU) const { 364e8d8bef9SDimitry Andric AU.setPreservesAll(); 36581ad6265SDimitry Andric AU.addRequired<BasicBlockSectionsProfileReader>(); 366e8d8bef9SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU); 367e8d8bef9SDimitry Andric } 368e8d8bef9SDimitry Andric 36981ad6265SDimitry Andric MachineFunctionPass *llvm::createBasicBlockSectionsPass() { 37081ad6265SDimitry Andric return new BasicBlockSections(); 371e8d8bef9SDimitry Andric } 372