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