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