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