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