1 //===-- ShrinkWrap.cpp - Compute safe point for prolog/epilog insertion ---===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This pass looks for safe point where the prologue and epilogue can be 11 // inserted. 12 // The safe point for the prologue (resp. epilogue) is called Save 13 // (resp. Restore). 14 // A point is safe for prologue (resp. epilogue) if and only if 15 // it 1) dominates (resp. post-dominates) all the frame related operations and 16 // between 2) two executions of the Save (resp. Restore) point there is an 17 // execution of the Restore (resp. Save) point. 18 // 19 // For instance, the following points are safe: 20 // for (int i = 0; i < 10; ++i) { 21 // Save 22 // ... 23 // Restore 24 // } 25 // Indeed, the execution looks like Save -> Restore -> Save -> Restore ... 26 // And the following points are not: 27 // for (int i = 0; i < 10; ++i) { 28 // Save 29 // ... 30 // } 31 // for (int i = 0; i < 10; ++i) { 32 // ... 33 // Restore 34 // } 35 // Indeed, the execution looks like Save -> Save -> ... -> Restore -> Restore. 36 // 37 // This pass also ensures that the safe points are 3) cheaper than the regular 38 // entry and exits blocks. 39 // 40 // Property #1 is ensured via the use of MachineDominatorTree and 41 // MachinePostDominatorTree. 42 // Property #2 is ensured via property #1 and MachineLoopInfo, i.e., both 43 // points must be in the same loop. 44 // Property #3 is ensured via the MachineBlockFrequencyInfo. 45 // 46 // If this pass found points matching all this properties, then 47 // MachineFrameInfo is updated this that information. 48 //===----------------------------------------------------------------------===// 49 #include "llvm/ADT/Statistic.h" 50 // To check for profitability. 51 #include "llvm/CodeGen/MachineBlockFrequencyInfo.h" 52 // For property #1 for Save. 53 #include "llvm/CodeGen/MachineDominators.h" 54 #include "llvm/CodeGen/MachineFunctionPass.h" 55 // To record the result of the analysis. 56 #include "llvm/CodeGen/MachineFrameInfo.h" 57 // For property #2. 58 #include "llvm/CodeGen/MachineLoopInfo.h" 59 // For property #1 for Restore. 60 #include "llvm/CodeGen/MachinePostDominators.h" 61 #include "llvm/CodeGen/Passes.h" 62 // To know about callee-saved. 63 #include "llvm/CodeGen/RegisterClassInfo.h" 64 #include "llvm/Support/Debug.h" 65 // To know about frame setup operation. 66 #include "llvm/Target/TargetInstrInfo.h" 67 // To access TargetInstrInfo. 68 #include "llvm/Target/TargetSubtargetInfo.h" 69 70 #define DEBUG_TYPE "shrink-wrap" 71 72 using namespace llvm; 73 74 STATISTIC(NumFunc, "Number of functions"); 75 STATISTIC(NumCandidates, "Number of shrink-wrapping candidates"); 76 STATISTIC(NumCandidatesDropped, 77 "Number of shrink-wrapping candidates dropped because of frequency"); 78 79 namespace { 80 /// \brief Class to determine where the safe point to insert the 81 /// prologue and epilogue are. 82 /// Unlike the paper from Fred C. Chow, PLDI'88, that introduces the 83 /// shrink-wrapping term for prologue/epilogue placement, this pass 84 /// does not rely on expensive data-flow analysis. Instead we use the 85 /// dominance properties and loop information to decide which point 86 /// are safe for such insertion. 87 class ShrinkWrap : public MachineFunctionPass { 88 /// Hold callee-saved information. 89 RegisterClassInfo RCI; 90 MachineDominatorTree *MDT; 91 MachinePostDominatorTree *MPDT; 92 /// Current safe point found for the prologue. 93 /// The prologue will be inserted before the first instruction 94 /// in this basic block. 95 MachineBasicBlock *Save; 96 /// Current safe point found for the epilogue. 97 /// The epilogue will be inserted before the first terminator instruction 98 /// in this basic block. 99 MachineBasicBlock *Restore; 100 /// Hold the information of the basic block frequency. 101 /// Use to check the profitability of the new points. 102 MachineBlockFrequencyInfo *MBFI; 103 /// Hold the loop information. Used to determine if Save and Restore 104 /// are in the same loop. 105 MachineLoopInfo *MLI; 106 /// Frequency of the Entry block. 107 uint64_t EntryFreq; 108 /// Current opcode for frame setup. 109 int FrameSetupOpcode; 110 /// Current opcode for frame destroy. 111 int FrameDestroyOpcode; 112 /// Entry block. 113 const MachineBasicBlock *Entry; 114 115 /// \brief Check if \p MI uses or defines a callee-saved register or 116 /// a frame index. If this is the case, this means \p MI must happen 117 /// after Save and before Restore. 118 bool useOrDefCSROrFI(const MachineInstr &MI) const; 119 120 /// \brief Update the Save and Restore points such that \p MBB is in 121 /// the region that is dominated by Save and post-dominated by Restore 122 /// and Save and Restore still match the safe point definition. 123 /// Such point may not exist and Save and/or Restore may be null after 124 /// this call. 125 void updateSaveRestorePoints(MachineBasicBlock &MBB); 126 127 /// \brief Initialize the pass for \p MF. 128 void init(MachineFunction &MF) { 129 RCI.runOnMachineFunction(MF); 130 MDT = &getAnalysis<MachineDominatorTree>(); 131 MPDT = &getAnalysis<MachinePostDominatorTree>(); 132 Save = nullptr; 133 Restore = nullptr; 134 MBFI = &getAnalysis<MachineBlockFrequencyInfo>(); 135 MLI = &getAnalysis<MachineLoopInfo>(); 136 EntryFreq = MBFI->getEntryFreq(); 137 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); 138 FrameSetupOpcode = TII.getCallFrameSetupOpcode(); 139 FrameDestroyOpcode = TII.getCallFrameDestroyOpcode(); 140 Entry = &MF.front(); 141 142 ++NumFunc; 143 } 144 145 /// Check whether or not Save and Restore points are still interesting for 146 /// shrink-wrapping. 147 bool ArePointsInteresting() const { return Save != Entry && Save && Restore; } 148 149 public: 150 static char ID; 151 152 ShrinkWrap() : MachineFunctionPass(ID) { 153 initializeShrinkWrapPass(*PassRegistry::getPassRegistry()); 154 } 155 156 void getAnalysisUsage(AnalysisUsage &AU) const override { 157 AU.setPreservesAll(); 158 AU.addRequired<MachineBlockFrequencyInfo>(); 159 AU.addRequired<MachineDominatorTree>(); 160 AU.addRequired<MachinePostDominatorTree>(); 161 AU.addRequired<MachineLoopInfo>(); 162 MachineFunctionPass::getAnalysisUsage(AU); 163 } 164 165 const char *getPassName() const override { 166 return "Shrink Wrapping analysis"; 167 } 168 169 /// \brief Perform the shrink-wrapping analysis and update 170 /// the MachineFrameInfo attached to \p MF with the results. 171 bool runOnMachineFunction(MachineFunction &MF) override; 172 }; 173 } // End anonymous namespace. 174 175 char ShrinkWrap::ID = 0; 176 char &llvm::ShrinkWrapID = ShrinkWrap::ID; 177 178 INITIALIZE_PASS_BEGIN(ShrinkWrap, "shrink-wrap", "Shrink Wrap Pass", false, 179 false) 180 INITIALIZE_PASS_DEPENDENCY(MachineBlockFrequencyInfo) 181 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) 182 INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTree) 183 INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) 184 INITIALIZE_PASS_END(ShrinkWrap, "shrink-wrap", "Shrink Wrap Pass", false, false) 185 186 bool ShrinkWrap::useOrDefCSROrFI(const MachineInstr &MI) const { 187 if (MI.getOpcode() == FrameSetupOpcode || 188 MI.getOpcode() == FrameDestroyOpcode) { 189 DEBUG(dbgs() << "Frame instruction: " << MI << '\n'); 190 return true; 191 } 192 for (const MachineOperand &MO : MI.operands()) { 193 bool UseCSR = false; 194 if (MO.isReg()) { 195 unsigned PhysReg = MO.getReg(); 196 if (!PhysReg) 197 continue; 198 assert(TargetRegisterInfo::isPhysicalRegister(PhysReg) && 199 "Unallocated register?!"); 200 UseCSR = RCI.getLastCalleeSavedAlias(PhysReg); 201 } 202 // TODO: Handle regmask more accurately. 203 // For now, be conservative about them. 204 if (UseCSR || MO.isFI() || MO.isRegMask()) { 205 DEBUG(dbgs() << "Use or define CSR(" << UseCSR << ") or FI(" << MO.isFI() 206 << "): " << MI << '\n'); 207 return true; 208 } 209 } 210 return false; 211 } 212 213 /// \brief Helper function to find the immediate (post) dominator. 214 template <typename ListOfBBs, typename DominanceAnalysis> 215 MachineBasicBlock *FindIDom(MachineBasicBlock &Block, ListOfBBs BBs, 216 DominanceAnalysis &Dom) { 217 MachineBasicBlock *IDom = &Block; 218 for (MachineBasicBlock *BB : BBs) { 219 IDom = Dom.findNearestCommonDominator(IDom, BB); 220 if (!IDom) 221 break; 222 } 223 return IDom; 224 } 225 226 void ShrinkWrap::updateSaveRestorePoints(MachineBasicBlock &MBB) { 227 // Get rid of the easy cases first. 228 if (!Save) 229 Save = &MBB; 230 else 231 Save = MDT->findNearestCommonDominator(Save, &MBB); 232 233 if (!Save) { 234 DEBUG(dbgs() << "Found a block that is not reachable from Entry\n"); 235 return; 236 } 237 238 if (!Restore) 239 Restore = &MBB; 240 else 241 Restore = MPDT->findNearestCommonDominator(Restore, &MBB); 242 243 // Make sure we would be able to insert the restore code before the 244 // terminator. 245 if (Restore == &MBB) { 246 for (const MachineInstr &Terminator : MBB.terminators()) { 247 if (!useOrDefCSROrFI(Terminator)) 248 continue; 249 // One of the terminator needs to happen before the restore point. 250 if (MBB.succ_empty()) { 251 Restore = nullptr; 252 break; 253 } 254 // Look for a restore point that post-dominates all the successors. 255 // The immediate post-dominator is what we are looking for. 256 Restore = FindIDom<>(*Restore, Restore->successors(), *MPDT); 257 break; 258 } 259 } 260 261 if (!Restore) { 262 DEBUG(dbgs() << "Restore point needs to be spanned on several blocks\n"); 263 return; 264 } 265 266 // Make sure Save and Restore are suitable for shrink-wrapping: 267 // 1. all path from Save needs to lead to Restore before exiting. 268 // 2. all path to Restore needs to go through Save from Entry. 269 // We achieve that by making sure that: 270 // A. Save dominates Restore. 271 // B. Restore post-dominates Save. 272 // C. Save and Restore are in the same loop. 273 bool SaveDominatesRestore = false; 274 bool RestorePostDominatesSave = false; 275 while (Save && Restore && 276 (!(SaveDominatesRestore = MDT->dominates(Save, Restore)) || 277 !(RestorePostDominatesSave = MPDT->dominates(Restore, Save)) || 278 MLI->getLoopFor(Save) != MLI->getLoopFor(Restore))) { 279 // Fix (A). 280 if (!SaveDominatesRestore) { 281 Save = MDT->findNearestCommonDominator(Save, Restore); 282 continue; 283 } 284 // Fix (B). 285 if (!RestorePostDominatesSave) 286 Restore = MPDT->findNearestCommonDominator(Restore, Save); 287 288 // Fix (C). 289 if (Save && Restore && Save != Restore && 290 MLI->getLoopFor(Save) != MLI->getLoopFor(Restore)) { 291 if (MLI->getLoopDepth(Save) > MLI->getLoopDepth(Restore)) 292 // Push Save outside of this loop. 293 Save = FindIDom<>(*Save, Save->predecessors(), *MDT); 294 else 295 // Push Restore outside of this loop. 296 Restore = FindIDom<>(*Restore, Restore->successors(), *MPDT); 297 } 298 } 299 } 300 301 bool ShrinkWrap::runOnMachineFunction(MachineFunction &MF) { 302 if (MF.empty()) 303 return false; 304 DEBUG(dbgs() << "**** Analysing " << MF.getName() << '\n'); 305 306 init(MF); 307 308 for (MachineBasicBlock &MBB : MF) { 309 DEBUG(dbgs() << "Look into: " << MBB.getNumber() << ' ' << MBB.getName() 310 << '\n'); 311 312 for (const MachineInstr &MI : MBB) { 313 if (!useOrDefCSROrFI(MI)) 314 continue; 315 // Save (resp. restore) point must dominate (resp. post dominate) 316 // MI. Look for the proper basic block for those. 317 updateSaveRestorePoints(MBB); 318 // If we are at a point where we cannot improve the placement of 319 // save/restore instructions, just give up. 320 if (!ArePointsInteresting()) { 321 DEBUG(dbgs() << "No Shrink wrap candidate found\n"); 322 return false; 323 } 324 // No need to look for other instructions, this basic block 325 // will already be part of the handled region. 326 break; 327 } 328 } 329 if (!ArePointsInteresting()) { 330 // If the points are not interesting at this point, then they must be null 331 // because it means we did not encounter any frame/CSR related code. 332 // Otherwise, we would have returned from the previous loop. 333 assert(!Save && !Restore && "We miss a shrink-wrap opportunity?!"); 334 DEBUG(dbgs() << "Nothing to shrink-wrap\n"); 335 return false; 336 } 337 338 DEBUG(dbgs() << "\n ** Results **\nFrequency of the Entry: " << EntryFreq 339 << '\n'); 340 341 do { 342 DEBUG(dbgs() << "Shrink wrap candidates (#, Name, Freq):\nSave: " 343 << Save->getNumber() << ' ' << Save->getName() << ' ' 344 << MBFI->getBlockFreq(Save).getFrequency() << "\nRestore: " 345 << Restore->getNumber() << ' ' << Restore->getName() << ' ' 346 << MBFI->getBlockFreq(Restore).getFrequency() << '\n'); 347 348 bool IsSaveCheap; 349 if ((IsSaveCheap = EntryFreq >= MBFI->getBlockFreq(Save).getFrequency()) && 350 EntryFreq >= MBFI->getBlockFreq(Restore).getFrequency()) 351 break; 352 DEBUG(dbgs() << "New points are too expensive\n"); 353 MachineBasicBlock *NewBB; 354 if (!IsSaveCheap) { 355 Save = FindIDom<>(*Save, Save->predecessors(), *MDT); 356 if (!Save) 357 break; 358 NewBB = Save; 359 } else { 360 // Restore is expensive. 361 Restore = FindIDom<>(*Restore, Restore->successors(), *MPDT); 362 if (!Restore) 363 break; 364 NewBB = Restore; 365 } 366 updateSaveRestorePoints(*NewBB); 367 } while (Save && Restore); 368 369 if (!ArePointsInteresting()) { 370 ++NumCandidatesDropped; 371 return false; 372 } 373 374 DEBUG(dbgs() << "Final shrink wrap candidates:\nSave: " << Save->getNumber() 375 << ' ' << Save->getName() << "\nRestore: " 376 << Restore->getNumber() << ' ' << Restore->getName() << '\n'); 377 378 MachineFrameInfo *MFI = MF.getFrameInfo(); 379 MFI->setSavePoint(Save); 380 MFI->setRestorePoint(Restore); 381 ++NumCandidates; 382 return false; 383 } 384