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