Reapply r128045 and r128051 with fixes.

This will extend the ranges of debug info variables in registers until they are
clobbered.

Fix 1: Don't mistake DBG_VALUE instructions referring to incoming arguments on
the stack with DBG_VALUE instructions referring to variables in the frame
pointer. This fixes the gdb test-suite failure.

Fix 2: Don't trace through copies to physical registers setting up call
arguments. These registers are call clobbered, and the source register is more
likely to be a callee-saved register that can be extended through the call
instruction.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128114 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 15330c2..7c50b1e 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -2382,9 +2382,9 @@
 /// DBG_VALUE instruction, is in a defined reg.
 static bool isDbgValueInDefinedReg(const MachineInstr *MI) {
   assert (MI->isDebugValue() && "Invalid DBG_VALUE machine instruction!");
-  if (MI->getOperand(0).isReg() && MI->getOperand(0).getReg())
-    return true;
-  return false;
+  return MI->getNumOperands() == 3 &&
+         MI->getOperand(0).isReg() && MI->getOperand(0).getReg() &&
+         MI->getOperand(1).isImm() && MI->getOperand(1).getImm() == 0;
 }
 
 /// collectVariableInfo - Populate DbgScope entries with variables' info.
@@ -2407,7 +2407,7 @@
       DbgValues.push_back(MInsn);
     }
 
-  // This is a collection of DBV_VALUE instructions describing same variable.
+  // This is a collection of DBG_VALUE instructions describing same variable.
   SmallVector<const MachineInstr *, 4> MultipleValues;
   for(SmallVector<const MachineInstr *, 8>::iterator I = DbgValues.begin(),
         E = DbgValues.end(); I != E; ++I) {
@@ -2424,8 +2424,7 @@
            ME = DbgValues.end(); MI != ME; ++MI) {
       const MDNode *Var =
         (*MI)->getOperand((*MI)->getNumOperands()-1).getMetadata();
-      if (Var == DV && 
-          !PrevMI->isIdenticalTo(*MI))
+      if (Var == DV && !PrevMI->isIdenticalTo(*MI))
         MultipleValues.push_back(*MI);
       PrevMI = *MI;
     }
@@ -2448,7 +2447,7 @@
       DbgVariableToDbgInstMap[AbsVar] = MInsn;
       VarToAbstractVarMap[RegVar] = AbsVar;
     }
-    if (MultipleValues.size() <= 1) {
+    if (MultipleValues.size() <= 1 && !RegClobberInsn.count(MInsn)) {
       DbgVariableToDbgInstMap[RegVar] = MInsn;
       continue;
     }
@@ -2458,16 +2457,11 @@
       RegVar->setDotDebugLocOffset(0);
     else
       RegVar->setDotDebugLocOffset(DotDebugLocEntries.size());
-    const MachineInstr *Begin = NULL;
-    const MachineInstr *End = NULL;
+
     for (SmallVector<const MachineInstr *, 4>::iterator
            MVI = MultipleValues.begin(), MVE = MultipleValues.end();
          MVI != MVE; ++MVI) {
-      if (!Begin) {
-        Begin = *MVI;
-        continue;
-      }
-      End = *MVI;
+      const MachineInstr *Begin = *MVI;
       MachineLocation MLoc;
       if (Begin->getNumOperands() == 3) {
         if (Begin->getOperand(0).isReg() && Begin->getOperand(1).isImm())
@@ -2475,25 +2469,25 @@
       } else
         MLoc = Asm->getDebugValueLocation(Begin);
 
-      const MCSymbol *FLabel = getLabelBeforeInsn(Begin);
-      const MCSymbol *SLabel = getLabelBeforeInsn(End);
-      if (MLoc.getReg())
-        DotDebugLocEntries.push_back(DotDebugLocEntry(FLabel, SLabel, MLoc));
+      if (!MLoc.getReg())
+        continue;
 
-      Begin = End;
-      if (MVI + 1 == MVE) {
-        // If End is the last instruction then its value is valid
+      // Compute the range for a register location.
+      const MCSymbol *FLabel = getLabelBeforeInsn(Begin);
+      const MCSymbol *SLabel = 0;
+
+      if (const MachineInstr *ClobberMI = RegClobberInsn.lookup(Begin))
+        // The register range starting at Begin may be clobbered.
+        SLabel = getLabelAfterInsn(ClobberMI);
+      else if (MVI + 1 == MVE)
+        // If Begin is the last instruction then its value is valid
         // until the end of the funtion.
-        MachineLocation EMLoc;
-        if (End->getNumOperands() == 3) {
-          if (End->getOperand(0).isReg() && Begin->getOperand(1).isImm())
-          EMLoc.set(Begin->getOperand(0).getReg(), Begin->getOperand(1).getImm());
-        } else
-          EMLoc = Asm->getDebugValueLocation(End);
-        if (EMLoc.getReg()) 
-          DotDebugLocEntries.
-            push_back(DotDebugLocEntry(SLabel, FunctionEndSym, EMLoc));
-      }
+        SLabel = FunctionEndSym;
+      else
+        // The value is valid until the next DBG_VALUE.
+        SLabel = getLabelBeforeInsn(MVI[1]);
+
+      DotDebugLocEntries.push_back(DotDebugLocEntry(FLabel, SLabel, MLoc));
     }
     DotDebugLocEntries.push_back(DotDebugLocEntry());
   }
@@ -2568,7 +2562,7 @@
 
 /// endInstruction - Process end of an instruction.
 void DwarfDebug::endInstruction(const MachineInstr *MI) {
-  if (InsnsEndScopeSet.count(MI) != 0) {
+  if (InsnsNeedsLabelAfter.count(MI) != 0) {
     // Emit a label if this instruction ends a scope.
     MCSymbol *Label = MMI->getContext().CreateTempSymbol();
     Asm->OutStreamer.EmitLabel(Label);
@@ -2833,7 +2827,7 @@
            RE = Ranges.end(); RI != RE; ++RI) {
       assert(RI->first && "DbgRange does not have first instruction!");
       assert(RI->second && "DbgRange does not have second instruction!");
-      InsnsEndScopeSet.insert(RI->second);
+      InsnsNeedsLabelAfter.insert(RI->second);
     }
   }
 }
@@ -2914,6 +2908,14 @@
   /// ProcessedArgs - Collection of arguments already processed.
   SmallPtrSet<const MDNode *, 8> ProcessedArgs;
 
+  /// LastDbgValue - Refer back to the last DBG_VALUE instruction to mention MD.
+  DenseMap<const MDNode*, const MachineInstr*> LastDbgValue;
+
+  const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo();
+
+  /// LiveUserVar - Map physreg numbers to the MDNode they contain.
+  std::vector<const MDNode*> LiveUserVar(TRI->getNumRegs());
+
   DebugLoc PrevLoc;
   for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
        I != E; ++I)
@@ -2923,7 +2925,15 @@
       DebugLoc DL = MI->getDebugLoc();
       if (MI->isDebugValue()) {
         assert (MI->getNumOperands() > 1 && "Invalid machine instruction!");
-        DIVariable DV(MI->getOperand(MI->getNumOperands() - 1).getMetadata());
+
+        // Keep track of variables in registers.
+        const MDNode *Var =
+          MI->getOperand(MI->getNumOperands() - 1).getMetadata();
+        LastDbgValue[Var] = MI;
+        if (isDbgValueInDefinedReg(MI))
+          LiveUserVar[MI->getOperand(0).getReg()] = Var;
+
+        DIVariable DV(Var);
         if (!DV.Verify()) continue;
         // If DBG_VALUE is for a local variable then it needs a label.
         if (DV.getTag() != dwarf::DW_TAG_arg_variable)
@@ -2944,6 +2954,32 @@
         } else if (DL != PrevLoc)
           // Otherwise, instruction needs a location only if it is new location.
           InsnNeedsLabel.insert(MI);
+
+        // Check if the instruction clobbers any registers with debug vars.
+        for (MachineInstr::const_mop_iterator MOI = MI->operands_begin(),
+               MOE = MI->operands_end(); MOI != MOE; ++MOI) {
+          if (!MOI->isReg() || !MOI->isDef() || !MOI->getReg())
+            continue;
+          for (const unsigned *AI = TRI->getOverlaps(MOI->getReg());
+               unsigned Reg = *AI; ++AI) {
+            const MDNode *Var = LiveUserVar[Reg];
+            if (!Var)
+              continue;
+            // Reg is now clobbered.
+            LiveUserVar[Reg] = 0;
+
+            // Was MD last defined by a DBG_VALUE referring to Reg?
+            const MachineInstr *Last = LastDbgValue.lookup(Var);
+            if (!Last || Last->getParent() != MI->getParent())
+              continue;
+            if (!isDbgValueInDefinedReg(Last) ||
+                Last->getOperand(0).getReg() != Reg)
+              continue;
+            // MD is clobbered. Make sure the next instruction gets a label.
+            InsnsNeedsLabelAfter.insert(MI);
+            RegClobberInsn[Last] = MI;
+          }
+        }
       }
 
       if (!DL.isUnknown() || UnknownLocations)
@@ -3013,7 +3049,8 @@
   VarToAbstractVarMap.clear();
   DbgVariableToDbgInstMap.clear();
   DeleteContainerSeconds(DbgScopeMap);
-  InsnsEndScopeSet.clear();
+  InsnsNeedsLabelAfter.clear();
+  RegClobberInsn.clear();
   ConcreteScopes.clear();
   DeleteContainerSeconds(AbstractScopes);
   AbstractScopesList.clear();