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