1*0b57cec5SDimitry Andric //===- lib/Codegen/MachineRegionInfo.cpp ----------------------------------===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric
9*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegionInfo.h"
10*0b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
11*0b57cec5SDimitry Andric #include "llvm/Analysis/RegionInfoImpl.h"
12*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachinePostDominators.h"
13*0b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
14*0b57cec5SDimitry Andric #include "llvm/InitializePasses.h"
15*0b57cec5SDimitry Andric #include "llvm/Pass.h"
16*0b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
17*0b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
18*0b57cec5SDimitry Andric
19*0b57cec5SDimitry Andric #define DEBUG_TYPE "machine-region-info"
20*0b57cec5SDimitry Andric
21*0b57cec5SDimitry Andric using namespace llvm;
22*0b57cec5SDimitry Andric
23*0b57cec5SDimitry Andric STATISTIC(numMachineRegions, "The # of machine regions");
24*0b57cec5SDimitry Andric STATISTIC(numMachineSimpleRegions, "The # of simple machine regions");
25*0b57cec5SDimitry Andric
26*0b57cec5SDimitry Andric namespace llvm {
27*0b57cec5SDimitry Andric
28*0b57cec5SDimitry Andric template class RegionBase<RegionTraits<MachineFunction>>;
29*0b57cec5SDimitry Andric template class RegionNodeBase<RegionTraits<MachineFunction>>;
30*0b57cec5SDimitry Andric template class RegionInfoBase<RegionTraits<MachineFunction>>;
31*0b57cec5SDimitry Andric
32*0b57cec5SDimitry Andric } // end namespace llvm
33*0b57cec5SDimitry Andric
34*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
35*0b57cec5SDimitry Andric // MachineRegion implementation
36*0b57cec5SDimitry Andric
MachineRegion(MachineBasicBlock * Entry,MachineBasicBlock * Exit,MachineRegionInfo * RI,MachineDominatorTree * DT,MachineRegion * Parent)37*0b57cec5SDimitry Andric MachineRegion::MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit,
38*0b57cec5SDimitry Andric MachineRegionInfo* RI,
39*0b57cec5SDimitry Andric MachineDominatorTree *DT, MachineRegion *Parent) :
40*0b57cec5SDimitry Andric RegionBase<RegionTraits<MachineFunction>>(Entry, Exit, RI, DT, Parent) {}
41*0b57cec5SDimitry Andric
42*0b57cec5SDimitry Andric MachineRegion::~MachineRegion() = default;
43*0b57cec5SDimitry Andric
44*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
45*0b57cec5SDimitry Andric // MachineRegionInfo implementation
46*0b57cec5SDimitry Andric
47*0b57cec5SDimitry Andric MachineRegionInfo::MachineRegionInfo() = default;
48*0b57cec5SDimitry Andric
49*0b57cec5SDimitry Andric MachineRegionInfo::~MachineRegionInfo() = default;
50*0b57cec5SDimitry Andric
updateStatistics(MachineRegion * R)51*0b57cec5SDimitry Andric void MachineRegionInfo::updateStatistics(MachineRegion *R) {
52*0b57cec5SDimitry Andric ++numMachineRegions;
53*0b57cec5SDimitry Andric
54*0b57cec5SDimitry Andric // TODO: Slow. Should only be enabled if -stats is used.
55*0b57cec5SDimitry Andric if (R->isSimple())
56*0b57cec5SDimitry Andric ++numMachineSimpleRegions;
57*0b57cec5SDimitry Andric }
58*0b57cec5SDimitry Andric
recalculate(MachineFunction & F,MachineDominatorTree * DT_,MachinePostDominatorTree * PDT_,MachineDominanceFrontier * DF_)59*0b57cec5SDimitry Andric void MachineRegionInfo::recalculate(MachineFunction &F,
60*0b57cec5SDimitry Andric MachineDominatorTree *DT_,
61*0b57cec5SDimitry Andric MachinePostDominatorTree *PDT_,
62*0b57cec5SDimitry Andric MachineDominanceFrontier *DF_) {
63*0b57cec5SDimitry Andric DT = DT_;
64*0b57cec5SDimitry Andric PDT = PDT_;
65*0b57cec5SDimitry Andric DF = DF_;
66*0b57cec5SDimitry Andric
67*0b57cec5SDimitry Andric MachineBasicBlock *Entry = GraphTraits<MachineFunction*>::getEntryNode(&F);
68*0b57cec5SDimitry Andric
69*0b57cec5SDimitry Andric TopLevelRegion = new MachineRegion(Entry, nullptr, this, DT, nullptr);
70*0b57cec5SDimitry Andric updateStatistics(TopLevelRegion);
71*0b57cec5SDimitry Andric calculate(F);
72*0b57cec5SDimitry Andric }
73*0b57cec5SDimitry Andric
74*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
75*0b57cec5SDimitry Andric // MachineRegionInfoPass implementation
76*0b57cec5SDimitry Andric //
77*0b57cec5SDimitry Andric
MachineRegionInfoPass()78*0b57cec5SDimitry Andric MachineRegionInfoPass::MachineRegionInfoPass() : MachineFunctionPass(ID) {
79*0b57cec5SDimitry Andric initializeMachineRegionInfoPassPass(*PassRegistry::getPassRegistry());
80*0b57cec5SDimitry Andric }
81*0b57cec5SDimitry Andric
82*0b57cec5SDimitry Andric MachineRegionInfoPass::~MachineRegionInfoPass() = default;
83*0b57cec5SDimitry Andric
runOnMachineFunction(MachineFunction & F)84*0b57cec5SDimitry Andric bool MachineRegionInfoPass::runOnMachineFunction(MachineFunction &F) {
85*0b57cec5SDimitry Andric releaseMemory();
86*0b57cec5SDimitry Andric
87*0b57cec5SDimitry Andric auto DT = &getAnalysis<MachineDominatorTree>();
88*0b57cec5SDimitry Andric auto PDT = &getAnalysis<MachinePostDominatorTree>();
89*0b57cec5SDimitry Andric auto DF = &getAnalysis<MachineDominanceFrontier>();
90*0b57cec5SDimitry Andric
91*0b57cec5SDimitry Andric RI.recalculate(F, DT, PDT, DF);
92*0b57cec5SDimitry Andric
93*0b57cec5SDimitry Andric LLVM_DEBUG(RI.dump());
94*0b57cec5SDimitry Andric
95*0b57cec5SDimitry Andric return false;
96*0b57cec5SDimitry Andric }
97*0b57cec5SDimitry Andric
releaseMemory()98*0b57cec5SDimitry Andric void MachineRegionInfoPass::releaseMemory() {
99*0b57cec5SDimitry Andric RI.releaseMemory();
100*0b57cec5SDimitry Andric }
101*0b57cec5SDimitry Andric
verifyAnalysis() const102*0b57cec5SDimitry Andric void MachineRegionInfoPass::verifyAnalysis() const {
103*0b57cec5SDimitry Andric // Only do verification when user wants to, otherwise this expensive check
104*0b57cec5SDimitry Andric // will be invoked by PMDataManager::verifyPreservedAnalysis when
105*0b57cec5SDimitry Andric // a regionpass (marked PreservedAll) finish.
106*0b57cec5SDimitry Andric if (MachineRegionInfo::VerifyRegionInfo)
107*0b57cec5SDimitry Andric RI.verifyAnalysis();
108*0b57cec5SDimitry Andric }
109*0b57cec5SDimitry Andric
getAnalysisUsage(AnalysisUsage & AU) const110*0b57cec5SDimitry Andric void MachineRegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const {
111*0b57cec5SDimitry Andric AU.setPreservesAll();
112*0b57cec5SDimitry Andric AU.addRequired<MachineDominatorTree>();
113*0b57cec5SDimitry Andric AU.addRequired<MachinePostDominatorTree>();
114*0b57cec5SDimitry Andric AU.addRequired<MachineDominanceFrontier>();
115*0b57cec5SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU);
116*0b57cec5SDimitry Andric }
117*0b57cec5SDimitry Andric
print(raw_ostream & OS,const Module *) const118*0b57cec5SDimitry Andric void MachineRegionInfoPass::print(raw_ostream &OS, const Module *) const {
119*0b57cec5SDimitry Andric RI.print(OS);
120*0b57cec5SDimitry Andric }
121*0b57cec5SDimitry Andric
122*0b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const123*0b57cec5SDimitry Andric LLVM_DUMP_METHOD void MachineRegionInfoPass::dump() const {
124*0b57cec5SDimitry Andric RI.dump();
125*0b57cec5SDimitry Andric }
126*0b57cec5SDimitry Andric #endif
127*0b57cec5SDimitry Andric
128*0b57cec5SDimitry Andric char MachineRegionInfoPass::ID = 0;
129*0b57cec5SDimitry Andric char &MachineRegionInfoPassID = MachineRegionInfoPass::ID;
130*0b57cec5SDimitry Andric
131*0b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(MachineRegionInfoPass, DEBUG_TYPE,
132*0b57cec5SDimitry Andric "Detect single entry single exit regions", true, true)
133*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
134*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTree)
135*0b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontier)
136*0b57cec5SDimitry Andric INITIALIZE_PASS_END(MachineRegionInfoPass, DEBUG_TYPE,
137*0b57cec5SDimitry Andric "Detect single entry single exit regions", true, true)
138*0b57cec5SDimitry Andric
139*0b57cec5SDimitry Andric // Create methods available outside of this file, to use them
140*0b57cec5SDimitry Andric // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
141*0b57cec5SDimitry Andric // the link time optimization.
142*0b57cec5SDimitry Andric
143*0b57cec5SDimitry Andric namespace llvm {
144*0b57cec5SDimitry Andric
createMachineRegionInfoPass()145*0b57cec5SDimitry Andric FunctionPass *createMachineRegionInfoPass() {
146*0b57cec5SDimitry Andric return new MachineRegionInfoPass();
147*0b57cec5SDimitry Andric }
148*0b57cec5SDimitry Andric
149 } // end namespace llvm
150