xref: /netbsd-src/external/apache2/llvm/dist/llvm/lib/CodeGen/MachineLoopInfo.cpp (revision 7330f729ccf0bd976a06f95fad452fe774fc7fd1)
1*7330f729Sjoerg //===- MachineLoopInfo.cpp - Natural Loop Calculator ----------------------===//
2*7330f729Sjoerg //
3*7330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*7330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
5*7330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*7330f729Sjoerg //
7*7330f729Sjoerg //===----------------------------------------------------------------------===//
8*7330f729Sjoerg //
9*7330f729Sjoerg // This file defines the MachineLoopInfo class that is used to identify natural
10*7330f729Sjoerg // loops and determine the loop depth of various nodes of the CFG.  Note that
11*7330f729Sjoerg // the loops identified may actually be several natural loops that share the
12*7330f729Sjoerg // same header node... not just a single natural loop.
13*7330f729Sjoerg //
14*7330f729Sjoerg //===----------------------------------------------------------------------===//
15*7330f729Sjoerg 
16*7330f729Sjoerg #include "llvm/CodeGen/MachineLoopInfo.h"
17*7330f729Sjoerg #include "llvm/Analysis/LoopInfoImpl.h"
18*7330f729Sjoerg #include "llvm/CodeGen/MachineDominators.h"
19*7330f729Sjoerg #include "llvm/CodeGen/Passes.h"
20*7330f729Sjoerg #include "llvm/Config/llvm-config.h"
21*7330f729Sjoerg #include "llvm/Support/Debug.h"
22*7330f729Sjoerg #include "llvm/Support/raw_ostream.h"
23*7330f729Sjoerg using namespace llvm;
24*7330f729Sjoerg 
25*7330f729Sjoerg // Explicitly instantiate methods in LoopInfoImpl.h for MI-level Loops.
26*7330f729Sjoerg template class llvm::LoopBase<MachineBasicBlock, MachineLoop>;
27*7330f729Sjoerg template class llvm::LoopInfoBase<MachineBasicBlock, MachineLoop>;
28*7330f729Sjoerg 
29*7330f729Sjoerg char MachineLoopInfo::ID = 0;
30*7330f729Sjoerg INITIALIZE_PASS_BEGIN(MachineLoopInfo, "machine-loops",
31*7330f729Sjoerg                 "Machine Natural Loop Construction", true, true)
32*7330f729Sjoerg INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
33*7330f729Sjoerg INITIALIZE_PASS_END(MachineLoopInfo, "machine-loops",
34*7330f729Sjoerg                 "Machine Natural Loop Construction", true, true)
35*7330f729Sjoerg 
36*7330f729Sjoerg char &llvm::MachineLoopInfoID = MachineLoopInfo::ID;
37*7330f729Sjoerg 
38*7330f729Sjoerg bool MachineLoopInfo::runOnMachineFunction(MachineFunction &) {
39*7330f729Sjoerg   calculate(getAnalysis<MachineDominatorTree>());
40*7330f729Sjoerg   return false;
41*7330f729Sjoerg }
42*7330f729Sjoerg 
43*7330f729Sjoerg void MachineLoopInfo::calculate(MachineDominatorTree &MDT) {
44*7330f729Sjoerg   releaseMemory();
45*7330f729Sjoerg   LI.analyze(MDT.getBase());
46*7330f729Sjoerg }
47*7330f729Sjoerg 
48*7330f729Sjoerg void MachineLoopInfo::getAnalysisUsage(AnalysisUsage &AU) const {
49*7330f729Sjoerg   AU.setPreservesAll();
50*7330f729Sjoerg   AU.addRequired<MachineDominatorTree>();
51*7330f729Sjoerg   MachineFunctionPass::getAnalysisUsage(AU);
52*7330f729Sjoerg }
53*7330f729Sjoerg 
54*7330f729Sjoerg MachineBasicBlock *MachineLoop::getTopBlock() {
55*7330f729Sjoerg   MachineBasicBlock *TopMBB = getHeader();
56*7330f729Sjoerg   MachineFunction::iterator Begin = TopMBB->getParent()->begin();
57*7330f729Sjoerg   if (TopMBB->getIterator() != Begin) {
58*7330f729Sjoerg     MachineBasicBlock *PriorMBB = &*std::prev(TopMBB->getIterator());
59*7330f729Sjoerg     while (contains(PriorMBB)) {
60*7330f729Sjoerg       TopMBB = PriorMBB;
61*7330f729Sjoerg       if (TopMBB->getIterator() == Begin)
62*7330f729Sjoerg         break;
63*7330f729Sjoerg       PriorMBB = &*std::prev(TopMBB->getIterator());
64*7330f729Sjoerg     }
65*7330f729Sjoerg   }
66*7330f729Sjoerg   return TopMBB;
67*7330f729Sjoerg }
68*7330f729Sjoerg 
69*7330f729Sjoerg MachineBasicBlock *MachineLoop::getBottomBlock() {
70*7330f729Sjoerg   MachineBasicBlock *BotMBB = getHeader();
71*7330f729Sjoerg   MachineFunction::iterator End = BotMBB->getParent()->end();
72*7330f729Sjoerg   if (BotMBB->getIterator() != std::prev(End)) {
73*7330f729Sjoerg     MachineBasicBlock *NextMBB = &*std::next(BotMBB->getIterator());
74*7330f729Sjoerg     while (contains(NextMBB)) {
75*7330f729Sjoerg       BotMBB = NextMBB;
76*7330f729Sjoerg       if (BotMBB == &*std::next(BotMBB->getIterator()))
77*7330f729Sjoerg         break;
78*7330f729Sjoerg       NextMBB = &*std::next(BotMBB->getIterator());
79*7330f729Sjoerg     }
80*7330f729Sjoerg   }
81*7330f729Sjoerg   return BotMBB;
82*7330f729Sjoerg }
83*7330f729Sjoerg 
84*7330f729Sjoerg MachineBasicBlock *MachineLoop::findLoopControlBlock() {
85*7330f729Sjoerg   if (MachineBasicBlock *Latch = getLoopLatch()) {
86*7330f729Sjoerg     if (isLoopExiting(Latch))
87*7330f729Sjoerg       return Latch;
88*7330f729Sjoerg     else
89*7330f729Sjoerg       return getExitingBlock();
90*7330f729Sjoerg   }
91*7330f729Sjoerg   return nullptr;
92*7330f729Sjoerg }
93*7330f729Sjoerg 
94*7330f729Sjoerg DebugLoc MachineLoop::getStartLoc() const {
95*7330f729Sjoerg   // Try the pre-header first.
96*7330f729Sjoerg   if (MachineBasicBlock *PHeadMBB = getLoopPreheader())
97*7330f729Sjoerg     if (const BasicBlock *PHeadBB = PHeadMBB->getBasicBlock())
98*7330f729Sjoerg       if (DebugLoc DL = PHeadBB->getTerminator()->getDebugLoc())
99*7330f729Sjoerg         return DL;
100*7330f729Sjoerg 
101*7330f729Sjoerg   // If we have no pre-header or there are no instructions with debug
102*7330f729Sjoerg   // info in it, try the header.
103*7330f729Sjoerg   if (MachineBasicBlock *HeadMBB = getHeader())
104*7330f729Sjoerg     if (const BasicBlock *HeadBB = HeadMBB->getBasicBlock())
105*7330f729Sjoerg       return HeadBB->getTerminator()->getDebugLoc();
106*7330f729Sjoerg 
107*7330f729Sjoerg   return DebugLoc();
108*7330f729Sjoerg }
109*7330f729Sjoerg 
110*7330f729Sjoerg MachineBasicBlock *
111*7330f729Sjoerg MachineLoopInfo::findLoopPreheader(MachineLoop *L,
112*7330f729Sjoerg                                    bool SpeculativePreheader) const {
113*7330f729Sjoerg   if (MachineBasicBlock *PB = L->getLoopPreheader())
114*7330f729Sjoerg     return PB;
115*7330f729Sjoerg 
116*7330f729Sjoerg   if (!SpeculativePreheader)
117*7330f729Sjoerg     return nullptr;
118*7330f729Sjoerg 
119*7330f729Sjoerg   MachineBasicBlock *HB = L->getHeader(), *LB = L->getLoopLatch();
120*7330f729Sjoerg   if (HB->pred_size() != 2 || HB->hasAddressTaken())
121*7330f729Sjoerg     return nullptr;
122*7330f729Sjoerg   // Find the predecessor of the header that is not the latch block.
123*7330f729Sjoerg   MachineBasicBlock *Preheader = nullptr;
124*7330f729Sjoerg   for (MachineBasicBlock *P : HB->predecessors()) {
125*7330f729Sjoerg     if (P == LB)
126*7330f729Sjoerg       continue;
127*7330f729Sjoerg     // Sanity.
128*7330f729Sjoerg     if (Preheader)
129*7330f729Sjoerg       return nullptr;
130*7330f729Sjoerg     Preheader = P;
131*7330f729Sjoerg   }
132*7330f729Sjoerg 
133*7330f729Sjoerg   // Check if the preheader candidate is a successor of any other loop
134*7330f729Sjoerg   // headers. We want to avoid having two loop setups in the same block.
135*7330f729Sjoerg   for (MachineBasicBlock *S : Preheader->successors()) {
136*7330f729Sjoerg     if (S == HB)
137*7330f729Sjoerg       continue;
138*7330f729Sjoerg     MachineLoop *T = getLoopFor(S);
139*7330f729Sjoerg     if (T && T->getHeader() == S)
140*7330f729Sjoerg       return nullptr;
141*7330f729Sjoerg   }
142*7330f729Sjoerg   return Preheader;
143*7330f729Sjoerg }
144*7330f729Sjoerg 
145*7330f729Sjoerg #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
146*7330f729Sjoerg LLVM_DUMP_METHOD void MachineLoop::dump() const {
147*7330f729Sjoerg   print(dbgs());
148*7330f729Sjoerg }
149*7330f729Sjoerg #endif
150