[llvm] r282506 - Propagate DBG_VALUE entries when there are unvisited predecessors

Keith Walker via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 27 09:46:08 PDT 2016


Author: kwalker
Date: Tue Sep 27 11:46:07 2016
New Revision: 282506

URL: http://llvm.org/viewvc/llvm-project?rev=282506&view=rev
Log:
Propagate DBG_VALUE entries when there are unvisited predecessors

Variables are sometimes missing their debug location information in
blocks in which the variables should be available. This would occur
when one or more predecessor blocks had not yet been visited by the
routine which propagated the information from predecessor blocks.

This is addressed by only considering predecessor blocks which have
already been visited.

The solution to this problem was suggested by Daniel Berlin on the
LLVM developer mailing list.

Differential Revision: https://reviews.llvm.org/D24927

Added:
    llvm/trunk/test/CodeGen/ARM/dbg-range-extension.mir
Modified:
    llvm/trunk/lib/CodeGen/LiveDebugValues.cpp

Modified: llvm/trunk/lib/CodeGen/LiveDebugValues.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveDebugValues.cpp?rev=282506&r1=282505&r2=282506&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LiveDebugValues.cpp (original)
+++ llvm/trunk/lib/CodeGen/LiveDebugValues.cpp Tue Sep 27 11:46:07 2016
@@ -201,7 +201,8 @@ private:
                 VarLocInMBB &OutLocs, VarLocMap &VarLocIDs);
 
   bool join(MachineBasicBlock &MBB, VarLocInMBB &OutLocs, VarLocInMBB &InLocs,
-            const VarLocMap &VarLocIDs);
+            const VarLocMap &VarLocIDs,
+            SmallPtrSet<const MachineBasicBlock *, 16> &Visited);
 
   bool ExtendRanges(MachineFunction &MF);
 
@@ -368,7 +369,8 @@ bool LiveDebugValues::transfer(MachineIn
 /// inserting a new DBG_VALUE instruction at the start of the @MBB - if the same
 /// source variable in all the predecessors of @MBB reside in the same location.
 bool LiveDebugValues::join(MachineBasicBlock &MBB, VarLocInMBB &OutLocs,
-                           VarLocInMBB &InLocs, const VarLocMap &VarLocIDs) {
+                           VarLocInMBB &InLocs, const VarLocMap &VarLocIDs,
+                           SmallPtrSet<const MachineBasicBlock *, 16> &Visited) {
   DEBUG(dbgs() << "join MBB: " << MBB.getName() << "\n");
   bool Changed = false;
 
@@ -376,21 +378,32 @@ bool LiveDebugValues::join(MachineBasicB
 
   // For all predecessors of this MBB, find the set of VarLocs that
   // can be joined.
+  int NumVisited = 0;
   for (auto p : MBB.predecessors()) {
+    // Ignore unvisited predecessor blocks.  As we are processing
+    // the blocks in reverse post-order any unvisited block can
+    // be considered to not remove any incoming values.
+    if (!Visited.count(p))
+      continue;
     auto OL = OutLocs.find(p);
     // Join is null in case of empty OutLocs from any of the pred.
     if (OL == OutLocs.end())
       return false;
 
-    // Just copy over the Out locs to incoming locs for the first predecessor.
-    if (p == *MBB.pred_begin()) {
+    // Just copy over the Out locs to incoming locs for the first visited
+    // predecessor, and for all other predecessors join the Out locs.
+    if (!NumVisited)
       InLocsT = OL->second;
-      continue;
-    }
-    // Join with this predecessor.
-    InLocsT &= OL->second;
+    else
+      InLocsT &= OL->second;
+    NumVisited++;
   }
 
+  // As we are processing blocks in reverse post-order we
+  // should have processed at least one predecessor, unless it
+  // is the entry block which has no predecessor.
+  assert((NumVisited || MBB.pred_empty()) &&
+         "Should have processed at least one predecessor");
   if (InLocsT.empty())
     return false;
 
@@ -463,6 +476,7 @@ bool LiveDebugValues::ExtendRanges(Machi
   // To solve it, we perform join() and transfer() using the two worklist method
   // until the ranges converge.
   // Ranges have converged when both worklists are empty.
+  SmallPtrSet<const MachineBasicBlock *, 16> Visited;
   while (!Worklist.empty() || !Pending.empty()) {
     // We track what is on the pending worklist to avoid inserting the same
     // thing twice.  We could avoid this with a custom priority queue, but this
@@ -472,8 +486,8 @@ bool LiveDebugValues::ExtendRanges(Machi
     while (!Worklist.empty()) {
       MachineBasicBlock *MBB = OrderToBB[Worklist.top()];
       Worklist.pop();
-      MBBJoined = join(*MBB, OutLocs, InLocs, VarLocIDs);
-
+      MBBJoined = join(*MBB, OutLocs, InLocs, VarLocIDs, Visited);
+      Visited.insert(MBB);
       if (MBBJoined) {
         MBBJoined = false;
         Changed = true;

Added: llvm/trunk/test/CodeGen/ARM/dbg-range-extension.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/dbg-range-extension.mir?rev=282506&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/dbg-range-extension.mir (added)
+++ llvm/trunk/test/CodeGen/ARM/dbg-range-extension.mir Tue Sep 27 11:46:07 2016
@@ -0,0 +1,282 @@
+# RUN: llc -mtriple=arm-eabi -run-pass=livedebugvalues %s -o - | FileCheck %s
+#
+# Check that the debug information for variables are propagated into the correct blocks.
+#
+# Generated from the C source:
+#
+# int func2(int,  int);
+# void func(int a) {
+#   int b = func2(10, 11);
+#   if (a) {
+#     int c = func2(12, 13);
+#     for(int i = 1; i < a; i++) {
+#       func2(i, i+b);
+#     }
+#     func2(b,c);
+#   }
+#   func2(b,a);
+# }
+
+# CHECK: [[VAR_A:![0-9]+]] = !DILocalVariable(name: "a",
+# CHECK: [[VAR_B:![0-9]+]] = !DILocalVariable(name: "b",
+# CHECK: [[VAR_C:![0-9]+]] = !DILocalVariable(name: "c",
+# CHECK: [[VAR_I:![0-9]+]] = !DILocalVariable(name: "i",
+
+# CHECK: bb.0.entry
+# CHECK: DBG_VALUE debug-use %r0, debug-use _, [[VAR_A]]
+# CHECK: DBG_VALUE debug-use [[REG_A:%r[0-9]+]], debug-use _, [[VAR_A]]
+# CHECK: DBG_VALUE debug-use [[REG_B:%r[0-9]+]], debug-use _, [[VAR_B]]
+
+# CHECK: bb.1.if.then
+# CHECK: DBG_VALUE debug-use [[REG_B]], debug-use _, [[VAR_B]]
+# CHECK: DBG_VALUE debug-use [[REG_A]], debug-use _, [[VAR_A]]
+# CHECK: DBG_VALUE debug-use [[REG_C:%r[0-9]+]], debug-use _, [[VAR_C]]
+# CHECK: DBG_VALUE 1, 0, [[VAR_I]]
+
+# CHECK: bb.2.for.body
+# CHECK: DBG_VALUE debug-use [[REG_I:%r[0-9]+]], debug-use _, [[VAR_I]]
+# CHECK: DBG_VALUE debug-use [[REG_C]], debug-use _, [[VAR_C]]
+# CHECK: DBG_VALUE debug-use [[REG_B]], debug-use _, [[VAR_B]]
+# CHECK: DBG_VALUE debug-use [[REG_A]], debug-use _, [[VAR_A]]
+# CHECK: DBG_VALUE debug-use [[REG_I]], debug-use _, [[VAR_I]]
+
+# CHECK: bb.3.for.cond
+# CHECK: DBG_VALUE debug-use [[REG_C]], debug-use _, [[VAR_C]]
+# CHECK: DBG_VALUE debug-use [[REG_B]], debug-use _, [[VAR_B]]
+# CHECK: DBG_VALUE debug-use [[REG_A]], debug-use _, [[VAR_A]]
+# CHECK: DBG_VALUE debug-use [[REG_I]], debug-use _, [[VAR_I]]
+
+# CHECK: bb.4.for.cond.cleanup
+# CHECK: DBG_VALUE debug-use [[REG_I]], debug-use _, [[VAR_I]]
+# CHECK: DBG_VALUE debug-use [[REG_C]], debug-use _, [[VAR_C]]
+# CHECK: DBG_VALUE debug-use [[REG_B]], debug-use _, [[VAR_B]]
+# CHECK: DBG_VALUE debug-use [[REG_A]], debug-use _, [[VAR_A]]
+
+# CHECK: bb.5.if.end
+# CHECK: DBG_VALUE debug-use [[REG_B]], debug-use _, [[VAR_B]]
+# CHECK: DBG_VALUE debug-use [[REG_A]], debug-use _, [[VAR_A]]
+--- |
+  ; ModuleID = '/data/kwalker/work/OpenSource-llvm/llvm/test/CodeGen/ARM/dbg-range-extension.ll'
+  source_filename = "/data/kwalker/work/OpenSource-llvm/llvm/test/CodeGen/ARM/dbg-range-extension.ll"
+  target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
+  target triple = "arm---eabi"
+  
+  ; Function Attrs: minsize nounwind optsize
+  define void @func(i32 %a) local_unnamed_addr #0 !dbg !8 {
+  entry:
+    tail call void @llvm.dbg.value(metadata i32 %a, i64 0, metadata !13, metadata !20), !dbg !21
+    %call = tail call i32 @func2(i32 10, i32 11) #0, !dbg !22
+    tail call void @llvm.dbg.value(metadata i32 %call, i64 0, metadata !14, metadata !20), !dbg !23
+    %tobool = icmp eq i32 %a, 0, !dbg !24
+    br i1 %tobool, label %if.end, label %if.then, !dbg !25
+  
+  if.then:                                          ; preds = %entry
+    %call1 = tail call i32 @func2(i32 12, i32 13) #0, !dbg !26
+    tail call void @llvm.dbg.value(metadata i32 %call1, i64 0, metadata !15, metadata !20), !dbg !27
+    tail call void @llvm.dbg.value(metadata i32 1, i64 0, metadata !18, metadata !20), !dbg !28
+    br label %for.cond, !dbg !29
+  
+  for.cond:                                         ; preds = %for.body, %if.then
+    %i.0 = phi i32 [ 1, %if.then ], [ %inc, %for.body ]
+    tail call void @llvm.dbg.value(metadata i32 %i.0, i64 0, metadata !18, metadata !20), !dbg !28
+    %cmp = icmp slt i32 %i.0, %a, !dbg !30
+    br i1 %cmp, label %for.body, label %for.cond.cleanup, !dbg !33
+  
+  for.cond.cleanup:                                 ; preds = %for.cond
+    %call3 = tail call i32 @func2(i32 %call, i32 %call1) #0, !dbg !34
+    br label %if.end, !dbg !35
+  
+  for.body:                                         ; preds = %for.cond
+    %0 = add i32 %call, %i.0, !dbg !36
+    %call2 = tail call i32 @func2(i32 %i.0, i32 %0) #0, !dbg !36
+    %inc = add nuw nsw i32 %i.0, 1, !dbg !38
+    tail call void @llvm.dbg.value(metadata i32 %inc, i64 0, metadata !18, metadata !20), !dbg !28
+    br label %for.cond, !dbg !40, !llvm.loop !41
+  
+  if.end:                                           ; preds = %for.cond.cleanup, %entry
+    %call4 = tail call i32 @func2(i32 %call, i32 %a) #0, !dbg !43
+    ret void, !dbg !44
+  }
+  
+  ; Function Attrs: minsize optsize
+  declare i32 @func2(i32, i32) local_unnamed_addr #1
+  
+  ; Function Attrs: nounwind readnone
+  declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #2
+  
+  ; Function Attrs: nounwind
+  declare void @llvm.stackprotector(i8*, i8**) #3
+  
+  attributes #0 = { minsize nounwind optsize }
+  attributes #1 = { minsize optsize }
+  attributes #2 = { nounwind readnone }
+  attributes #3 = { nounwind }
+  
+  !llvm.dbg.cu = !{!0}
+  !llvm.module.flags = !{!3, !4, !5, !6}
+  !llvm.ident = !{!7}
+  
+  !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+  !1 = !DIFile(filename: "loop.c", directory: "/tmp")
+  !2 = !{}
+  !3 = !{i32 2, !"Dwarf Version", i32 4}
+  !4 = !{i32 2, !"Debug Info Version", i32 3}
+  !5 = !{i32 1, !"wchar_size", i32 4}
+  !6 = !{i32 1, !"min_enum_size", i32 4}
+  !7 = !{!"clang version 4.0.0 (http://llvm.org/git/clang.git b8f10df3679b36f51e1de7c4351b82d297825089) (http://llvm.org/git/llvm.git c2a5d16d1e3b8c49f5bbb1ff87a76ac4f88edb89)"}
+  !8 = distinct !DISubprogram(name: "func", scope: !1, file: !1, line: 2, type: !9, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !12)
+  !9 = !DISubroutineType(types: !10)
+  !10 = !{null, !11}
+  !11 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
+  !12 = !{!13, !14, !15, !18}
+  !13 = !DILocalVariable(name: "a", arg: 1, scope: !8, file: !1, line: 2, type: !11)
+  !14 = !DILocalVariable(name: "b", scope: !8, file: !1, line: 3, type: !11)
+  !15 = !DILocalVariable(name: "c", scope: !16, file: !1, line: 5, type: !11)
+  !16 = distinct !DILexicalBlock(scope: !17, file: !1, line: 4, column: 9)
+  !17 = distinct !DILexicalBlock(scope: !8, file: !1, line: 4, column: 6)
+  !18 = !DILocalVariable(name: "i", scope: !19, file: !1, line: 6, type: !11)
+  !19 = distinct !DILexicalBlock(scope: !16, file: !1, line: 6, column: 3)
+  !20 = !DIExpression()
+  !21 = !DILocation(line: 2, column: 15, scope: !8)
+  !22 = !DILocation(line: 3, column: 17, scope: !8)
+  !23 = !DILocation(line: 3, column: 13, scope: !8)
+  !24 = !DILocation(line: 4, column: 6, scope: !17)
+  !25 = !DILocation(line: 4, column: 6, scope: !8)
+  !26 = !DILocation(line: 5, column: 11, scope: !16)
+  !27 = !DILocation(line: 5, column: 7, scope: !16)
+  !28 = !DILocation(line: 6, column: 11, scope: !19)
+  !29 = !DILocation(line: 6, column: 7, scope: !19)
+  !30 = !DILocation(line: 6, column: 20, scope: !31)
+  !31 = !DILexicalBlockFile(scope: !32, file: !1, discriminator: 1)
+  !32 = distinct !DILexicalBlock(scope: !19, file: !1, line: 6, column: 3)
+  !33 = !DILocation(line: 6, column: 3, scope: !31)
+  !34 = !DILocation(line: 9, column: 3, scope: !16)
+  !35 = !DILocation(line: 10, column: 2, scope: !16)
+  !36 = !DILocation(line: 7, column: 4, scope: !37)
+  !37 = distinct !DILexicalBlock(scope: !32, file: !1, line: 6, column: 30)
+  !38 = !DILocation(line: 6, column: 26, scope: !39)
+  !39 = !DILexicalBlockFile(scope: !32, file: !1, discriminator: 3)
+  !40 = !DILocation(line: 6, column: 3, scope: !39)
+  !41 = distinct !{!41, !42}
+  !42 = !DILocation(line: 6, column: 3, scope: !16)
+  !43 = !DILocation(line: 11, column: 2, scope: !8)
+  !44 = !DILocation(line: 12, column: 1, scope: !8)
+
+...
+---
+name:            func
+alignment:       2
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: false
+liveins:         
+  - { reg: '%r0' }
+calleeSavedRegisters: [ '%lr', '%d8', '%d9', '%d10', '%d11', '%d12', '%d13', 
+                        '%d14', '%d15', '%q4', '%q5', '%q6', '%q7', '%r4', 
+                        '%r5', '%r6', '%r7', '%r8', '%r9', '%r10', '%r11', 
+                        '%s16', '%s17', '%s18', '%s19', '%s20', '%s21', 
+                        '%s22', '%s23', '%s24', '%s25', '%s26', '%s27', 
+                        '%s28', '%s29', '%s30', '%s31', '%d8_d10', '%d9_d11', 
+                        '%d10_d12', '%d11_d13', '%d12_d14', '%d13_d15', 
+                        '%q4_q5', '%q5_q6', '%q6_q7', '%q4_q5_q6_q7', '%r4_r5', 
+                        '%r6_r7', '%r8_r9', '%r10_r11', '%d8_d9_d10', '%d9_d10_d11', 
+                        '%d10_d11_d12', '%d11_d12_d13', '%d12_d13_d14', 
+                        '%d13_d14_d15', '%d8_d10_d12', '%d9_d11_d13', '%d10_d12_d14', 
+                        '%d11_d13_d15', '%d8_d10_d12_d14', '%d9_d11_d13_d15', 
+                        '%d9_d10', '%d11_d12', '%d13_d14', '%d9_d10_d11_d12', 
+                        '%d11_d12_d13_d14' ]
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       24
+  offsetAdjustment: 0
+  maxAlignment:    4
+  adjustsStack:    true
+  hasCalls:        true
+  maxCallFrameSize: 0
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+stack:           
+  - { id: 0, type: spill-slot, offset: -4, size: 4, alignment: 4, callee-saved-register: '%lr' }
+  - { id: 1, type: spill-slot, offset: -8, size: 4, alignment: 4, callee-saved-register: '%r11' }
+  - { id: 2, type: spill-slot, offset: -12, size: 4, alignment: 4, callee-saved-register: '%r7' }
+  - { id: 3, type: spill-slot, offset: -16, size: 4, alignment: 4, callee-saved-register: '%r6' }
+  - { id: 4, type: spill-slot, offset: -20, size: 4, alignment: 4, callee-saved-register: '%r5' }
+  - { id: 5, type: spill-slot, offset: -24, size: 4, alignment: 4, callee-saved-register: '%r4' }
+body:             |
+  bb.0.entry:
+    successors: %bb.5.if.end, %bb.1.if.then
+    liveins: %r0, %r4, %r5, %r6, %r7, %r11, %lr
+  
+    %sp = frame-setup STMDB_UPD %sp, 14, _, killed %r4, killed %r5, killed %r6, killed %r7, killed %r11, killed %lr
+    frame-setup CFI_INSTRUCTION def_cfa_offset 24
+    frame-setup CFI_INSTRUCTION offset %lr, -4
+    frame-setup CFI_INSTRUCTION offset %r11, -8
+    frame-setup CFI_INSTRUCTION offset %r7, -12
+    frame-setup CFI_INSTRUCTION offset %r6, -16
+    frame-setup CFI_INSTRUCTION offset %r5, -20
+    frame-setup CFI_INSTRUCTION offset %r4, -24
+    DBG_VALUE debug-use %r0, debug-use _, !13, !20, debug-location !21
+    %r4 = MOVr killed %r0, 14, _, _
+    DBG_VALUE debug-use %r4, debug-use _, !13, !20, debug-location !21
+    %r0 = MOVi 10, 14, _, _, debug-location !22
+    %r1 = MOVi 11, 14, _, _, debug-location !22
+    BL @func2, csr_aapcs, implicit-def dead %lr, implicit %sp, implicit killed %r0, implicit killed %r1, implicit-def %sp, implicit-def %r0, debug-location !22
+    %r5 = MOVr killed %r0, 14, _, _, debug-location !22
+    DBG_VALUE debug-use %r5, debug-use _, !14, !20, debug-location !23
+    CMPri %r4, 0, 14, _, implicit-def %cpsr, debug-location !25
+    Bcc %bb.5.if.end, 0, killed %cpsr
+  
+  bb.1.if.then:
+    successors: %bb.3.for.cond
+    liveins: %r4, %r5
+  
+    %r0 = MOVi 12, 14, _, _, debug-location !26
+    %r1 = MOVi 13, 14, _, _, debug-location !26
+    BL @func2, csr_aapcs, implicit-def dead %lr, implicit %sp, implicit killed %r0, implicit killed %r1, implicit-def %sp, implicit-def %r0, debug-location !26
+    %r6 = MOVr killed %r0, 14, _, _, debug-location !26
+    DBG_VALUE debug-use %r6, debug-use _, !15, !20, debug-location !27
+    %r7 = MOVi 1, 14, _, _
+    DBG_VALUE 1, 0, !18, !20, debug-location !28
+    B %bb.3.for.cond
+  
+  bb.2.for.body:
+    successors: %bb.3.for.cond
+    liveins: %r4, %r5, %r6, %r7
+  
+    %r1 = ADDrr %r5, %r7, 14, _, _, debug-location !36
+    %r0 = MOVr %r7, 14, _, _, debug-location !36
+    BL @func2, csr_aapcs, implicit-def dead %lr, implicit %sp, implicit killed %r0, implicit killed %r1, implicit-def %sp, implicit-def dead %r0, debug-location !36
+    %r7 = ADDri killed %r7, 1, 14, _, _, debug-location !38
+    DBG_VALUE debug-use %r7, debug-use _, !18, !20, debug-location !28
+  
+  bb.3.for.cond:
+    successors: %bb.2.for.body, %bb.4.for.cond.cleanup
+    liveins: %r4, %r5, %r6, %r7
+  
+    DBG_VALUE debug-use %r7, debug-use _, !18, !20, debug-location !28
+    CMPrr %r7, %r4, 14, _, implicit-def %cpsr, debug-location !33
+    Bcc %bb.2.for.body, 11, killed %cpsr, debug-location !33
+  
+  bb.4.for.cond.cleanup:
+    successors: %bb.5.if.end
+    liveins: %r4, %r5, %r6
+  
+    %r0 = MOVr %r5, 14, _, _, debug-location !34
+    %r1 = MOVr killed %r6, 14, _, _, debug-location !34
+    BL @func2, csr_aapcs, implicit-def dead %lr, implicit %sp, implicit killed %r0, implicit killed %r1, implicit-def %sp, implicit-def dead %r0, debug-location !34
+  
+  bb.5.if.end:
+    liveins: %r4, %r5
+  
+    %r0 = MOVr killed %r5, 14, _, _, debug-location !43
+    %r1 = MOVr killed %r4, 14, _, _, debug-location !43
+    %sp = LDMIA_UPD %sp, 14, _, def %r4, def %r5, def %r6, def %r7, def %r11, def %lr, debug-location !43
+    TAILJMPd @func2, implicit %sp, implicit %sp, implicit killed %r0, implicit killed %r1, debug-location !43
+
+...




More information about the llvm-commits mailing list