1f22ef01cSRoman Divacky //===- MachineLoopInfo.cpp - Natural Loop Calculator ----------------------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky //                     The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // This file defines the MachineLoopInfo class that is used to identify natural
11f22ef01cSRoman Divacky // loops and determine the loop depth of various nodes of the CFG.  Note that
12f22ef01cSRoman Divacky // the loops identified may actually be several natural loops that share the
13f22ef01cSRoman Divacky // same header node... not just a single natural loop.
14f22ef01cSRoman Divacky //
15f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
16f22ef01cSRoman Divacky 
17f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineLoopInfo.h"
18139f7f9bSDimitry Andric #include "llvm/Analysis/LoopInfoImpl.h"
19f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineDominators.h"
20f22ef01cSRoman Divacky #include "llvm/CodeGen/Passes.h"
21*4ba319b5SDimitry Andric #include "llvm/Config/llvm-config.h"
22f22ef01cSRoman Divacky #include "llvm/Support/Debug.h"
23ff0cc061SDimitry Andric #include "llvm/Support/raw_ostream.h"
24f22ef01cSRoman Divacky using namespace llvm;
25f22ef01cSRoman Divacky 
267ae0e2c9SDimitry Andric // Explicitly instantiate methods in LoopInfoImpl.h for MI-level Loops.
277ae0e2c9SDimitry Andric template class llvm::LoopBase<MachineBasicBlock, MachineLoop>;
287ae0e2c9SDimitry Andric template class llvm::LoopInfoBase<MachineBasicBlock, MachineLoop>;
29f22ef01cSRoman Divacky 
30f22ef01cSRoman Divacky char MachineLoopInfo::ID = 0;
312754fe60SDimitry Andric INITIALIZE_PASS_BEGIN(MachineLoopInfo, "machine-loops",
322754fe60SDimitry Andric                 "Machine Natural Loop Construction", true, true)
332754fe60SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
342754fe60SDimitry Andric INITIALIZE_PASS_END(MachineLoopInfo, "machine-loops",
352754fe60SDimitry Andric                 "Machine Natural Loop Construction", true, true)
36f22ef01cSRoman Divacky 
37e580952dSDimitry Andric char &llvm::MachineLoopInfoID = MachineLoopInfo::ID;
38f22ef01cSRoman Divacky 
runOnMachineFunction(MachineFunction &)39f22ef01cSRoman Divacky bool MachineLoopInfo::runOnMachineFunction(MachineFunction &) {
40f22ef01cSRoman Divacky   releaseMemory();
417d523365SDimitry Andric   LI.analyze(getAnalysis<MachineDominatorTree>().getBase());
42f22ef01cSRoman Divacky   return false;
43f22ef01cSRoman Divacky }
44f22ef01cSRoman Divacky 
getAnalysisUsage(AnalysisUsage & AU) const45f22ef01cSRoman Divacky void MachineLoopInfo::getAnalysisUsage(AnalysisUsage &AU) const {
46f22ef01cSRoman Divacky   AU.setPreservesAll();
47f22ef01cSRoman Divacky   AU.addRequired<MachineDominatorTree>();
48f22ef01cSRoman Divacky   MachineFunctionPass::getAnalysisUsage(AU);
49f22ef01cSRoman Divacky }
50f22ef01cSRoman Divacky 
getTopBlock()51f22ef01cSRoman Divacky MachineBasicBlock *MachineLoop::getTopBlock() {
52f22ef01cSRoman Divacky   MachineBasicBlock *TopMBB = getHeader();
53f22ef01cSRoman Divacky   MachineFunction::iterator Begin = TopMBB->getParent()->begin();
543ca95b02SDimitry Andric   if (TopMBB->getIterator() != Begin) {
557d523365SDimitry Andric     MachineBasicBlock *PriorMBB = &*std::prev(TopMBB->getIterator());
56f22ef01cSRoman Divacky     while (contains(PriorMBB)) {
57f22ef01cSRoman Divacky       TopMBB = PriorMBB;
583ca95b02SDimitry Andric       if (TopMBB->getIterator() == Begin)
593ca95b02SDimitry Andric         break;
607d523365SDimitry Andric       PriorMBB = &*std::prev(TopMBB->getIterator());
61f22ef01cSRoman Divacky     }
62f22ef01cSRoman Divacky   }
63f22ef01cSRoman Divacky   return TopMBB;
64f22ef01cSRoman Divacky }
65f22ef01cSRoman Divacky 
getBottomBlock()66f22ef01cSRoman Divacky MachineBasicBlock *MachineLoop::getBottomBlock() {
67f22ef01cSRoman Divacky   MachineBasicBlock *BotMBB = getHeader();
68f22ef01cSRoman Divacky   MachineFunction::iterator End = BotMBB->getParent()->end();
693ca95b02SDimitry Andric   if (BotMBB->getIterator() != std::prev(End)) {
707d523365SDimitry Andric     MachineBasicBlock *NextMBB = &*std::next(BotMBB->getIterator());
71f22ef01cSRoman Divacky     while (contains(NextMBB)) {
72f22ef01cSRoman Divacky       BotMBB = NextMBB;
737d523365SDimitry Andric       if (BotMBB == &*std::next(BotMBB->getIterator()))
747d523365SDimitry Andric         break;
757d523365SDimitry Andric       NextMBB = &*std::next(BotMBB->getIterator());
76f22ef01cSRoman Divacky     }
77f22ef01cSRoman Divacky   }
78f22ef01cSRoman Divacky   return BotMBB;
79f22ef01cSRoman Divacky }
80f22ef01cSRoman Divacky 
findLoopControlBlock()81d88c1a5aSDimitry Andric MachineBasicBlock *MachineLoop::findLoopControlBlock() {
82d88c1a5aSDimitry Andric   if (MachineBasicBlock *Latch = getLoopLatch()) {
83d88c1a5aSDimitry Andric     if (isLoopExiting(Latch))
84d88c1a5aSDimitry Andric       return Latch;
85d88c1a5aSDimitry Andric     else
86d88c1a5aSDimitry Andric       return getExitingBlock();
87d88c1a5aSDimitry Andric   }
88d88c1a5aSDimitry Andric   return nullptr;
89d88c1a5aSDimitry Andric }
90d88c1a5aSDimitry Andric 
getStartLoc() const917a7e6055SDimitry Andric DebugLoc MachineLoop::getStartLoc() const {
927a7e6055SDimitry Andric   // Try the pre-header first.
937a7e6055SDimitry Andric   if (MachineBasicBlock *PHeadMBB = getLoopPreheader())
947a7e6055SDimitry Andric     if (const BasicBlock *PHeadBB = PHeadMBB->getBasicBlock())
957a7e6055SDimitry Andric       if (DebugLoc DL = PHeadBB->getTerminator()->getDebugLoc())
967a7e6055SDimitry Andric         return DL;
977a7e6055SDimitry Andric 
987a7e6055SDimitry Andric   // If we have no pre-header or there are no instructions with debug
997a7e6055SDimitry Andric   // info in it, try the header.
1007a7e6055SDimitry Andric   if (MachineBasicBlock *HeadMBB = getHeader())
1017a7e6055SDimitry Andric     if (const BasicBlock *HeadBB = HeadMBB->getBasicBlock())
1027a7e6055SDimitry Andric       return HeadBB->getTerminator()->getDebugLoc();
1037a7e6055SDimitry Andric 
1047a7e6055SDimitry Andric   return DebugLoc();
1057a7e6055SDimitry Andric }
1067a7e6055SDimitry Andric 
107d88c1a5aSDimitry Andric MachineBasicBlock *
findLoopPreheader(MachineLoop * L,bool SpeculativePreheader) const108d88c1a5aSDimitry Andric MachineLoopInfo::findLoopPreheader(MachineLoop *L,
109d88c1a5aSDimitry Andric                                    bool SpeculativePreheader) const {
110d88c1a5aSDimitry Andric   if (MachineBasicBlock *PB = L->getLoopPreheader())
111d88c1a5aSDimitry Andric     return PB;
112d88c1a5aSDimitry Andric 
113d88c1a5aSDimitry Andric   if (!SpeculativePreheader)
114d88c1a5aSDimitry Andric     return nullptr;
115d88c1a5aSDimitry Andric 
116d88c1a5aSDimitry Andric   MachineBasicBlock *HB = L->getHeader(), *LB = L->getLoopLatch();
117d88c1a5aSDimitry Andric   if (HB->pred_size() != 2 || HB->hasAddressTaken())
118d88c1a5aSDimitry Andric     return nullptr;
119d88c1a5aSDimitry Andric   // Find the predecessor of the header that is not the latch block.
120d88c1a5aSDimitry Andric   MachineBasicBlock *Preheader = nullptr;
121d88c1a5aSDimitry Andric   for (MachineBasicBlock *P : HB->predecessors()) {
122d88c1a5aSDimitry Andric     if (P == LB)
123d88c1a5aSDimitry Andric       continue;
124d88c1a5aSDimitry Andric     // Sanity.
125d88c1a5aSDimitry Andric     if (Preheader)
126d88c1a5aSDimitry Andric       return nullptr;
127d88c1a5aSDimitry Andric     Preheader = P;
128d88c1a5aSDimitry Andric   }
129d88c1a5aSDimitry Andric 
130d88c1a5aSDimitry Andric   // Check if the preheader candidate is a successor of any other loop
131d88c1a5aSDimitry Andric   // headers. We want to avoid having two loop setups in the same block.
132d88c1a5aSDimitry Andric   for (MachineBasicBlock *S : Preheader->successors()) {
133d88c1a5aSDimitry Andric     if (S == HB)
134d88c1a5aSDimitry Andric       continue;
135d88c1a5aSDimitry Andric     MachineLoop *T = getLoopFor(S);
136d88c1a5aSDimitry Andric     if (T && T->getHeader() == S)
137d88c1a5aSDimitry Andric       return nullptr;
138d88c1a5aSDimitry Andric   }
139d88c1a5aSDimitry Andric   return Preheader;
140d88c1a5aSDimitry Andric }
141d88c1a5aSDimitry Andric 
1423861d79fSDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const1433ca95b02SDimitry Andric LLVM_DUMP_METHOD void MachineLoop::dump() const {
144f22ef01cSRoman Divacky   print(dbgs());
145f22ef01cSRoman Divacky }
1463861d79fSDimitry Andric #endif
147