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