[llvm-commits] [llvm] r151205 - in /llvm/trunk/lib/CodeGen: ScheduleDAGInstrs.cpp ScheduleDAGInstrs.h

Andrew Trick atrick at apple.com
Wed Feb 22 13:59:00 PST 2012


Author: atrick
Date: Wed Feb 22 15:59:00 2012
New Revision: 151205

URL: http://llvm.org/viewvc/llvm-project?rev=151205&view=rev
Log:
misched: Use SparseSet for VRegDegs for constant time clear().

Modified:
    llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp
    llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.h

Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp?rev=151205&r1=151204&r2=151205&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp (original)
+++ llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Wed Feb 22 15:59:00 2012
@@ -373,13 +373,18 @@
   // uses. We're conservative for now until we have a way to guarantee the uses
   // are not eliminated sometime during scheduling. The output dependence edge
   // is also useful if output latency exceeds def-use latency.
-  SUnit *&DefSU = VRegDefs[Reg];
-  if (DefSU && DefSU != SU && DefSU != &ExitSU) {
-    unsigned OutLatency = TII->getOutputLatency(InstrItins, MI, OperIdx,
-                                                DefSU->getInstr());
-    DefSU->addPred(SDep(SU, SDep::Output, OutLatency, Reg));
+  VReg2SUnitMap::iterator DefI = findVRegDef(Reg);
+  if (DefI == VRegDefs.end())
+    VRegDefs.insert(VReg2SUnit(Reg, SU));
+  else {
+    SUnit *DefSU = DefI->SU;
+    if (DefSU != SU && DefSU != &ExitSU) {
+      unsigned OutLatency = TII->getOutputLatency(InstrItins, MI, OperIdx,
+                                                  DefSU->getInstr());
+      DefSU->addPred(SDep(SU, SDep::Output, OutLatency, Reg));
+    }
+    DefI->SU = SU;
   }
-  DefSU = SU;
 }
 
 /// addVRegUseDeps - Add a register data dependency if the instruction that
@@ -418,12 +423,9 @@
   }
 
   // Add antidependence to the following def of the vreg it uses.
-  DenseMap<unsigned, SUnit*>::const_iterator I = VRegDefs.find(Reg);
-  if (I != VRegDefs.end()) {
-    SUnit *DefSU = I->second;
-    if (DefSU != SU)
-      DefSU->addPred(SDep(SU, SDep::Anti, 0, Reg));
-  }
+  VReg2SUnitMap::iterator DefI = findVRegDef(Reg);
+  if (DefI != VRegDefs.end() && DefI->SU != SU)
+    DefI->SU->addPred(SDep(SU, SDep::Anti, 0, Reg));
 }
 
 /// Create an SUnit for each real instruction, numbered in top-down toplological
@@ -488,7 +490,11 @@
     assert(Defs[i].empty() && "Only BuildGraph should push/pop Defs");
   }
 
-  assert(VRegDefs.size() == 0 && "Only BuildSchedGraph may access VRegDefs");
+  assert(VRegDefs.empty() && "Only BuildSchedGraph may access VRegDefs");
+  // FIXME: Allow SparseSet to reserve space for the creation of virtual
+  // registers during scheduling. Don't artificially inflate the Universe
+  // because we want to assert that vregs are not created during DAG building.
+  VRegDefs.setUniverse(MRI.getNumVirtRegs());
 
   // Walk the list of instructions, from bottom moving up.
   MachineInstr *PrevMI = NULL;

Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.h?rev=151205&r1=151204&r2=151205&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.h (original)
+++ llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.h Wed Feb 22 15:59:00 2012
@@ -20,8 +20,8 @@
 #include "llvm/CodeGen/ScheduleDAG.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/ADT/IndexedMap.h"
 #include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SparseSet.h"
 #include <map>
 
 namespace llvm {
@@ -125,9 +125,24 @@
     std::vector<std::vector<SUnit *> > Defs;
     std::vector<std::vector<SUnit *> > Uses;
 
+    /// An individual mapping from virtual register number to SUnit.
+    struct VReg2SUnit {
+      unsigned VirtReg;
+      SUnit *SU;
+
+      VReg2SUnit(unsigned reg, SUnit *su): VirtReg(reg), SU(su) {}
+
+      unsigned getSparseSetKey() const {
+        return TargetRegisterInfo::virtReg2Index(VirtReg);
+      }
+    };
+    // Use SparseSet as a SparseMap by relying on the fact that it never
+    // compares ValueT's, only unsigned keys. This allows the set to be cleared
+    // between scheduling regions in constant time.
+    typedef SparseSet<VReg2SUnit> VReg2SUnitMap;
+
     // Track the last instructon in this region defining each virtual register.
-    // FIXME: turn this into a sparse set with constant time clear().
-    DenseMap<unsigned, SUnit*> VRegDefs;
+    VReg2SUnitMap VRegDefs;
 
     /// PendingLoads - Remember where unknown loads are after the most recent
     /// unknown store, as we iterate. As with Defs and Uses, this is here
@@ -235,6 +250,10 @@
     void addPhysRegDeps(SUnit *SU, unsigned OperIdx);
     void addVRegDefDeps(SUnit *SU, unsigned OperIdx);
     void addVRegUseDeps(SUnit *SU, unsigned OperIdx);
+
+    VReg2SUnitMap::iterator findVRegDef(unsigned VirtReg) {
+      return VRegDefs.find(TargetRegisterInfo::virtReg2Index(VirtReg));
+    }
   };
 }
 





More information about the llvm-commits mailing list