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
MachineRegion(MachineBasicBlock * Entry,MachineBasicBlock * Exit,MachineRegionInfo * RI,MachineDominatorTree * DT,MachineRegion * Parent)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
updateStatistics(MachineRegion * R)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
recalculate(MachineFunction & F,MachineDominatorTree * DT_,MachinePostDominatorTree * PDT_,MachineDominanceFrontier * DF_)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
MachineRegionInfoPass()78 MachineRegionInfoPass::MachineRegionInfoPass() : MachineFunctionPass(ID) {
79 initializeMachineRegionInfoPassPass(*PassRegistry::getPassRegistry());
80 }
81
82 MachineRegionInfoPass::~MachineRegionInfoPass() = default;
83
runOnMachineFunction(MachineFunction & F)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
releaseMemory()98 void MachineRegionInfoPass::releaseMemory() {
99 RI.releaseMemory();
100 }
101
verifyAnalysis() const102 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
getAnalysisUsage(AnalysisUsage & AU) const110 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
print(raw_ostream & OS,const Module *) const118 void MachineRegionInfoPass::print(raw_ostream &OS, const Module *) const {
119 RI.print(OS);
120 }
121
122 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const123 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
createMachineRegionInfoPass()145 FunctionPass *createMachineRegionInfoPass() {
146 return new MachineRegionInfoPass();
147 }
148
149 } // end namespace llvm
150