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" 74*bdd1243dSDimitry 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" 81*bdd1243dSDimitry 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 94fe6060f1SDimitry Andric 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; 126e8d8bef9SDimitry Andric INITIALIZE_PASS(BasicBlockSections, "bbsections-prepare", 127e8d8bef9SDimitry Andric "Prepares for basic block sections, by splitting functions " 128e8d8bef9SDimitry Andric "into clusters of basic blocks.", 129e8d8bef9SDimitry Andric false, false) 130e8d8bef9SDimitry Andric 131e8d8bef9SDimitry Andric // This function updates and optimizes the branching instructions of every basic 132e8d8bef9SDimitry Andric // block in a given function to account for changes in the layout. 133*bdd1243dSDimitry Andric static void 134*bdd1243dSDimitry Andric updateBranches(MachineFunction &MF, 135*bdd1243dSDimitry Andric const SmallVector<MachineBasicBlock *> &PreLayoutFallThroughs) { 136e8d8bef9SDimitry Andric const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); 137e8d8bef9SDimitry Andric SmallVector<MachineOperand, 4> Cond; 138e8d8bef9SDimitry Andric for (auto &MBB : MF) { 139e8d8bef9SDimitry Andric auto NextMBBI = std::next(MBB.getIterator()); 140e8d8bef9SDimitry Andric auto *FTMBB = PreLayoutFallThroughs[MBB.getNumber()]; 141e8d8bef9SDimitry Andric // If this block had a fallthrough before we need an explicit unconditional 142e8d8bef9SDimitry Andric // branch to that block if either 143e8d8bef9SDimitry Andric // 1- the block ends a section, which means its next block may be 144e8d8bef9SDimitry Andric // reorderd by the linker, or 145e8d8bef9SDimitry Andric // 2- the fallthrough block is not adjacent to the block in the new 146e8d8bef9SDimitry Andric // order. 147e8d8bef9SDimitry Andric if (FTMBB && (MBB.isEndSection() || &*NextMBBI != FTMBB)) 148e8d8bef9SDimitry Andric TII->insertUnconditionalBranch(MBB, FTMBB, MBB.findBranchDebugLoc()); 149e8d8bef9SDimitry Andric 150e8d8bef9SDimitry Andric // We do not optimize branches for machine basic blocks ending sections, as 151e8d8bef9SDimitry Andric // their adjacent block might be reordered by the linker. 152e8d8bef9SDimitry Andric if (MBB.isEndSection()) 153e8d8bef9SDimitry Andric continue; 154e8d8bef9SDimitry Andric 155e8d8bef9SDimitry Andric // It might be possible to optimize branches by flipping the branch 156e8d8bef9SDimitry Andric // condition. 157e8d8bef9SDimitry Andric Cond.clear(); 158e8d8bef9SDimitry Andric MachineBasicBlock *TBB = nullptr, *FBB = nullptr; // For analyzeBranch. 159e8d8bef9SDimitry Andric if (TII->analyzeBranch(MBB, TBB, FBB, Cond)) 160e8d8bef9SDimitry Andric continue; 161e8d8bef9SDimitry Andric MBB.updateTerminator(FTMBB); 162e8d8bef9SDimitry Andric } 163e8d8bef9SDimitry Andric } 164e8d8bef9SDimitry Andric 165e8d8bef9SDimitry Andric // This function provides the BBCluster information associated with a function. 166e8d8bef9SDimitry Andric // Returns true if a valid association exists and false otherwise. 16781ad6265SDimitry Andric bool getBBClusterInfoForFunction( 16881ad6265SDimitry Andric const MachineFunction &MF, 16981ad6265SDimitry Andric BasicBlockSectionsProfileReader *BBSectionsProfileReader, 170*bdd1243dSDimitry Andric DenseMap<unsigned, BBClusterInfo> &V) { 171e8d8bef9SDimitry Andric 172e8d8bef9SDimitry Andric // Find the assoicated cluster information. 17381ad6265SDimitry Andric std::pair<bool, SmallVector<BBClusterInfo, 4>> P = 17481ad6265SDimitry Andric BBSectionsProfileReader->getBBClusterInfoForFunction(MF.getName()); 17581ad6265SDimitry Andric if (!P.first) 176e8d8bef9SDimitry Andric return false; 177e8d8bef9SDimitry Andric 17881ad6265SDimitry Andric if (P.second.empty()) { 179e8d8bef9SDimitry Andric // This indicates that sections are desired for all basic blocks of this 180e8d8bef9SDimitry Andric // function. We clear the BBClusterInfo vector to denote this. 181e8d8bef9SDimitry Andric V.clear(); 182e8d8bef9SDimitry Andric return true; 183e8d8bef9SDimitry Andric } 184e8d8bef9SDimitry Andric 185*bdd1243dSDimitry Andric for (const BBClusterInfo &BBCI : P.second) 186*bdd1243dSDimitry Andric V[BBCI.BBID] = BBCI; 187e8d8bef9SDimitry Andric return true; 188e8d8bef9SDimitry Andric } 189e8d8bef9SDimitry Andric 190e8d8bef9SDimitry Andric // This function sorts basic blocks according to the cluster's information. 191e8d8bef9SDimitry Andric // All explicitly specified clusters of basic blocks will be ordered 192e8d8bef9SDimitry Andric // accordingly. All non-specified BBs go into a separate "Cold" section. 193e8d8bef9SDimitry Andric // Additionally, if exception handling landing pads end up in more than one 194e8d8bef9SDimitry Andric // clusters, they are moved into a single "Exception" section. Eventually, 195e8d8bef9SDimitry Andric // clusters are ordered in increasing order of their IDs, with the "Exception" 196e8d8bef9SDimitry Andric // and "Cold" succeeding all other clusters. 197*bdd1243dSDimitry Andric // FuncBBClusterInfo represent the cluster information for basic blocks. It 198*bdd1243dSDimitry Andric // maps from BBID of basic blocks to their cluster information. If this is 199*bdd1243dSDimitry Andric // empty, it means unique sections for all basic blocks in the function. 200e8d8bef9SDimitry Andric static void 201e8d8bef9SDimitry Andric assignSections(MachineFunction &MF, 202*bdd1243dSDimitry Andric const DenseMap<unsigned, BBClusterInfo> &FuncBBClusterInfo) { 203e8d8bef9SDimitry Andric assert(MF.hasBBSections() && "BB Sections is not set for function."); 204e8d8bef9SDimitry Andric // This variable stores the section ID of the cluster containing eh_pads (if 205e8d8bef9SDimitry Andric // all eh_pads are one cluster). If more than one cluster contain eh_pads, we 206e8d8bef9SDimitry Andric // set it equal to ExceptionSectionID. 207*bdd1243dSDimitry Andric std::optional<MBBSectionID> EHPadsSectionID; 208e8d8bef9SDimitry Andric 209e8d8bef9SDimitry Andric for (auto &MBB : MF) { 210e8d8bef9SDimitry Andric // With the 'all' option, every basic block is placed in a unique section. 211e8d8bef9SDimitry Andric // With the 'list' option, every basic block is placed in a section 212e8d8bef9SDimitry Andric // associated with its cluster, unless we want individual unique sections 213e8d8bef9SDimitry Andric // for every basic block in this function (if FuncBBClusterInfo is empty). 214e8d8bef9SDimitry Andric if (MF.getTarget().getBBSectionsType() == llvm::BasicBlockSection::All || 215e8d8bef9SDimitry Andric FuncBBClusterInfo.empty()) { 216e8d8bef9SDimitry Andric // If unique sections are desired for all basic blocks of the function, we 217*bdd1243dSDimitry Andric // set every basic block's section ID equal to its original position in 218*bdd1243dSDimitry Andric // the layout (which is equal to its number). This ensures that basic 219*bdd1243dSDimitry Andric // blocks are ordered canonically. 220*bdd1243dSDimitry Andric MBB.setSectionID(MBB.getNumber()); 221*bdd1243dSDimitry Andric } else { 222*bdd1243dSDimitry Andric // TODO: Replace `getBBIDOrNumber` with `getBBID` once version 1 is 223*bdd1243dSDimitry Andric // deprecated. 224*bdd1243dSDimitry Andric auto I = FuncBBClusterInfo.find(MBB.getBBIDOrNumber()); 225*bdd1243dSDimitry Andric if (I != FuncBBClusterInfo.end()) { 226*bdd1243dSDimitry Andric MBB.setSectionID(I->second.ClusterID); 227*bdd1243dSDimitry Andric } else { 228e8d8bef9SDimitry Andric // BB goes into the special cold section if it is not specified in the 229e8d8bef9SDimitry Andric // cluster info map. 230e8d8bef9SDimitry Andric MBB.setSectionID(MBBSectionID::ColdSectionID); 231e8d8bef9SDimitry Andric } 232*bdd1243dSDimitry Andric } 233e8d8bef9SDimitry Andric 234e8d8bef9SDimitry Andric if (MBB.isEHPad() && EHPadsSectionID != MBB.getSectionID() && 235e8d8bef9SDimitry Andric EHPadsSectionID != MBBSectionID::ExceptionSectionID) { 236e8d8bef9SDimitry Andric // If we already have one cluster containing eh_pads, this must be updated 237e8d8bef9SDimitry Andric // to ExceptionSectionID. Otherwise, we set it equal to the current 238e8d8bef9SDimitry Andric // section ID. 23981ad6265SDimitry Andric EHPadsSectionID = EHPadsSectionID ? MBBSectionID::ExceptionSectionID 240e8d8bef9SDimitry Andric : MBB.getSectionID(); 241e8d8bef9SDimitry Andric } 242e8d8bef9SDimitry Andric } 243e8d8bef9SDimitry Andric 244e8d8bef9SDimitry Andric // If EHPads are in more than one section, this places all of them in the 245e8d8bef9SDimitry Andric // special exception section. 246e8d8bef9SDimitry Andric if (EHPadsSectionID == MBBSectionID::ExceptionSectionID) 247e8d8bef9SDimitry Andric for (auto &MBB : MF) 248e8d8bef9SDimitry Andric if (MBB.isEHPad()) 24981ad6265SDimitry Andric MBB.setSectionID(*EHPadsSectionID); 250e8d8bef9SDimitry Andric } 251e8d8bef9SDimitry Andric 252e8d8bef9SDimitry Andric void llvm::sortBasicBlocksAndUpdateBranches( 253e8d8bef9SDimitry Andric MachineFunction &MF, MachineBasicBlockComparator MBBCmp) { 254*bdd1243dSDimitry Andric [[maybe_unused]] const MachineBasicBlock *EntryBlock = &MF.front(); 255*bdd1243dSDimitry Andric SmallVector<MachineBasicBlock *> PreLayoutFallThroughs(MF.getNumBlockIDs()); 256e8d8bef9SDimitry Andric for (auto &MBB : MF) 257e8d8bef9SDimitry Andric PreLayoutFallThroughs[MBB.getNumber()] = MBB.getFallThrough(); 258e8d8bef9SDimitry Andric 259e8d8bef9SDimitry Andric MF.sort(MBBCmp); 260*bdd1243dSDimitry Andric assert(&MF.front() == EntryBlock && 261*bdd1243dSDimitry Andric "Entry block should not be displaced by basic block sections"); 262e8d8bef9SDimitry Andric 263e8d8bef9SDimitry Andric // Set IsBeginSection and IsEndSection according to the assigned section IDs. 264e8d8bef9SDimitry Andric MF.assignBeginEndSections(); 265e8d8bef9SDimitry Andric 266e8d8bef9SDimitry Andric // After reordering basic blocks, we must update basic block branches to 267e8d8bef9SDimitry Andric // insert explicit fallthrough branches when required and optimize branches 268e8d8bef9SDimitry Andric // when possible. 269e8d8bef9SDimitry Andric updateBranches(MF, PreLayoutFallThroughs); 270e8d8bef9SDimitry Andric } 271e8d8bef9SDimitry Andric 272e8d8bef9SDimitry Andric // If the exception section begins with a landing pad, that landing pad will 273e8d8bef9SDimitry Andric // assume a zero offset (relative to @LPStart) in the LSDA. However, a value of 274e8d8bef9SDimitry Andric // zero implies "no landing pad." This function inserts a NOP just before the EH 275fcaf7f86SDimitry Andric // pad label to ensure a nonzero offset. 276fcaf7f86SDimitry Andric void llvm::avoidZeroOffsetLandingPad(MachineFunction &MF) { 277e8d8bef9SDimitry Andric for (auto &MBB : MF) { 278e8d8bef9SDimitry Andric if (MBB.isBeginSection() && MBB.isEHPad()) { 279e8d8bef9SDimitry Andric MachineBasicBlock::iterator MI = MBB.begin(); 280e8d8bef9SDimitry Andric while (!MI->isEHLabel()) 281e8d8bef9SDimitry Andric ++MI; 282fe6060f1SDimitry Andric MCInst Nop = MF.getSubtarget().getInstrInfo()->getNop(); 283e8d8bef9SDimitry Andric BuildMI(MBB, MI, DebugLoc(), 284fe6060f1SDimitry Andric MF.getSubtarget().getInstrInfo()->get(Nop.getOpcode())); 285e8d8bef9SDimitry Andric } 286e8d8bef9SDimitry Andric } 287e8d8bef9SDimitry Andric } 288e8d8bef9SDimitry Andric 289fe6060f1SDimitry Andric // This checks if the source of this function has drifted since this binary was 290fe6060f1SDimitry Andric // profiled previously. For now, we are piggy backing on what PGO does to 291fe6060f1SDimitry Andric // detect this with instrumented profiles. PGO emits an hash of the IR and 292fe6060f1SDimitry Andric // checks if the hash has changed. Advanced basic block layout is usually done 293fe6060f1SDimitry Andric // on top of PGO optimized binaries and hence this check works well in practice. 294fe6060f1SDimitry Andric static bool hasInstrProfHashMismatch(MachineFunction &MF) { 295fe6060f1SDimitry Andric if (!BBSectionsDetectSourceDrift) 296fe6060f1SDimitry Andric return false; 297fe6060f1SDimitry Andric 298fe6060f1SDimitry Andric const char MetadataName[] = "instr_prof_hash_mismatch"; 299fe6060f1SDimitry Andric auto *Existing = MF.getFunction().getMetadata(LLVMContext::MD_annotation); 300fe6060f1SDimitry Andric if (Existing) { 301fe6060f1SDimitry Andric MDTuple *Tuple = cast<MDTuple>(Existing); 302fcaf7f86SDimitry Andric for (const auto &N : Tuple->operands()) 303fe6060f1SDimitry Andric if (cast<MDString>(N.get())->getString() == MetadataName) 304fe6060f1SDimitry Andric return true; 305fe6060f1SDimitry Andric } 306fe6060f1SDimitry Andric 307fe6060f1SDimitry Andric return false; 308fe6060f1SDimitry Andric } 309fe6060f1SDimitry Andric 310e8d8bef9SDimitry Andric bool BasicBlockSections::runOnMachineFunction(MachineFunction &MF) { 311e8d8bef9SDimitry Andric auto BBSectionsType = MF.getTarget().getBBSectionsType(); 312e8d8bef9SDimitry Andric assert(BBSectionsType != BasicBlockSection::None && 313e8d8bef9SDimitry Andric "BB Sections not enabled!"); 314fe6060f1SDimitry Andric 315fe6060f1SDimitry Andric // Check for source drift. If the source has changed since the profiles 316fe6060f1SDimitry Andric // were obtained, optimizing basic blocks might be sub-optimal. 317fe6060f1SDimitry Andric // This only applies to BasicBlockSection::List as it creates 318fe6060f1SDimitry Andric // clusters of basic blocks using basic block ids. Source drift can 319fe6060f1SDimitry Andric // invalidate these groupings leading to sub-optimal code generation with 320fe6060f1SDimitry Andric // regards to performance. 321fe6060f1SDimitry Andric if (BBSectionsType == BasicBlockSection::List && 322fe6060f1SDimitry Andric hasInstrProfHashMismatch(MF)) 323fe6060f1SDimitry Andric return true; 324*bdd1243dSDimitry Andric // Renumber blocks before sorting them. This is useful during sorting, 325*bdd1243dSDimitry Andric // basic blocks in the same section will retain the default order. 326*bdd1243dSDimitry Andric // This renumbering should also be done for basic block labels to match the 327*bdd1243dSDimitry Andric // profiles with the correct blocks. 328*bdd1243dSDimitry Andric // For LLVM_BB_ADDR_MAP versions 2 and higher, this renumbering serves 329*bdd1243dSDimitry Andric // the different purpose of accessing the original layout positions and 330*bdd1243dSDimitry Andric // finding the original fallthroughs. 331*bdd1243dSDimitry Andric // TODO: Change the above comment accordingly when version 1 is deprecated. 332e8d8bef9SDimitry Andric MF.RenumberBlocks(); 333e8d8bef9SDimitry Andric 334e8d8bef9SDimitry Andric if (BBSectionsType == BasicBlockSection::Labels) { 335e8d8bef9SDimitry Andric MF.setBBSectionsType(BBSectionsType); 336e8d8bef9SDimitry Andric return true; 337e8d8bef9SDimitry Andric } 338e8d8bef9SDimitry Andric 33981ad6265SDimitry Andric BBSectionsProfileReader = &getAnalysis<BasicBlockSectionsProfileReader>(); 34081ad6265SDimitry Andric 341*bdd1243dSDimitry Andric // Map from BBID of blocks to their cluster information. 342*bdd1243dSDimitry Andric DenseMap<unsigned, BBClusterInfo> FuncBBClusterInfo; 343e8d8bef9SDimitry Andric if (BBSectionsType == BasicBlockSection::List && 34481ad6265SDimitry Andric !getBBClusterInfoForFunction(MF, BBSectionsProfileReader, 345e8d8bef9SDimitry Andric FuncBBClusterInfo)) 346e8d8bef9SDimitry Andric return true; 347e8d8bef9SDimitry Andric MF.setBBSectionsType(BBSectionsType); 348e8d8bef9SDimitry Andric assignSections(MF, FuncBBClusterInfo); 349e8d8bef9SDimitry Andric 350e8d8bef9SDimitry Andric // We make sure that the cluster including the entry basic block precedes all 351e8d8bef9SDimitry Andric // other clusters. 352e8d8bef9SDimitry Andric auto EntryBBSectionID = MF.front().getSectionID(); 353e8d8bef9SDimitry Andric 354e8d8bef9SDimitry Andric // Helper function for ordering BB sections as follows: 355e8d8bef9SDimitry Andric // * Entry section (section including the entry block). 356e8d8bef9SDimitry Andric // * Regular sections (in increasing order of their Number). 357e8d8bef9SDimitry Andric // ... 358e8d8bef9SDimitry Andric // * Exception section 359e8d8bef9SDimitry Andric // * Cold section 360e8d8bef9SDimitry Andric auto MBBSectionOrder = [EntryBBSectionID](const MBBSectionID &LHS, 361e8d8bef9SDimitry Andric const MBBSectionID &RHS) { 362e8d8bef9SDimitry Andric // We make sure that the section containing the entry block precedes all the 363e8d8bef9SDimitry Andric // other sections. 364e8d8bef9SDimitry Andric if (LHS == EntryBBSectionID || RHS == EntryBBSectionID) 365e8d8bef9SDimitry Andric return LHS == EntryBBSectionID; 366e8d8bef9SDimitry Andric return LHS.Type == RHS.Type ? LHS.Number < RHS.Number : LHS.Type < RHS.Type; 367e8d8bef9SDimitry Andric }; 368e8d8bef9SDimitry Andric 369e8d8bef9SDimitry Andric // We sort all basic blocks to make sure the basic blocks of every cluster are 370e8d8bef9SDimitry Andric // contiguous and ordered accordingly. Furthermore, clusters are ordered in 371e8d8bef9SDimitry Andric // increasing order of their section IDs, with the exception and the 372e8d8bef9SDimitry Andric // cold section placed at the end of the function. 373e8d8bef9SDimitry Andric auto Comparator = [&](const MachineBasicBlock &X, 374e8d8bef9SDimitry Andric const MachineBasicBlock &Y) { 375e8d8bef9SDimitry Andric auto XSectionID = X.getSectionID(); 376e8d8bef9SDimitry Andric auto YSectionID = Y.getSectionID(); 377e8d8bef9SDimitry Andric if (XSectionID != YSectionID) 378e8d8bef9SDimitry Andric return MBBSectionOrder(XSectionID, YSectionID); 379e8d8bef9SDimitry Andric // If the two basic block are in the same section, the order is decided by 380e8d8bef9SDimitry Andric // their position within the section. 381e8d8bef9SDimitry Andric if (XSectionID.Type == MBBSectionID::SectionType::Default) 382*bdd1243dSDimitry Andric return FuncBBClusterInfo.lookup(X.getBBIDOrNumber()).PositionInCluster < 383*bdd1243dSDimitry Andric FuncBBClusterInfo.lookup(Y.getBBIDOrNumber()).PositionInCluster; 384e8d8bef9SDimitry Andric return X.getNumber() < Y.getNumber(); 385e8d8bef9SDimitry Andric }; 386e8d8bef9SDimitry Andric 387e8d8bef9SDimitry Andric sortBasicBlocksAndUpdateBranches(MF, Comparator); 388e8d8bef9SDimitry Andric avoidZeroOffsetLandingPad(MF); 389e8d8bef9SDimitry Andric return true; 390e8d8bef9SDimitry Andric } 391e8d8bef9SDimitry Andric 392e8d8bef9SDimitry Andric void BasicBlockSections::getAnalysisUsage(AnalysisUsage &AU) const { 393e8d8bef9SDimitry Andric AU.setPreservesAll(); 39481ad6265SDimitry Andric AU.addRequired<BasicBlockSectionsProfileReader>(); 395e8d8bef9SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU); 396e8d8bef9SDimitry Andric } 397e8d8bef9SDimitry Andric 39881ad6265SDimitry Andric MachineFunctionPass *llvm::createBasicBlockSectionsPass() { 39981ad6265SDimitry Andric return new BasicBlockSections(); 400e8d8bef9SDimitry Andric } 401