xref: /freebsd/contrib/llvm-project/llvm/lib/CodeGen/MachineRegionInfo.cpp (revision b64c5a0ace59af62eff52bfe110a521dc73c937b)
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);
68 
69   TopLevelRegion = new MachineRegion(Entry, nullptr, this, DT, nullptr);
70   updateStatistics(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, PDT, 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