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"
21f22ef01cSRoman Divacky #include "llvm/Support/Debug.h"
22ff0cc061SDimitry Andric #include "llvm/Support/raw_ostream.h"
23f22ef01cSRoman Divacky using namespace llvm;
24f22ef01cSRoman Divacky 
257ae0e2c9SDimitry Andric // Explicitly instantiate methods in LoopInfoImpl.h for MI-level Loops.
267ae0e2c9SDimitry Andric template class llvm::LoopBase<MachineBasicBlock, MachineLoop>;
277ae0e2c9SDimitry Andric template class llvm::LoopInfoBase<MachineBasicBlock, MachineLoop>;
28f22ef01cSRoman Divacky 
29f22ef01cSRoman Divacky char MachineLoopInfo::ID = 0;
302754fe60SDimitry Andric INITIALIZE_PASS_BEGIN(MachineLoopInfo, "machine-loops",
312754fe60SDimitry Andric                 "Machine Natural Loop Construction", true, true)
322754fe60SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
332754fe60SDimitry Andric INITIALIZE_PASS_END(MachineLoopInfo, "machine-loops",
342754fe60SDimitry Andric                 "Machine Natural Loop Construction", true, true)
35f22ef01cSRoman Divacky 
36e580952dSDimitry Andric char &llvm::MachineLoopInfoID = MachineLoopInfo::ID;
37f22ef01cSRoman Divacky 
38f22ef01cSRoman Divacky bool MachineLoopInfo::runOnMachineFunction(MachineFunction &) {
39f22ef01cSRoman Divacky   releaseMemory();
407d523365SDimitry Andric   LI.analyze(getAnalysis<MachineDominatorTree>().getBase());
41f22ef01cSRoman Divacky   return false;
42f22ef01cSRoman Divacky }
43f22ef01cSRoman Divacky 
44f22ef01cSRoman Divacky void MachineLoopInfo::getAnalysisUsage(AnalysisUsage &AU) const {
45f22ef01cSRoman Divacky   AU.setPreservesAll();
46f22ef01cSRoman Divacky   AU.addRequired<MachineDominatorTree>();
47f22ef01cSRoman Divacky   MachineFunctionPass::getAnalysisUsage(AU);
48f22ef01cSRoman Divacky }
49f22ef01cSRoman Divacky 
50f22ef01cSRoman Divacky MachineBasicBlock *MachineLoop::getTopBlock() {
51f22ef01cSRoman Divacky   MachineBasicBlock *TopMBB = getHeader();
52f22ef01cSRoman Divacky   MachineFunction::iterator Begin = TopMBB->getParent()->begin();
533ca95b02SDimitry Andric   if (TopMBB->getIterator() != Begin) {
547d523365SDimitry Andric     MachineBasicBlock *PriorMBB = &*std::prev(TopMBB->getIterator());
55f22ef01cSRoman Divacky     while (contains(PriorMBB)) {
56f22ef01cSRoman Divacky       TopMBB = PriorMBB;
573ca95b02SDimitry Andric       if (TopMBB->getIterator() == Begin)
583ca95b02SDimitry Andric         break;
597d523365SDimitry Andric       PriorMBB = &*std::prev(TopMBB->getIterator());
60f22ef01cSRoman Divacky     }
61f22ef01cSRoman Divacky   }
62f22ef01cSRoman Divacky   return TopMBB;
63f22ef01cSRoman Divacky }
64f22ef01cSRoman Divacky 
65f22ef01cSRoman Divacky MachineBasicBlock *MachineLoop::getBottomBlock() {
66f22ef01cSRoman Divacky   MachineBasicBlock *BotMBB = getHeader();
67f22ef01cSRoman Divacky   MachineFunction::iterator End = BotMBB->getParent()->end();
683ca95b02SDimitry Andric   if (BotMBB->getIterator() != std::prev(End)) {
697d523365SDimitry Andric     MachineBasicBlock *NextMBB = &*std::next(BotMBB->getIterator());
70f22ef01cSRoman Divacky     while (contains(NextMBB)) {
71f22ef01cSRoman Divacky       BotMBB = NextMBB;
727d523365SDimitry Andric       if (BotMBB == &*std::next(BotMBB->getIterator()))
737d523365SDimitry Andric         break;
747d523365SDimitry Andric       NextMBB = &*std::next(BotMBB->getIterator());
75f22ef01cSRoman Divacky     }
76f22ef01cSRoman Divacky   }
77f22ef01cSRoman Divacky   return BotMBB;
78f22ef01cSRoman Divacky }
79f22ef01cSRoman Divacky 
803861d79fSDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
813ca95b02SDimitry Andric LLVM_DUMP_METHOD void MachineLoop::dump() const {
82f22ef01cSRoman Divacky   print(dbgs());
83f22ef01cSRoman Divacky }
843861d79fSDimitry Andric #endif
85