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
21using namespace llvm;
22
23STATISTIC(numMachineRegions, "The # of machine regions");
24STATISTIC(numMachineSimpleRegions, "The # of simple machine regions");
25
26namespace llvm {
27
28template class RegionBase<RegionTraits<MachineFunction>>;
29template class RegionNodeBase<RegionTraits<MachineFunction>>;
30template class RegionInfoBase<RegionTraits<MachineFunction>>;
31
32} // end namespace llvm
33
34//===----------------------------------------------------------------------===//
35// MachineRegion implementation
36
37MachineRegion::MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit,
38 MachineRegionInfo* RI,
39 MachineDominatorTree *DT, MachineRegion *Parent) :
40 RegionBase<RegionTraits<MachineFunction>>(Entry, Exit, RI, DT, Parent) {}
41
42MachineRegion::~MachineRegion() = default;
43
44//===----------------------------------------------------------------------===//
45// MachineRegionInfo implementation
46
47MachineRegionInfo::MachineRegionInfo() = default;
48
49MachineRegionInfo::~MachineRegionInfo() = default;
50
51void 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
59void 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
78MachineRegionInfoPass::MachineRegionInfoPass() : MachineFunctionPass(ID) {
79 initializeMachineRegionInfoPassPass(*PassRegistry::getPassRegistry());
80}
81
82MachineRegionInfoPass::~MachineRegionInfoPass() = default;
83
84bool 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
99void MachineRegionInfoPass::releaseMemory() {
100 RI.releaseMemory();
101}
102
103void 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
111void 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
119void MachineRegionInfoPass::print(raw_ostream &OS, const Module *) const {
120 RI.print(OS);
121}
122
123#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
124LLVM_DUMP_METHOD void MachineRegionInfoPass::dump() const {
125 RI.dump();
126}
127#endif
128
129char MachineRegionInfoPass::ID = 0;
130char &MachineRegionInfoPassID = MachineRegionInfoPass::ID;
131
132INITIALIZE_PASS_BEGIN(MachineRegionInfoPass, DEBUG_TYPE,
133 "Detect single entry single exit regions", true, true)
134INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
135INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTreeWrapperPass)
136INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontier)
137INITIALIZE_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
144namespace llvm {
145
146FunctionPass *createMachineRegionInfoPass() {
147 return new MachineRegionInfoPass();
148}
149
150} // end namespace llvm
151