xref: /llvm-project/llvm/lib/CodeGen/MachineRegionInfo.cpp (revision 431305927f21c3db7bf687175fad4883ed672492)
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 "machine-region-info"
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 
90   DEBUG(RI.dump());
91 
92   return false;
93 }
94 
95 void MachineRegionInfoPass::releaseMemory() {
96   RI.releaseMemory();
97 }
98 
99 void MachineRegionInfoPass::verifyAnalysis() const {
100   // Only do verification when user wants to, otherwise this expensive check
101   // will be invoked by PMDataManager::verifyPreservedAnalysis when
102   // a regionpass (marked PreservedAll) finish.
103   if (MachineRegionInfo::VerifyRegionInfo)
104     RI.verifyAnalysis();
105 }
106 
107 void MachineRegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const {
108   AU.setPreservesAll();
109   AU.addRequired<MachineDominatorTree>();
110   AU.addRequired<MachinePostDominatorTree>();
111   AU.addRequired<MachineDominanceFrontier>();
112   MachineFunctionPass::getAnalysisUsage(AU);
113 }
114 
115 void MachineRegionInfoPass::print(raw_ostream &OS, const Module *) const {
116   RI.print(OS);
117 }
118 
119 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
120 LLVM_DUMP_METHOD void MachineRegionInfoPass::dump() const {
121   RI.dump();
122 }
123 #endif
124 
125 char MachineRegionInfoPass::ID = 0;
126 
127 INITIALIZE_PASS_BEGIN(MachineRegionInfoPass, DEBUG_TYPE,
128                       "Detect single entry single exit regions", true, true)
129 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
130 INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTree)
131 INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontier)
132 INITIALIZE_PASS_END(MachineRegionInfoPass, DEBUG_TYPE,
133                     "Detect single entry single exit regions", true, true)
134 
135 // Create methods available outside of this file, to use them
136 // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
137 // the link time optimization.
138 
139 namespace llvm {
140   FunctionPass *createMachineRegionInfoPass() {
141     return new MachineRegionInfoPass();
142   }
143 }
144 
145