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