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
75//===----------------------------------------------------------------------===//
76// MachineRegionInfoPass implementation
77//
78
79MachineRegionInfoPass::MachineRegionInfoPass() : MachineFunctionPass(ID) {}
80
81MachineRegionInfoPass::~MachineRegionInfoPass() = default;
82
83bool MachineRegionInfoPass::runOnMachineFunction(MachineFunction &F) {
84 releaseMemory();
85
86 auto DT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
87 auto PDT =
88 &getAnalysis<MachinePostDominatorTreeWrapperPass>().getPostDomTree();
89 auto DF = &getAnalysis<MachineDominanceFrontierWrapperPass>().getMDF();
90
91 RI.recalculate(F, DT_: DT, PDT_: PDT, DF_: DF);
92
93 LLVM_DEBUG(RI.dump());
94
95 return false;
96}
97
98void MachineRegionInfoPass::releaseMemory() {
99 RI.releaseMemory();
100}
101
102void MachineRegionInfoPass::verifyAnalysis() const {
103 // Only do verification when user wants to, otherwise this expensive check
104 // will be invoked by PMDataManager::verifyPreservedAnalysis when
105 // a regionpass (marked PreservedAll) finish.
106 if (MachineRegionInfo::VerifyRegionInfo)
107 RI.verifyAnalysis();
108}
109
110void MachineRegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const {
111 AU.setPreservesAll();
112 AU.addRequired<MachineDominatorTreeWrapperPass>();
113 AU.addRequired<MachinePostDominatorTreeWrapperPass>();
114 AU.addRequired<MachineDominanceFrontierWrapperPass>();
115 MachineFunctionPass::getAnalysisUsage(AU);
116}
117
118void MachineRegionInfoPass::print(raw_ostream &OS, const Module *) const {
119 RI.print(OS);
120}
121
122#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
123LLVM_DUMP_METHOD void MachineRegionInfoPass::dump() const {
124 RI.dump();
125}
126#endif
127
128char MachineRegionInfoPass::ID = 0;
129char &llvm::MachineRegionInfoPassID = MachineRegionInfoPass::ID;
130
131INITIALIZE_PASS_BEGIN(MachineRegionInfoPass, DEBUG_TYPE,
132 "Detect single entry single exit regions", true, true)
133INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
134INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTreeWrapperPass)
135INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontierWrapperPass)
136INITIALIZE_PASS_END(MachineRegionInfoPass, DEBUG_TYPE,
137 "Detect single entry single exit regions", true, true)
138
139// Create methods available outside of this file, to use them
140// "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
141// the link time optimization.
142
143namespace llvm {
144
145FunctionPass *createMachineRegionInfoPass() {
146 return new MachineRegionInfoPass();
147}
148
149} // end namespace llvm
150