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