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