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
MachineRegion(MachineBasicBlock * Entry,MachineBasicBlock * Exit,MachineRegionInfo * RI,MachineDominatorTree * DT,MachineRegion * Parent)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
~MachineRegion()31 MachineRegion::~MachineRegion() { }
32
33 //===----------------------------------------------------------------------===//
34 // MachineRegionInfo implementation
35 //
36
MachineRegionInfo()37 MachineRegionInfo::MachineRegionInfo() :
38 RegionInfoBase<RegionTraits<MachineFunction>>() {
39
40 }
41
~MachineRegionInfo()42 MachineRegionInfo::~MachineRegionInfo() {
43
44 }
45
updateStatistics(MachineRegion * R)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
recalculate(MachineFunction & F,MachineDominatorTree * DT_,MachinePostDominatorTree * PDT_,MachineDominanceFrontier * DF_)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
MachineRegionInfoPass()73 MachineRegionInfoPass::MachineRegionInfoPass() : MachineFunctionPass(ID) {
74 initializeMachineRegionInfoPassPass(*PassRegistry::getPassRegistry());
75 }
76
~MachineRegionInfoPass()77 MachineRegionInfoPass::~MachineRegionInfoPass() {
78
79 }
80
runOnMachineFunction(MachineFunction & F)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
releaseMemory()92 void MachineRegionInfoPass::releaseMemory() {
93 RI.releaseMemory();
94 }
95
verifyAnalysis() const96 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
getAnalysisUsage(AnalysisUsage & AU) const104 void MachineRegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const {
105 AU.setPreservesAll();
106 AU.addRequiredTransitive<DominatorTreeWrapperPass>();
107 AU.addRequired<PostDominatorTree>();
108 AU.addRequired<DominanceFrontier>();
109 }
110
print(raw_ostream & OS,const Module *) const111 void MachineRegionInfoPass::print(raw_ostream &OS, const Module *) const {
112 RI.print(OS);
113 }
114
115 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const116 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 {
createMachineRegionInfoPass()136 FunctionPass *createMachineRegionInfoPass() {
137 return new MachineRegionInfoPass();
138 }
139 }
140
141