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/CodeGen/Passes.h"
14#include "llvm/Config/llvm-config.h"
15#include "llvm/InitializePasses.h"
16#include "llvm/Pass.h"
17#include "llvm/Support/Compiler.h"
18#include "llvm/Support/Debug.h"
19
20#define DEBUG_TYPE "machine-region-info"
21
22using namespace llvm;
23
24STATISTIC(numMachineRegions, "The # of machine regions");
25STATISTIC(numMachineSimpleRegions, "The # of simple machine regions");
26
27namespace llvm {
28
29template class LLVM_EXPORT_TEMPLATE RegionBase<RegionTraits<MachineFunction>>;
30template class LLVM_EXPORT_TEMPLATE
31 RegionNodeBase<RegionTraits<MachineFunction>>;
32template class LLVM_EXPORT_TEMPLATE
33 RegionInfoBase<RegionTraits<MachineFunction>>;
34
35} // end namespace llvm
36
37//===----------------------------------------------------------------------===//
38// RegionTraits<MachineFunction> implementation
39//
40
41void RegionTraits<MachineFunction>::updateStatistics(MachineRegion *R) {
42 ++numMachineRegions;
43
44 // TODO: Slow. Should only be enabled if -stats is used.
45 if (R->isSimple())
46 ++numMachineSimpleRegions;
47}
48
49//===----------------------------------------------------------------------===//
50// MachineRegion implementation
51
52MachineRegion::MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit,
53 MachineRegionInfo* RI,
54 MachineDominatorTree *DT, MachineRegion *Parent) :
55 RegionBase<RegionTraits<MachineFunction>>(Entry, Exit, RI, DT, Parent) {}
56
57MachineRegion::~MachineRegion() = default;
58
59//===----------------------------------------------------------------------===//
60// MachineRegionInfo implementation
61
62MachineRegionInfo::MachineRegionInfo() = default;
63
64MachineRegionInfo::~MachineRegionInfo() = default;
65
66void MachineRegionInfo::recalculate(MachineFunction &F,
67 MachineDominatorTree *DT_,
68 MachinePostDominatorTree *PDT_,
69 MachineDominanceFrontier *DF_) {
70 DT = DT_;
71 PDT = PDT_;
72 DF = DF_;
73
74 MachineBasicBlock *Entry = GraphTraits<MachineFunction*>::getEntryNode(F: &F);
75
76 TopLevelRegion = new MachineRegion(Entry, nullptr, this, DT, nullptr);
77 RegionTraits<MachineFunction>::updateStatistics(R: TopLevelRegion);
78 calculate(F);
79}
80
81bool MachineRegionInfo::invalidate(
82 MachineFunction &F, const PreservedAnalyses &PA,
83 MachineFunctionAnalysisManager::Invalidator &) {
84 // Check whether the analysis, all analyses on functions, or the function's
85 // CFG has been preserved.
86 auto PAC = PA.getChecker<MachineRegionInfoAnalysis>();
87 return !(PAC.preserved() ||
88 PAC.preservedSet<AllAnalysesOn<MachineFunction>>() ||
89 PAC.preservedSet<CFGAnalyses>());
90}
91
92//===----------------------------------------------------------------------===//
93// MachineRegionAnalysis implementation
94//
95AnalysisKey MachineRegionInfoAnalysis::Key;
96MachineRegionInfo
97MachineRegionInfoAnalysis::run(MachineFunction &MF,
98 MachineFunctionAnalysisManager &MFAM) {
99 MachineRegionInfo MRI;
100 MRI.recalculate(F&: MF, DT_: &MFAM.getResult<MachineDominatorTreeAnalysis>(IR&: MF),
101 PDT_: &MFAM.getResult<MachinePostDominatorTreeAnalysis>(IR&: MF),
102 DF_: &MFAM.getResult<MachineDominanceFrontierAnalysis>(IR&: MF));
103 return MRI;
104}
105
106PreservedAnalyses
107MachineRegionInfoPrinterPass::run(MachineFunction &MF,
108 MachineFunctionAnalysisManager &MFAM) {
109 MachineRegionInfo &MRI = MFAM.getResult<MachineRegionInfoAnalysis>(IR&: MF);
110 MRI.print(OS);
111 return PreservedAnalyses::all();
112}
113
114//===----------------------------------------------------------------------===//
115// MachineRegionInfoPass implementation
116//
117
118MachineRegionInfoPass::MachineRegionInfoPass() : MachineFunctionPass(ID) {}
119
120MachineRegionInfoPass::~MachineRegionInfoPass() = default;
121
122bool MachineRegionInfoPass::runOnMachineFunction(MachineFunction &F) {
123 releaseMemory();
124
125 auto DT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
126 auto PDT =
127 &getAnalysis<MachinePostDominatorTreeWrapperPass>().getPostDomTree();
128 auto DF = &getAnalysis<MachineDominanceFrontierWrapperPass>().getMDF();
129
130 RI.recalculate(F, DT_: DT, PDT_: PDT, DF_: DF);
131
132 LLVM_DEBUG(RI.dump());
133
134 return false;
135}
136
137void MachineRegionInfoPass::releaseMemory() {
138 RI.releaseMemory();
139}
140
141void MachineRegionInfoPass::verifyAnalysis() const {
142 // Only do verification when user wants to, otherwise this expensive check
143 // will be invoked by PMDataManager::verifyPreservedAnalysis when
144 // a regionpass (marked PreservedAll) finish.
145 if (MachineRegionInfo::VerifyRegionInfo)
146 RI.verifyAnalysis();
147}
148
149void MachineRegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const {
150 AU.setPreservesAll();
151 AU.addRequired<MachineDominatorTreeWrapperPass>();
152 AU.addRequired<MachinePostDominatorTreeWrapperPass>();
153 AU.addRequired<MachineDominanceFrontierWrapperPass>();
154 MachineFunctionPass::getAnalysisUsage(AU);
155}
156
157void MachineRegionInfoPass::print(raw_ostream &OS, const Module *) const {
158 RI.print(OS);
159}
160
161#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
162LLVM_DUMP_METHOD void MachineRegionInfoPass::dump() const {
163 RI.dump();
164}
165#endif
166
167char MachineRegionInfoPass::ID = 0;
168char &llvm::MachineRegionInfoPassID = MachineRegionInfoPass::ID;
169
170INITIALIZE_PASS_BEGIN(MachineRegionInfoPass, DEBUG_TYPE,
171 "Detect single entry single exit regions", true, true)
172INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
173INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTreeWrapperPass)
174INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontierWrapperPass)
175INITIALIZE_PASS_END(MachineRegionInfoPass, DEBUG_TYPE,
176 "Detect single entry single exit regions", true, true)
177
178// Create methods available outside of this file, to use them
179// "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
180// the link time optimization.
181
182namespace llvm {
183
184FunctionPass *createMachineRegionInfoPass() {
185 return new MachineRegionInfoPass();
186}
187
188} // end namespace llvm
189