[llvm-branch-commits] [llvm-branch] r71053 - in /llvm/branches/Apple/Dib: include/llvm/CodeGen/ include/llvm/Target/ lib/CodeGen/ lib/CodeGen/SelectionDAG/ lib/Target/ test/CodeGen/X86/

Bill Wendling isanbard at gmail.com
Tue May 5 17:37:53 PDT 2009


Author: void
Date: Tue May  5 19:37:50 2009
New Revision: 71053

URL: http://llvm.org/viewvc/llvm-project?rev=71053&view=rev
Log:
--- Merging r70524 into '.':
U    lib/CodeGen/RegAllocLinearScan.cpp
D    lib/CodeGen/PhysRegTracker.h
--- Merging r70787 into '.':
U    include/llvm/Target/TargetRegisterInfo.h
U    include/llvm/Target/TargetInstrInfo.h
U    include/llvm/CodeGen/LiveStackAnalysis.h
U    include/llvm/CodeGen/LiveIntervalAnalysis.h
U    lib/CodeGen/StackSlotColoring.cpp
U    lib/CodeGen/LiveIntervalAnalysis.cpp
U    lib/CodeGen/RegAllocPBQP.cpp
U    lib/CodeGen/VirtRegMap.cpp
U    lib/CodeGen/LiveStackAnalysis.cpp
U    lib/CodeGen/PreAllocSplitting.cpp
U    lib/CodeGen/VirtRegMap.h
G    lib/CodeGen/RegAllocLinearScan.cpp
--- Merging r70792 into '.':
G    lib/CodeGen/StackSlotColoring.cpp
--- Merging r70815 into '.':
G    lib/CodeGen/StackSlotColoring.cpp
--- Merging r70821 into '.':
G    lib/CodeGen/VirtRegMap.cpp
G    lib/CodeGen/VirtRegMap.h
--- Merging r70937 into '.':
G    lib/CodeGen/StackSlotColoring.cpp
--- Merging r70950 into '.':
G    include/llvm/Target/TargetInstrInfo.h
U    lib/CodeGen/PostRASchedulerList.cpp
U    lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp
U    lib/Target/TargetInstrInfo.cpp
--- Merging r70953 into '.':
G    lib/CodeGen/StackSlotColoring.cpp
--- Merging r71010 into '.':
A    test/CodeGen/X86/stack-color-with-reg.ll
G    lib/CodeGen/StackSlotColoring.cpp
U    lib/CodeGen/LLVMTargetMachine.cpp


Added:
    llvm/branches/Apple/Dib/test/CodeGen/X86/stack-color-with-reg.ll
      - copied unchanged from r71010, llvm/trunk/test/CodeGen/X86/stack-color-with-reg.ll
Removed:
    llvm/branches/Apple/Dib/lib/CodeGen/PhysRegTracker.h
Modified:
    llvm/branches/Apple/Dib/include/llvm/CodeGen/LiveIntervalAnalysis.h
    llvm/branches/Apple/Dib/include/llvm/CodeGen/LiveStackAnalysis.h
    llvm/branches/Apple/Dib/include/llvm/Target/TargetInstrInfo.h
    llvm/branches/Apple/Dib/include/llvm/Target/TargetRegisterInfo.h
    llvm/branches/Apple/Dib/lib/CodeGen/LLVMTargetMachine.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/LiveIntervalAnalysis.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/LiveStackAnalysis.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/PostRASchedulerList.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/PreAllocSplitting.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/RegAllocLinearScan.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/RegAllocPBQP.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/StackSlotColoring.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/VirtRegMap.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/VirtRegMap.h
    llvm/branches/Apple/Dib/lib/Target/TargetInstrInfo.cpp

Modified: llvm/branches/Apple/Dib/include/llvm/CodeGen/LiveIntervalAnalysis.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/include/llvm/CodeGen/LiveIntervalAnalysis.h?rev=71053&r1=71052&r2=71053&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/include/llvm/CodeGen/LiveIntervalAnalysis.h (original)
+++ llvm/branches/Apple/Dib/include/llvm/CodeGen/LiveIntervalAnalysis.h Tue May  5 19:37:50 2009
@@ -356,15 +356,13 @@
     std::vector<LiveInterval*>
     addIntervalsForSpills(const LiveInterval& i,
                           SmallVectorImpl<LiveInterval*> &SpillIs,
-                          const MachineLoopInfo *loopInfo, VirtRegMap& vrm,
-                          float &SSWeight);
+                          const MachineLoopInfo *loopInfo, VirtRegMap& vrm);
     
     /// addIntervalsForSpillsFast - Quickly create new intervals for spilled
     /// defs / uses without remat or splitting.
     std::vector<LiveInterval*>
     addIntervalsForSpillsFast(const LiveInterval &li,
-                              const MachineLoopInfo *loopInfo,
-                              VirtRegMap &vrm, float& SSWeight);
+                              const MachineLoopInfo *loopInfo, VirtRegMap &vrm);
 
     /// spillPhysRegAroundRegDefsUses - Spill the specified physical register
     /// around all defs and uses of the specified interval. Return true if it
@@ -512,7 +510,7 @@
         SmallVector<int, 4> &ReMatIds, const MachineLoopInfo *loopInfo,
         unsigned &NewVReg, unsigned ImpUse, bool &HasDef, bool &HasUse,
         DenseMap<unsigned,unsigned> &MBBVRegsMap,
-        std::vector<LiveInterval*> &NewLIs, float &SSWeight);
+        std::vector<LiveInterval*> &NewLIs);
     void rewriteInstructionsForSpills(const LiveInterval &li, bool TrySplit,
         LiveInterval::Ranges::const_iterator &I,
         MachineInstr *OrigDefMI, MachineInstr *DefMI, unsigned Slot, int LdSlot,
@@ -524,7 +522,7 @@
         BitVector &RestoreMBBs,
         DenseMap<unsigned,std::vector<SRInfo> > &RestoreIdxes,
         DenseMap<unsigned,unsigned> &MBBVRegsMap,
-        std::vector<LiveInterval*> &NewLIs, float &SSWeight);
+        std::vector<LiveInterval*> &NewLIs);
 
     static LiveInterval* createInterval(unsigned Reg);
 

Modified: llvm/branches/Apple/Dib/include/llvm/CodeGen/LiveStackAnalysis.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/include/llvm/CodeGen/LiveStackAnalysis.h?rev=71053&r1=71052&r2=71053&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/include/llvm/CodeGen/LiveStackAnalysis.h (original)
+++ llvm/branches/Apple/Dib/include/llvm/CodeGen/LiveStackAnalysis.h Tue May  5 19:37:50 2009
@@ -18,6 +18,7 @@
 
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/LiveInterval.h"
+#include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/Support/Allocator.h"
 #include <map>
 
@@ -28,44 +29,66 @@
     ///
     BumpPtrAllocator VNInfoAllocator;
 
-    /// s2iMap - Stack slot indices to live interval mapping.
+    /// S2IMap - Stack slot indices to live interval mapping.
     ///
     typedef std::map<int, LiveInterval> SS2IntervalMap;
-    SS2IntervalMap s2iMap;
+    SS2IntervalMap S2IMap;
 
+    /// S2RCMap - Stack slot indices to register class mapping.
+    std::map<int, const TargetRegisterClass*> S2RCMap;
+    
   public:
     static char ID; // Pass identification, replacement for typeid
     LiveStacks() : MachineFunctionPass(&ID) {}
 
     typedef SS2IntervalMap::iterator iterator;
     typedef SS2IntervalMap::const_iterator const_iterator;
-    const_iterator begin() const { return s2iMap.begin(); }
-    const_iterator end() const { return s2iMap.end(); }
-    iterator begin() { return s2iMap.begin(); }
-    iterator end() { return s2iMap.end(); }
-    unsigned getNumIntervals() const { return (unsigned)s2iMap.size(); }
-
-    LiveInterval &getOrCreateInterval(int Slot) {
-      SS2IntervalMap::iterator I = s2iMap.find(Slot);
-      if (I == s2iMap.end())
-        I = s2iMap.insert(I,std::make_pair(Slot,LiveInterval(Slot,0.0F,true)));
+    const_iterator begin() const { return S2IMap.begin(); }
+    const_iterator end() const { return S2IMap.end(); }
+    iterator begin() { return S2IMap.begin(); }
+    iterator end() { return S2IMap.end(); }
+
+    unsigned getNumIntervals() const { return (unsigned)S2IMap.size(); }
+
+    LiveInterval &getOrCreateInterval(int Slot, const TargetRegisterClass *RC) {
+      assert(Slot >= 0 && "Spill slot indice must be >= 0");
+      SS2IntervalMap::iterator I = S2IMap.find(Slot);
+      if (I == S2IMap.end()) {
+        I = S2IMap.insert(I,std::make_pair(Slot, LiveInterval(Slot,0.0F,true)));
+        S2RCMap.insert(std::make_pair(Slot, RC));
+      } else {
+        // Use the largest common subclass register class.
+        const TargetRegisterClass *OldRC = S2RCMap[Slot];
+        S2RCMap[Slot] = getCommonSubClass(OldRC, RC);
+      }
       return I->second;
     }
 
     LiveInterval &getInterval(int Slot) {
-      SS2IntervalMap::iterator I = s2iMap.find(Slot);
-      assert(I != s2iMap.end() && "Interval does not exist for stack slot");
+      assert(Slot >= 0 && "Spill slot indice must be >= 0");
+      SS2IntervalMap::iterator I = S2IMap.find(Slot);
+      assert(I != S2IMap.end() && "Interval does not exist for stack slot");
       return I->second;
     }
 
     const LiveInterval &getInterval(int Slot) const {
-      SS2IntervalMap::const_iterator I = s2iMap.find(Slot);
-      assert(I != s2iMap.end() && "Interval does not exist for stack slot");
+      assert(Slot >= 0 && "Spill slot indice must be >= 0");
+      SS2IntervalMap::const_iterator I = S2IMap.find(Slot);
+      assert(I != S2IMap.end() && "Interval does not exist for stack slot");
       return I->second;
     }
 
-    bool hasInterval(unsigned Slot) const {
-      return s2iMap.count(Slot);
+    bool hasInterval(int Slot) const {
+      return S2IMap.count(Slot);
+    }
+
+    const TargetRegisterClass *getIntervalRegClass(int Slot) const {
+      assert(Slot >= 0 && "Spill slot indice must be >= 0");
+      std::map<int, const TargetRegisterClass*>::const_iterator
+        I = S2RCMap.find(Slot);
+      assert(I != S2RCMap.end() &&
+             "Register class info does not exist for stack slot");
+      return I->second;
     }
 
     BumpPtrAllocator& getVNInfoAllocator() { return VNInfoAllocator; }

Modified: llvm/branches/Apple/Dib/include/llvm/Target/TargetInstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/include/llvm/Target/TargetInstrInfo.h?rev=71053&r1=71052&r2=71053&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/include/llvm/Target/TargetInstrInfo.h (original)
+++ llvm/branches/Apple/Dib/include/llvm/Target/TargetInstrInfo.h Tue May  5 19:37:50 2009
@@ -20,6 +20,7 @@
 namespace llvm {
 
 class TargetRegisterClass;
+class TargetRegisterInfo;
 class LiveVariables;
 class CalleeSavedInfo;
 class SDNode;
@@ -391,7 +392,7 @@
   /// possible, returns true as well as the new instructions by reference.
   virtual bool unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI,
                                 unsigned Reg, bool UnfoldLoad, bool UnfoldStore,
-                                  SmallVectorImpl<MachineInstr*> &NewMIs) const{
+                                 SmallVectorImpl<MachineInstr*> &NewMIs) const{
     return false;
   }
 
@@ -505,6 +506,12 @@
   virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const;
 };
 
+/// getInstrOperandRegClass - Return register class of the operand of an
+/// instruction of the specified TargetInstrDesc.
+const TargetRegisterClass*
+getInstrOperandRegClass(const TargetRegisterInfo *TRI,
+                        const TargetInstrDesc &II, unsigned Op);
+
 } // End llvm namespace
 
 #endif

Modified: llvm/branches/Apple/Dib/include/llvm/Target/TargetRegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/include/llvm/Target/TargetRegisterInfo.h?rev=71053&r1=71052&r2=71053&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/include/llvm/Target/TargetRegisterInfo.h (original)
+++ llvm/branches/Apple/Dib/include/llvm/Target/TargetRegisterInfo.h Tue May  5 19:37:50 2009
@@ -228,8 +228,6 @@
     return end();
   }
 
-
-
   /// getSize - Return the size of the register in bytes, which is also the size
   /// of a stack slot allocated to hold a spilled copy of this register.
   unsigned getSize() const { return RegSize; }
@@ -630,6 +628,7 @@
   virtual void getInitialFrameState(std::vector<MachineMove> &Moves) const;
 };
 
+
 // This is useful when building IndexedMaps keyed on virtual registers
 struct VirtReg2IndexFunctor : std::unary_function<unsigned, unsigned> {
   unsigned operator()(unsigned Reg) const {
@@ -637,6 +636,11 @@
   }
 };
 
+/// getCommonSubClass - find the largest common subclass of A and B. Return NULL
+/// if there is no common subclass.
+const TargetRegisterClass *getCommonSubClass(const TargetRegisterClass *A,
+                                             const TargetRegisterClass *B);
+
 } // End llvm namespace
 
 #endif

Modified: llvm/branches/Apple/Dib/lib/CodeGen/LLVMTargetMachine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/LLVMTargetMachine.cpp?rev=71053&r1=71052&r2=71053&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/LLVMTargetMachine.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/LLVMTargetMachine.cpp Tue May  5 19:37:50 2009
@@ -193,7 +193,7 @@
 
   // Perform stack slot coloring.
   if (OptLevel != CodeGenOpt::None)
-    PM.add(createStackSlotColoringPass());
+    PM.add(createStackSlotColoringPass(OptLevel >= CodeGenOpt::Aggressive));
 
   if (PrintMachineCode)  // Print the register-allocated code
     PM.add(createMachineFunctionPrinterPass(cerr));

Modified: llvm/branches/Apple/Dib/lib/CodeGen/LiveIntervalAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=71053&r1=71052&r2=71053&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/LiveIntervalAnalysis.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/LiveIntervalAnalysis.cpp Tue May  5 19:37:50 2009
@@ -1229,9 +1229,7 @@
                  const MachineLoopInfo *loopInfo,
                  unsigned &NewVReg, unsigned ImpUse, bool &HasDef, bool &HasUse,
                  DenseMap<unsigned,unsigned> &MBBVRegsMap,
-                 std::vector<LiveInterval*> &NewLIs, float &SSWeight) {
-  MachineBasicBlock *MBB = MI->getParent();
-  unsigned loopDepth = loopInfo->getLoopDepth(MBB);
+                 std::vector<LiveInterval*> &NewLIs) {
   bool CanFold = false;
  RestartInstruction:
   for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
@@ -1312,11 +1310,6 @@
       // the INSERT_SUBREG and both target registers that would overlap.
       HasUse = false;
 
-    // Update stack slot spill weight if we are splitting.
-    float Weight = getSpillWeight(HasDef, HasUse, loopDepth);
-    if (!TrySplit)
-      SSWeight += Weight;
-
     // Create a new virtual register for the spill interval.
     // Create the new register now so we can map the fold instruction
     // to the new register so when it is unfolded we get the correct
@@ -1348,10 +1341,8 @@
           HasUse = false;
           HasDef = false;
           CanFold = false;
-          if (isNotInMIMap(MI)) {
-            SSWeight -= Weight;
+          if (isNotInMIMap(MI))
             break;
-          }
           goto RestartInstruction;
         }
       } else {
@@ -1486,7 +1477,7 @@
                     BitVector &RestoreMBBs,
                     DenseMap<unsigned, std::vector<SRInfo> > &RestoreIdxes,
                     DenseMap<unsigned,unsigned> &MBBVRegsMap,
-                    std::vector<LiveInterval*> &NewLIs, float &SSWeight) {
+                    std::vector<LiveInterval*> &NewLIs) {
   bool AllCanFold = true;
   unsigned NewVReg = 0;
   unsigned start = getBaseIndex(I->start);
@@ -1588,7 +1579,7 @@
                          index, end, MI, ReMatOrigDefMI, ReMatDefMI,
                          Slot, LdSlot, isLoad, isLoadSS, DefIsReMat,
                          CanDelete, vrm, rc, ReMatIds, loopInfo, NewVReg,
-                         ImpUse, HasDef, HasUse, MBBVRegsMap, NewLIs, SSWeight);
+                         ImpUse, HasDef, HasUse, MBBVRegsMap, NewLIs);
     if (!HasDef && !HasUse)
       continue;
 
@@ -1747,7 +1738,7 @@
 std::vector<LiveInterval*> LiveIntervals::
 addIntervalsForSpillsFast(const LiveInterval &li,
                           const MachineLoopInfo *loopInfo,
-                          VirtRegMap &vrm, float& SSWeight) {
+                          VirtRegMap &vrm) {
   unsigned slot = vrm.assignVirt2StackSlot(li.reg);
 
   std::vector<LiveInterval*> added;
@@ -1761,8 +1752,6 @@
 
   const TargetRegisterClass* rc = mri_->getRegClass(li.reg);
 
-  SSWeight = 0.0f;
-
   MachineRegisterInfo::reg_iterator RI = mri_->reg_begin(li.reg);
   while (RI != mri_->reg_end()) {
     MachineInstr* MI = &*RI;
@@ -1825,15 +1814,6 @@
       DOUT << "\t\t\t\tadded new interval: ";
       DEBUG(nI.dump());
       DOUT << '\n';
-      
-      unsigned loopDepth = loopInfo->getLoopDepth(MI->getParent());
-      if (HasUse) {
-        if (HasDef)
-          SSWeight += getSpillWeight(true, true, loopDepth);
-        else
-          SSWeight += getSpillWeight(false, true, loopDepth);
-      } else
-        SSWeight += getSpillWeight(true, false, loopDepth);
     }
     
     
@@ -1846,11 +1826,10 @@
 std::vector<LiveInterval*> LiveIntervals::
 addIntervalsForSpills(const LiveInterval &li,
                       SmallVectorImpl<LiveInterval*> &SpillIs,
-                      const MachineLoopInfo *loopInfo, VirtRegMap &vrm,
-                      float &SSWeight) {
+                      const MachineLoopInfo *loopInfo, VirtRegMap &vrm) {
   
   if (EnableFastSpilling)
-    return addIntervalsForSpillsFast(li, loopInfo, vrm, SSWeight);
+    return addIntervalsForSpillsFast(li, loopInfo, vrm);
   
   assert(li.weight != HUGE_VALF &&
          "attempt to spill already spilled interval!");
@@ -1859,9 +1838,6 @@
   li.print(DOUT, tri_);
   DOUT << '\n';
 
-  // Spill slot weight.
-  SSWeight = 0.0f;
-
   // Each bit specify whether a spill is required in the MBB.
   BitVector SpillMBBs(mf_->getNumBlockIDs());
   DenseMap<unsigned, std::vector<SRInfo> > SpillIdxes;
@@ -1916,18 +1892,17 @@
                              Slot, LdSlot, isLoad, isLoadSS, DefIsReMat,
                              false, vrm, rc, ReMatIds, loopInfo,
                              SpillMBBs, SpillIdxes, RestoreMBBs, RestoreIdxes,
-                             MBBVRegsMap, NewLIs, SSWeight);
+                             MBBVRegsMap, NewLIs);
       } else {
         rewriteInstructionsForSpills(li, false, I, NULL, 0,
                              Slot, 0, false, false, false,
                              false, vrm, rc, ReMatIds, loopInfo,
                              SpillMBBs, SpillIdxes, RestoreMBBs, RestoreIdxes,
-                             MBBVRegsMap, NewLIs, SSWeight);
+                             MBBVRegsMap, NewLIs);
       }
       IsFirstRange = false;
     }
 
-    SSWeight = 0.0f;  // Already accounted for when split.
     handleSpilledImpDefs(li, vrm, rc, NewLIs);
     return NewLIs;
   }
@@ -2001,7 +1976,7 @@
                                Slot, LdSlot, isLoad, isLoadSS, DefIsReMat,
                                CanDelete, vrm, rc, ReMatIds, loopInfo,
                                SpillMBBs, SpillIdxes, RestoreMBBs, RestoreIdxes,
-                               MBBVRegsMap, NewLIs, SSWeight);
+                               MBBVRegsMap, NewLIs);
   }
 
   // Insert spills / restores if we are splitting.
@@ -2015,8 +1990,6 @@
   if (NeedStackSlot) {
     int Id = SpillMBBs.find_first();
     while (Id != -1) {
-      MachineBasicBlock *MBB = mf_->getBlockNumbered(Id);
-      unsigned loopDepth = loopInfo->getLoopDepth(MBB);
       std::vector<SRInfo> &spills = SpillIdxes[Id];
       for (unsigned i = 0, e = spills.size(); i != e; ++i) {
         int index = spills[i].index;
@@ -2073,10 +2046,6 @@
           if (isKill)
             AddedKill.insert(&nI);
         }
-
-        // Update spill slot weight.
-        if (!isReMat)
-          SSWeight += getSpillWeight(true, false, loopDepth);
       }
       Id = SpillMBBs.find_next(Id);
     }
@@ -2084,9 +2053,6 @@
 
   int Id = RestoreMBBs.find_first();
   while (Id != -1) {
-    MachineBasicBlock *MBB = mf_->getBlockNumbered(Id);
-    unsigned loopDepth = loopInfo->getLoopDepth(MBB);
-
     std::vector<SRInfo> &restores = RestoreIdxes[Id];
     for (unsigned i = 0, e = restores.size(); i != e; ++i) {
       int index = restores[i].index;
@@ -2148,10 +2114,6 @@
         nI.removeRange(getLoadIndex(index), getUseIndex(index)+1);
       else
         vrm.addRestorePoint(VReg, MI);
-
-      // Update spill slot weight.
-      if (!isReMat)
-        SSWeight += getSpillWeight(false, true, loopDepth);
     }
     Id = RestoreMBBs.find_next(Id);
   }

Modified: llvm/branches/Apple/Dib/lib/CodeGen/LiveStackAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/LiveStackAnalysis.cpp?rev=71053&r1=71052&r2=71053&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/LiveStackAnalysis.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/LiveStackAnalysis.cpp Tue May  5 19:37:50 2009
@@ -32,7 +32,8 @@
 void LiveStacks::releaseMemory() {
   // Release VNInfo memroy regions after all VNInfo objects are dtor'd.
   VNInfoAllocator.Reset();
-  s2iMap.clear();
+  S2IMap.clear();
+  S2RCMap.clear();
 }
 
 bool LiveStacks::runOnMachineFunction(MachineFunction &) {
@@ -42,10 +43,15 @@
 }
 
 /// print - Implement the dump method.
-void LiveStacks::print(std::ostream &O, const Module* ) const {
+void LiveStacks::print(std::ostream &O, const Module*) const {
   O << "********** INTERVALS **********\n";
   for (const_iterator I = begin(), E = end(); I != E; ++I) {
     I->second.print(O);
-    O << "\n";
+    int Slot = I->first;
+    const TargetRegisterClass *RC = getIntervalRegClass(Slot);
+    if (RC)
+      O << " [" << RC->getName() << "]\n";
+    else
+      O << " [Unknown]\n";
   }
 }

Removed: llvm/branches/Apple/Dib/lib/CodeGen/PhysRegTracker.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/PhysRegTracker.h?rev=71052&view=auto

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/PhysRegTracker.h (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/PhysRegTracker.h (removed)
@@ -1,73 +0,0 @@
-//===-- llvm/CodeGen/PhysRegTracker.h - Physical Register Tracker -*- C++ -*-=//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements a physical register tracker. The tracker
-// tracks physical register usage through addRegUse and
-// delRegUse. isRegAvail checks if a physical register is available or
-// not taking into consideration register aliases.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_PHYSREGTRACKER_H
-#define LLVM_CODEGEN_PHYSREGTRACKER_H
-
-#include "llvm/Target/TargetRegisterInfo.h"
-
-namespace llvm {
-
-    class PhysRegTracker {
-        const TargetRegisterInfo* tri_;
-        std::vector<unsigned> regUse_;
-
-    public:
-        explicit PhysRegTracker(const TargetRegisterInfo& tri)
-            : tri_(&tri),
-              regUse_(tri_->getNumRegs(), 0) {
-        }
-
-        PhysRegTracker(const PhysRegTracker& rhs)
-            : tri_(rhs.tri_),
-              regUse_(rhs.regUse_) {
-        }
-
-        const PhysRegTracker& operator=(const PhysRegTracker& rhs) {
-            tri_ = rhs.tri_;
-            regUse_ = rhs.regUse_;
-            return *this;
-        }
-
-        void addRegUse(unsigned physReg) {
-            assert(TargetRegisterInfo::isPhysicalRegister(physReg) &&
-                   "should be physical register!");
-            ++regUse_[physReg];
-            for (const unsigned* as = tri_->getAliasSet(physReg); *as; ++as)
-                ++regUse_[*as];
-        }
-
-        void delRegUse(unsigned physReg) {
-            assert(TargetRegisterInfo::isPhysicalRegister(physReg) &&
-                   "should be physical register!");
-            assert(regUse_[physReg] != 0);
-            --regUse_[physReg];
-            for (const unsigned* as = tri_->getAliasSet(physReg); *as; ++as) {
-                assert(regUse_[*as] != 0);
-                --regUse_[*as];
-            }
-        }
-
-        bool isRegAvail(unsigned physReg) const {
-            assert(TargetRegisterInfo::isPhysicalRegister(physReg) &&
-                   "should be physical register!");
-            return regUse_[physReg] == 0;
-        }
-    };
-
-} // End llvm namespace
-
-#endif

Modified: llvm/branches/Apple/Dib/lib/CodeGen/PostRASchedulerList.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/PostRASchedulerList.cpp?rev=71053&r1=71052&r2=71053&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/PostRASchedulerList.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/PostRASchedulerList.cpp Tue May  5 19:37:50 2009
@@ -418,18 +418,6 @@
   ScheduleDAGInstrs::FinishBlock();
 }
 
-/// getInstrOperandRegClass - Return register class of the operand of an
-/// instruction of the specified TargetInstrDesc.
-static const TargetRegisterClass*
-getInstrOperandRegClass(const TargetRegisterInfo *TRI,
-                         const TargetInstrDesc &II, unsigned Op) {
-  if (Op >= II.getNumOperands())
-    return NULL;
-  if (II.OpInfo[Op].isLookupPtrRegClass())
-    return TRI->getPointerRegClass();
-  return TRI->getRegClass(II.OpInfo[Op].RegClass);
-}
-
 /// CriticalPathStep - Return the next SUnit after SU on the bottom-up
 /// critical path.
 static SDep *CriticalPathStep(SUnit *SU) {

Modified: llvm/branches/Apple/Dib/lib/CodeGen/PreAllocSplitting.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/PreAllocSplitting.cpp?rev=71053&r1=71052&r2=71053&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/PreAllocSplitting.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/PreAllocSplitting.cpp Tue May  5 19:37:50 2009
@@ -339,7 +339,7 @@
   }
 
   // Create live interval for stack slot.
-  CurrSLI = &LSs->getOrCreateInterval(SS);
+  CurrSLI = &LSs->getOrCreateInterval(SS, RC);
   if (CurrSLI->hasAtLeastOneValue())
     CurrSValNo = CurrSLI->getValNumInfo(0);
   else
@@ -926,8 +926,7 @@
   if (I != IntervalSSMap.end()) {
     SS = I->second;
   } else {
-    SS = MFI->CreateStackObject(RC->getSize(), RC->getAlignment());
-    
+    SS = MFI->CreateStackObject(RC->getSize(), RC->getAlignment());    
   }
   
   MachineInstr* FMI = TII->foldMemoryOperand(*MBB->getParent(),
@@ -939,7 +938,7 @@
     ++NumFolds;
     
     IntervalSSMap[vreg] = SS;
-    CurrSLI = &LSs->getOrCreateInterval(SS);
+    CurrSLI = &LSs->getOrCreateInterval(SS, RC);
     if (CurrSLI->hasAtLeastOneValue())
       CurrSValNo = CurrSLI->getValNumInfo(0);
     else

Modified: llvm/branches/Apple/Dib/lib/CodeGen/RegAllocLinearScan.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/RegAllocLinearScan.cpp?rev=71053&r1=71052&r2=71053&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/RegAllocLinearScan.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/RegAllocLinearScan.cpp Tue May  5 19:37:50 2009
@@ -12,7 +12,6 @@
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "regalloc"
-#include "PhysRegTracker.h"
 #include "VirtRegMap.h"
 #include "Spiller.h"
 #include "llvm/Function.h"
@@ -118,8 +117,14 @@
                                 SmallVector<LiveInterval*, 64>,
                                 greater_ptr<LiveInterval> > IntervalHeap;
     IntervalHeap unhandled_;
-    std::auto_ptr<PhysRegTracker> prt_;
+
+    /// regUse_ - Tracks register usage.
+    SmallVector<unsigned, 32> regUse_;
+    SmallVector<unsigned, 32> regUseBackUp_;
+
+    /// vrm_ - Tracks register assignments.
     VirtRegMap* vrm_;
+
     std::auto_ptr<Spiller> spiller_;
 
   public:
@@ -202,7 +207,66 @@
     unsigned attemptTrivialCoalescing(LiveInterval &cur, unsigned Reg);
 
     ///
-    /// register handling helpers
+    /// Register usage / availability tracking helpers.
+    ///
+
+    void initRegUses() {
+      regUse_.resize(tri_->getNumRegs(), 0);
+      regUseBackUp_.resize(tri_->getNumRegs(), 0);
+    }
+
+    void finalizeRegUses() {
+#ifndef NDEBUG
+      // Verify all the registers are "freed".
+      bool Error = false;
+      for (unsigned i = 0, e = tri_->getNumRegs(); i != e; ++i) {
+        if (regUse_[i] != 0) {
+          cerr << tri_->getName(i) << " is still in use!\n";
+          Error = true;
+        }
+      }
+      if (Error)
+        abort();
+#endif
+      regUse_.clear();
+      regUseBackUp_.clear();
+    }
+
+    void addRegUse(unsigned physReg) {
+      assert(TargetRegisterInfo::isPhysicalRegister(physReg) &&
+             "should be physical register!");
+      ++regUse_[physReg];
+      for (const unsigned* as = tri_->getAliasSet(physReg); *as; ++as)
+        ++regUse_[*as];
+    }
+
+    void delRegUse(unsigned physReg) {
+      assert(TargetRegisterInfo::isPhysicalRegister(physReg) &&
+             "should be physical register!");
+      assert(regUse_[physReg] != 0);
+      --regUse_[physReg];
+      for (const unsigned* as = tri_->getAliasSet(physReg); *as; ++as) {
+        assert(regUse_[*as] != 0);
+        --regUse_[*as];
+      }
+    }
+
+    bool isRegAvail(unsigned physReg) const {
+      assert(TargetRegisterInfo::isPhysicalRegister(physReg) &&
+             "should be physical register!");
+      return regUse_[physReg] == 0;
+    }
+
+    void backUpRegUses() {
+      regUseBackUp_ = regUse_;
+    }
+
+    void restoreRegUses() {
+      regUse_ = regUseBackUp_;
+    }
+
+    ///
+    /// Register handling helpers.
     ///
 
     /// getFreePhysReg - return a free physical register for this virtual
@@ -335,8 +399,10 @@
   // If this is the first function compiled, compute the related reg classes.
   if (RelatedRegClasses.empty())
     ComputeRelatedRegClasses();
-  
-  if (!prt_.get()) prt_.reset(new PhysRegTracker(*tri_));
+
+  // Also resize register usage trackers.
+  initRegUses();
+
   vrm_ = &getAnalysis<VirtRegMap>();
   if (!spiller_.get()) spiller_.reset(createSpiller());
 
@@ -348,6 +414,9 @@
   spiller_->runOnMachineFunction(*mf_, *vrm_, li_);
 
   assert(unhandled_.empty() && "Unhandled live intervals remain!");
+
+  finalizeRegUses();
+
   fixed_.clear();
   active_.clear();
   inactive_.clear();
@@ -410,7 +479,7 @@
     DEBUG(printIntervals("inactive", inactive_.begin(), inactive_.end()));
   }
 
-  // expire any remaining active intervals
+  // Expire any remaining active intervals
   while (!active_.empty()) {
     IntervalPtr &IP = active_.back();
     unsigned reg = IP.first->reg;
@@ -418,11 +487,11 @@
     assert(TargetRegisterInfo::isVirtualRegister(reg) &&
            "Can only allocate virtual registers!");
     reg = vrm_->getPhys(reg);
-    prt_->delRegUse(reg);
+    delRegUse(reg);
     active_.pop_back();
   }
 
-  // expire any remaining inactive intervals
+  // Expire any remaining inactive intervals
   DEBUG(for (IntervalPtrs::reverse_iterator
                i = inactive_.rbegin(); i != inactive_.rend(); ++i)
         DOUT << "\tinterval " << *i->first << " expired\n");
@@ -457,6 +526,13 @@
   }
 
   DOUT << *vrm_;
+
+  // Look for physical registers that end up not being allocated even though
+  // register allocator had to spill other registers in its register class.
+  if (ls_->getNumIntervals() == 0)
+    return;
+  if (!vrm_->FindUnusedRegisters(tri_, li_))
+    return;
 }
 
 /// processActiveIntervals - expire old intervals and move non-overlapping ones
@@ -477,7 +553,7 @@
       assert(TargetRegisterInfo::isVirtualRegister(reg) &&
              "Can only allocate virtual registers!");
       reg = vrm_->getPhys(reg);
-      prt_->delRegUse(reg);
+      delRegUse(reg);
 
       // Pop off the end of the list.
       active_[i] = active_.back();
@@ -490,7 +566,7 @@
       assert(TargetRegisterInfo::isVirtualRegister(reg) &&
              "Can only allocate virtual registers!");
       reg = vrm_->getPhys(reg);
-      prt_->delRegUse(reg);
+      delRegUse(reg);
       // add to inactive.
       inactive_.push_back(std::make_pair(Interval, IntervalPos));
 
@@ -531,7 +607,7 @@
       assert(TargetRegisterInfo::isVirtualRegister(reg) &&
              "Can only allocate virtual registers!");
       reg = vrm_->getPhys(reg);
-      prt_->addRegUse(reg);
+      addRegUse(reg);
       // add to active
       active_.push_back(std::make_pair(Interval, IntervalPos));
 
@@ -573,9 +649,9 @@
   //      bl should get the same spill weight otherwise it will be choosen
   //      as a spill candidate since spilling bh doesn't make ebx available.
   for (unsigned i = 0, e = Supers.size(); i != e; ++i) {
-      for (const unsigned *sr = tri_->getSubRegisters(Supers[i]); *sr; ++sr)
-        if (!Processed.count(*sr))
-          Weights[*sr] += weight;
+    for (const unsigned *sr = tri_->getSubRegisters(Supers[i]); *sr; ++sr)
+      if (!Processed.count(*sr))
+        Weights[*sr] += weight;
   }
 }
 
@@ -601,13 +677,14 @@
 /// addStackInterval - Create a LiveInterval for stack if the specified live
 /// interval has been spilled.
 static void addStackInterval(LiveInterval *cur, LiveStacks *ls_,
-                             LiveIntervals *li_, float &Weight,
-                             VirtRegMap &vrm_) {
+                             LiveIntervals *li_,
+                             MachineRegisterInfo* mri_, VirtRegMap &vrm_) {
   int SS = vrm_.getStackSlot(cur->reg);
   if (SS == VirtRegMap::NO_STACK_SLOT)
     return;
-  LiveInterval &SI = ls_->getOrCreateInterval(SS);
-  SI.weight += Weight;
+
+  const TargetRegisterClass *RC = mri_->getRegClass(cur->reg);
+  LiveInterval &SI = ls_->getOrCreateInterval(SS, RC);
 
   VNInfo *VNI;
   if (SI.hasAtLeastOneValue())
@@ -622,10 +699,10 @@
 
 /// getConflictWeight - Return the number of conflicts between cur
 /// live interval and defs and uses of Reg weighted by loop depthes.
-static float getConflictWeight(LiveInterval *cur, unsigned Reg,
-                                  LiveIntervals *li_,
-                                  MachineRegisterInfo *mri_,
-                                  const MachineLoopInfo *loopInfo) {
+static
+float getConflictWeight(LiveInterval *cur, unsigned Reg, LiveIntervals *li_,
+                        MachineRegisterInfo *mri_,
+                        const MachineLoopInfo *loopInfo) {
   float Conflicts = 0;
   for (MachineRegisterInfo::reg_iterator I = mri_->reg_begin(Reg),
          E = mri_->reg_end(); I != E; ++I) {
@@ -776,7 +853,7 @@
     return;
   }
 
-  PhysRegTracker backupPrt = *prt_;
+  backUpRegUses();
 
   std::vector<std::pair<unsigned, float> > SpillWeightsToAdd;
   unsigned StartPosition = cur->beginNumber();
@@ -811,7 +888,7 @@
     }
   }
 
-  // for every interval in inactive we overlap with, mark the
+  // For every interval in inactive we overlap with, mark the
   // register as not free and update spill weights.
   for (IntervalPtrs::const_iterator i = inactive_.begin(),
          e = inactive_.end(); i != e; ++i) {
@@ -824,7 +901,7 @@
     if (RelatedRegClasses.getLeaderValue(RegRC) == RCLeader &&
         cur->overlapsFrom(*i->first, i->second-1)) {
       Reg = vrm_->getPhys(Reg);
-      prt_->addRegUse(Reg);
+      addRegUse(Reg);
       SpillWeightsToAdd.push_back(std::make_pair(Reg, i->first->weight));
     }
   }
@@ -866,7 +943,7 @@
     
     // Okay, the register picked by our speculative getFreePhysReg call turned
     // out to be in use.  Actually add all of the conflicting fixed registers to
-    // prt so we can do an accurate query.
+    // regUse_ so we can do an accurate query.
     if (ConflictsWithFixed) {
       // For every interval in fixed we overlap with, mark the register as not
       // free and update spill weights.
@@ -883,13 +960,13 @@
             --II;
           if (cur->overlapsFrom(*I, II)) {
             unsigned reg = I->reg;
-            prt_->addRegUse(reg);
+            addRegUse(reg);
             SpillWeightsToAdd.push_back(std::make_pair(reg, I->weight));
           }
         }
       }
 
-      // Using the newly updated prt_ object, which includes conflicts in the
+      // Using the newly updated regUse_ object, which includes conflicts in the
       // future, see if there are any registers available.
       physReg = getFreePhysReg(cur);
     }
@@ -897,15 +974,15 @@
     
   // Restore the physical register tracker, removing information about the
   // future.
-  *prt_ = backupPrt;
+  restoreRegUses();
   
-  // if we find a free register, we are done: assign this virtual to
+  // If we find a free register, we are done: assign this virtual to
   // the free physical register and add this interval to the active
   // list.
   if (physReg) {
     DOUT <<  tri_->getName(physReg) << '\n';
     vrm_->assignVirt2Phys(cur->reg, physReg);
-    prt_->addRegUse(physReg);
+    addRegUse(physReg);
     active_.push_back(std::make_pair(cur, cur->begin()));
     handled_.push_back(cur);
 
@@ -1015,12 +1092,11 @@
   // linearscan.
   if (cur->weight != HUGE_VALF && cur->weight <= minWeight) {
     DOUT << "\t\t\tspilling(c): " << *cur << '\n';
-    float SSWeight;
     SmallVector<LiveInterval*, 8> spillIs;
     std::vector<LiveInterval*> added =
-      li_->addIntervalsForSpills(*cur, spillIs, loopInfo, *vrm_, SSWeight);
+      li_->addIntervalsForSpills(*cur, spillIs, loopInfo, *vrm_);
     std::sort(added.begin(), added.end(), LISorter());
-    addStackInterval(cur, ls_, li_, SSWeight, *vrm_);
+    addStackInterval(cur, ls_, li_, mri_, *vrm_);
     if (added.empty())
       return;  // Early exit if all spills were folded.
 
@@ -1092,10 +1168,9 @@
     spillIs.pop_back();
     DOUT << "\t\t\tspilling(a): " << *sli << '\n';
     earliestStart = std::min(earliestStart, sli->beginNumber());
-    float SSWeight;
     std::vector<LiveInterval*> newIs =
-      li_->addIntervalsForSpills(*sli, spillIs, loopInfo, *vrm_, SSWeight);
-    addStackInterval(sli, ls_, li_, SSWeight, *vrm_);
+      li_->addIntervalsForSpills(*sli, spillIs, loopInfo, *vrm_);
+    addStackInterval(sli, ls_, li_, mri_, *vrm_);
     std::copy(newIs.begin(), newIs.end(), std::back_inserter(added));
     spilled.insert(sli->reg);
   }
@@ -1114,14 +1189,14 @@
     handled_.pop_back();
 
     // When undoing a live interval allocation we must know if it is active or
-    // inactive to properly update the PhysRegTracker and the VirtRegMap.
+    // inactive to properly update regUse_ and the VirtRegMap.
     IntervalPtrs::iterator it;
     if ((it = FindIntervalInVector(active_, i)) != active_.end()) {
       active_.erase(it);
       assert(!TargetRegisterInfo::isPhysicalRegister(i->reg));
       if (!spilled.count(i->reg))
         unhandled_.push(i);
-      prt_->delRegUse(vrm_->getPhys(i->reg));
+      delRegUse(vrm_->getPhys(i->reg));
       vrm_->clearVirt(i->reg);
     } else if ((it = FindIntervalInVector(inactive_, i)) != inactive_.end()) {
       inactive_.erase(it);
@@ -1163,7 +1238,7 @@
       DOUT << "\t\t\tundo changes for: " << *HI << '\n';
       active_.push_back(std::make_pair(HI, HI->begin()));
       assert(!TargetRegisterInfo::isPhysicalRegister(HI->reg));
-      prt_->addRegUse(vrm_->getPhys(HI->reg));
+      addRegUse(vrm_->getPhys(HI->reg));
     }
   }
 
@@ -1214,7 +1289,7 @@
     // Ignore "downgraded" registers.
     if (SkipDGRegs && DowngradedRegs.count(Reg))
       continue;
-    if (prt_->isRegAvail(Reg)) {
+    if (isRegAvail(Reg)) {
       FreeReg = Reg;
       if (FreeReg < inactiveCounts.size())
         FreeRegInactiveCount = inactiveCounts[FreeReg];
@@ -1238,7 +1313,7 @@
     // Ignore "downgraded" registers.
     if (SkipDGRegs && DowngradedRegs.count(Reg))
       continue;
-    if (prt_->isRegAvail(Reg) && Reg < inactiveCounts.size() &&
+    if (isRegAvail(Reg) && Reg < inactiveCounts.size() &&
         FreeRegInactiveCount < inactiveCounts[Reg]) {
       FreeReg = Reg;
       FreeRegInactiveCount = inactiveCounts[Reg];
@@ -1281,7 +1356,7 @@
   // available first.
   if (cur->preference) {
     DOUT << "(preferred: " << tri_->getName(cur->preference) << ") ";
-    if (prt_->isRegAvail(cur->preference) && 
+    if (isRegAvail(cur->preference) && 
         RC->contains(cur->preference))
       return cur->preference;
   }

Modified: llvm/branches/Apple/Dib/lib/CodeGen/RegAllocPBQP.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/RegAllocPBQP.cpp?rev=71053&r1=71052&r2=71053&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/RegAllocPBQP.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/RegAllocPBQP.cpp Tue May  5 19:37:50 2009
@@ -165,7 +165,7 @@
 
     //! \brief Adds a stack interval if the given live interval has been
     //! spilled. Used to support stack slot coloring.
-    void addStackInterval(const LiveInterval *spilled, float &weight);
+    void addStackInterval(const LiveInterval *spilled,MachineRegisterInfo* mri);
 
     //! \brief Given a solved PBQP problem maps this solution back to a register
     //! assignment.
@@ -637,14 +637,15 @@
   return solver;
 }
 
-void PBQPRegAlloc::addStackInterval(const LiveInterval *spilled, float &weight) {
+void PBQPRegAlloc::addStackInterval(const LiveInterval *spilled,
+                                    MachineRegisterInfo* mri) {
   int stackSlot = vrm->getStackSlot(spilled->reg);
 
   if (stackSlot == VirtRegMap::NO_STACK_SLOT)
     return;
 
-  LiveInterval &stackInterval = lss->getOrCreateInterval(stackSlot);
-  stackInterval.weight += weight;
+  const TargetRegisterClass *RC = mri->getRegClass(spilled->reg);
+  LiveInterval &stackInterval = lss->getOrCreateInterval(stackSlot, RC);
 
   VNInfo *vni;
   if (stackInterval.getNumValNums() != 0)
@@ -688,16 +689,13 @@
       // of allocation
       vregIntervalsToAlloc.erase(&lis->getInterval(virtReg));
 
-      float ssWeight;
-
       // Insert spill ranges for this live range
       const LiveInterval *spillInterval = node2LI[node];
       double oldSpillWeight = spillInterval->weight;
       SmallVector<LiveInterval*, 8> spillIs;
       std::vector<LiveInterval*> newSpills =
-        lis->addIntervalsForSpills(*spillInterval, spillIs, loopInfo, *vrm,
-                                   ssWeight);
-      addStackInterval(spillInterval, ssWeight);
+        lis->addIntervalsForSpills(*spillInterval, spillIs, loopInfo, *vrm);
+      addStackInterval(spillInterval, mri);
 
       DOUT << "VREG " << virtReg << " -> SPILLED (Cost: "
            << oldSpillWeight << ", New vregs: ";

Modified: llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp?rev=71053&r1=71052&r2=71053&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp Tue May  5 19:37:50 2009
@@ -28,20 +28,6 @@
 #include "llvm/Support/MathExtras.h"
 using namespace llvm;
 
-/// getInstrOperandRegClass - Return register class of the operand of an
-/// instruction of the specified TargetInstrDesc.
-static const TargetRegisterClass*
-getInstrOperandRegClass(const TargetRegisterInfo *TRI, 
-                        const TargetInstrDesc &II, unsigned Op) {
-  if (Op >= II.getNumOperands()) {
-    assert(II.isVariadic() && "Invalid operand # of instruction");
-    return NULL;
-  }
-  if (II.OpInfo[Op].isLookupPtrRegClass())
-    return TRI->getPointerRegClass();
-  return TRI->getRegClass(II.OpInfo[Op].RegClass);
-}
-
 /// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an
 /// implicit physical register output.
 void ScheduleDAGSDNodes::EmitCopyFromReg(SDNode *Node, unsigned ResNo,

Modified: llvm/branches/Apple/Dib/lib/CodeGen/StackSlotColoring.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/StackSlotColoring.cpp?rev=71053&r1=71052&r2=71053&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/StackSlotColoring.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/StackSlotColoring.cpp Tue May  5 19:37:50 2009
@@ -12,9 +12,13 @@
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "stackcoloring"
+#include "VirtRegMap.h"
 #include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/LiveIntervalAnalysis.h"
 #include "llvm/CodeGen/LiveStackAnalysis.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/PseudoSourceValue.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Compiler.h"
@@ -32,21 +36,37 @@
              cl::init(false), cl::Hidden,
              cl::desc("Suppress slot sharing during stack coloring"));
 
+static cl::opt<bool>
+ColorWithRegsOpt("color-ss-with-regs",
+                 cl::init(false), cl::Hidden,
+                 cl::desc("Color stack slots with free registers"));
+
+
 static cl::opt<int> DCELimit("ssc-dce-limit", cl::init(-1), cl::Hidden);
 
-STATISTIC(NumEliminated,   "Number of stack slots eliminated due to coloring");
-STATISTIC(NumDeadAccesses,
-                          "Number of trivially dead stack accesses eliminated");
+STATISTIC(NumEliminated, "Number of stack slots eliminated due to coloring");
+STATISTIC(NumRegRepl,    "Number of stack slot refs replaced with reg refs");
+STATISTIC(NumLoadElim,   "Number of loads eliminated");
+STATISTIC(NumStoreElim,  "Number of stores eliminated");
+STATISTIC(NumDead,       "Number of trivially dead stack accesses eliminated");
 
 namespace {
   class VISIBILITY_HIDDEN StackSlotColoring : public MachineFunctionPass {
+    bool ColorWithRegs;
     LiveStacks* LS;
+    VirtRegMap* VRM;
     MachineFrameInfo *MFI;
+    MachineRegisterInfo *MRI;
     const TargetInstrInfo  *TII;
+    const TargetRegisterInfo *TRI;
+    const MachineLoopInfo *loopInfo;
 
     // SSIntervals - Spill slot intervals.
     std::vector<LiveInterval*> SSIntervals;
 
+    // SSRefs - Keep a list of frame index references for each spill slot.
+    SmallVector<SmallVector<MachineInstr*, 8>, 16> SSRefs;
+
     // OrigAlignments - Alignments of stack objects before coloring.
     SmallVector<unsigned, 16> OrigAlignments;
 
@@ -66,16 +86,21 @@
     BitVector UsedColors;
 
     // Assignments - Color to intervals mapping.
-    SmallVector<SmallVector<LiveInterval*,4>,16> Assignments;
+    SmallVector<SmallVector<LiveInterval*,4>, 16> Assignments;
 
   public:
     static char ID; // Pass identification
-    StackSlotColoring() : MachineFunctionPass(&ID), NextColor(-1) {}
+    StackSlotColoring() :
+      MachineFunctionPass(&ID), ColorWithRegs(false), NextColor(-1) {}
+    StackSlotColoring(bool RegColor) :
+      MachineFunctionPass(&ID), ColorWithRegs(RegColor), NextColor(-1) {}
     
     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
       AU.addRequired<LiveStacks>();
-      
-      AU.addPreservedID(MachineLoopInfoID);
+      AU.addRequired<VirtRegMap>();
+      AU.addPreserved<VirtRegMap>();      
+      AU.addRequired<MachineLoopInfo>();
+      AU.addPreserved<MachineLoopInfo>();
       AU.addPreservedID(MachineDominatorsID);
       MachineFunctionPass::getAnalysisUsage(AU);
     }
@@ -86,11 +111,27 @@
     }
 
   private:
-    bool InitializeSlots();
+    void InitializeSlots();
+    void ScanForSpillSlotRefs(MachineFunction &MF);
     bool OverlapWithAssignments(LiveInterval *li, int Color) const;
     int ColorSlot(LiveInterval *li);
     bool ColorSlots(MachineFunction &MF);
-    bool removeDeadStores(MachineBasicBlock* MBB);
+    bool ColorSlotsWithFreeRegs(SmallVector<int, 16> &SlotMapping,
+                                SmallVector<SmallVector<int, 4>, 16> &RevMap,
+                                BitVector &SlotIsReg);
+    void RewriteInstruction(MachineInstr *MI, int OldFI, int NewFI,
+                            MachineFunction &MF);
+    bool PropagateBackward(MachineBasicBlock::iterator MII,
+                           MachineBasicBlock *MBB,
+                           unsigned OldReg, unsigned NewReg);
+    bool PropagateForward(MachineBasicBlock::iterator MII,
+                          MachineBasicBlock *MBB,
+                          unsigned OldReg, unsigned NewReg);
+    void UnfoldAndRewriteInstruction(MachineInstr *MI, int OldFI,
+                                    unsigned Reg, const TargetRegisterClass *RC,
+                                    MachineFunction &MF);
+    bool AllMemRefsCanBeUnfolded(int SS);
+    bool RemoveDeadStores(MachineBasicBlock* MBB);
   };
 } // end anonymous namespace
 
@@ -99,8 +140,8 @@
 static RegisterPass<StackSlotColoring>
 X("stack-slot-coloring", "Stack Slot Coloring");
 
-FunctionPass *llvm::createStackSlotColoringPass() {
-  return new StackSlotColoring();
+FunctionPass *llvm::createStackSlotColoringPass(bool RegColor) {
+  return new StackSlotColoring(RegColor);
 }
 
 namespace {
@@ -113,12 +154,39 @@
   };
 }
 
+/// ScanForSpillSlotRefs - Scan all the machine instructions for spill slot
+/// references and update spill slot weights.
+void StackSlotColoring::ScanForSpillSlotRefs(MachineFunction &MF) {
+  SSRefs.resize(MFI->getObjectIndexEnd());
+
+  // FIXME: Need the equivalent of MachineRegisterInfo for frameindex operands.
+  for (MachineFunction::iterator MBBI = MF.begin(), E = MF.end();
+       MBBI != E; ++MBBI) {
+    MachineBasicBlock *MBB = &*MBBI;
+    unsigned loopDepth = loopInfo->getLoopDepth(MBB);
+    for (MachineBasicBlock::iterator MII = MBB->begin(), EE = MBB->end();
+         MII != EE; ++MII) {
+      MachineInstr *MI = &*MII;
+      for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+        MachineOperand &MO = MI->getOperand(i);
+        if (!MO.isFI())
+          continue;
+        int FI = MO.getIndex();
+        if (FI < 0)
+          continue;
+        if (!LS->hasInterval(FI))
+          continue;
+        LiveInterval &li = LS->getInterval(FI);
+        li.weight += LiveIntervals::getSpillWeight(false, true, loopDepth);
+        SSRefs[FI].push_back(MI);
+      }
+    }
+  }
+}
+
 /// InitializeSlots - Process all spill stack slot liveintervals and add them
 /// to a sorted (by weight) list.
-bool StackSlotColoring::InitializeSlots() {
-  if (LS->getNumIntervals() < 2)
-    return false;
-
+void StackSlotColoring::InitializeSlots() {
   int LastFI = MFI->getObjectIndexEnd();
   OrigAlignments.resize(LastFI);
   OrigSizes.resize(LastFI);
@@ -127,8 +195,10 @@
   Assignments.resize(LastFI);
 
   // Gather all spill slots into a list.
+  DOUT << "Spill slot intervals:\n";
   for (LiveStacks::iterator i = LS->begin(), e = LS->end(); i != e; ++i) {
     LiveInterval &li = i->second;
+    DEBUG(li.dump());
     int FI = li.getStackSlotIndex();
     if (MFI->isDeadObjectIndex(FI))
       continue;
@@ -137,13 +207,13 @@
     OrigSizes[FI]      = MFI->getObjectSize(FI);
     AllColors.set(FI);
   }
+  DOUT << '\n';
 
   // Sort them by weight.
   std::stable_sort(SSIntervals.begin(), SSIntervals.end(), IntervalSorter());
 
   // Get first "color".
   NextColor = AllColors.find_first();
-  return true;
 }
 
 /// OverlapWithAssignments - Return true if LiveInterval overlaps with any
@@ -159,6 +229,78 @@
   return false;
 }
 
+/// ColorSlotsWithFreeRegs - If there are any free registers available, try
+/// replacing spill slots references with registers instead.
+bool
+StackSlotColoring::ColorSlotsWithFreeRegs(SmallVector<int, 16> &SlotMapping,
+                                   SmallVector<SmallVector<int, 4>, 16> &RevMap,
+                                   BitVector &SlotIsReg) {
+  if (!(ColorWithRegs || ColorWithRegsOpt) || !VRM->HasUnusedRegisters())
+    return false;
+
+  bool Changed = false;
+  DOUT << "Assigning unused registers to spill slots:\n";
+  for (unsigned i = 0, e = SSIntervals.size(); i != e; ++i) {
+    LiveInterval *li = SSIntervals[i];
+    int SS = li->getStackSlotIndex();
+    if (!UsedColors[SS] || li->weight < 20)
+      // If the weight is < 20, i.e. two references in a loop with depth 1,
+      // don't bother with it.
+      continue;
+
+    // These slots allow to share the same registers.
+    bool AllColored = true;
+    SmallVector<unsigned, 4> ColoredRegs;
+    for (unsigned j = 0, ee = RevMap[SS].size(); j != ee; ++j) {
+      int RSS = RevMap[SS][j];
+      const TargetRegisterClass *RC = LS->getIntervalRegClass(RSS);
+      // If it's not colored to another stack slot, try coloring it
+      // to a "free" register.
+      if (!RC) {
+        AllColored = false;
+        continue;
+      }
+      unsigned Reg = VRM->getFirstUnusedRegister(RC);
+      if (!Reg) {
+        AllColored = false;
+        continue;
+      }
+      if (!AllMemRefsCanBeUnfolded(RSS)) {
+        AllColored = false;
+        continue;
+      } else {
+        DOUT << "Assigning fi#" << RSS << " to " << TRI->getName(Reg) << '\n';
+        ColoredRegs.push_back(Reg);
+        SlotMapping[RSS] = Reg;
+        SlotIsReg.set(RSS);
+        Changed = true;
+      }
+    }
+
+    // Register and its sub-registers are no longer free.
+    while (!ColoredRegs.empty()) {
+      unsigned Reg = ColoredRegs.back();
+      ColoredRegs.pop_back();
+      VRM->setRegisterUsed(Reg);
+      // If reg is a callee-saved register, it will have to be spilled in
+      // the prologue.
+      MRI->setPhysRegUsed(Reg);
+      for (const unsigned *AS = TRI->getAliasSet(Reg); *AS; ++AS) {
+        VRM->setRegisterUsed(*AS);
+        MRI->setPhysRegUsed(*AS);
+      }
+    }
+    // This spill slot is dead after the rewrites
+    if (AllColored) {
+      MFI->RemoveStackObject(SS);
+      ++NumEliminated;
+    }
+  }
+  DOUT << '\n';
+
+  return Changed;
+}
+
 /// ColorSlot - Assign a "color" (stack slot) to the specified stack slot.
 ///
 int StackSlotColoring::ColorSlot(LiveInterval *li) {
@@ -207,56 +349,63 @@
 /// operands in the function.
 bool StackSlotColoring::ColorSlots(MachineFunction &MF) {
   unsigned NumObjs = MFI->getObjectIndexEnd();
-  std::vector<int> SlotMapping(NumObjs, -1);
+  SmallVector<int, 16> SlotMapping(NumObjs, -1);
+  SmallVector<float, 16> SlotWeights(NumObjs, 0.0);
+  SmallVector<SmallVector<int, 4>, 16> RevMap(NumObjs);
+  BitVector SlotIsReg(NumObjs);
+  BitVector UsedColors(NumObjs);
 
+  DOUT << "Color spill slot intervals:\n";
   bool Changed = false;
   for (unsigned i = 0, e = SSIntervals.size(); i != e; ++i) {
     LiveInterval *li = SSIntervals[i];
     int SS = li->getStackSlotIndex();
     int NewSS = ColorSlot(li);
+    assert(NewSS >= 0 && "Stack coloring failed?");
     SlotMapping[SS] = NewSS;
+    RevMap[NewSS].push_back(SS);
+    SlotWeights[NewSS] += li->weight;
+    UsedColors.set(NewSS);
     Changed |= (SS != NewSS);
   }
 
+  DOUT << "\nSpill slots after coloring:\n";
+  for (unsigned i = 0, e = SSIntervals.size(); i != e; ++i) {
+    LiveInterval *li = SSIntervals[i];
+    int SS = li->getStackSlotIndex();
+    li->weight = SlotWeights[SS];
+  }
+  // Sort them by new weight.
+  std::stable_sort(SSIntervals.begin(), SSIntervals.end(), IntervalSorter());
+
+#ifndef NDEBUG
+  for (unsigned i = 0, e = SSIntervals.size(); i != e; ++i)
+    DEBUG(SSIntervals[i]->dump());
+  DOUT << '\n';
+#endif
+
+  // Can we "color" a stack slot with a unused register?
+  Changed |= ColorSlotsWithFreeRegs(SlotMapping, RevMap, SlotIsReg);
+
   if (!Changed)
     return false;
 
   // Rewrite all MO_FrameIndex operands.
-  // FIXME: Need the equivalent of MachineRegisterInfo for frameindex operands.
-  for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
-       MBB != E; ++MBB) {
-    for (MachineBasicBlock::iterator MII = MBB->begin(), EE = MBB->end();
-         MII != EE; ++MII) {
-      MachineInstr &MI = *MII;
-      for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
-        MachineOperand &MO = MI.getOperand(i);
-        if (!MO.isFI())
-          continue;
-        int FI = MO.getIndex();
-        if (FI < 0)
-          continue;
-        int NewFI = SlotMapping[FI];
-        if (NewFI == -1)
-          continue;
-        MO.setIndex(NewFI);
+  for (unsigned SS = 0, SE = SSRefs.size(); SS != SE; ++SS) {
+    bool isReg = SlotIsReg[SS];
+    int NewFI = SlotMapping[SS];
+    if (NewFI == -1 || (NewFI == (int)SS && !isReg))
+      continue;
 
-        // Update the MachineMemOperand for the new memory location.
-        // FIXME: We need a better method of managing these too.
-        SmallVector<MachineMemOperand, 2> MMOs(MI.memoperands_begin(),
-                                               MI.memoperands_end());
-        MI.clearMemOperands(MF);
-        const Value *OldSV = PseudoSourceValue::getFixedStack(FI);
-        for (unsigned i = 0, e = MMOs.size(); i != e; ++i) {
-          if (MMOs[i].getValue() == OldSV) {
-            MachineMemOperand MMO(PseudoSourceValue::getFixedStack(NewFI),
-                                  MMOs[i].getFlags(), MMOs[i].getOffset(),
-                                  MMOs[i].getSize(), MMOs[i].getAlignment());
-            MI.addMemOperand(MF, MMO);
-          } else
-            MI.addMemOperand(MF, MMOs[i]);
-        }
+    SmallVector<MachineInstr*, 8> &RefMIs = SSRefs[SS];
+    for (unsigned i = 0, e = RefMIs.size(); i != e; ++i)
+      if (!isReg)
+        RewriteInstruction(RefMIs[i], SS, NewFI, MF);
+      else {
+        // Rewrite to use a register instead.
+        const TargetRegisterClass *RC = LS->getIntervalRegClass(SS);
+        UnfoldAndRewriteInstruction(RefMIs[i], SS, NewFI, RC, MF);
       }
-    }
   }
 
   // Delete unused stack slots.
@@ -269,12 +418,200 @@
   return true;
 }
 
-/// removeDeadStores - Scan through a basic block and look for loads followed
+/// AllMemRefsCanBeUnfolded - Return true if all references of the specified
+/// spill slot index can be unfolded.
+bool StackSlotColoring::AllMemRefsCanBeUnfolded(int SS) {
+  SmallVector<MachineInstr*, 8> &RefMIs = SSRefs[SS];
+  for (unsigned i = 0, e = RefMIs.size(); i != e; ++i) {
+    MachineInstr *MI = RefMIs[i];
+    if (TII->isLoadFromStackSlot(MI, SS) ||
+        TII->isStoreToStackSlot(MI, SS))
+      // Restore and spill will become copies.
+      return true;
+    if (!TII->getOpcodeAfterMemoryUnfold(MI->getOpcode(), false, false))
+      return false;
+    for (unsigned j = 0, ee = MI->getNumOperands(); j != ee; ++j) {
+      MachineOperand &MO = MI->getOperand(j);
+      if (MO.isFI() && MO.getIndex() != SS)
+        // If it uses another frameindex, we can, currently* unfold it.
+        return false;
+    }
+  }
+  return true;
+}
+
+/// RewriteInstruction - Rewrite specified instruction by replacing references
+/// to old frame index with new one.
+void StackSlotColoring::RewriteInstruction(MachineInstr *MI, int OldFI,
+                                           int NewFI, MachineFunction &MF) {
+  for (unsigned i = 0, ee = MI->getNumOperands(); i != ee; ++i) {
+    MachineOperand &MO = MI->getOperand(i);
+    if (!MO.isFI())
+      continue;
+    int FI = MO.getIndex();
+    if (FI != OldFI)
+      continue;
+    MO.setIndex(NewFI);
+  }
+
+  // Update the MachineMemOperand for the new memory location.
+  // FIXME: We need a better method of managing these too.
+  SmallVector<MachineMemOperand, 2> MMOs(MI->memoperands_begin(),
+                                         MI->memoperands_end());
+  MI->clearMemOperands(MF);
+  const Value *OldSV = PseudoSourceValue::getFixedStack(OldFI);
+  for (unsigned i = 0, ee = MMOs.size(); i != ee; ++i) {
+    if (MMOs[i].getValue() != OldSV)
+      MI->addMemOperand(MF, MMOs[i]);
+    else {
+      MachineMemOperand MMO(PseudoSourceValue::getFixedStack(NewFI),
+                            MMOs[i].getFlags(), MMOs[i].getOffset(),
+                            MMOs[i].getSize(),  MMOs[i].getAlignment());
+      MI->addMemOperand(MF, MMO);
+    }
+  }
+}
+
+/// PropagateBackward - Traverse backward and look for the definition of
+/// OldReg. If it can successfully update all of the references with NewReg,
+/// do so and return true.
+bool StackSlotColoring::PropagateBackward(MachineBasicBlock::iterator MII,
+                                          MachineBasicBlock *MBB,
+                                          unsigned OldReg, unsigned NewReg) {
+  if (MII == MBB->begin())
+    return false;
+
+  SmallVector<MachineOperand*, 4> Refs;
+  while (--MII != MBB->begin()) {
+    bool FoundDef = false;  // Not counting 2address def.
+    bool FoundUse = false;
+    bool FoundKill = false;
+    const TargetInstrDesc &TID = MII->getDesc();
+    for (unsigned i = 0, e = MII->getNumOperands(); i != e; ++i) {
+      MachineOperand &MO = MII->getOperand(i);
+      if (!MO.isReg())
+        continue;
+      unsigned Reg = MO.getReg();
+      if (Reg == 0)
+        continue;
+      if (Reg == OldReg) {
+        const TargetRegisterClass *RC = getInstrOperandRegClass(TRI, TID, i);
+        if (RC && !RC->contains(NewReg))
+          return false;
+
+        if (MO.isUse()) {
+          FoundUse = true;
+          if (MO.isKill())
+            FoundKill = true;
+          Refs.push_back(&MO);
+        } else {
+          Refs.push_back(&MO);
+          if (!MII->isRegTiedToUseOperand(i))
+            FoundDef = true;
+        }
+      } else if (TRI->regsOverlap(Reg, NewReg)) {
+        return false;
+      } else if (TRI->regsOverlap(Reg, OldReg)) {
+        if (!MO.isUse() || !MO.isKill())
+          return false;
+      }
+    }
+    if (FoundDef) {
+      for (unsigned i = 0, e = Refs.size(); i != e; ++i)
+        Refs[i]->setReg(NewReg);
+      return true;
+    }
+  }
+  return false;
+}
+
+/// PropagateForward - Traverse forward and look for the kill of OldReg. If
+/// it can successfully update all of the uses with NewReg, do so and
+/// return true.
+bool StackSlotColoring::PropagateForward(MachineBasicBlock::iterator MII,
+                                         MachineBasicBlock *MBB,
+                                         unsigned OldReg, unsigned NewReg) {
+  if (MII == MBB->end())
+    return false;
+
+  SmallVector<MachineOperand*, 4> Uses;
+  while (++MII != MBB->end()) {
+    bool FoundUse = false;
+    bool FoundKill = false;
+    const TargetInstrDesc &TID = MII->getDesc();
+    for (unsigned i = 0, e = MII->getNumOperands(); i != e; ++i) {
+      MachineOperand &MO = MII->getOperand(i);
+      if (!MO.isReg())
+        continue;
+      unsigned Reg = MO.getReg();
+      if (Reg == 0)
+        continue;
+      if (Reg == OldReg) {
+        if (MO.isDef())
+          return false;
+
+        const TargetRegisterClass *RC = getInstrOperandRegClass(TRI, TID, i);
+        if (RC && !RC->contains(NewReg))
+          return false;
+        FoundUse = true;
+        if (MO.isKill())
+          FoundKill = true;
+        Uses.push_back(&MO);
+      } else if (TRI->regsOverlap(Reg, NewReg) ||
+                 TRI->regsOverlap(Reg, OldReg))
+        return false;
+    }
+    if (FoundKill) {
+      for (unsigned i = 0, e = Uses.size(); i != e; ++i)
+        Uses[i]->setReg(NewReg);
+      return true;
+    }
+  }
+  return false;
+}
+
+/// UnfoldAndRewriteInstruction - Rewrite specified instruction by unfolding
+/// folded memory references and replacing those references with register
+/// references instead.
+void StackSlotColoring::UnfoldAndRewriteInstruction(MachineInstr *MI, int OldFI,
+                                                  unsigned Reg,
+                                                  const TargetRegisterClass *RC,
+                                                  MachineFunction &MF) {
+  MachineBasicBlock *MBB = MI->getParent();
+  if (unsigned DstReg = TII->isLoadFromStackSlot(MI, OldFI)) {
+    if (PropagateForward(MI, MBB, DstReg, Reg)) {
+      DOUT << "Eliminated load: ";
+      DEBUG(MI->dump());
+      ++NumLoadElim;
+    } else {
+      TII->copyRegToReg(*MBB, MI, DstReg, Reg, RC, RC);
+      ++NumRegRepl;
+    }
+  } else if (unsigned SrcReg = TII->isStoreToStackSlot(MI, OldFI)) {
+    if (MI->killsRegister(SrcReg) && PropagateBackward(MI, MBB, SrcReg, Reg)) {
+      DOUT << "Eliminated store: ";
+      DEBUG(MI->dump());
+      ++NumStoreElim;
+    } else {
+      TII->copyRegToReg(*MBB, MI, Reg, SrcReg, RC, RC);
+      ++NumRegRepl;
+    }
+  } else {
+    SmallVector<MachineInstr*, 4> NewMIs;
+    bool Success = TII->unfoldMemoryOperand(MF, MI, Reg, false, false, NewMIs);
+    assert(Success && "Failed to unfold!");
+    MBB->insert(MI, NewMIs[0]);
+    ++NumRegRepl;
+  }
+  MBB->erase(MI);
+}
+
+/// RemoveDeadStores - Scan through a basic block and look for loads followed
 /// by stores.  If they're both using the same stack slot, then the store is
 /// definitely dead.  This could obviously be much more aggressive (consider
 /// pairs with instructions between them), but such extensions might have a
 /// considerable compile time impact.
-bool StackSlotColoring::removeDeadStores(MachineBasicBlock* MBB) {
+bool StackSlotColoring::RemoveDeadStores(MachineBasicBlock* MBB) {
   // FIXME: This could be much more aggressive, but we need to investigate
   // the compile time impact of doing so.
   bool changed = false;
@@ -283,7 +620,7 @@
 
   for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
        I != E; ++I) {
-    if (DCELimit != -1 && (int)NumDeadAccesses >= DCELimit)
+    if (DCELimit != -1 && (int)NumDead >= DCELimit)
       break;
     
     MachineBasicBlock::iterator NextMI = next(I);
@@ -296,11 +633,11 @@
     if (!(StoreReg = TII->isStoreToStackSlot(NextMI, SecondSS))) continue;
     if (FirstSS != SecondSS || LoadReg != StoreReg || FirstSS == -1) continue;
     
-    ++NumDeadAccesses;
+    ++NumDead;
     changed = true;
     
     if (NextMI->findRegisterUseOperandIdx(LoadReg, true, 0) != -1) {
-      ++NumDeadAccesses;
+      ++NumDead;
       toErase.push_back(I);
     }
     
@@ -320,15 +657,32 @@
   DOUT << "********** Stack Slot Coloring **********\n";
 
   MFI = MF.getFrameInfo();
+  MRI = &MF.getRegInfo(); 
   TII = MF.getTarget().getInstrInfo();
+  TRI = MF.getTarget().getRegisterInfo();
   LS = &getAnalysis<LiveStacks>();
+  VRM = &getAnalysis<VirtRegMap>();
+  loopInfo = &getAnalysis<MachineLoopInfo>();
 
   bool Changed = false;
-  if (InitializeSlots())
-    Changed = ColorSlots(MF);
+
+  unsigned NumSlots = LS->getNumIntervals();
+  if (NumSlots < 2) {
+    if (NumSlots == 0 || !VRM->HasUnusedRegisters())
+      // Nothing to do!
+      return false;
+  }
+
+  // Gather spill slot references
+  ScanForSpillSlotRefs(MF);
+  InitializeSlots();
+  Changed = ColorSlots(MF);
 
   NextColor = -1;
   SSIntervals.clear();
+  for (unsigned i = 0, e = SSRefs.size(); i != e; ++i)
+    SSRefs[i].clear();
+  SSRefs.clear();
   OrigAlignments.clear();
   OrigSizes.clear();
   AllColors.clear();
@@ -339,7 +693,7 @@
 
   if (Changed) {
     for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I)
-      Changed |= removeDeadStores(I);
+      Changed |= RemoveDeadStores(I);
   }
 
   return Changed;

Modified: llvm/branches/Apple/Dib/lib/CodeGen/VirtRegMap.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/VirtRegMap.cpp?rev=71053&r1=71052&r2=71053&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/VirtRegMap.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/VirtRegMap.cpp Tue May  5 19:37:50 2009
@@ -19,12 +19,14 @@
 #define DEBUG_TYPE "virtregmap"
 #include "VirtRegMap.h"
 #include "llvm/Function.h"
+#include "llvm/CodeGen/LiveIntervalAnalysis.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Debug.h"
@@ -50,6 +52,7 @@
 
 bool VirtRegMap::runOnMachineFunction(MachineFunction &mf) {
   TII = mf.getTarget().getInstrInfo();
+  TRI = mf.getTarget().getRegisterInfo();
   MF = &mf;
   
   ReMatId = MAX_STACK_SLOT+1;
@@ -72,6 +75,13 @@
   SpillSlotToUsesMap.resize(8);
   ImplicitDefed.resize(MF->getRegInfo().getLastVirtReg()+1-
                        TargetRegisterInfo::FirstVirtualRegister);
+
+  allocatableRCRegs.clear();
+  for (TargetRegisterInfo::regclass_iterator I = TRI->regclass_begin(),
+         E = TRI->regclass_end(); I != E; ++I)
+    allocatableRCRegs.insert(std::make_pair(*I,
+                                            TRI->getAllocatableSet(mf, *I)));
+
   grow();
   
   return false;
@@ -201,6 +211,41 @@
   EmergencySpillMap.erase(MI);
 }
 
+/// FindUnusedRegisters - Gather a list of allocatable registers that
+/// have not been allocated to any virtual register.
+bool VirtRegMap::FindUnusedRegisters(const TargetRegisterInfo *TRI,
+                                     LiveIntervals* LIs) {
+  unsigned NumRegs = TRI->getNumRegs();
+  UnusedRegs.reset();
+  UnusedRegs.resize(NumRegs);
+
+  BitVector Used(NumRegs);
+  for (unsigned i = TargetRegisterInfo::FirstVirtualRegister,
+         e = MF->getRegInfo().getLastVirtReg(); i <= e; ++i)
+    if (Virt2PhysMap[i] != (unsigned)VirtRegMap::NO_PHYS_REG)
+      Used.set(Virt2PhysMap[i]);
+
+  BitVector Allocatable = TRI->getAllocatableSet(*MF);
+  bool AnyUnused = false;
+  for (unsigned Reg = 1; Reg < NumRegs; ++Reg) {
+    if (Allocatable[Reg] && !Used[Reg] && !LIs->hasInterval(Reg)) {
+      bool ReallyUnused = true;
+      for (const unsigned *AS = TRI->getAliasSet(Reg); *AS; ++AS) {
+        if (Used[*AS] || LIs->hasInterval(*AS)) {
+          ReallyUnused = false;
+          break;
+        }
+      }
+      if (ReallyUnused) {
+        AnyUnused = true;
+        UnusedRegs.set(Reg);
+      }
+    }
+  }
+
+  return AnyUnused;
+}
+
 void VirtRegMap::print(std::ostream &OS, const Module* M) const {
   const TargetRegisterInfo* TRI = MF->getTarget().getRegisterInfo();
 

Modified: llvm/branches/Apple/Dib/lib/CodeGen/VirtRegMap.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/VirtRegMap.h?rev=71053&r1=71052&r2=71053&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/VirtRegMap.h (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/VirtRegMap.h Tue May  5 19:37:50 2009
@@ -20,6 +20,7 @@
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/IndexedMap.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
@@ -27,9 +28,11 @@
 #include <map>
 
 namespace llvm {
+  class LiveIntervals;
   class MachineInstr;
   class MachineFunction;
   class TargetInstrInfo;
+  class TargetRegisterInfo;
 
   class VirtRegMap : public MachineFunctionPass {
   public:
@@ -45,8 +48,11 @@
 
   private:
     const TargetInstrInfo *TII;
-
+    const TargetRegisterInfo *TRI;
     MachineFunction *MF;
+
+    DenseMap<const TargetRegisterClass*, BitVector> allocatableRCRegs;
+
     /// Virt2PhysMap - This is a virtual to physical register
     /// mapping. Each virtual register is required to have an entry in
     /// it; even spilled virtual registers (the register mapped to a
@@ -122,6 +128,9 @@
     /// the register is implicitly defined.
     BitVector ImplicitDefed;
 
+    /// UnusedRegs - A list of physical registers that have not been used.
+    BitVector UnusedRegs;
+
     VirtRegMap(const VirtRegMap&);     // DO NOT IMPLEMENT
     void operator=(const VirtRegMap&); // DO NOT IMPLEMENT
 
@@ -277,8 +286,10 @@
 
     /// @brief records the specified MachineInstr as a spill point for virtReg.
     void addSpillPoint(unsigned virtReg, bool isKill, MachineInstr *Pt) {
-      if (SpillPt2VirtMap.find(Pt) != SpillPt2VirtMap.end())
-        SpillPt2VirtMap[Pt].push_back(std::make_pair(virtReg, isKill));
+      std::map<MachineInstr*, std::vector<std::pair<unsigned,bool> > >::iterator
+        I = SpillPt2VirtMap.find(Pt);
+      if (I != SpillPt2VirtMap.end())
+        I->second.push_back(std::make_pair(virtReg, isKill));
       else {
         std::vector<std::pair<unsigned,bool> > Virts;
         Virts.push_back(std::make_pair(virtReg, isKill));
@@ -289,7 +300,7 @@
     /// @brief - transfer spill point information from one instruction to
     /// another.
     void transferSpillPts(MachineInstr *Old, MachineInstr *New) {
-      std::map<MachineInstr*,std::vector<std::pair<unsigned,bool> > >::iterator
+      std::map<MachineInstr*, std::vector<std::pair<unsigned,bool> > >::iterator
         I = SpillPt2VirtMap.find(Old);
       if (I == SpillPt2VirtMap.end())
         return;
@@ -315,8 +326,10 @@
 
     /// @brief records the specified MachineInstr as a restore point for virtReg.
     void addRestorePoint(unsigned virtReg, MachineInstr *Pt) {
-      if (RestorePt2VirtMap.find(Pt) != RestorePt2VirtMap.end())
-        RestorePt2VirtMap[Pt].push_back(virtReg);
+      std::map<MachineInstr*, std::vector<unsigned> >::iterator I =
+        RestorePt2VirtMap.find(Pt);
+      if (I != RestorePt2VirtMap.end())
+        I->second.push_back(virtReg);
       else {
         std::vector<unsigned> Virts;
         Virts.push_back(virtReg);
@@ -327,7 +340,7 @@
     /// @brief - transfer restore point information from one instruction to
     /// another.
     void transferRestorePts(MachineInstr *Old, MachineInstr *New) {
-      std::map<MachineInstr*,std::vector<unsigned> >::iterator I =
+      std::map<MachineInstr*, std::vector<unsigned> >::iterator I =
         RestorePt2VirtMap.find(Old);
       if (I == RestorePt2VirtMap.end())
         return;
@@ -430,6 +443,40 @@
     /// the folded instruction map and spill point map.
     void RemoveMachineInstrFromMaps(MachineInstr *MI);
 
+    /// FindUnusedRegisters - Gather a list of allocatable registers that
+    /// have not been allocated to any virtual register.
+    bool FindUnusedRegisters(const TargetRegisterInfo *TRI,
+                             LiveIntervals* LIs);
+
+    /// HasUnusedRegisters - Return true if there are any allocatable registers
+    /// that have not been allocated to any virtual register.
+    bool HasUnusedRegisters() const {
+      return !UnusedRegs.none();
+    }
+
+    /// setRegisterUsed - Remember the physical register is now used.
+    void setRegisterUsed(unsigned Reg) {
+      UnusedRegs.reset(Reg);
+    }
+
+    /// isRegisterUnused - Return true if the physical register has not been
+    /// used.
+    bool isRegisterUnused(unsigned Reg) const {
+      return UnusedRegs[Reg];
+    }
+
+    /// getFirstUnusedRegister - Return the first physical register that has not
+    /// been used.
+    unsigned getFirstUnusedRegister(const TargetRegisterClass *RC) {
+      int Reg = UnusedRegs.find_first();
+      while (Reg != -1) {
+        if (allocatableRCRegs[RC][Reg])
+          return (unsigned)Reg;
+        Reg = UnusedRegs.find_next(Reg);
+      }
+      return 0;
+    }
+
     void print(std::ostream &OS, const Module* M = 0) const;
     void print(std::ostream *OS) const { if (OS) print(*OS); }
     void dump() const;

Modified: llvm/branches/Apple/Dib/lib/Target/TargetInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/Target/TargetInstrInfo.cpp?rev=71053&r1=71052&r2=71053&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/Target/TargetInstrInfo.cpp (original)
+++ llvm/branches/Apple/Dib/lib/Target/TargetInstrInfo.cpp Tue May  5 19:37:50 2009
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/Constant.h"
 #include "llvm/DerivedTypes.h"
 using namespace llvm;
@@ -35,3 +36,15 @@
     return true;
   return !isPredicated(MI);
 }
+
+/// getInstrOperandRegClass - Return register class of the operand of an
+/// instruction of the specified TargetInstrDesc.
+const TargetRegisterClass*
+llvm::getInstrOperandRegClass(const TargetRegisterInfo *TRI,
+                        const TargetInstrDesc &II, unsigned Op) {
+  if (Op >= II.getNumOperands())
+    return NULL;
+  if (II.OpInfo[Op].isLookupPtrRegClass())
+    return TRI->getPointerRegClass();
+  return TRI->getRegClass(II.OpInfo[Op].RegClass);
+}





More information about the llvm-branch-commits mailing list