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" 13336734acSTobias Grosser #include "llvm/ADT/PostOrderIterator.h" 14336734acSTobias Grosser #include "llvm/ADT/Statistic.h" 15ed0881b2SChandler Carruth #include "llvm/Analysis/LoopInfo.h" 16d9903888SChandler Carruth #include "llvm/Analysis/RegionInfoImpl.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> 24*20dcc9f7SMichael Kruse #ifndef NDEBUG 25*20dcc9f7SMichael Kruse #include "llvm/Analysis/RegionPrinter.h" 26*20dcc9f7SMichael Kruse #endif 27336734acSTobias Grosser 28336734acSTobias Grosser using namespace llvm; 29336734acSTobias Grosser 30f1221bd0SChandler Carruth #define DEBUG_TYPE "region" 31f1221bd0SChandler Carruth 321b8d8379SMatt Arsenault namespace llvm { 331b8d8379SMatt Arsenault template class RegionBase<RegionTraits<Function>>; 341b8d8379SMatt Arsenault template class RegionNodeBase<RegionTraits<Function>>; 351b8d8379SMatt Arsenault template class RegionInfoBase<RegionTraits<Function>>; 361b8d8379SMatt Arsenault } 37336734acSTobias Grosser 38336734acSTobias Grosser STATISTIC(numRegions, "The # of regions"); 39336734acSTobias Grosser STATISTIC(numSimpleRegions, "The # of simple regions"); 40336734acSTobias Grosser 411b8d8379SMatt Arsenault // Always verify if expensive checking is enabled. 421b8d8379SMatt Arsenault 431b8d8379SMatt Arsenault static cl::opt<bool,true> 441b8d8379SMatt Arsenault VerifyRegionInfoX( 451b8d8379SMatt Arsenault "verify-region-info", 461b8d8379SMatt Arsenault cl::location(RegionInfoBase<RegionTraits<Function>>::VerifyRegionInfo), 471b8d8379SMatt Arsenault cl::desc("Verify region info (time consuming)")); 481b8d8379SMatt Arsenault 491b8d8379SMatt Arsenault 501b8d8379SMatt Arsenault static cl::opt<Region::PrintStyle, true> printStyleX("print-region-style", 511b8d8379SMatt Arsenault cl::location(RegionInfo::printStyle), 528b304ff9STobias Grosser cl::Hidden, 53336734acSTobias Grosser cl::desc("style of printing regions"), 54336734acSTobias Grosser cl::values( 558b304ff9STobias Grosser clEnumValN(Region::PrintNone, "none", "print no details"), 568b304ff9STobias Grosser clEnumValN(Region::PrintBB, "bb", 5714c05c40SHongbin Zheng "print regions in detail with block_iterator"), 588b304ff9STobias Grosser clEnumValN(Region::PrintRN, "rn", 598b304ff9STobias Grosser "print regions in detail with element_iterator"), 60336734acSTobias Grosser clEnumValEnd)); 611b8d8379SMatt Arsenault 621b8d8379SMatt Arsenault 63336734acSTobias Grosser //===----------------------------------------------------------------------===// 641b8d8379SMatt Arsenault // Region implementation 651b8d8379SMatt Arsenault // 66336734acSTobias Grosser 671b8d8379SMatt Arsenault Region::Region(BasicBlock *Entry, BasicBlock *Exit, 681b8d8379SMatt Arsenault RegionInfo* RI, 691b8d8379SMatt Arsenault DominatorTree *DT, Region *Parent) : 701b8d8379SMatt Arsenault RegionBase<RegionTraits<Function>>(Entry, Exit, RI, DT, Parent) { 7118e39cecSDaniel Dunbar 72336734acSTobias Grosser } 73336734acSTobias Grosser 741b8d8379SMatt Arsenault Region::~Region() { } 75336734acSTobias Grosser 76336734acSTobias Grosser //===----------------------------------------------------------------------===// 77336734acSTobias Grosser // RegionInfo implementation 78336734acSTobias Grosser // 79336734acSTobias Grosser 801b8d8379SMatt Arsenault RegionInfo::RegionInfo() : 811b8d8379SMatt Arsenault RegionInfoBase<RegionTraits<Function>>() { 821b8d8379SMatt Arsenault 83336734acSTobias Grosser } 84336734acSTobias Grosser 851b8d8379SMatt Arsenault RegionInfo::~RegionInfo() { 86336734acSTobias Grosser 87336734acSTobias Grosser } 88336734acSTobias Grosser 89336734acSTobias Grosser void RegionInfo::updateStatistics(Region *R) { 90336734acSTobias Grosser ++numRegions; 91336734acSTobias Grosser 92336734acSTobias Grosser // TODO: Slow. Should only be enabled if -stats is used. 931b8d8379SMatt Arsenault if (R->isSimple()) 941b8d8379SMatt Arsenault ++numSimpleRegions; 95336734acSTobias Grosser } 96336734acSTobias Grosser 978eb82fc4SNAKAMURA Takumi void RegionInfo::recalculate(Function &F, DominatorTree *DT_, 988eb82fc4SNAKAMURA Takumi PostDominatorTree *PDT_, DominanceFrontier *DF_) { 991b8d8379SMatt Arsenault DT = DT_; 1001b8d8379SMatt Arsenault PDT = PDT_; 1011b8d8379SMatt Arsenault DF = DF_; 102336734acSTobias Grosser 1031b8d8379SMatt Arsenault TopLevelRegion = new Region(&F.getEntryBlock(), nullptr, 1041b8d8379SMatt Arsenault this, DT, nullptr); 105336734acSTobias Grosser updateStatistics(TopLevelRegion); 1061b8d8379SMatt Arsenault calculate(F); 1071b8d8379SMatt Arsenault } 108336734acSTobias Grosser 109*20dcc9f7SMichael Kruse #ifndef NDEBUG 110*20dcc9f7SMichael Kruse void RegionInfo::view() { viewRegion(this); } 111*20dcc9f7SMichael Kruse 112*20dcc9f7SMichael Kruse void RegionInfo::viewOnly() { viewRegionOnly(this); } 113*20dcc9f7SMichael Kruse #endif 114*20dcc9f7SMichael Kruse 1151b8d8379SMatt Arsenault //===----------------------------------------------------------------------===// 1161b8d8379SMatt Arsenault // RegionInfoPass implementation 1171b8d8379SMatt Arsenault // 118336734acSTobias Grosser 1191b8d8379SMatt Arsenault RegionInfoPass::RegionInfoPass() : FunctionPass(ID) { 1201b8d8379SMatt Arsenault initializeRegionInfoPassPass(*PassRegistry::getPassRegistry()); 1211b8d8379SMatt Arsenault } 1221b8d8379SMatt Arsenault 1231b8d8379SMatt Arsenault RegionInfoPass::~RegionInfoPass() { 1241b8d8379SMatt Arsenault 1251b8d8379SMatt Arsenault } 1261b8d8379SMatt Arsenault 1271b8d8379SMatt Arsenault bool RegionInfoPass::runOnFunction(Function &F) { 1281b8d8379SMatt Arsenault releaseMemory(); 1291b8d8379SMatt Arsenault 1301b8d8379SMatt Arsenault auto DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 1311b8d8379SMatt Arsenault auto PDT = &getAnalysis<PostDominatorTree>(); 1321b8d8379SMatt Arsenault auto DF = &getAnalysis<DominanceFrontier>(); 1331b8d8379SMatt Arsenault 1341b8d8379SMatt Arsenault RI.recalculate(F, DT, PDT, DF); 135336734acSTobias Grosser return false; 136336734acSTobias Grosser } 137336734acSTobias Grosser 1381b8d8379SMatt Arsenault void RegionInfoPass::releaseMemory() { 1391b8d8379SMatt Arsenault RI.releaseMemory(); 1401b8d8379SMatt Arsenault } 1411b8d8379SMatt Arsenault 1421b8d8379SMatt Arsenault void RegionInfoPass::verifyAnalysis() const { 1431b8d8379SMatt Arsenault RI.verifyAnalysis(); 1441b8d8379SMatt Arsenault } 1451b8d8379SMatt Arsenault 1461b8d8379SMatt Arsenault void RegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const { 147336734acSTobias Grosser AU.setPreservesAll(); 14873523021SChandler Carruth AU.addRequiredTransitive<DominatorTreeWrapperPass>(); 149336734acSTobias Grosser AU.addRequired<PostDominatorTree>(); 150336734acSTobias Grosser AU.addRequired<DominanceFrontier>(); 151336734acSTobias Grosser } 152336734acSTobias Grosser 1531b8d8379SMatt Arsenault void RegionInfoPass::print(raw_ostream &OS, const Module *) const { 1541b8d8379SMatt Arsenault RI.print(OS); 155336734acSTobias Grosser } 156336734acSTobias Grosser 157118b0c78SNAKAMURA Takumi #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 1581b8d8379SMatt Arsenault void RegionInfoPass::dump() const { 1591b8d8379SMatt Arsenault RI.dump(); 160336734acSTobias Grosser } 161118b0c78SNAKAMURA Takumi #endif 162336734acSTobias Grosser 1631b8d8379SMatt Arsenault char RegionInfoPass::ID = 0; 164336734acSTobias Grosser 1651b8d8379SMatt Arsenault INITIALIZE_PASS_BEGIN(RegionInfoPass, "regions", 1668ac477ffSOwen Anderson "Detect single entry single exit regions", true, true) 16773523021SChandler Carruth INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 1688ac477ffSOwen Anderson INITIALIZE_PASS_DEPENDENCY(PostDominatorTree) 1698ac477ffSOwen Anderson INITIALIZE_PASS_DEPENDENCY(DominanceFrontier) 1701b8d8379SMatt Arsenault INITIALIZE_PASS_END(RegionInfoPass, "regions", 171df7a4f25SOwen Anderson "Detect single entry single exit regions", true, true) 172336734acSTobias Grosser 173336734acSTobias Grosser // Create methods available outside of this file, to use them 174336734acSTobias Grosser // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by 175336734acSTobias Grosser // the link time optimization. 176336734acSTobias Grosser 177336734acSTobias Grosser namespace llvm { 178336734acSTobias Grosser FunctionPass *createRegionInfoPass() { 1791b8d8379SMatt Arsenault return new RegionInfoPass(); 180336734acSTobias Grosser } 181336734acSTobias Grosser } 182336734acSTobias Grosser 183