1 //===- RegionPass.cpp - Region Pass and Region Pass Manager ---------------===// 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 // This file implements RegionPass and RGPassManager. All region optimization 10 // and transformation passes are derived from RegionPass. RGPassManager is 11 // responsible for managing RegionPasses. 12 // Most of this code has been COPIED from LoopPass.cpp 13 // 14 //===----------------------------------------------------------------------===// 15 #include "llvm/Analysis/RegionPass.h" 16 #include "llvm/IR/OptBisect.h" 17 #include "llvm/IR/PassTimingInfo.h" 18 #include "llvm/IR/PrintPasses.h" 19 #include "llvm/IR/StructuralHash.h" 20 #include "llvm/Support/Debug.h" 21 #include "llvm/Support/Timer.h" 22 #include "llvm/Support/raw_ostream.h" 23 using namespace llvm; 24 25 #define DEBUG_TYPE "regionpassmgr" 26 27 //===----------------------------------------------------------------------===// 28 // RGPassManager 29 // 30 31 char RGPassManager::ID = 0; 32 33 RGPassManager::RGPassManager() 34 : FunctionPass(ID), PMDataManager() { 35 RI = nullptr; 36 CurrentRegion = nullptr; 37 } 38 39 // Recurse through all subregions and all regions into RQ. 40 static void addRegionIntoQueue(Region &R, std::deque<Region *> &RQ) { 41 RQ.push_back(&R); 42 for (const auto &E : R) 43 addRegionIntoQueue(*E, RQ); 44 } 45 46 /// Pass Manager itself does not invalidate any analysis info. 47 void RGPassManager::getAnalysisUsage(AnalysisUsage &Info) const { 48 Info.addRequired<RegionInfoPass>(); 49 Info.setPreservesAll(); 50 } 51 52 /// run - Execute all of the passes scheduled for execution. Keep track of 53 /// whether any of the passes modifies the function, and if so, return true. 54 bool RGPassManager::runOnFunction(Function &F) { 55 RI = &getAnalysis<RegionInfoPass>().getRegionInfo(); 56 bool Changed = false; 57 58 // Collect inherited analysis from Module level pass manager. 59 populateInheritedAnalysis(TPM->activeStack); 60 61 addRegionIntoQueue(*RI->getTopLevelRegion(), RQ); 62 63 if (RQ.empty()) // No regions, skip calling finalizers 64 return false; 65 66 // Initialization 67 for (Region *R : RQ) { 68 for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { 69 RegionPass *RP = (RegionPass *)getContainedPass(Index); 70 Changed |= RP->doInitialization(R, *this); 71 } 72 } 73 74 // Walk Regions 75 while (!RQ.empty()) { 76 77 CurrentRegion = RQ.back(); 78 79 // Run all passes on the current Region. 80 for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { 81 RegionPass *P = (RegionPass*)getContainedPass(Index); 82 83 if (isPassDebuggingExecutionsOrMore()) { 84 dumpPassInfo(P, EXECUTION_MSG, ON_REGION_MSG, 85 CurrentRegion->getNameStr()); 86 dumpRequiredSet(P); 87 } 88 89 initializeAnalysisImpl(P); 90 91 bool LocalChanged = false; 92 { 93 PassManagerPrettyStackEntry X(P, *CurrentRegion->getEntry()); 94 95 TimeRegion PassTimer(getPassTimer(P)); 96 #ifdef EXPENSIVE_CHECKS 97 uint64_t RefHash = StructuralHash(F); 98 #endif 99 LocalChanged = P->runOnRegion(CurrentRegion, *this); 100 101 #ifdef EXPENSIVE_CHECKS 102 if (!LocalChanged && (RefHash != StructuralHash(F))) { 103 llvm::errs() << "Pass modifies its input and doesn't report it: " 104 << P->getPassName() << "\n"; 105 llvm_unreachable("Pass modifies its input and doesn't report it"); 106 } 107 #endif 108 109 Changed |= LocalChanged; 110 } 111 112 if (isPassDebuggingExecutionsOrMore()) { 113 if (LocalChanged) 114 dumpPassInfo(P, MODIFICATION_MSG, ON_REGION_MSG, 115 CurrentRegion->getNameStr()); 116 dumpPreservedSet(P); 117 } 118 119 // Manually check that this region is still healthy. This is done 120 // instead of relying on RegionInfo::verifyRegion since RegionInfo 121 // is a function pass and it's really expensive to verify every 122 // Region in the function every time. That level of checking can be 123 // enabled with the -verify-region-info option. 124 { 125 TimeRegion PassTimer(getPassTimer(P)); 126 CurrentRegion->verifyRegion(); 127 } 128 129 // Then call the regular verifyAnalysis functions. 130 verifyPreservedAnalysis(P); 131 132 if (LocalChanged) 133 removeNotPreservedAnalysis(P); 134 recordAvailableAnalysis(P); 135 removeDeadPasses(P, 136 (!isPassDebuggingExecutionsOrMore()) 137 ? "<deleted>" 138 : CurrentRegion->getNameStr(), 139 ON_REGION_MSG); 140 } 141 142 // Pop the region from queue after running all passes. 143 RQ.pop_back(); 144 145 // Free all region nodes created in region passes. 146 RI->clearNodeCache(); 147 } 148 149 // Finalization 150 for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { 151 RegionPass *P = (RegionPass*)getContainedPass(Index); 152 Changed |= P->doFinalization(); 153 } 154 155 // Print the region tree after all pass. 156 LLVM_DEBUG(dbgs() << "\nRegion tree of function " << F.getName() 157 << " after all region Pass:\n"; 158 RI->dump(); dbgs() << "\n";); 159 160 return Changed; 161 } 162 163 /// Print passes managed by this manager 164 void RGPassManager::dumpPassStructure(unsigned Offset) { 165 errs().indent(Offset*2) << "Region Pass Manager\n"; 166 for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { 167 Pass *P = getContainedPass(Index); 168 P->dumpPassStructure(Offset + 1); 169 dumpLastUses(P, Offset+1); 170 } 171 } 172 173 namespace { 174 //===----------------------------------------------------------------------===// 175 // PrintRegionPass 176 class PrintRegionPass : public RegionPass { 177 private: 178 std::string Banner; 179 raw_ostream &Out; // raw_ostream to print on. 180 181 public: 182 static char ID; 183 PrintRegionPass(const std::string &B, raw_ostream &o) 184 : RegionPass(ID), Banner(B), Out(o) {} 185 186 void getAnalysisUsage(AnalysisUsage &AU) const override { 187 AU.setPreservesAll(); 188 } 189 190 bool runOnRegion(Region *R, RGPassManager &RGM) override { 191 if (!isFunctionInPrintList(R->getEntry()->getParent()->getName())) 192 return false; 193 Out << Banner; 194 for (const auto *BB : R->blocks()) { 195 if (BB) 196 BB->print(Out); 197 else 198 Out << "Printing <null> Block"; 199 } 200 201 return false; 202 } 203 204 StringRef getPassName() const override { return "Print Region IR"; } 205 }; 206 207 char PrintRegionPass::ID = 0; 208 } //end anonymous namespace 209 210 //===----------------------------------------------------------------------===// 211 // RegionPass 212 213 // Check if this pass is suitable for the current RGPassManager, if 214 // available. This pass P is not suitable for a RGPassManager if P 215 // is not preserving higher level analysis info used by other 216 // RGPassManager passes. In such case, pop RGPassManager from the 217 // stack. This will force assignPassManager() to create new 218 // LPPassManger as expected. 219 void RegionPass::preparePassManager(PMStack &PMS) { 220 221 // Find RGPassManager 222 while (!PMS.empty() && 223 PMS.top()->getPassManagerType() > PMT_RegionPassManager) 224 PMS.pop(); 225 226 227 // If this pass is destroying high level information that is used 228 // by other passes that are managed by LPM then do not insert 229 // this pass in current LPM. Use new RGPassManager. 230 if (PMS.top()->getPassManagerType() == PMT_RegionPassManager && 231 !PMS.top()->preserveHigherLevelAnalysis(this)) 232 PMS.pop(); 233 } 234 235 /// Assign pass manager to manage this pass. 236 void RegionPass::assignPassManager(PMStack &PMS, 237 PassManagerType PreferredType) { 238 // Find RGPassManager 239 while (!PMS.empty() && 240 PMS.top()->getPassManagerType() > PMT_RegionPassManager) 241 PMS.pop(); 242 243 RGPassManager *RGPM; 244 245 // Create new Region Pass Manager if it does not exist. 246 if (PMS.top()->getPassManagerType() == PMT_RegionPassManager) 247 RGPM = (RGPassManager*)PMS.top(); 248 else { 249 250 assert (!PMS.empty() && "Unable to create Region Pass Manager"); 251 PMDataManager *PMD = PMS.top(); 252 253 // [1] Create new Region Pass Manager 254 RGPM = new RGPassManager(); 255 RGPM->populateInheritedAnalysis(PMS); 256 257 // [2] Set up new manager's top level manager 258 PMTopLevelManager *TPM = PMD->getTopLevelManager(); 259 TPM->addIndirectPassManager(RGPM); 260 261 // [3] Assign manager to manage this new manager. This may create 262 // and push new managers into PMS 263 TPM->schedulePass(RGPM); 264 265 // [4] Push new manager into PMS 266 PMS.push(RGPM); 267 } 268 269 RGPM->add(this); 270 } 271 272 /// Get the printer pass 273 Pass *RegionPass::createPrinterPass(raw_ostream &O, 274 const std::string &Banner) const { 275 return new PrintRegionPass(Banner, O); 276 } 277 278 static std::string getDescription(const Region &R) { 279 return "region"; 280 } 281 282 bool RegionPass::skipRegion(Region &R) const { 283 Function &F = *R.getEntry()->getParent(); 284 OptPassGate &Gate = F.getContext().getOptPassGate(); 285 if (Gate.isEnabled() && !Gate.shouldRunPass(this, getDescription(R))) 286 return true; 287 288 if (F.hasOptNone()) { 289 // Report this only once per function. 290 if (R.getEntry() == &F.getEntryBlock()) 291 LLVM_DEBUG(dbgs() << "Skipping pass '" << getPassName() 292 << "' on function " << F.getName() << "\n"); 293 return true; 294 } 295 return false; 296 } 297