1 2 #include "llvm/CodeGen/MachineRegionInfo.h" 3 #include "llvm/ADT/Statistic.h" 4 #include "llvm/Analysis/RegionInfoImpl.h" 5 #include "llvm/CodeGen/MachinePostDominators.h" 6 7 #define DEBUG_TYPE "region" 8 9 using namespace llvm; 10 11 STATISTIC(numMachineRegions, "The # of machine regions"); 12 STATISTIC(numMachineSimpleRegions, "The # of simple machine regions"); 13 14 namespace llvm { 15 template class RegionBase<RegionTraits<MachineFunction>>; 16 template class RegionNodeBase<RegionTraits<MachineFunction>>; 17 template class RegionInfoBase<RegionTraits<MachineFunction>>; 18 } 19 20 //===----------------------------------------------------------------------===// 21 // MachineRegion implementation 22 // 23 24 MachineRegion::MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit, 25 MachineRegionInfo* RI, 26 MachineDominatorTree *DT, MachineRegion *Parent) : 27 RegionBase<RegionTraits<MachineFunction>>(Entry, Exit, RI, DT, Parent) { 28 29 } 30 31 MachineRegion::~MachineRegion() { } 32 33 //===----------------------------------------------------------------------===// 34 // MachineRegionInfo implementation 35 // 36 37 MachineRegionInfo::MachineRegionInfo() : 38 RegionInfoBase<RegionTraits<MachineFunction>>() { 39 40 } 41 42 MachineRegionInfo::~MachineRegionInfo() { 43 44 } 45 46 void MachineRegionInfo::updateStatistics(MachineRegion *R) { 47 ++numMachineRegions; 48 49 // TODO: Slow. Should only be enabled if -stats is used. 50 if (R->isSimple()) 51 ++numMachineSimpleRegions; 52 } 53 54 void MachineRegionInfo::recalculate(MachineFunction &F, 55 MachineDominatorTree *DT_, 56 MachinePostDominatorTree *PDT_, 57 MachineDominanceFrontier *DF_) { 58 DT = DT_; 59 PDT = PDT_; 60 DF = DF_; 61 62 MachineBasicBlock *Entry = GraphTraits<MachineFunction*>::getEntryNode(&F); 63 64 TopLevelRegion = new MachineRegion(Entry, nullptr, this, DT, nullptr); 65 updateStatistics(TopLevelRegion); 66 calculate(F); 67 } 68 69 //===----------------------------------------------------------------------===// 70 // MachineRegionInfoPass implementation 71 // 72 73 MachineRegionInfoPass::MachineRegionInfoPass() : MachineFunctionPass(ID) { 74 initializeMachineRegionInfoPassPass(*PassRegistry::getPassRegistry()); 75 } 76 77 MachineRegionInfoPass::~MachineRegionInfoPass() { 78 79 } 80 81 bool MachineRegionInfoPass::runOnMachineFunction(MachineFunction &F) { 82 releaseMemory(); 83 84 auto DT = &getAnalysis<MachineDominatorTree>(); 85 auto PDT = &getAnalysis<MachinePostDominatorTree>(); 86 auto DF = &getAnalysis<MachineDominanceFrontier>(); 87 88 RI.recalculate(F, DT, PDT, DF); 89 return false; 90 } 91 92 void MachineRegionInfoPass::releaseMemory() { 93 RI.releaseMemory(); 94 } 95 96 void MachineRegionInfoPass::verifyAnalysis() const { 97 // Only do verification when user wants to, otherwise this expensive check 98 // will be invoked by PMDataManager::verifyPreservedAnalysis when 99 // a regionpass (marked PreservedAll) finish. 100 if (MachineRegionInfo::VerifyRegionInfo) 101 RI.verifyAnalysis(); 102 } 103 104 void MachineRegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const { 105 AU.setPreservesAll(); 106 AU.addRequiredTransitive<DominatorTreeWrapperPass>(); 107 AU.addRequired<PostDominatorTreeWrapperPass>(); 108 AU.addRequired<DominanceFrontierWrapperPass>(); 109 } 110 111 void MachineRegionInfoPass::print(raw_ostream &OS, const Module *) const { 112 RI.print(OS); 113 } 114 115 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 116 LLVM_DUMP_METHOD void MachineRegionInfoPass::dump() const { 117 RI.dump(); 118 } 119 #endif 120 121 char MachineRegionInfoPass::ID = 0; 122 123 INITIALIZE_PASS_BEGIN(MachineRegionInfoPass, "regions", 124 "Detect single entry single exit regions", true, true) 125 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) 126 INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTree) 127 INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontier) 128 INITIALIZE_PASS_END(MachineRegionInfoPass, "regions", 129 "Detect single entry single exit regions", true, true) 130 131 // Create methods available outside of this file, to use them 132 // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by 133 // the link time optimization. 134 135 namespace llvm { 136 FunctionPass *createMachineRegionInfoPass() { 137 return new MachineRegionInfoPass(); 138 } 139 } 140 141