[llvm] r298360 - [DebugInfo][X86] Teach Optimize LEAs pass to handle debug values

Andrea Di Biagio via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 21 04:36:21 PDT 2017


Author: adibiagio
Date: Tue Mar 21 06:36:21 2017
New Revision: 298360

URL: http://llvm.org/viewvc/llvm-project?rev=298360&view=rev
Log:
[DebugInfo][X86] Teach Optimize LEAs pass to handle debug values

This patch fixes an issue in the Optimize LEAs pass where redundant LEAs were
not removed because they were being used by debug values. The debug values are
now ignored when determining whether LEAs are redundant.

For now the debug values for the redundant LEAs are marked as undefined,
effectively lost. The intention is for a follow up patch which will attempt to
preserve the debug values where possible.

Patch by Andrew Ng.

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

Added:
    llvm/trunk/test/CodeGen/X86/lea-opt-with-debug.mir
Modified:
    llvm/trunk/lib/Target/X86/X86OptimizeLEAs.cpp

Modified: llvm/trunk/lib/Target/X86/X86OptimizeLEAs.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86OptimizeLEAs.cpp?rev=298360&r1=298359&r2=298360&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86OptimizeLEAs.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86OptimizeLEAs.cpp Tue Mar 21 06:36:21 2017
@@ -389,9 +389,6 @@ bool OptimizeLEAPass::isReplaceable(cons
   assert(isLEA(First) && isLEA(Last) &&
          "The function works only with LEA instructions");
 
-  // Get new address displacement.
-  AddrDispShift = getAddrDispShift(Last, 1, First, 1);
-
   // Make sure that LEA def registers belong to the same class. There may be
   // instructions (like MOV8mr_NOREX) which allow a limited set of registers to
   // be used as their operands, so we must be sure that replacing one LEA
@@ -400,10 +397,13 @@ bool OptimizeLEAPass::isReplaceable(cons
       MRI->getRegClass(Last.getOperand(0).getReg()))
     return false;
 
+  // Get new address displacement.
+  AddrDispShift = getAddrDispShift(Last, 1, First, 1);
+
   // Loop over all uses of the Last LEA to check that its def register is
   // used only as address base for memory accesses. If so, it can be
   // replaced, otherwise - no.
-  for (auto &MO : MRI->use_operands(Last.getOperand(0).getReg())) {
+  for (auto &MO : MRI->use_nodbg_operands(Last.getOperand(0).getReg())) {
     MachineInstr &MI = *MO.getParent();
 
     // Get the number of the first memory operand.
@@ -563,8 +563,9 @@ bool OptimizeLEAPass::removeRedundantLEA
         // Loop over all uses of the Last LEA and update their operands. Note
         // that the correctness of this has already been checked in the
         // isReplaceable function.
-        for (auto UI = MRI->use_begin(Last.getOperand(0).getReg()),
-                  UE = MRI->use_end();
+        unsigned LastVReg = Last.getOperand(0).getReg();
+        for (auto UI = MRI->use_nodbg_begin(LastVReg),
+                  UE = MRI->use_nodbg_end();
              UI != UE;) {
           MachineOperand &MO = *UI++;
           MachineInstr &MI = *MO.getParent();
@@ -586,6 +587,9 @@ bool OptimizeLEAPass::removeRedundantLEA
             Op.setOffset(Op.getOffset() + AddrDispShift);
         }
 
+        // Mark debug values referring to Last LEA as undefined.
+        MRI->markUsesInDebugValueAsUndef(LastVReg);
+
         // Since we can possibly extend register lifetime, clear kill flags.
         MRI->clearKillFlags(First.getOperand(0).getReg());
 
@@ -594,7 +598,7 @@ bool OptimizeLEAPass::removeRedundantLEA
 
         // By this moment, all of the Last LEA's uses must be replaced. So we
         // can freely remove it.
-        assert(MRI->use_empty(Last.getOperand(0).getReg()) &&
+        assert(MRI->use_empty(LastVReg) &&
                "The LEA's def register must have no uses");
         Last.eraseFromParent();
 

Added: llvm/trunk/test/CodeGen/X86/lea-opt-with-debug.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/lea-opt-with-debug.mir?rev=298360&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/lea-opt-with-debug.mir (added)
+++ llvm/trunk/test/CodeGen/X86/lea-opt-with-debug.mir Tue Mar 21 06:36:21 2017
@@ -0,0 +1,122 @@
+# RUN: llc -mtriple=x86_64-unknown-unknown -start-after peephole-opt -stop-before detect-dead-lanes -o - %s | FileCheck %s
+
+# Test that pass optimize LEA can remove a redundant LEA even when it is also
+# used by a DBG_VALUE.
+
+--- |
+  target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+  %struct.A = type { i32, i32, i32 }
+
+  @c = common local_unnamed_addr global %struct.A* null, align 8
+  @a = common local_unnamed_addr global i32 0, align 4
+  @d = common local_unnamed_addr global i32 0, align 4
+  @b = common local_unnamed_addr global i32 0, align 4
+
+  define i32 @fn1() local_unnamed_addr !dbg !8 {
+    %1 = load %struct.A*, %struct.A** @c, align 8, !dbg !13
+    %2 = load i32, i32* @a, align 4, !dbg !13
+    %3 = sext i32 %2 to i64, !dbg !13
+    %4 = getelementptr inbounds %struct.A, %struct.A* %1, i64 %3, !dbg !13
+    %5 = ptrtoint %struct.A* %4 to i64, !dbg !13
+    %6 = trunc i64 %5 to i32, !dbg !13
+    store i32 %6, i32* @d, align 4, !dbg !13
+    %7 = getelementptr inbounds %struct.A, %struct.A* %1, i64 %3, i32 2, !dbg !14
+    tail call void @llvm.dbg.value(metadata i32* %7, i64 0, metadata !11, metadata !15), !dbg !16
+    br label %8, !dbg !17
+
+  ; <label>:8:                                      ; preds = %8, %0
+    %9 = load i32, i32* %7, align 4, !dbg !18
+    store i32 %9, i32* @d, align 4, !dbg !18
+    br label %8, !dbg !19
+  }
+
+  ; Function Attrs: nounwind readnone
+  declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #0
+
+  attributes #0 = { nounwind readnone }
+
+  !llvm.dbg.cu = !{!0}
+  !llvm.module.flags = !{!5, !6, !7}
+
+  !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, globals: !2)
+  !1 = !DIFile(filename: "test.c", directory: "")
+  !2 = !{}
+  !3 = !{!4}
+  !4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+  !5 = !{i32 2, !"Dwarf Version", i32 4}
+  !6 = !{i32 2, !"Debug Info Version", i32 3}
+  !7 = !{i32 1, !"PIC Level", i32 2}
+  !8 = distinct !DISubprogram(name: "fn1", scope: !1, file: !1, line: 7, type: !9, isLocal: false, isDefinition: true, scopeLine: 7, isOptimized: true, unit: !0, variables: !10)
+  !9 = !DISubroutineType(types: !3)
+  !10 = !{!11}
+  !11 = !DILocalVariable(name: "e", scope: !8, file: !1, line: 8, type: !12)
+  !12 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64)
+  !13 = !DILocation(line: 9, scope: !8)
+  !14 = !DILocation(line: 10, scope: !8)
+  !15 = !DIExpression()
+  !16 = !DILocation(line: 8, scope: !8)
+  !17 = !DILocation(line: 11, scope: !8)
+  !18 = !DILocation(line: 13, scope: !8)
+  !19 = !DILocation(line: 14, scope: !8)
+
+...
+---
+name:            fn1
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: gr64 }
+  - { id: 1, class: gr64 }
+  - { id: 2, class: gr64_nosp }
+  - { id: 3, class: gr64_nosp }
+  - { id: 4, class: gr64 }
+  - { id: 5, class: gr32 }
+  - { id: 6, class: gr32 }
+frameInfo:
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  maxCallFrameSize: 0
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+body:             |
+  bb.0 (%ir-block.0):
+    successors: %bb.1(0x80000000)
+
+    ; CHECK: %3 = LEA64r %2, 2, %2, 0, _, debug-location !13
+    ; CHECK-NEXT: %4 = LEA64r %1, 4, %3, 0, _, debug-location !13
+    ; CHECK-NOT: %0 = LEA64r %1, 4, %3, 8, _, debug-location !14
+    ; CHECK: DBG_VALUE debug-use _, debug-use _, !11, !15, debug-location !16
+
+    %1 = MOV64rm %rip, 1, _, @c, _, debug-location !13 :: (dereferenceable load 8 from @c)
+    %2 = MOVSX64rm32 %rip, 1, _, @a, _, debug-location !13 :: (dereferenceable load 4 from @a)
+    %3 = LEA64r %2, 2, %2, 0, _, debug-location !13
+    %4 = LEA64r %1, 4, %3, 0, _, debug-location !13
+    %5 = COPY %4.sub_32bit, debug-location !13
+    MOV32mr %rip, 1, _, @d, _, killed %5, debug-location !13 :: (store 4 into @d)
+    %0 = LEA64r %1, 4, %3, 8, _, debug-location !14
+    DBG_VALUE debug-use %0, debug-use _, !11, !15, debug-location !16
+
+    ; CHECK-LABEL: bb.1 (%ir-block.8):
+    ; CHECK: %6 = MOV32rm %4, 1, _, 8, _, debug-location !18 :: (load 4 from %ir.7)
+
+  bb.1 (%ir-block.8):
+    successors: %bb.1(0x80000000)
+
+    %6 = MOV32rm %0, 1, _, 0, _, debug-location !18 :: (load 4 from %ir.7)
+    MOV32mr %rip, 1, _, @d, _, killed %6, debug-location !18 :: (store 4 into @d)
+    JMP_1 %bb.1, debug-location !19
+
+...




More information about the llvm-commits mailing list