| //===- 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; | |
| } |