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::recalculate(MachineFunction &F,
53                                     MachineDominatorTree *DT_,
54                                     MachinePostDominatorTree *PDT_,
55                                     MachineDominanceFrontier *DF_) {
56   DT = DT_;
57   PDT = PDT_;
58   DF = DF_;
59 
60   MachineBasicBlock *Entry = GraphTraits<MachineFunction*>::getEntryNode(&F);
61 
62   TopLevelRegion = new MachineRegion(Entry, nullptr, this, DT, nullptr);
63   updateStatistics(TopLevelRegion);
64   calculate(F);
65 }
66 
67 //===----------------------------------------------------------------------===//
68 // MachineRegionInfoPass implementation
69 //
70 
71 MachineRegionInfoPass::MachineRegionInfoPass() : MachineFunctionPass(ID) {
72   initializeMachineRegionInfoPassPass(*PassRegistry::getPassRegistry());
73 }
74 
75 MachineRegionInfoPass::~MachineRegionInfoPass() {
76 
77 }
78 
79 bool MachineRegionInfoPass::runOnMachineFunction(MachineFunction &F) {
80   releaseMemory();
81 
82   auto DT = &getAnalysis<MachineDominatorTree>();
83   auto PDT = &getAnalysis<MachinePostDominatorTree>();
84   auto DF = &getAnalysis<MachineDominanceFrontier>();
85 
86   RI.recalculate(F, DT, PDT, DF);
87   return false;
88 }
89 
90 void MachineRegionInfoPass::releaseMemory() {
91   RI.releaseMemory();
92 }
93 
94 void MachineRegionInfoPass::verifyAnalysis() const {
95   // Only do verification when user wants to, otherwise this expensive check
96   // will be invoked by PMDataManager::verifyPreservedAnalysis when
97   // a regionpass (marked PreservedAll) finish.
98   if (MachineRegionInfo::VerifyRegionInfo)
99     RI.verifyAnalysis();
100 }
101 
102 void MachineRegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const {
103   AU.setPreservesAll();
104   AU.addRequiredTransitive<DominatorTreeWrapperPass>();
105   AU.addRequired<PostDominatorTree>();
106   AU.addRequired<DominanceFrontier>();
107 }
108 
109 void MachineRegionInfoPass::print(raw_ostream &OS, const Module *) const {
110   RI.print(OS);
111 }
112 
113 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
114 void MachineRegionInfoPass::dump() const {
115   RI.dump();
116 }
117 #endif
118 
119 char MachineRegionInfoPass::ID = 0;
120 
121 INITIALIZE_PASS_BEGIN(MachineRegionInfoPass, "regions",
122                 "Detect single entry single exit regions", true, true)
123 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
124 INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTree)
125 INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontier)
126 INITIALIZE_PASS_END(MachineRegionInfoPass, "regions",
127                 "Detect single entry single exit regions", true, true)
128 
129 // Create methods available outside of this file, to use them
130 // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
131 // the link time optimization.
132 
133 namespace llvm {
134   FunctionPass *createMachineRegionInfoPass() {
135     return new MachineRegionInfoPass();
136   }
137 }
138 
139