Dont emit 'DBG_VALUE %noreg, ...' to terminate user variable ranges.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Tue, 22 Mar 2011 00:21:41 +0000 (00:21 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Tue, 22 Mar 2011 00:21:41 +0000 (00:21 +0000)
These ranges get completely jumbled by the post-ra scheduler, and it is not
really reasonable to expect it to make sense of them.

Instead, teach DwarfDebug to notice when user variables in registers are
clobbered, and terminate the ranges there.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128045 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/AsmPrinter/DwarfDebug.cpp
lib/CodeGen/AsmPrinter/DwarfDebug.h
lib/CodeGen/LiveDebugVariables.cpp
test/CodeGen/X86/dbg-value-range.ll

index 15330c28d2ced92f82493b30352352c091ecaa82..d65270edf6edfc34542456fe71b4b46f9696facc 100644 (file)
@@ -2424,8 +2424,7 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
            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 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
       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 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
       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 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
       } else
         MLoc = Asm->getDebugValueLocation(Begin);
 
+      if (!MLoc.getReg())
+        continue;
+
+      // Compute the range for a register location.
       const MCSymbol *FLabel = getLabelBeforeInsn(Begin);
-      const MCSymbol *SLabel = getLabelBeforeInsn(End);
-      if (MLoc.getReg())
-        DotDebugLocEntries.push_back(DotDebugLocEntry(FLabel, SLabel, MLoc));
+      const MCSymbol *SLabel = 0;
 
-      Begin = End;
-      if (MVI + 1 == MVE) {
-        // If End is the last instruction then its value is valid
+      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 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
 
 /// 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 @@ void DwarfDebug::identifyScopeMarkers() {
            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 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
   /// 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 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
       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 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
         } 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,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
   VarToAbstractVarMap.clear();
   DbgVariableToDbgInstMap.clear();
   DeleteContainerSeconds(DbgScopeMap);
-  InsnsEndScopeSet.clear();
+  InsnsNeedsLabelAfter.clear();
   ConcreteScopes.clear();
   DeleteContainerSeconds(AbstractScopes);
   AbstractScopesList.clear();
index 2863ea380603afc016afa4860047a1b78c60faaf..e59ab5bd821096492560337a98647ceadb3c05af 100644 (file)
@@ -200,8 +200,6 @@ class DwarfDebug {
 
   typedef SmallVector<DbgScope *, 2> ScopeVector;
 
-  SmallPtrSet<const MachineInstr *, 8> InsnsEndScopeSet;
-
   /// InlineInfo - Keep track of inlined functions and their location.  This
   /// information is used to populate debug_inlined section.
   typedef std::pair<const MCSymbol *, DIE *> InlineInfoLabels;
@@ -224,6 +222,16 @@ class DwarfDebug {
   /// a debuggging information entity.
   SmallPtrSet<const MachineInstr *, 8> InsnNeedsLabel;
 
+  /// InsnsNeedsLabelAfter - Collection of instructions that need a label after
+  /// the instruction because they end a scope of clobber a register.
+  SmallPtrSet<const MachineInstr *, 8> InsnsNeedsLabelAfter;
+
+  /// RegClobberInsn - For each DBG_VALUE instruction referring to a register
+  /// that is clobbered before the variable gets a new DBG_VALUE, map the
+  /// instruction that clobbered the register. This instruction will also be in
+  /// InsnsNeedsLabelAfter.
+  DenseMap<const MachineInstr *, const MachineInstr *> RegClobberInsn;
+
   SmallVector<const MCSymbol *, 8> DebugRangeSymbols;
 
   /// Previous instruction's location information. This is used to determine
index 20e997ae377bdb6935959cf3c206548e40686ffa..900dc0132783764c0a9c6f127479af8f4559a98c 100644 (file)
@@ -101,10 +101,6 @@ class UserValue {
   void insertDebugValue(MachineBasicBlock *MBB, SlotIndex Idx, unsigned LocNo,
                         LiveIntervals &LIS, const TargetInstrInfo &TII);
 
-  /// insertDebugKill - Insert an undef DBG_VALUE into MBB at Idx.
-  void insertDebugKill(MachineBasicBlock *MBB, SlotIndex Idx,
-                       LiveIntervals &LIS, const TargetInstrInfo &TII);
-
 public:
   /// UserValue - Create a new UserValue.
   UserValue(const MDNode *var, unsigned o, DebugLoc L, 
@@ -752,13 +748,6 @@ void UserValue::insertDebugValue(MachineBasicBlock *MBB, SlotIndex Idx,
     .addOperand(Loc).addImm(offset).addMetadata(variable);
 }
 
-void UserValue::insertDebugKill(MachineBasicBlock *MBB, SlotIndex Idx,
-                               LiveIntervals &LIS, const TargetInstrInfo &TII) {
-  MachineBasicBlock::iterator I = findInsertLocation(MBB, Idx, LIS);
-  BuildMI(*MBB, I, findDebugLoc(), TII.get(TargetOpcode::DBG_VALUE)).addReg(0)
-    .addImm(offset).addMetadata(variable);
-}
-
 void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,
                                 const TargetInstrInfo &TII) {
   MachineFunction::iterator MFEnd = VRM->getMachineFunction().end();
@@ -790,12 +779,6 @@ void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,
       break;
 
     ++I;
-    if (Stop == MBBEnd)
-      continue;
-    // The current interval ends before MBB.
-    // Insert a kill if there is a gap.
-    if (!I.valid() || I.start() > Stop)
-      insertDebugKill(MBB, Stop, LIS, TII);
   }
 }
 
index 2985224d9dbdc6aed3db8ae1598f65ad557f9f8a..665cedcb0b38e68f332a6d7709e148b141fe59f5 100644 (file)
@@ -41,15 +41,17 @@ declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone
 !18 = metadata !{i32 7, i32 2, metadata !12, null}
 !19 = metadata !{i32 8, i32 2, metadata !12, null}
 
-; check that variable bar:b value range is appropriately trucated in debug info. Here Ltmp5 is end of
-; location range.
+; Check that variable bar:b value range is appropriately trucated in debug info.
+; The variable is in %rdi which is clobbered by 'movl %ebx, %edi'
+; Here Ltmp7 is the end of the location range.
 
 ;CHECK:Ltmp6
-;CHECK-NEXT: DEBUG_VALUE: bar:b <- undef
+;CHECK-NEXT: movl
+;CHECK-NEXT: Ltmp7
 
 ;CHECK:Ldebug_loc0:
 ;CHECK-NEXT:   .quad   Ltmp
-;CHECK-NEXT:   .quad   Ltmp6
+;CHECK-NEXT:   .quad   Ltmp7
 ;CHECK-NEXT:   .short  1
 ;CHECK-NEXT:   .byte   85
 ;CHECK-NEXT:   .quad   0