whitespace
[oota-llvm.git] / lib / CodeGen / RegAllocBasic.cpp
index d0e635512902cfc8a9c738ed03653bbd847b1e04..1175923cd270358beb380a6540f661f418d78e10 100644 (file)
@@ -42,9 +42,8 @@
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Timer.h"
 
-#include <vector>
-#include <queue>
 #include <cstdlib>
 
 using namespace llvm;
@@ -54,19 +53,14 @@ static RegisterRegAlloc basicRegAlloc("basic", "basic register allocator",
 
 // Temporary verification option until we can put verification inside
 // MachineVerifier.
-static cl::opt<bool>
-VerifyRegAlloc("verify-regalloc",
-               cl::desc("Verify live intervals before renaming"));
+static cl::opt<bool, true>
+VerifyRegAlloc("verify-regalloc", cl::location(RegAllocBase::VerifyEnabled),
+               cl::desc("Verify during register allocation"));
 
-namespace {
-
-class PhysicalRegisterDescription : public AbstractRegisterDescription {
-  const TargetRegisterInfo *TRI;
-public:
-  PhysicalRegisterDescription(const TargetRegisterInfo *T): TRI(T) {}
-  virtual const char *getName(unsigned Reg) const { return TRI->getName(Reg); }
-};
+const char *RegAllocBase::TimerGroupName = "Register Allocation";
+bool RegAllocBase::VerifyEnabled = false;
 
+namespace {
 /// RABasic provides a minimal implementation of the basic register allocation
 /// algorithm. It prioritizes live virtual registers by spill weight and spills
 /// whenever a register is unavailable. This is not practical in production but
@@ -76,9 +70,6 @@ class RABasic : public MachineFunctionPass, public RegAllocBase
 {
   // context
   MachineFunction *MF;
-  const TargetMachine *TM;
-  MachineRegisterInfo *MRI;
-
   BitVector ReservedRegs;
 
   // analyses
@@ -103,6 +94,8 @@ public:
 
   virtual Spiller &spiller() { return *SpillerInstance; }
 
+  virtual float getPriority(LiveInterval *LI) { return LI->weight; }
+
   virtual unsigned selectOrSplit(LiveInterval &VirtReg,
                                  SmallVectorImpl<LiveInterval*> &SplitVRegs);
 
@@ -165,8 +158,7 @@ void RegAllocBase::verify() {
 
   // Verify disjoint unions.
   for (unsigned PhysReg = 0; PhysReg < PhysReg2LiveUnion.numRegs(); ++PhysReg) {
-    DEBUG(PhysicalRegisterDescription PRD(TRI);
-          PhysReg2LiveUnion[PhysReg].dump(&PRD));
+    DEBUG(PhysReg2LiveUnion[PhysReg].print(dbgs(), TRI));
     LiveVirtRegBitSet &VRegs = unionVRegs[PhysReg];
     PhysReg2LiveUnion[PhysReg].verify(VRegs);
     // Union + intersection test could be done efficiently in one pass, but
@@ -206,9 +198,10 @@ void RegAllocBase::LiveUnionArray::init(LiveIntervalUnion::Allocator &allocator,
     new(Array + r) LiveIntervalUnion(r, allocator);
 }
 
-void RegAllocBase::init(const TargetRegisterInfo &tri, VirtRegMap &vrm,
-                        LiveIntervals &lis) {
-  TRI = &tri;
+void RegAllocBase::init(VirtRegMap &vrm, LiveIntervals &lis) {
+  NamedRegionTimer T("Initialize", TimerGroupName, TimePassesIsEnabled);
+  TRI = &vrm.getTargetRegInfo();
+  MRI = &vrm.getRegInfo();
   VRM = &vrm;
   LIS = &lis;
   PhysReg2LiveUnion.init(UnionAllocator, TRI->getNumRegs());
@@ -230,49 +223,18 @@ void RegAllocBase::releaseMemory() {
   PhysReg2LiveUnion.clear();
 }
 
-namespace llvm {
-/// This class defines a queue of live virtual registers prioritized by spill
-/// weight. The heaviest vreg is popped first.
-///
-/// Currently, this is trivial wrapper that gives us an opaque type in the
-/// header, but we may later give it a virtual interface for register allocators
-/// to override the priority queue comparator.
-class LiveVirtRegQueue {
-  typedef std::priority_queue
-    <LiveInterval*, std::vector<LiveInterval*>, LessSpillWeightPriority>
-    PriorityQ;
-  PriorityQ PQ;
-
-public:
-  // Is the queue empty?
-  bool empty() { return PQ.empty(); }
-
-  // Get the highest priority lvr (top + pop)
-  LiveInterval *get() {
-    LiveInterval *VirtReg = PQ.top();
-    PQ.pop();
-    return VirtReg;
-  }
-  // Add this lvr to the queue
-  void push(LiveInterval *VirtReg) {
-    PQ.push(VirtReg);
-  }
-};
-} // end namespace llvm
-
 // Visit all the live virtual registers. If they are already assigned to a
 // physical register, unify them with the corresponding LiveIntervalUnion,
 // otherwise push them on the priority queue for later assignment.
-void RegAllocBase::seedLiveVirtRegs(LiveVirtRegQueue &VirtRegQ) {
+void RegAllocBase::
+seedLiveVirtRegs(std::priority_queue<std::pair<float, unsigned> > &VirtRegQ) {
   for (LiveIntervals::iterator I = LIS->begin(), E = LIS->end(); I != E; ++I) {
     unsigned RegNum = I->first;
     LiveInterval &VirtReg = *I->second;
-    if (TargetRegisterInfo::isPhysicalRegister(RegNum)) {
+    if (TargetRegisterInfo::isPhysicalRegister(RegNum))
       PhysReg2LiveUnion[RegNum].unify(VirtReg);
-    }
-    else {
-      VirtRegQ.push(&VirtReg);
-    }
+    else
+      VirtRegQ.push(std::make_pair(getPriority(&VirtReg), RegNum));
   }
 }
 
@@ -281,27 +243,30 @@ void RegAllocBase::seedLiveVirtRegs(LiveVirtRegQueue &VirtRegQ) {
 void RegAllocBase::allocatePhysRegs() {
 
   // Push each vreg onto a queue or "precolor" by adding it to a physreg union.
-  LiveVirtRegQueue VirtRegQ;
+  std::priority_queue<std::pair<float, unsigned> > VirtRegQ;
   seedLiveVirtRegs(VirtRegQ);
 
   // Continue assigning vregs one at a time to available physical registers.
   while (!VirtRegQ.empty()) {
     // Pop the highest priority vreg.
-    LiveInterval *VirtReg = VirtRegQ.get();
+    LiveInterval &VirtReg = LIS->getInterval(VirtRegQ.top().second);
+    VirtRegQ.pop();
 
     // selectOrSplit requests the allocator to return an available physical
     // register if possible and populate a list of new live intervals that
     // result from splitting.
+    DEBUG(dbgs() << "\nselectOrSplit " << MRI->getRegClass(VirtReg.reg)->getName()
+                 << ':' << VirtReg << '\n');
     typedef SmallVector<LiveInterval*, 4> VirtRegVec;
     VirtRegVec SplitVRegs;
-    unsigned AvailablePhysReg = selectOrSplit(*VirtReg, SplitVRegs);
+    unsigned AvailablePhysReg = selectOrSplit(VirtReg, SplitVRegs);
 
     if (AvailablePhysReg) {
-      DEBUG(dbgs() << "allocating: " << TRI->getName(AvailablePhysReg) <<
-            " " << *VirtReg << '\n');
-      assert(!VRM->hasPhys(VirtReg->reg) && "duplicate vreg in union");
-      VRM->assignVirt2Phys(VirtReg->reg, AvailablePhysReg);
-      PhysReg2LiveUnion[AvailablePhysReg].unify(*VirtReg);
+      DEBUG(dbgs() << "allocating: " << TRI->getName(AvailablePhysReg)
+                   << " for " << VirtReg << '\n');
+      assert(!VRM->hasPhys(VirtReg.reg) && "duplicate vreg in union");
+      VRM->assignVirt2Phys(VirtReg.reg, AvailablePhysReg);
+      PhysReg2LiveUnion[AvailablePhysReg].unify(VirtReg);
     }
     for (VirtRegVec::iterator I = SplitVRegs.begin(), E = SplitVRegs.end();
          I != E; ++I) {
@@ -310,7 +275,8 @@ void RegAllocBase::allocatePhysRegs() {
       DEBUG(dbgs() << "queuing new interval: " << *SplitVirtReg << "\n");
       assert(TargetRegisterInfo::isVirtualRegister(SplitVirtReg->reg) &&
              "expect split value in virtual register");
-      VirtRegQ.push(SplitVirtReg);
+      VirtRegQ.push(std::make_pair(getPriority(SplitVirtReg),
+                                   SplitVirtReg->reg));
     }
   }
 }
@@ -320,12 +286,9 @@ void RegAllocBase::allocatePhysRegs() {
 // physical register. Return the interfering register.
 unsigned RegAllocBase::checkPhysRegInterference(LiveInterval &VirtReg,
                                                 unsigned PhysReg) {
-  if (query(VirtReg, PhysReg).checkInterference())
-    return PhysReg;
-  for (const unsigned *AliasI = TRI->getAliasSet(PhysReg); *AliasI; ++AliasI) {
+  for (const unsigned *AliasI = TRI->getOverlaps(PhysReg); *AliasI; ++AliasI)
     if (query(VirtReg, *AliasI).checkInterference())
       return *AliasI;
-  }
   return 0;
 }
 
@@ -366,15 +329,9 @@ RegAllocBase::spillInterferences(LiveInterval &VirtReg, unsigned PhysReg,
                                  SmallVectorImpl<LiveInterval*> &SplitVRegs) {
   // Record each interference and determine if all are spillable before mutating
   // either the union or live intervals.
-
-  // Collect interferences assigned to the requested physical register.
-  LiveIntervalUnion::Query &QPreg = query(VirtReg, PhysReg);
-  unsigned NumInterferences = QPreg.collectInterferingVRegs();
-  if (QPreg.seenUnspillableVReg()) {
-    return false;
-  }
+  unsigned NumInterferences = 0;
   // Collect interferences assigned to any alias of the physical register.
-  for (const unsigned *asI = TRI->getAliasSet(PhysReg); *asI; ++asI) {
+  for (const unsigned *asI = TRI->getOverlaps(PhysReg); *asI; ++asI) {
     LiveIntervalUnion::Query &QAlias = query(VirtReg, *asI);
     NumInterferences += QAlias.collectInterferingVRegs();
     if (QAlias.seenUnspillableVReg()) {
@@ -386,14 +343,14 @@ RegAllocBase::spillInterferences(LiveInterval &VirtReg, unsigned PhysReg,
   assert(NumInterferences > 0 && "expect interference");
 
   // Spill each interfering vreg allocated to PhysReg or an alias.
-  spillReg(VirtReg, PhysReg, SplitVRegs);
-  for (const unsigned *AliasI = TRI->getAliasSet(PhysReg); *AliasI; ++AliasI)
+  for (const unsigned *AliasI = TRI->getOverlaps(PhysReg); *AliasI; ++AliasI)
     spillReg(VirtReg, *AliasI, SplitVRegs);
   return true;
 }
 
 // Add newly allocated physical registers to the MBB live in sets.
 void RegAllocBase::addMBBLiveIns(MachineFunction *MF) {
+  NamedRegionTimer T("MBB Live Ins", TimerGroupName, TimePassesIsEnabled);
   typedef SmallVector<MachineBasicBlock*, 8> MBBVec;
   MBBVec liveInMBBs;
   MachineBasicBlock &entryMBB = *MF->begin();
@@ -445,7 +402,6 @@ unsigned RABasic::selectOrSplit(LiveInterval &VirtReg,
 
   // Check for an available register in this class.
   const TargetRegisterClass *TRC = MRI->getRegClass(VirtReg.reg);
-  DEBUG(dbgs() << "RegClass: " << TRC->getName() << ' ');
 
   for (TargetRegisterClass::iterator I = TRC->allocation_order_begin(*MF),
          E = TRC->allocation_order_end(*MF);
@@ -464,15 +420,13 @@ unsigned RABasic::selectOrSplit(LiveInterval &VirtReg,
     LiveInterval *interferingVirtReg =
       Queries[interfReg].firstInterference().liveUnionPos().value();
 
-    // The current VirtReg must either spillable, or one of its interferences
+    // The current VirtReg must either be spillable, or one of its interferences
     // must have less spill weight.
     if (interferingVirtReg->weight < VirtReg.weight ) {
       PhysRegSpillCands.push_back(PhysReg);
     }
   }
   // Try to spill another interfering reg with less spill weight.
-  //
-  // FIXME: RAGreedy will sort this list by spill weight.
   for (SmallVectorImpl<unsigned>::iterator PhysRegI = PhysRegSpillCands.begin(),
          PhysRegE = PhysRegSpillCands.end(); PhysRegI != PhysRegE; ++PhysRegI) {
 
@@ -500,14 +454,9 @@ bool RABasic::runOnMachineFunction(MachineFunction &mf) {
                << ((Value*)mf.getFunction())->getName() << '\n');
 
   MF = &mf;
-  TM = &mf.getTarget();
-  MRI = &mf.getRegInfo();
-
   DEBUG(RMF = &getAnalysis<RenderMachineFunction>());
 
-  const TargetRegisterInfo *TRI = TM->getRegisterInfo();
-  RegAllocBase::init(*TRI, getAnalysis<VirtRegMap>(),
-                     getAnalysis<LiveIntervals>());
+  RegAllocBase::init(getAnalysis<VirtRegMap>(), getAnalysis<LiveIntervals>());
 
   ReservedRegs = TRI->getReservedRegs(*MF);
 
@@ -527,7 +476,7 @@ bool RABasic::runOnMachineFunction(MachineFunction &mf) {
   // make the rewriter a separate pass and override verifyAnalysis instead. When
   // that happens, verification naturally falls under VerifyMachineCode.
 #ifndef NDEBUG
-  if (VerifyRegAlloc) {
+  if (VerifyEnabled) {
     // Verify accuracy of LiveIntervals. The standard machine code verifier
     // ensures that each LiveIntervals covers all uses of the virtual reg.
 
@@ -535,7 +484,7 @@ bool RABasic::runOnMachineFunction(MachineFunction &mf) {
     // spiller. Always use -spiller=inline with -verify-regalloc. Even with the
     // inline spiller, some tests fail to verify because the coalescer does not
     // always generate verifiable code.
-    MF->verify(this);
+    MF->verify(this, "In RABasic::verify");
 
     // Verify that LiveIntervals are partitioned into unions and disjoint within
     // the unions.