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