improve "cannot yet select" errors a trivial amount: now
[oota-llvm.git] / lib / CodeGen / LiveDebugVariables.cpp
index 4f48d766aefacb26b354ad8acda1239d6e836492..baedfc3efb5c49a14d931dc2bce45a0ee0f6322f 100644 (file)
@@ -188,6 +188,11 @@ class UserValue {
   /// Map of slot indices where this value is live.
   LocMap locInts;
 
+  /// coalesceLocation - After LocNo was changed, check if it has become
+  /// identical to another location, and coalesce them. This may cause LocNo or
+  /// a later location to be erased, but no earlier location will be erased.
+  void coalesceLocation(unsigned LocNo);
+
   /// insertDebugValue - Insert a DBG_VALUE into MBB at Idx for LocNo.
   void insertDebugValue(MachineBasicBlock *MBB, SlotIndex Idx, unsigned LocNo,
                         LiveIntervals &LIS, const TargetInstrInfo &TII);
@@ -303,7 +308,7 @@ class LDVImpl {
 
   /// Map virtual register to eq class leader.
   typedef DenseMap<unsigned, UserValue*> VRMap;
-  VRMap virtRegMap;
+  VRMap virtRegToEqClass;
 
   /// Map user variable to eq class leader.
   typedef DenseMap<const MDNode *, UserValue*> UVMap;
@@ -342,7 +347,7 @@ public:
   void clear() {
     DeleteContainerPointers(userValues);
     userValues.clear();
-    virtRegMap.clear();
+    virtRegToEqClass.clear();
     userVarMap.clear();
   }
 
@@ -409,6 +414,30 @@ void LDVImpl::print(raw_ostream &OS) {
     userValues[i]->print(OS, TRI);
 }
 
+void UserValue::coalesceLocation(unsigned LocNo) {
+  unsigned KeepLoc = std::find(locations.begin(), locations.begin() + LocNo,
+                               locations[LocNo]) - locations.begin();
+  unsigned EraseLoc = LocNo;
+  if (KeepLoc == LocNo) {
+    EraseLoc = std::find(locations.begin() + LocNo + 1, locations.end(),
+                         locations[LocNo]) - locations.begin();
+    // No matches.
+    if (EraseLoc == locations.size())
+      return;
+  }
+  assert(KeepLoc < EraseLoc);
+  locations.erase(locations.begin() + EraseLoc);
+
+  // Rewrite values.
+  for (LocMap::iterator I = locInts.begin(); I.valid(); ++I) {
+    unsigned v = I.value();
+    if (v == EraseLoc)
+      I.setValue(KeepLoc);      // Coalesce when possible.
+    else if (v > EraseLoc)
+      I.setValueUnchecked(v-1); // Avoid coalescing with untransformed values.
+  }
+}
+
 UserValue *LDVImpl::getUserValue(const MDNode *Var, unsigned Offset) {
   UserValue *&Leader = userVarMap[Var];
   if (Leader) {
@@ -427,12 +456,12 @@ UserValue *LDVImpl::getUserValue(const MDNode *Var, unsigned Offset) {
 
 void LDVImpl::mapVirtReg(unsigned VirtReg, UserValue *EC) {
   assert(TargetRegisterInfo::isVirtualRegister(VirtReg) && "Only map VirtRegs");
-  UserValue *&Leader = virtRegMap[VirtReg];
+  UserValue *&Leader = virtRegToEqClass[VirtReg];
   Leader = UserValue::merge(Leader, EC);
 }
 
 UserValue *LDVImpl::lookupVirtReg(unsigned VirtReg) {
-  if (UserValue *UV = virtRegMap.lookup(VirtReg))
+  if (UserValue *UV = virtRegToEqClass.lookup(VirtReg))
     return UV->getLeader();
   return 0;
 }
@@ -613,13 +642,15 @@ LiveDebugVariables::~LiveDebugVariables() {
 void UserValue::
 renameRegister(unsigned OldReg, unsigned NewReg, unsigned SubIdx,
                const TargetRegisterInfo *TRI) {
-  for (unsigned i = 0, e = locations.size(); i != e; ++i) {
-    Location &Loc = locations[i];
+  for (unsigned i = locations.size(); i; --i) {
+    unsigned LocNo = i - 1;
+    Location &Loc = locations[LocNo];
     if (Loc.Kind != OldReg)
       continue;
     Loc.Kind = NewReg;
     if (SubIdx && Loc.Data.SubIdx)
       Loc.Data.SubIdx = TRI->composeSubRegIndices(SubIdx, Loc.Data.SubIdx);
+    coalesceLocation(LocNo);
   }
 }
 
@@ -631,7 +662,7 @@ renameRegister(unsigned OldReg, unsigned NewReg, unsigned SubIdx) {
 
   if (TargetRegisterInfo::isVirtualRegister(NewReg))
     mapVirtReg(NewReg, UV);
-  virtRegMap.erase(OldReg);
+  virtRegToEqClass.erase(OldReg);
 
   do {
     UV->renameRegister(OldReg, NewReg, SubIdx, TRI);
@@ -668,6 +699,7 @@ UserValue::rewriteLocations(VirtRegMap &VRM, const TargetRegisterInfo &TRI) {
     } else {
       Loc.Kind = Location::locUndef;
     }
+    coalesceLocation(LocNo);
   }
   DEBUG(print(dbgs(), &TRI));
 }