Add MachineLoopRanges analysis.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Wed, 15 Dec 2010 23:41:23 +0000 (23:41 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Wed, 15 Dec 2010 23:41:23 +0000 (23:41 +0000)
A MachineLoopRange contains the intervals of slot indexes covered by the blocks
in a loop. This representation of the loop blocks is more efficient to compare
against interfering registers during register coalescing.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121917 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/MachineLoopRanges.h [new file with mode: 0644]
include/llvm/CodeGen/Passes.h
include/llvm/InitializePasses.h
lib/CodeGen/CMakeLists.txt
lib/CodeGen/MachineLoopRanges.cpp [new file with mode: 0644]

diff --git a/include/llvm/CodeGen/MachineLoopRanges.h b/include/llvm/CodeGen/MachineLoopRanges.h
new file mode 100644 (file)
index 0000000..7e6bec6
--- /dev/null
@@ -0,0 +1,84 @@
+//===- MachineLoopRanges.h - Ranges of machine loops -----------*- c++ -*--===//
+//
+//                     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 interface to the MachineLoopRanges analysis.
+//
+// Provide on-demand information about the ranges of machine instructions
+// covered by a loop.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINELOOPRANGES_H
+#define LLVM_CODEGEN_MACHINELOOPRANGES_H
+
+#include "llvm/ADT/IntervalMap.h"
+#include "llvm/CodeGen/SlotIndexes.h"
+
+namespace llvm {
+
+class MachineLoop;
+class MachineLoopInfo;
+class raw_ostream;
+
+/// MachineLoopRange - Range information for a single loop.
+class MachineLoopRange {
+  friend class MachineLoopRanges;
+  typedef IntervalMap<SlotIndex, unsigned, 4> RangeMap;
+  typedef RangeMap::Allocator Allocator;
+
+  /// The mapped loop.
+  const MachineLoop *const Loop;
+
+  /// Map intervals to a bit mask.
+  /// Bit 0 = inside loop block.
+  RangeMap Intervals;
+
+  /// Create a MachineLoopRange, only accessible to MachineLoopRanges.
+  MachineLoopRange(const MachineLoop*, Allocator&, SlotIndexes&);
+
+public:
+  /// overlaps - Return true if this loop overlaps the given range of machine
+  /// inteructions.
+  bool overlaps(SlotIndex Start, SlotIndex Stop);
+
+  /// print - Print loop ranges on OS.
+  void print(raw_ostream&) const;
+};
+
+raw_ostream &operator<<(raw_ostream&, const MachineLoopRange&);
+
+/// MachineLoopRanges - Analysis pass that provides on-demand per-loop range
+/// information.
+class MachineLoopRanges : public MachineFunctionPass {
+  typedef DenseMap<const MachineLoop*, MachineLoopRange*> CacheMap;
+  typedef MachineLoopRange::Allocator MapAllocator;
+
+  MapAllocator Allocator;
+  SlotIndexes *Indexes;
+  CacheMap Cache;
+
+public:
+  static char ID; // Pass identification, replacement for typeid
+
+  MachineLoopRanges() : MachineFunctionPass(ID), Indexes(0) {}
+  ~MachineLoopRanges() { releaseMemory(); }
+
+  /// getLoopRange - Return the range of loop.
+  MachineLoopRange *getLoopRange(const MachineLoop *Loop);
+
+private:
+  virtual bool runOnMachineFunction(MachineFunction&);
+  virtual void releaseMemory();
+  virtual void getAnalysisUsage(AnalysisUsage&) const;
+};
+
+
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_MACHINELOOPRANGES_H
index 4d9d293bdd6da1715eacebd56578c23768e388aa..620206fe6e3088b8c2e92c1a3e4168c6f21a545c 100644 (file)
@@ -45,6 +45,11 @@ namespace llvm {
   ///
   extern char &MachineLoopInfoID;
 
+  /// MachineLoopRanges pass - This pass is an on-demand loop coverage
+  /// analysis pass.
+  ///
+  extern char &MachineLoopRangesID;
+
   /// MachineDominators pass - This pass is a machine dominators analysis pass.
   ///
   extern char &MachineDominatorsID;
index b2ca7fb9337882bcfa32d1a0a1e79e3a5424f71f..0fe94c4e15002319443ffccda356c165d0dc7cd7 100644 (file)
@@ -142,6 +142,7 @@ void initializeMachineCSEPass(PassRegistry&);
 void initializeMachineDominatorTreePass(PassRegistry&);
 void initializeMachineLICMPass(PassRegistry&);
 void initializeMachineLoopInfoPass(PassRegistry&);
+void initializeMachineLoopRangesPass(PassRegistry&);
 void initializeMachineModuleInfoPass(PassRegistry&);
 void initializeMachineSinkingPass(PassRegistry&);
 void initializeMachineVerifierPassPass(PassRegistry&);
index cbebacbdf73c30ecdbc724bb58c0af27765997c7..a43a0c5d53b252fb3e4156bace2bc47736916494 100644 (file)
@@ -40,6 +40,7 @@ add_llvm_library(LLVMCodeGen
   MachineInstr.cpp
   MachineLICM.cpp
   MachineLoopInfo.cpp
+  MachineLoopRanges.cpp
   MachineModuleInfo.cpp
   MachineModuleInfoImpls.cpp
   MachinePassRegistry.cpp
diff --git a/lib/CodeGen/MachineLoopRanges.cpp b/lib/CodeGen/MachineLoopRanges.cpp
new file mode 100644 (file)
index 0000000..9af49b0
--- /dev/null
@@ -0,0 +1,85 @@
+//===- 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) {
+  // 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);
+  }
+}
+
+/// overlaps - Return true if this loop overlaps the given range of machine
+/// instructions.
+bool MachineLoopRange::overlaps(SlotIndex Start, SlotIndex Stop) {
+  RangeMap::const_iterator I = Intervals.find(Start);
+  return I.valid() && Stop > I.start();
+}
+
+void MachineLoopRange::print(raw_ostream &OS) const {
+  OS << "Loop#" << Loop->getHeader()->getNumber() << " =";
+  for (RangeMap::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;
+}