1336734acSTobias Grosser //===- RegionInfo.cpp - SESE region detection analysis --------------------===// 2336734acSTobias Grosser // 3336734acSTobias Grosser // The LLVM Compiler Infrastructure 4336734acSTobias Grosser // 5336734acSTobias Grosser // This file is distributed under the University of Illinois Open Source 6336734acSTobias Grosser // License. See LICENSE.TXT for details. 7336734acSTobias Grosser // 8336734acSTobias Grosser //===----------------------------------------------------------------------===// 9336734acSTobias Grosser // Detects single entry single exit regions in the control flow graph. 10336734acSTobias Grosser //===----------------------------------------------------------------------===// 11336734acSTobias Grosser 12336734acSTobias Grosser #include "llvm/Analysis/RegionInfo.h" 13*1b8d8379SMatt Arsenault #include "llvm/Analysis/RegionInfoImpl.h" 14336734acSTobias Grosser #include "llvm/ADT/PostOrderIterator.h" 15336734acSTobias Grosser #include "llvm/ADT/Statistic.h" 16ed0881b2SChandler Carruth #include "llvm/Analysis/LoopInfo.h" 17ed0881b2SChandler Carruth #include "llvm/Analysis/RegionIterator.h" 18336734acSTobias Grosser #include "llvm/Support/CommandLine.h" 19336734acSTobias Grosser #include "llvm/Support/Debug.h" 208a8cd2baSChandler Carruth #include "llvm/Support/ErrorHandling.h" 21336734acSTobias Grosser #include <algorithm> 22ec649acbSDavid Blaikie #include <iterator> 23570d3020SBill Wendling #include <set> 24336734acSTobias Grosser 25336734acSTobias Grosser using namespace llvm; 26336734acSTobias Grosser 27f1221bd0SChandler Carruth #define DEBUG_TYPE "region" 28f1221bd0SChandler Carruth 29*1b8d8379SMatt Arsenault namespace llvm { 30*1b8d8379SMatt Arsenault template class RegionBase<RegionTraits<Function>>; 31*1b8d8379SMatt Arsenault template class RegionNodeBase<RegionTraits<Function>>; 32*1b8d8379SMatt Arsenault template class RegionInfoBase<RegionTraits<Function>>; 33*1b8d8379SMatt Arsenault } 34336734acSTobias Grosser 35336734acSTobias Grosser STATISTIC(numRegions, "The # of regions"); 36336734acSTobias Grosser STATISTIC(numSimpleRegions, "The # of simple regions"); 37336734acSTobias Grosser 38*1b8d8379SMatt Arsenault // Always verify if expensive checking is enabled. 39*1b8d8379SMatt Arsenault 40*1b8d8379SMatt Arsenault static cl::opt<bool,true> 41*1b8d8379SMatt Arsenault VerifyRegionInfoX( 42*1b8d8379SMatt Arsenault "verify-region-info", 43*1b8d8379SMatt Arsenault cl::location(RegionInfoBase<RegionTraits<Function>>::VerifyRegionInfo), 44*1b8d8379SMatt Arsenault cl::desc("Verify region info (time consuming)")); 45*1b8d8379SMatt Arsenault 46*1b8d8379SMatt Arsenault 47*1b8d8379SMatt Arsenault static cl::opt<Region::PrintStyle, true> printStyleX("print-region-style", 48*1b8d8379SMatt Arsenault cl::location(RegionInfo::printStyle), 498b304ff9STobias Grosser cl::Hidden, 50336734acSTobias Grosser cl::desc("style of printing regions"), 51336734acSTobias Grosser cl::values( 528b304ff9STobias Grosser clEnumValN(Region::PrintNone, "none", "print no details"), 538b304ff9STobias Grosser clEnumValN(Region::PrintBB, "bb", 5414c05c40SHongbin Zheng "print regions in detail with block_iterator"), 558b304ff9STobias Grosser clEnumValN(Region::PrintRN, "rn", 568b304ff9STobias Grosser "print regions in detail with element_iterator"), 57336734acSTobias Grosser clEnumValEnd)); 58*1b8d8379SMatt Arsenault 59*1b8d8379SMatt Arsenault 60336734acSTobias Grosser //===----------------------------------------------------------------------===// 61*1b8d8379SMatt Arsenault // Region implementation 62*1b8d8379SMatt Arsenault // 63336734acSTobias Grosser 64*1b8d8379SMatt Arsenault Region::Region(BasicBlock *Entry, BasicBlock *Exit, 65*1b8d8379SMatt Arsenault RegionInfo* RI, 66*1b8d8379SMatt Arsenault DominatorTree *DT, Region *Parent) : 67*1b8d8379SMatt Arsenault RegionBase<RegionTraits<Function>>(Entry, Exit, RI, DT, Parent) { 6818e39cecSDaniel Dunbar 69336734acSTobias Grosser } 70336734acSTobias Grosser 71*1b8d8379SMatt Arsenault Region::~Region() { } 72336734acSTobias Grosser 73336734acSTobias Grosser //===----------------------------------------------------------------------===// 74336734acSTobias Grosser // RegionInfo implementation 75336734acSTobias Grosser // 76336734acSTobias Grosser 77*1b8d8379SMatt Arsenault RegionInfo::RegionInfo() : 78*1b8d8379SMatt Arsenault RegionInfoBase<RegionTraits<Function>>() { 79*1b8d8379SMatt Arsenault 80336734acSTobias Grosser } 81336734acSTobias Grosser 82*1b8d8379SMatt Arsenault RegionInfo::~RegionInfo() { 83336734acSTobias Grosser 84336734acSTobias Grosser } 85336734acSTobias Grosser 86336734acSTobias Grosser void RegionInfo::updateStatistics(Region *R) { 87336734acSTobias Grosser ++numRegions; 88336734acSTobias Grosser 89336734acSTobias Grosser // TODO: Slow. Should only be enabled if -stats is used. 90*1b8d8379SMatt Arsenault if (R->isSimple()) 91*1b8d8379SMatt Arsenault ++numSimpleRegions; 92336734acSTobias Grosser } 93336734acSTobias Grosser 94*1b8d8379SMatt Arsenault void RegionInfo::RegionInfo::recalculate(Function &F, 95*1b8d8379SMatt Arsenault DominatorTree *DT_, 96*1b8d8379SMatt Arsenault PostDominatorTree *PDT_, 97*1b8d8379SMatt Arsenault DominanceFrontier *DF_) { 98*1b8d8379SMatt Arsenault DT = DT_; 99*1b8d8379SMatt Arsenault PDT = PDT_; 100*1b8d8379SMatt Arsenault DF = DF_; 101336734acSTobias Grosser 102*1b8d8379SMatt Arsenault TopLevelRegion = new Region(&F.getEntryBlock(), nullptr, 103*1b8d8379SMatt Arsenault this, DT, nullptr); 104336734acSTobias Grosser updateStatistics(TopLevelRegion); 105*1b8d8379SMatt Arsenault calculate(F); 106*1b8d8379SMatt Arsenault } 107336734acSTobias Grosser 108*1b8d8379SMatt Arsenault //===----------------------------------------------------------------------===// 109*1b8d8379SMatt Arsenault // RegionInfoPass implementation 110*1b8d8379SMatt Arsenault // 111336734acSTobias Grosser 112*1b8d8379SMatt Arsenault RegionInfoPass::RegionInfoPass() : FunctionPass(ID) { 113*1b8d8379SMatt Arsenault initializeRegionInfoPassPass(*PassRegistry::getPassRegistry()); 114*1b8d8379SMatt Arsenault } 115*1b8d8379SMatt Arsenault 116*1b8d8379SMatt Arsenault RegionInfoPass::~RegionInfoPass() { 117*1b8d8379SMatt Arsenault 118*1b8d8379SMatt Arsenault } 119*1b8d8379SMatt Arsenault 120*1b8d8379SMatt Arsenault bool RegionInfoPass::runOnFunction(Function &F) { 121*1b8d8379SMatt Arsenault releaseMemory(); 122*1b8d8379SMatt Arsenault 123*1b8d8379SMatt Arsenault auto DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 124*1b8d8379SMatt Arsenault auto PDT = &getAnalysis<PostDominatorTree>(); 125*1b8d8379SMatt Arsenault auto DF = &getAnalysis<DominanceFrontier>(); 126*1b8d8379SMatt Arsenault 127*1b8d8379SMatt Arsenault RI.recalculate(F, DT, PDT, DF); 128336734acSTobias Grosser return false; 129336734acSTobias Grosser } 130336734acSTobias Grosser 131*1b8d8379SMatt Arsenault void RegionInfoPass::releaseMemory() { 132*1b8d8379SMatt Arsenault RI.releaseMemory(); 133*1b8d8379SMatt Arsenault } 134*1b8d8379SMatt Arsenault 135*1b8d8379SMatt Arsenault void RegionInfoPass::verifyAnalysis() const { 136*1b8d8379SMatt Arsenault RI.verifyAnalysis(); 137*1b8d8379SMatt Arsenault } 138*1b8d8379SMatt Arsenault 139*1b8d8379SMatt Arsenault void RegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const { 140336734acSTobias Grosser AU.setPreservesAll(); 14173523021SChandler Carruth AU.addRequiredTransitive<DominatorTreeWrapperPass>(); 142336734acSTobias Grosser AU.addRequired<PostDominatorTree>(); 143336734acSTobias Grosser AU.addRequired<DominanceFrontier>(); 144336734acSTobias Grosser } 145336734acSTobias Grosser 146*1b8d8379SMatt Arsenault void RegionInfoPass::print(raw_ostream &OS, const Module *) const { 147*1b8d8379SMatt Arsenault RI.print(OS); 148336734acSTobias Grosser } 149336734acSTobias Grosser 150*1b8d8379SMatt Arsenault void RegionInfoPass::dump() const { 151*1b8d8379SMatt Arsenault RI.dump(); 152336734acSTobias Grosser } 153336734acSTobias Grosser 154*1b8d8379SMatt Arsenault char RegionInfoPass::ID = 0; 155336734acSTobias Grosser 156*1b8d8379SMatt Arsenault INITIALIZE_PASS_BEGIN(RegionInfoPass, "regions", 1578ac477ffSOwen Anderson "Detect single entry single exit regions", true, true) 15873523021SChandler Carruth INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 1598ac477ffSOwen Anderson INITIALIZE_PASS_DEPENDENCY(PostDominatorTree) 1608ac477ffSOwen Anderson INITIALIZE_PASS_DEPENDENCY(DominanceFrontier) 161*1b8d8379SMatt Arsenault INITIALIZE_PASS_END(RegionInfoPass, "regions", 162df7a4f25SOwen Anderson "Detect single entry single exit regions", true, true) 163336734acSTobias Grosser 164336734acSTobias Grosser // Create methods available outside of this file, to use them 165336734acSTobias Grosser // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by 166336734acSTobias Grosser // the link time optimization. 167336734acSTobias Grosser 168336734acSTobias Grosser namespace llvm { 169336734acSTobias Grosser FunctionPass *createRegionInfoPass() { 170*1b8d8379SMatt Arsenault return new RegionInfoPass(); 171336734acSTobias Grosser } 172336734acSTobias Grosser } 173336734acSTobias Grosser 174