1 //===- MachineLoopRanges.cpp - Ranges of machine loops --------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file provides the implementation of the MachineLoopRanges analysis. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/CodeGen/MachineLoopRanges.h" 15 #include "llvm/CodeGen/MachineLoopInfo.h" 16 #include "llvm/CodeGen/Passes.h" 17 18 using namespace llvm; 19 20 char MachineLoopRanges::ID = 0; 21 INITIALIZE_PASS_BEGIN(MachineLoopRanges, "machine-loop-ranges", 22 "Machine Loop Ranges", true, true) 23 INITIALIZE_PASS_DEPENDENCY(SlotIndexes) 24 INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) 25 INITIALIZE_PASS_END(MachineLoopRanges, "machine-loop-ranges", 26 "Machine Loop Ranges", true, true) 27 28 char &llvm::MachineLoopRangesID = MachineLoopRanges::ID; 29 30 void MachineLoopRanges::getAnalysisUsage(AnalysisUsage &AU) const { 31 AU.setPreservesAll(); 32 AU.addRequiredTransitive<SlotIndexes>(); 33 AU.addRequiredTransitive<MachineLoopInfo>(); 34 MachineFunctionPass::getAnalysisUsage(AU); 35 } 36 37 /// runOnMachineFunction - Don't do much, loop ranges are computed on demand. 38 bool MachineLoopRanges::runOnMachineFunction(MachineFunction &) { 39 releaseMemory(); 40 Indexes = &getAnalysis<SlotIndexes>(); 41 return false; 42 } 43 44 void MachineLoopRanges::releaseMemory() { 45 DeleteContainerSeconds(Cache); 46 Cache.clear(); 47 } 48 49 MachineLoopRange *MachineLoopRanges::getLoopRange(const MachineLoop *Loop) { 50 MachineLoopRange *&Range = Cache[Loop]; 51 if (!Range) 52 Range = new MachineLoopRange(Loop, Allocator, *Indexes); 53 return Range; 54 } 55 56 /// Create a MachineLoopRange, only accessible to MachineLoopRanges. 57 MachineLoopRange::MachineLoopRange(const MachineLoop *loop, 58 MachineLoopRange::Allocator &alloc, 59 SlotIndexes &Indexes) 60 : Loop(loop), Intervals(alloc), Area(0) { 61 // Compute loop coverage. 62 for (MachineLoop::block_iterator I = Loop->block_begin(), 63 E = Loop->block_end(); I != E; ++I) { 64 const std::pair<SlotIndex, SlotIndex> &Range = Indexes.getMBBRange(*I); 65 Intervals.insert(Range.first, Range.second, 1u); 66 Area += Range.first.distance(Range.second); 67 } 68 } 69 70 /// overlaps - Return true if this loop overlaps the given range of machine 71 /// instructions. 72 bool MachineLoopRange::overlaps(SlotIndex Start, SlotIndex Stop) { 73 Map::const_iterator I = Intervals.find(Start); 74 return I.valid() && Stop > I.start(); 75 } 76 77 unsigned MachineLoopRange::getNumber() const { 78 return Loop->getHeader()->getNumber(); 79 } 80 81 /// byNumber - Comparator for array_pod_sort that sorts a list of 82 /// MachineLoopRange pointers by number. 83 int MachineLoopRange::byNumber(const void *pa, const void *pb) { 84 const MachineLoopRange *a = *static_cast<MachineLoopRange *const *>(pa); 85 const MachineLoopRange *b = *static_cast<MachineLoopRange *const *>(pb); 86 unsigned na = a->getNumber(); 87 unsigned nb = b->getNumber(); 88 if (na < nb) 89 return -1; 90 if (na > nb) 91 return 1; 92 return 0; 93 } 94 95 /// byAreaDesc - Comparator for array_pod_sort that sorts a list of 96 /// MachineLoopRange pointers by: 97 /// 1. Descending area. 98 /// 2. Ascending number. 99 int MachineLoopRange::byAreaDesc(const void *pa, const void *pb) { 100 const MachineLoopRange *a = *static_cast<MachineLoopRange *const *>(pa); 101 const MachineLoopRange *b = *static_cast<MachineLoopRange *const *>(pb); 102 if (a->getArea() != b->getArea()) 103 return a->getArea() > b->getArea() ? -1 : 1; 104 return byNumber(pa, pb); 105 } 106 107 void MachineLoopRange::print(raw_ostream &OS) const { 108 OS << "Loop#" << getNumber() << " ="; 109 for (Map::const_iterator I = Intervals.begin(); I.valid(); ++I) 110 OS << " [" << I.start() << ';' << I.stop() << ')'; 111 } 112 113 raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineLoopRange &MLR) { 114 MLR.print(OS); 115 return OS; 116 } 117