[llvm] c93a9b1 - [DebugInfo][CGP] Update dbg.values when sinking address computations

Jeremy Morse via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 6 03:27:43 PST 2019


Author: Jeremy Morse
Date: 2019-12-06T11:27:19Z
New Revision: c93a9b15ce885f7a4d90b0f9ff2928fc7e2cd74a

URL: https://github.com/llvm/llvm-project/commit/c93a9b15ce885f7a4d90b0f9ff2928fc7e2cd74a
DIFF: https://github.com/llvm/llvm-project/commit/c93a9b15ce885f7a4d90b0f9ff2928fc7e2cd74a.diff

LOG: [DebugInfo][CGP] Update dbg.values when sinking address computations

One of CodeGenPrepare's optimizations is to duplicate address calculations
into basic blocks, so that as much information as possible can be folded
into memory addressing operands. This is great -- but the dbg.value
variable location intrinsics are not updated in the same way. This can lead
to dbg.values referring to address computations in other blocks that will
never be encoded into the DAG, while duplicate address computations are
performed locally that could be used by the dbg.value. Some of these (such
as non-constant-offset GEPs) can't be salvaged past.

Fix this by, whenever we duplicate an address computation into a block,
looking for dbg.value users of the original memory address in the same
block, and redirecting those to the local computation.

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

Added: 
    llvm/test/DebugInfo/Generic/codegenprep-addrsink.ll

Modified: 
    llvm/lib/CodeGen/CodeGenPrepare.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 0689f8e4f0c3..a041808199d4 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -375,6 +375,7 @@ class TypePromotionTransaction;
     bool optimizeSwitchInst(SwitchInst *SI);
     bool optimizeExtractElementInst(Instruction *Inst);
     bool dupRetToEnableTailCallOpts(BasicBlock *BB, bool &ModifiedDT);
+    bool fixupDbgValue(Instruction *I);
     bool placeDbgValues(Function &F);
     bool canFormExtLd(const SmallVectorImpl<Instruction *> &MovedExts,
                       LoadInst *&LI, Instruction *&Inst, bool HasPromoted);
@@ -2002,6 +2003,8 @@ bool CodeGenPrepare::optimizeCallInst(CallInst *CI, bool &ModifiedDT) {
     case Intrinsic::ctlz:
       // If counting zeros is expensive, try to avoid it.
       return despeculateCountZeros(II, TLI, DL, ModifiedDT);
+    case Intrinsic::dbg_value:
+      return fixupDbgValue(II);
     }
 
     if (TLI) {
@@ -7205,6 +7208,28 @@ bool CodeGenPrepare::optimizeBlock(BasicBlock &BB, bool &ModifiedDT) {
   return MadeChange;
 }
 
+// Some CGP optimizations may move or alter what's computed in a block. Check
+// whether a dbg.value intrinsic could be pointed at a more appropriate operand.
+bool CodeGenPrepare::fixupDbgValue(Instruction *I) {
+  assert(isa<DbgValueInst>(I));
+  DbgValueInst &DVI = *cast<DbgValueInst>(I);
+
+  // Does this dbg.value refer to a sunk address calculation?
+  Value *Location = DVI.getVariableLocation();
+  WeakTrackingVH SunkAddrVH = SunkAddrs[Location];
+  Value *SunkAddr = SunkAddrVH.pointsToAliveValue() ? SunkAddrVH : nullptr;
+  if (SunkAddr) {
+    // Point dbg.value at locally computed address, which should give the best
+    // opportunity to be accurately lowered. This update may change the type of
+    // pointer being referred to; however this makes no 
diff erence to debugging
+    // information, and we can't generate bitcasts that may affect codegen.
+    DVI.setOperand(0, MetadataAsValue::get(DVI.getContext(),
+                                           ValueAsMetadata::get(SunkAddr)));
+    return true;
+  }
+  return false;
+}
+
 // llvm.dbg.value is far away from the value then iSel may not be able
 // handle it properly. iSel will drop llvm.dbg.value if it can not
 // find a node corresponding to the value.

diff  --git a/llvm/test/DebugInfo/Generic/codegenprep-addrsink.ll b/llvm/test/DebugInfo/Generic/codegenprep-addrsink.ll
new file mode 100644
index 000000000000..5d245c917337
--- /dev/null
+++ b/llvm/test/DebugInfo/Generic/codegenprep-addrsink.ll
@@ -0,0 +1,70 @@
+; RUN: llc -start-before=codegenprepare -stop-after=codegenprepare %s -o - | FileCheck %s
+;
+; CGP duplicates address calculation into each basic block that contains loads
+; or stores, so that they can be folded into instruction memory operands for
+; example. dbg.value's should be redirected to identify such local address
+; computations, to give the best opportunity for variable locations to be
+; preserved.
+; This test has two dbg.values in it, one before and one after the relevant
+; memory instruction. Test that the one before does _not_ get updated (as that
+; would either make it use-before-def or shift when the variable appears), and
+; that the dbg.value after the memory instruction does get updated.
+;
+; Due to placeDbgValues, the dbg.values currently get shifted up a few
+; instructions.
+
+define dso_local i8 @foo(i32 *%p, i32 %cond) !dbg !7 {
+entry:
+; The first dbg.value of %arith, in the 'next' block, will be moved up here
+; by placeDbgValues,
+; CHECK-LABEL: entry:
+; CHECK:       dbg.value(metadata i8* %arith, metadata ![[DIVAR:[0-9]+]],
+; CHECK-SAME:    metadata !DIExpression()
+  %casted = bitcast i32 *%p to i8*
+  %arith = getelementptr i8, i8 *%casted, i32 3
+  %load1 = load i8, i8 *%arith
+  %cmpresult = icmp eq i32 %cond, 0
+  br i1 %cmpresult, label %next, label %ret
+
+next:
+; Address calcs should be duplicated into this block. One dbg.value should be
+; updated, and the other should not.
+; CHECK-LABEL: next:
+; CHECK:       %[[CASTVAR:[0-9a-zA-Z]+]] = bitcast i32* %p to i8*
+; CHECK-NEXT:  %[[GEPVAR:[0-9a-zA-Z]+]] = getelementptr i8, i8* %[[CASTVAR]],
+; CHECK-SAME:                             i64 3
+; CHECK-NEXT:  call void @llvm.dbg.value(metadata i8* %[[GEPVAR]],
+; CHECK-SAME:                            metadata ![[DIVAR]],
+; CHECK-NEXT:  %loaded = load i8, i8* %[[GEPVAR]]
+  call void @llvm.dbg.value(metadata i8 *%arith, metadata !12, metadata !DIExpression()), !dbg !14
+  %loaded = load i8, i8 *%arith
+  call void @llvm.dbg.value(metadata i8 *%arith, metadata !12, metadata !DIExpression()), !dbg !14
+  ret i8 %loaded
+
+ret:
+  ret i8 0
+}
+
+; CHECK: ![[DIVAR]] = !DILocalVariable(name: "p",
+
+declare void @llvm.dbg.value(metadata, metadata, metadata)
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+!1 = !DIFile(filename: "test.cpp", directory: ".")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 8.0.0 (trunk 348209)"}
+!7 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !1, file: !1, line: 4, type: !8, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
+!8 = !DISubroutineType(types: !9)
+!9 = !{null, !10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !{!12}
+!12 = !DILocalVariable(name: "p", arg: 1, scope: !7, file: !1, line: 4, type: !10)
+!14 = !DILocation(line: 4, column: 15, scope: !7)
+!20 = distinct !DILexicalBlock(scope: !7, file: !1, line: 8, column: 7)


        


More information about the llvm-commits mailing list