xref: /freebsd/contrib/llvm-project/llvm/lib/CodeGen/MachineRegionInfo.cpp (revision 37f1f2684f2670b204080ef2d6c303becd28545f)
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