| //===- MachineLoopRanges.cpp - Ranges of machine loops --------------------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file provides the implementation of the MachineLoopRanges analysis. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "llvm/CodeGen/MachineLoopRanges.h" |
| #include "llvm/CodeGen/MachineLoopInfo.h" |
| #include "llvm/CodeGen/Passes.h" |
| |
| using namespace llvm; |
| |
| char MachineLoopRanges::ID = 0; |
| INITIALIZE_PASS_BEGIN(MachineLoopRanges, "machine-loop-ranges", |
| "Machine Loop Ranges", true, true) |
| INITIALIZE_PASS_DEPENDENCY(SlotIndexes) |
| INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) |
| INITIALIZE_PASS_END(MachineLoopRanges, "machine-loop-ranges", |
| "Machine Loop Ranges", true, true) |
| |
| char &llvm::MachineLoopRangesID = MachineLoopRanges::ID; |
| |
| void MachineLoopRanges::getAnalysisUsage(AnalysisUsage &AU) const { |
| AU.setPreservesAll(); |
| AU.addRequiredTransitive<SlotIndexes>(); |
| AU.addRequiredTransitive<MachineLoopInfo>(); |
| MachineFunctionPass::getAnalysisUsage(AU); |
| } |
| |
| /// runOnMachineFunction - Don't do much, loop ranges are computed on demand. |
| bool MachineLoopRanges::runOnMachineFunction(MachineFunction &) { |
| releaseMemory(); |
| Indexes = &getAnalysis<SlotIndexes>(); |
| return false; |
| } |
| |
| void MachineLoopRanges::releaseMemory() { |
| DeleteContainerSeconds(Cache); |
| Cache.clear(); |
| } |
| |
| MachineLoopRange *MachineLoopRanges::getLoopRange(const MachineLoop *Loop) { |
| MachineLoopRange *&Range = Cache[Loop]; |
| if (!Range) |
| Range = new MachineLoopRange(Loop, Allocator, *Indexes); |
| return Range; |
| } |
| |
| /// Create a MachineLoopRange, only accessible to MachineLoopRanges. |
| MachineLoopRange::MachineLoopRange(const MachineLoop *loop, |
| MachineLoopRange::Allocator &alloc, |
| SlotIndexes &Indexes) |
| : Loop(loop), Intervals(alloc), Area(0) { |
| // Compute loop coverage. |
| for (MachineLoop::block_iterator I = Loop->block_begin(), |
| E = Loop->block_end(); I != E; ++I) { |
| const std::pair<SlotIndex, SlotIndex> &Range = Indexes.getMBBRange(*I); |
| Intervals.insert(Range.first, Range.second, 1u); |
| Area += Range.first.distance(Range.second); |
| } |
| } |
| |
| /// overlaps - Return true if this loop overlaps the given range of machine |
| /// instructions. |
| bool MachineLoopRange::overlaps(SlotIndex Start, SlotIndex Stop) { |
| Map::const_iterator I = Intervals.find(Start); |
| return I.valid() && Stop > I.start(); |
| } |
| |
| unsigned MachineLoopRange::getNumber() const { |
| return Loop->getHeader()->getNumber(); |
| } |
| |
| /// byNumber - Comparator for array_pod_sort that sorts a list of |
| /// MachineLoopRange pointers by number. |
| int MachineLoopRange::byNumber(const void *pa, const void *pb) { |
| const MachineLoopRange *a = *static_cast<MachineLoopRange *const *>(pa); |
| const MachineLoopRange *b = *static_cast<MachineLoopRange *const *>(pb); |
| unsigned na = a->getNumber(); |
| unsigned nb = b->getNumber(); |
| if (na < nb) |
| return -1; |
| if (na > nb) |
| return 1; |
| return 0; |
| } |
| |
| /// byAreaDesc - Comparator for array_pod_sort that sorts a list of |
| /// MachineLoopRange pointers by: |
| /// 1. Descending area. |
| /// 2. Ascending number. |
| int MachineLoopRange::byAreaDesc(const void *pa, const void *pb) { |
| const MachineLoopRange *a = *static_cast<MachineLoopRange *const *>(pa); |
| const MachineLoopRange *b = *static_cast<MachineLoopRange *const *>(pb); |
| if (a->getArea() != b->getArea()) |
| return a->getArea() > b->getArea() ? -1 : 1; |
| return byNumber(pa, pb); |
| } |
| |
| void MachineLoopRange::print(raw_ostream &OS) const { |
| OS << "Loop#" << getNumber() << " ="; |
| for (Map::const_iterator I = Intervals.begin(); I.valid(); ++I) |
| OS << " [" << I.start() << ';' << I.stop() << ')'; |
| } |
| |
| raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineLoopRange &MLR) { |
| MLR.print(OS); |
| return OS; |
| } |