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/Statistic.h" 1420dcc9f7SMichael Kruse #ifndef NDEBUG 1520dcc9f7SMichael Kruse #include "llvm/Analysis/RegionPrinter.h" 1620dcc9f7SMichael Kruse #endif 174f820d0eSEugene Zelenko #include "llvm/Analysis/RegionInfoImpl.h" 184f820d0eSEugene Zelenko #include "llvm/IR/Function.h" 194f820d0eSEugene Zelenko #include "llvm/IR/PassManager.h" 204f820d0eSEugene Zelenko #include "llvm/Pass.h" 214f820d0eSEugene Zelenko #include "llvm/Support/CommandLine.h" 224f820d0eSEugene Zelenko #include "llvm/Support/Compiler.h" 234f820d0eSEugene Zelenko #include "llvm/Support/raw_ostream.h" 24336734acSTobias Grosser 25336734acSTobias Grosser using namespace llvm; 26336734acSTobias Grosser 27f1221bd0SChandler Carruth #define DEBUG_TYPE "region" 28f1221bd0SChandler Carruth 291b8d8379SMatt Arsenault namespace llvm { 304f820d0eSEugene Zelenko 311b8d8379SMatt Arsenault template class RegionBase<RegionTraits<Function>>; 321b8d8379SMatt Arsenault template class RegionNodeBase<RegionTraits<Function>>; 331b8d8379SMatt Arsenault template class RegionInfoBase<RegionTraits<Function>>; 344f820d0eSEugene Zelenko 354f820d0eSEugene Zelenko } // end namespace llvm 36336734acSTobias Grosser 37336734acSTobias Grosser STATISTIC(numRegions, "The # of regions"); 38336734acSTobias Grosser STATISTIC(numSimpleRegions, "The # of simple regions"); 39336734acSTobias Grosser 401b8d8379SMatt Arsenault // Always verify if expensive checking is enabled. 411b8d8379SMatt Arsenault 421b8d8379SMatt Arsenault static cl::opt<bool,true> 431b8d8379SMatt Arsenault VerifyRegionInfoX( 441b8d8379SMatt Arsenault "verify-region-info", 451b8d8379SMatt Arsenault cl::location(RegionInfoBase<RegionTraits<Function>>::VerifyRegionInfo), 461b8d8379SMatt Arsenault cl::desc("Verify region info (time consuming)")); 471b8d8379SMatt Arsenault 481b8d8379SMatt Arsenault static cl::opt<Region::PrintStyle, true> printStyleX("print-region-style", 491b8d8379SMatt Arsenault cl::location(RegionInfo::printStyle), 508b304ff9STobias Grosser cl::Hidden, 51336734acSTobias Grosser cl::desc("style of printing regions"), 52336734acSTobias Grosser cl::values( 538b304ff9STobias Grosser clEnumValN(Region::PrintNone, "none", "print no details"), 548b304ff9STobias Grosser clEnumValN(Region::PrintBB, "bb", 5514c05c40SHongbin Zheng "print regions in detail with block_iterator"), 568b304ff9STobias Grosser clEnumValN(Region::PrintRN, "rn", 57732afdd0SMehdi Amini "print regions in detail with element_iterator"))); 581b8d8379SMatt Arsenault 59336734acSTobias Grosser //===----------------------------------------------------------------------===// 601b8d8379SMatt Arsenault // Region implementation 611b8d8379SMatt Arsenault // 62336734acSTobias Grosser 631b8d8379SMatt Arsenault Region::Region(BasicBlock *Entry, BasicBlock *Exit, 641b8d8379SMatt Arsenault RegionInfo* RI, 651b8d8379SMatt Arsenault DominatorTree *DT, Region *Parent) : 661b8d8379SMatt Arsenault RegionBase<RegionTraits<Function>>(Entry, Exit, RI, DT, Parent) { 6718e39cecSDaniel Dunbar 68336734acSTobias Grosser } 69336734acSTobias Grosser 704f820d0eSEugene Zelenko Region::~Region() = default; 71336734acSTobias Grosser 72336734acSTobias Grosser //===----------------------------------------------------------------------===// 73336734acSTobias Grosser // RegionInfo implementation 74336734acSTobias Grosser // 75336734acSTobias Grosser 764f820d0eSEugene Zelenko RegionInfo::RegionInfo() = default; 771b8d8379SMatt Arsenault 784f820d0eSEugene Zelenko RegionInfo::~RegionInfo() = default; 79336734acSTobias Grosser 80ca68a3ecSChandler Carruth bool RegionInfo::invalidate(Function &F, const PreservedAnalyses &PA, 81ca68a3ecSChandler Carruth FunctionAnalysisManager::Invalidator &) { 82ca68a3ecSChandler Carruth // Check whether the analysis, all analyses on functions, or the function's 83ca68a3ecSChandler Carruth // CFG have been preserved. 84ca68a3ecSChandler Carruth auto PAC = PA.getChecker<RegionInfoAnalysis>(); 85ca68a3ecSChandler Carruth return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>() || 86ca68a3ecSChandler Carruth PAC.preservedSet<CFGAnalyses>()); 87ca68a3ecSChandler Carruth } 88ca68a3ecSChandler Carruth 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 10920dcc9f7SMichael Kruse #ifndef NDEBUG 11020dcc9f7SMichael Kruse void RegionInfo::view() { viewRegion(this); } 11120dcc9f7SMichael Kruse 11220dcc9f7SMichael Kruse void RegionInfo::viewOnly() { viewRegionOnly(this); } 11320dcc9f7SMichael Kruse #endif 11420dcc9f7SMichael 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 1234f820d0eSEugene Zelenko RegionInfoPass::~RegionInfoPass() = default; 1241b8d8379SMatt Arsenault 1251b8d8379SMatt Arsenault bool RegionInfoPass::runOnFunction(Function &F) { 1261b8d8379SMatt Arsenault releaseMemory(); 1271b8d8379SMatt Arsenault 1281b8d8379SMatt Arsenault auto DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 1293f978407SHongbin Zheng auto PDT = &getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree(); 130751337faSHongbin Zheng auto DF = &getAnalysis<DominanceFrontierWrapperPass>().getDominanceFrontier(); 1311b8d8379SMatt Arsenault 1321b8d8379SMatt Arsenault RI.recalculate(F, DT, PDT, DF); 133336734acSTobias Grosser return false; 134336734acSTobias Grosser } 135336734acSTobias Grosser 1361b8d8379SMatt Arsenault void RegionInfoPass::releaseMemory() { 1371b8d8379SMatt Arsenault RI.releaseMemory(); 1381b8d8379SMatt Arsenault } 1391b8d8379SMatt Arsenault 1401b8d8379SMatt Arsenault void RegionInfoPass::verifyAnalysis() const { 1411b8d8379SMatt Arsenault RI.verifyAnalysis(); 1421b8d8379SMatt Arsenault } 1431b8d8379SMatt Arsenault 1441b8d8379SMatt Arsenault void RegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const { 145336734acSTobias Grosser AU.setPreservesAll(); 14673523021SChandler Carruth AU.addRequiredTransitive<DominatorTreeWrapperPass>(); 1473f978407SHongbin Zheng AU.addRequired<PostDominatorTreeWrapperPass>(); 148751337faSHongbin Zheng AU.addRequired<DominanceFrontierWrapperPass>(); 149336734acSTobias Grosser } 150336734acSTobias Grosser 1511b8d8379SMatt Arsenault void RegionInfoPass::print(raw_ostream &OS, const Module *) const { 1521b8d8379SMatt Arsenault RI.print(OS); 153336734acSTobias Grosser } 154336734acSTobias Grosser 155*615eb470SAaron Ballman #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 156eb2a2546SYaron Keren LLVM_DUMP_METHOD void RegionInfoPass::dump() const { 1571b8d8379SMatt Arsenault RI.dump(); 158336734acSTobias Grosser } 159118b0c78SNAKAMURA Takumi #endif 160336734acSTobias Grosser 1611b8d8379SMatt Arsenault char RegionInfoPass::ID = 0; 162336734acSTobias Grosser 1631b8d8379SMatt Arsenault INITIALIZE_PASS_BEGIN(RegionInfoPass, "regions", 1648ac477ffSOwen Anderson "Detect single entry single exit regions", true, true) 16573523021SChandler Carruth INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 1663f978407SHongbin Zheng INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass) 167751337faSHongbin Zheng INITIALIZE_PASS_DEPENDENCY(DominanceFrontierWrapperPass) 1681b8d8379SMatt Arsenault INITIALIZE_PASS_END(RegionInfoPass, "regions", 169df7a4f25SOwen Anderson "Detect single entry single exit regions", true, true) 170336734acSTobias Grosser 171336734acSTobias Grosser // Create methods available outside of this file, to use them 172336734acSTobias Grosser // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by 173336734acSTobias Grosser // the link time optimization. 174336734acSTobias Grosser 175336734acSTobias Grosser namespace llvm { 1764f820d0eSEugene Zelenko 177336734acSTobias Grosser FunctionPass *createRegionInfoPass() { 1781b8d8379SMatt Arsenault return new RegionInfoPass(); 179336734acSTobias Grosser } 1804f820d0eSEugene Zelenko 1814f820d0eSEugene Zelenko } // end namespace llvm 182336734acSTobias Grosser 183bc53977aSHongbin Zheng //===----------------------------------------------------------------------===// 184bc53977aSHongbin Zheng // RegionInfoAnalysis implementation 185bc53977aSHongbin Zheng // 186bc53977aSHongbin Zheng 187dab4eae2SChandler Carruth AnalysisKey RegionInfoAnalysis::Key; 188df0cd726SNAKAMURA Takumi 18936e0d01eSSean Silva RegionInfo RegionInfoAnalysis::run(Function &F, FunctionAnalysisManager &AM) { 190bc53977aSHongbin Zheng RegionInfo RI; 191b47f8010SChandler Carruth auto *DT = &AM.getResult<DominatorTreeAnalysis>(F); 192b47f8010SChandler Carruth auto *PDT = &AM.getResult<PostDominatorTreeAnalysis>(F); 193b47f8010SChandler Carruth auto *DF = &AM.getResult<DominanceFrontierAnalysis>(F); 194bc53977aSHongbin Zheng 195bc53977aSHongbin Zheng RI.recalculate(F, DT, PDT, DF); 196bc53977aSHongbin Zheng return RI; 197bc53977aSHongbin Zheng } 198bc53977aSHongbin Zheng 199bc53977aSHongbin Zheng RegionInfoPrinterPass::RegionInfoPrinterPass(raw_ostream &OS) 200bc53977aSHongbin Zheng : OS(OS) {} 201bc53977aSHongbin Zheng 202b47f8010SChandler Carruth PreservedAnalyses RegionInfoPrinterPass::run(Function &F, 203b47f8010SChandler Carruth FunctionAnalysisManager &AM) { 204bc53977aSHongbin Zheng OS << "Region Tree for function: " << F.getName() << "\n"; 205b47f8010SChandler Carruth AM.getResult<RegionInfoAnalysis>(F).print(OS); 206bc53977aSHongbin Zheng 207bc53977aSHongbin Zheng return PreservedAnalyses::all(); 208bc53977aSHongbin Zheng } 209bc53977aSHongbin Zheng 210bc53977aSHongbin Zheng PreservedAnalyses RegionInfoVerifierPass::run(Function &F, 21136e0d01eSSean Silva FunctionAnalysisManager &AM) { 212b47f8010SChandler Carruth AM.getResult<RegionInfoAnalysis>(F).verifyAnalysis(); 213bc53977aSHongbin Zheng 214bc53977aSHongbin Zheng return PreservedAnalyses::all(); 215bc53977aSHongbin Zheng } 216