1 //===-- BasicBlockPathCloning.cpp ---=========-----------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 /// \file 10 /// BasicBlockPathCloning implementation. 11 /// 12 /// The purpose of this pass is to clone basic block paths based on information 13 /// provided by the -fbasic-block-sections=list option. 14 /// Please refer to BasicBlockSectionsProfileReader.cpp to see a path cloning 15 /// example. 16 //===----------------------------------------------------------------------===// 17 // This pass clones the machine basic blocks alongs the given paths and sets up 18 // the CFG. It assigns BBIDs to the cloned blocks so that the 19 // `BasicBlockSections` pass can correctly map the cluster information to the 20 // blocks. The cloned block's BBID will have the same BaseID as the original 21 // block, but will get a unique non-zero CloneID (original blocks all have zero 22 // CloneIDs). This pass applies a path cloning if it satisfies the following 23 // conditions: 24 // 1. All BBIDs in the path should be mapped to existing blocks. 25 // 2. Each two consecutive BBIDs in the path must have a successor 26 // relationship in the CFG. 27 // 3. The path should not include a block with indirect branches, except for 28 // the last block. 29 // If a path does not satisfy all three conditions, it will be rejected, but the 30 // CloneIDs for its (supposed to be cloned) blocks will be bypassed to make sure 31 // that the `BasicBlockSections` pass can map cluster info correctly to the 32 // actually-cloned blocks. 33 //===----------------------------------------------------------------------===// 34 35 #include "llvm/ADT/SmallVector.h" 36 #include "llvm/ADT/StringRef.h" 37 #include "llvm/CodeGen/BasicBlockSectionUtils.h" 38 #include "llvm/CodeGen/BasicBlockSectionsProfileReader.h" 39 #include "llvm/CodeGen/MachineFunction.h" 40 #include "llvm/CodeGen/MachineFunctionPass.h" 41 #include "llvm/CodeGen/Passes.h" 42 #include "llvm/CodeGen/TargetInstrInfo.h" 43 #include "llvm/InitializePasses.h" 44 #include "llvm/Support/UniqueBBID.h" 45 #include "llvm/Support/WithColor.h" 46 #include "llvm/Target/TargetMachine.h" 47 48 using namespace llvm; 49 50 namespace { 51 52 // Clones the given block and assigns the given `CloneID` to its BBID. Copies 53 // the instructions into the new block and sets up its successors. 54 MachineBasicBlock *CloneMachineBasicBlock(MachineBasicBlock &OrigBB, 55 unsigned CloneID) { 56 auto &MF = *OrigBB.getParent(); 57 auto TII = MF.getSubtarget().getInstrInfo(); 58 // Create the clone block and set its BBID based on the original block. 59 MachineBasicBlock *CloneBB = MF.CreateMachineBasicBlock( 60 OrigBB.getBasicBlock(), UniqueBBID{OrigBB.getBBID()->BaseID, CloneID}); 61 MF.push_back(CloneBB); 62 63 // Copy the instructions. 64 for (auto &I : OrigBB.instrs()) { 65 // Bundled instructions are duplicated together. 66 if (I.isBundledWithPred()) 67 continue; 68 TII->duplicate(*CloneBB, CloneBB->end(), I); 69 } 70 71 // Add the successors of the original block as the new block's successors. 72 // We set the predecessor after returning from this call. 73 for (auto SI = OrigBB.succ_begin(), SE = OrigBB.succ_end(); SI != SE; ++SI) 74 CloneBB->copySuccessor(&OrigBB, SI); 75 76 if (auto FT = OrigBB.getFallThrough(/*JumpToFallThrough=*/false)) { 77 // The original block has an implicit fall through. 78 // Insert an explicit unconditional jump from the cloned block to the 79 // fallthrough block. Technically, this is only needed for the last block 80 // of the path, but we do it for all clones for consistency. 81 TII->insertUnconditionalBranch(*CloneBB, FT, CloneBB->findBranchDebugLoc()); 82 } 83 return CloneBB; 84 } 85 86 // Returns if we can legally apply the cloning represented by `ClonePath`. 87 // `BBIDToBlock` contains the original basic blocks in function `MF` keyed by 88 // their `BBID::BaseID`. 89 bool IsValidCloning(const MachineFunction &MF, 90 const DenseMap<unsigned, MachineBasicBlock *> &BBIDToBlock, 91 const SmallVector<unsigned> &ClonePath) { 92 const MachineBasicBlock *PrevBB = nullptr; 93 for (size_t I = 0; I < ClonePath.size(); ++I) { 94 unsigned BBID = ClonePath[I]; 95 const MachineBasicBlock *PathBB = BBIDToBlock.lookup(BBID); 96 if (!PathBB) { 97 WithColor::warning() << "no block with id " << BBID << " in function " 98 << MF.getName() << "\n"; 99 return false; 100 } 101 102 if (PrevBB) { 103 if (!PrevBB->isSuccessor(PathBB)) { 104 WithColor::warning() 105 << "block #" << BBID << " is not a successor of block #" 106 << PrevBB->getBBID()->BaseID << " in function " << MF.getName() 107 << "\n"; 108 return false; 109 } 110 111 for (auto &MI : *PathBB) { 112 // Avoid cloning when the block contains non-duplicable instructions. 113 // CFI instructions are marked as non-duplicable only because of Darwin, 114 // so we exclude them from this check. 115 if (MI.isNotDuplicable() && !MI.isCFIInstruction()) { 116 WithColor::warning() 117 << "block #" << BBID 118 << " has non-duplicable instructions in function " << MF.getName() 119 << "\n"; 120 return false; 121 } 122 } 123 if (PathBB->isMachineBlockAddressTaken()) { 124 // Avoid cloning blocks which have their address taken since we can't 125 // rewire branches to those blocks as easily. 126 WithColor::warning() 127 << "block #" << BBID 128 << " has its machine block address taken in function " 129 << MF.getName() << "\n"; 130 return false; 131 } 132 if (PathBB->isInlineAsmBrIndirectTarget()) { 133 // Similarly for branches to the block within an asm goto. 134 WithColor::warning() 135 << "block #" << BBID 136 << " is a branch target of an 'asm goto' in function " 137 << MF.getName() << "\n"; 138 return false; 139 } 140 } 141 142 if (I != ClonePath.size() - 1 && !PathBB->empty() && 143 PathBB->back().isIndirectBranch()) { 144 WithColor::warning() 145 << "block #" << BBID 146 << " has indirect branch and appears as the non-tail block of a " 147 "path in function " 148 << MF.getName() << "\n"; 149 return false; 150 } 151 PrevBB = PathBB; 152 } 153 return true; 154 } 155 156 // Applies all clonings specified in `ClonePaths` to `MF`. Returns true 157 // if any clonings have been applied. 158 bool ApplyCloning(MachineFunction &MF, 159 const SmallVector<SmallVector<unsigned>> &ClonePaths) { 160 if (ClonePaths.empty()) 161 return false; 162 bool AnyPathsCloned = false; 163 // Map from the final BB IDs to the `MachineBasicBlock`s. 164 DenseMap<unsigned, MachineBasicBlock *> BBIDToBlock; 165 for (auto &BB : MF) 166 BBIDToBlock.try_emplace(BB.getBBID()->BaseID, &BB); 167 168 DenseMap<unsigned, unsigned> NClonesForBBID; 169 auto TII = MF.getSubtarget().getInstrInfo(); 170 for (const auto &ClonePath : ClonePaths) { 171 if (!IsValidCloning(MF, BBIDToBlock, ClonePath)) { 172 // We still need to increment the number of clones so we can map 173 // to the cluster info correctly. 174 for (unsigned BBID : ClonePath) 175 ++NClonesForBBID[BBID]; 176 continue; 177 } 178 MachineBasicBlock *PrevBB = nullptr; 179 for (unsigned BBID : ClonePath) { 180 MachineBasicBlock *OrigBB = BBIDToBlock.at(BBID); 181 if (PrevBB == nullptr) { 182 // The first block in the path is not cloned. We only need to make it 183 // branch to the next cloned block in the path. Here, we make its 184 // fallthrough explicit so we can change it later. 185 if (auto FT = OrigBB->getFallThrough(/*JumpToFallThrough=*/false)) { 186 TII->insertUnconditionalBranch(*OrigBB, FT, 187 OrigBB->findBranchDebugLoc()); 188 } 189 PrevBB = OrigBB; 190 continue; 191 } 192 MachineBasicBlock *CloneBB = 193 CloneMachineBasicBlock(*OrigBB, ++NClonesForBBID[BBID]); 194 195 // Set up the previous block in the path to jump to the clone. This also 196 // transfers the successor/predecessor relationship of PrevBB and OrigBB 197 // to that of PrevBB and CloneBB. 198 PrevBB->ReplaceUsesOfBlockWith(OrigBB, CloneBB); 199 200 // Copy the livein set. 201 for (auto &LiveIn : OrigBB->liveins()) 202 CloneBB->addLiveIn(LiveIn); 203 204 PrevBB = CloneBB; 205 } 206 AnyPathsCloned = true; 207 } 208 return AnyPathsCloned; 209 } 210 } // end anonymous namespace 211 212 namespace llvm { 213 class BasicBlockPathCloning : public MachineFunctionPass { 214 public: 215 static char ID; 216 217 BasicBlockSectionsProfileReaderWrapperPass *BBSectionsProfileReader = nullptr; 218 219 BasicBlockPathCloning() : MachineFunctionPass(ID) { 220 initializeBasicBlockPathCloningPass(*PassRegistry::getPassRegistry()); 221 } 222 223 StringRef getPassName() const override { return "Basic Block Path Cloning"; } 224 225 void getAnalysisUsage(AnalysisUsage &AU) const override; 226 227 /// Identify basic blocks that need separate sections and prepare to emit them 228 /// accordingly. 229 bool runOnMachineFunction(MachineFunction &MF) override; 230 }; 231 232 } // namespace llvm 233 234 char BasicBlockPathCloning::ID = 0; 235 INITIALIZE_PASS_BEGIN( 236 BasicBlockPathCloning, "bb-path-cloning", 237 "Applies path clonings for the -basic-block-sections=list option", false, 238 false) 239 INITIALIZE_PASS_DEPENDENCY(BasicBlockSectionsProfileReaderWrapperPass) 240 INITIALIZE_PASS_END( 241 BasicBlockPathCloning, "bb-path-cloning", 242 "Applies path clonings for the -basic-block-sections=list option", false, 243 false) 244 245 bool BasicBlockPathCloning::runOnMachineFunction(MachineFunction &MF) { 246 assert(MF.getTarget().getBBSectionsType() == BasicBlockSection::List && 247 "BB Sections list not enabled!"); 248 if (hasInstrProfHashMismatch(MF)) 249 return false; 250 251 return ApplyCloning(MF, 252 getAnalysis<BasicBlockSectionsProfileReaderWrapperPass>() 253 .getClonePathsForFunction(MF.getName())); 254 } 255 256 void BasicBlockPathCloning::getAnalysisUsage(AnalysisUsage &AU) const { 257 AU.setPreservesAll(); 258 AU.addRequired<BasicBlockSectionsProfileReaderWrapperPass>(); 259 MachineFunctionPass::getAnalysisUsage(AU); 260 } 261 262 MachineFunctionPass *llvm::createBasicBlockPathCloningPass() { 263 return new BasicBlockPathCloning(); 264 } 265