Jakob Stoklund Olesen | ceadc01 | 2010-12-15 23:41:23 +0000 | [diff] [blame] | 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) { |
| 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 | } |
| 67 | } |
| 68 | |
| 69 | /// overlaps - Return true if this loop overlaps the given range of machine |
| 70 | /// instructions. |
| 71 | bool MachineLoopRange::overlaps(SlotIndex Start, SlotIndex Stop) { |
| 72 | RangeMap::const_iterator I = Intervals.find(Start); |
| 73 | return I.valid() && Stop > I.start(); |
| 74 | } |
| 75 | |
| 76 | void MachineLoopRange::print(raw_ostream &OS) const { |
| 77 | OS << "Loop#" << Loop->getHeader()->getNumber() << " ="; |
| 78 | for (RangeMap::const_iterator I = Intervals.begin(); I.valid(); ++I) |
| 79 | OS << " [" << I.start() << ';' << I.stop() << ')'; |
| 80 | } |
| 81 | |
| 82 | raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineLoopRange &MLR) { |
| 83 | MLR.print(OS); |
| 84 | return OS; |
| 85 | } |