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 21using namespace llvm; 22 23STATISTIC(numMachineRegions, "The # of machine regions"); 24STATISTIC(numMachineSimpleRegions, "The # of simple machine regions"); 25 26namespace llvm { 27 28template class RegionBase<RegionTraits<MachineFunction>>; 29template class RegionNodeBase<RegionTraits<MachineFunction>>; 30template class RegionInfoBase<RegionTraits<MachineFunction>>; 31 32} // end namespace llvm 33 34//===----------------------------------------------------------------------===// 35// MachineRegion implementation 36 37MachineRegion::MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit, 38 MachineRegionInfo* RI, 39 MachineDominatorTree *DT, MachineRegion *Parent) : 40 RegionBase<RegionTraits<MachineFunction>>(Entry, Exit, RI, DT, Parent) {} 41 42MachineRegion::~MachineRegion() = default; 43 44//===----------------------------------------------------------------------===// 45// MachineRegionInfo implementation 46 47MachineRegionInfo::MachineRegionInfo() = default; 48 49MachineRegionInfo::~MachineRegionInfo() = default; 50 51void 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 59void 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 78MachineRegionInfoPass::MachineRegionInfoPass() : MachineFunctionPass(ID) { 79 initializeMachineRegionInfoPassPass(*PassRegistry::getPassRegistry()); 80} 81 82MachineRegionInfoPass::~MachineRegionInfoPass() = default; 83 84bool 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 98void MachineRegionInfoPass::releaseMemory() { 99 RI.releaseMemory(); 100} 101 102void 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 110void 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 118void MachineRegionInfoPass::print(raw_ostream &OS, const Module *) const { 119 RI.print(OS); 120} 121 122#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 123LLVM_DUMP_METHOD void MachineRegionInfoPass::dump() const { 124 RI.dump(); 125} 126#endif 127 128char MachineRegionInfoPass::ID = 0; 129char &MachineRegionInfoPassID = MachineRegionInfoPass::ID; 130 131INITIALIZE_PASS_BEGIN(MachineRegionInfoPass, DEBUG_TYPE, 132 "Detect single entry single exit regions", true, true) 133INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) 134INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTree) 135INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontier) 136INITIALIZE_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 143namespace llvm { 144 145FunctionPass *createMachineRegionInfoPass() { 146 return new MachineRegionInfoPass(); 147} 148 149} // end namespace llvm 150