11b8d8379SMatt Arsenault #include "llvm/CodeGen/MachineRegionInfo.h" 21b8d8379SMatt Arsenault #include "llvm/ADT/Statistic.h" 31b8d8379SMatt Arsenault #include "llvm/Analysis/RegionInfoImpl.h" 4d9903888SChandler Carruth #include "llvm/CodeGen/MachinePostDominators.h" 51b8d8379SMatt Arsenault 643130592SMatthias Braun #define DEBUG_TYPE "machine-region-info" 75e23fb86SRichard Smith 81b8d8379SMatt Arsenault using namespace llvm; 91b8d8379SMatt Arsenault 101b8d8379SMatt Arsenault STATISTIC(numMachineRegions, "The # of machine regions"); 111b8d8379SMatt Arsenault STATISTIC(numMachineSimpleRegions, "The # of simple machine regions"); 121b8d8379SMatt Arsenault 131b8d8379SMatt Arsenault namespace llvm { 141b8d8379SMatt Arsenault template class RegionBase<RegionTraits<MachineFunction>>; 151b8d8379SMatt Arsenault template class RegionNodeBase<RegionTraits<MachineFunction>>; 161b8d8379SMatt Arsenault template class RegionInfoBase<RegionTraits<MachineFunction>>; 171b8d8379SMatt Arsenault } 181b8d8379SMatt Arsenault 191b8d8379SMatt Arsenault //===----------------------------------------------------------------------===// 201b8d8379SMatt Arsenault // MachineRegion implementation 211b8d8379SMatt Arsenault // 221b8d8379SMatt Arsenault 231b8d8379SMatt Arsenault MachineRegion::MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit, 241b8d8379SMatt Arsenault MachineRegionInfo* RI, 251b8d8379SMatt Arsenault MachineDominatorTree *DT, MachineRegion *Parent) : 261b8d8379SMatt Arsenault RegionBase<RegionTraits<MachineFunction>>(Entry, Exit, RI, DT, Parent) { 271b8d8379SMatt Arsenault 281b8d8379SMatt Arsenault } 291b8d8379SMatt Arsenault 301b8d8379SMatt Arsenault MachineRegion::~MachineRegion() { } 311b8d8379SMatt Arsenault 321b8d8379SMatt Arsenault //===----------------------------------------------------------------------===// 331b8d8379SMatt Arsenault // MachineRegionInfo implementation 341b8d8379SMatt Arsenault // 351b8d8379SMatt Arsenault 361b8d8379SMatt Arsenault MachineRegionInfo::MachineRegionInfo() : 371b8d8379SMatt Arsenault RegionInfoBase<RegionTraits<MachineFunction>>() { 381b8d8379SMatt Arsenault 391b8d8379SMatt Arsenault } 401b8d8379SMatt Arsenault 411b8d8379SMatt Arsenault MachineRegionInfo::~MachineRegionInfo() { 421b8d8379SMatt Arsenault 431b8d8379SMatt Arsenault } 441b8d8379SMatt Arsenault 451b8d8379SMatt Arsenault void MachineRegionInfo::updateStatistics(MachineRegion *R) { 461b8d8379SMatt Arsenault ++numMachineRegions; 471b8d8379SMatt Arsenault 481b8d8379SMatt Arsenault // TODO: Slow. Should only be enabled if -stats is used. 491b8d8379SMatt Arsenault if (R->isSimple()) 501b8d8379SMatt Arsenault ++numMachineSimpleRegions; 511b8d8379SMatt Arsenault } 521b8d8379SMatt Arsenault 5374a53322SNAKAMURA Takumi void MachineRegionInfo::recalculate(MachineFunction &F, 541b8d8379SMatt Arsenault MachineDominatorTree *DT_, 551b8d8379SMatt Arsenault MachinePostDominatorTree *PDT_, 561b8d8379SMatt Arsenault MachineDominanceFrontier *DF_) { 571b8d8379SMatt Arsenault DT = DT_; 581b8d8379SMatt Arsenault PDT = PDT_; 591b8d8379SMatt Arsenault DF = DF_; 601b8d8379SMatt Arsenault 611b8d8379SMatt Arsenault MachineBasicBlock *Entry = GraphTraits<MachineFunction*>::getEntryNode(&F); 621b8d8379SMatt Arsenault 631b8d8379SMatt Arsenault TopLevelRegion = new MachineRegion(Entry, nullptr, this, DT, nullptr); 641b8d8379SMatt Arsenault updateStatistics(TopLevelRegion); 651b8d8379SMatt Arsenault calculate(F); 661b8d8379SMatt Arsenault } 671b8d8379SMatt Arsenault 681b8d8379SMatt Arsenault //===----------------------------------------------------------------------===// 691b8d8379SMatt Arsenault // MachineRegionInfoPass implementation 701b8d8379SMatt Arsenault // 711b8d8379SMatt Arsenault 721b8d8379SMatt Arsenault MachineRegionInfoPass::MachineRegionInfoPass() : MachineFunctionPass(ID) { 731b8d8379SMatt Arsenault initializeMachineRegionInfoPassPass(*PassRegistry::getPassRegistry()); 741b8d8379SMatt Arsenault } 751b8d8379SMatt Arsenault 761b8d8379SMatt Arsenault MachineRegionInfoPass::~MachineRegionInfoPass() { 771b8d8379SMatt Arsenault 781b8d8379SMatt Arsenault } 791b8d8379SMatt Arsenault 801b8d8379SMatt Arsenault bool MachineRegionInfoPass::runOnMachineFunction(MachineFunction &F) { 811b8d8379SMatt Arsenault releaseMemory(); 821b8d8379SMatt Arsenault 831b8d8379SMatt Arsenault auto DT = &getAnalysis<MachineDominatorTree>(); 841b8d8379SMatt Arsenault auto PDT = &getAnalysis<MachinePostDominatorTree>(); 851b8d8379SMatt Arsenault auto DF = &getAnalysis<MachineDominanceFrontier>(); 861b8d8379SMatt Arsenault 871b8d8379SMatt Arsenault RI.recalculate(F, DT, PDT, DF); 8843130592SMatthias Braun 8943130592SMatthias Braun DEBUG(RI.dump()); 9043130592SMatthias Braun 911b8d8379SMatt Arsenault return false; 921b8d8379SMatt Arsenault } 931b8d8379SMatt Arsenault 941b8d8379SMatt Arsenault void MachineRegionInfoPass::releaseMemory() { 951b8d8379SMatt Arsenault RI.releaseMemory(); 961b8d8379SMatt Arsenault } 971b8d8379SMatt Arsenault 981b8d8379SMatt Arsenault void MachineRegionInfoPass::verifyAnalysis() const { 991b8d8379SMatt Arsenault // Only do verification when user wants to, otherwise this expensive check 1001b8d8379SMatt Arsenault // will be invoked by PMDataManager::verifyPreservedAnalysis when 1011b8d8379SMatt Arsenault // a regionpass (marked PreservedAll) finish. 1021b8d8379SMatt Arsenault if (MachineRegionInfo::VerifyRegionInfo) 1031b8d8379SMatt Arsenault RI.verifyAnalysis(); 1041b8d8379SMatt Arsenault } 1051b8d8379SMatt Arsenault 1061b8d8379SMatt Arsenault void MachineRegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const { 1071b8d8379SMatt Arsenault AU.setPreservesAll(); 10843130592SMatthias Braun AU.addRequired<MachineDominatorTree>(); 10943130592SMatthias Braun AU.addRequired<MachinePostDominatorTree>(); 11043130592SMatthias Braun AU.addRequired<MachineDominanceFrontier>(); 11143130592SMatthias Braun MachineFunctionPass::getAnalysisUsage(AU); 1121b8d8379SMatt Arsenault } 1131b8d8379SMatt Arsenault 1141b8d8379SMatt Arsenault void MachineRegionInfoPass::print(raw_ostream &OS, const Module *) const { 1151b8d8379SMatt Arsenault RI.print(OS); 1161b8d8379SMatt Arsenault } 1171b8d8379SMatt Arsenault 118118b0c78SNAKAMURA Takumi #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 119eb2a2546SYaron Keren LLVM_DUMP_METHOD void MachineRegionInfoPass::dump() const { 1201b8d8379SMatt Arsenault RI.dump(); 1211b8d8379SMatt Arsenault } 122118b0c78SNAKAMURA Takumi #endif 1231b8d8379SMatt Arsenault 1241b8d8379SMatt Arsenault char MachineRegionInfoPass::ID = 0; 125*695e4374SJan Sjodin char &MachineRegionInfoPassID = MachineRegionInfoPass::ID; 1261b8d8379SMatt Arsenault 12743130592SMatthias Braun INITIALIZE_PASS_BEGIN(MachineRegionInfoPass, DEBUG_TYPE, 1281b8d8379SMatt Arsenault "Detect single entry single exit regions", true, true) 1291b8d8379SMatt Arsenault INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) 1301b8d8379SMatt Arsenault INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTree) 1311b8d8379SMatt Arsenault INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontier) 13243130592SMatthias Braun INITIALIZE_PASS_END(MachineRegionInfoPass, DEBUG_TYPE, 1331b8d8379SMatt Arsenault "Detect single entry single exit regions", true, true) 1341b8d8379SMatt Arsenault 1351b8d8379SMatt Arsenault // Create methods available outside of this file, to use them 1361b8d8379SMatt Arsenault // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by 1371b8d8379SMatt Arsenault // the link time optimization. 1381b8d8379SMatt Arsenault 1391b8d8379SMatt Arsenault namespace llvm { 1401b8d8379SMatt Arsenault FunctionPass *createMachineRegionInfoPass() { 1411b8d8379SMatt Arsenault return new MachineRegionInfoPass(); 1421b8d8379SMatt Arsenault } 1431b8d8379SMatt Arsenault } 1441b8d8379SMatt Arsenault 145