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