[llvm] a0bd610 - [DebugInfo] Limit the number of values that may be referenced by a dbg.value

Stephen Tozer via llvm-commits llvm-commits at lists.llvm.org
Wed May 26 09:34:22 PDT 2021


Author: Stephen Tozer
Date: 2021-05-26T17:34:05+01:00
New Revision: a0bd6105d80698c53ceaa64bbe6e3b7e7bbf99ee

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

LOG: [DebugInfo] Limit the number of values that may be referenced by a dbg.value

Following the addition of salvaging dbg.values using DIArgLists to
reference multiple values, a case has been found where excessively large
DIArgLists are produced as a result of this salvaging, resulting in
large enough performance costs to effectively freeze the compiler.

This patch introduces an upper bound of 16 to the number of values that
may be salvaged into a dbg.value, to limit the impact of these extreme
cases to performance.

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

Added: 
    llvm/test/DebugInfo/limit-arglist-size.ll

Modified: 
    llvm/lib/Transforms/Utils/Local.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index 38ecb7550ec50..eeaf43a4a55db 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1724,6 +1724,9 @@ void llvm::salvageDebugInfo(Instruction &I) {
 
 void llvm::salvageDebugInfoForDbgValues(
     Instruction &I, ArrayRef<DbgVariableIntrinsic *> DbgUsers) {
+  // This is an arbitrary chosen limit on the maximum number of values we can
+  // salvage up to in a DIArgList, used for performance reasons.
+  const unsigned MaxDebugArgs = 16;
   bool Salvaged = false;
 
   for (auto *DII : DbgUsers) {
@@ -1748,11 +1751,15 @@ void llvm::salvageDebugInfoForDbgValues(
     DII->replaceVariableLocationOp(&I, I.getOperand(0));
     if (AdditionalValues.empty()) {
       DII->setExpression(SalvagedExpr);
-    } else if (isa<DbgValueInst>(DII)) {
+    } else if (isa<DbgValueInst>(DII) &&
+               DII->getNumVariableLocationOps() + AdditionalValues.size() <=
+                   MaxDebugArgs) {
       DII->addVariableLocationOps(AdditionalValues, SalvagedExpr);
     } else {
       // Do not salvage using DIArgList for dbg.addr/dbg.declare, as it is
       // currently only valid for stack value expressions.
+      // Also do not salvage if the resulting DIArgList would contain an
+      // unreasonably large number of values.
       Value *Undef = UndefValue::get(I.getOperand(0)->getType());
       DII->replaceVariableLocationOp(I.getOperand(0), Undef);
     }

diff  --git a/llvm/test/DebugInfo/limit-arglist-size.ll b/llvm/test/DebugInfo/limit-arglist-size.ll
new file mode 100644
index 0000000000000..951cc0e1c3cc7
--- /dev/null
+++ b/llvm/test/DebugInfo/limit-arglist-size.ll
@@ -0,0 +1,63 @@
+; RUN: opt -S -instcombine %s -o - | FileCheck %s
+
+; For performance reasons, we currently limit the number of values that can be
+; referenced by a dbg.value to 16. This test checks that we do not exceed this
+; limit during salvaging.
+
+; CHECK: DIArgList(i32 undef
+; CHECK-NOT: DW_OP_LLVM_arg, 16
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i32 @_Z3foov() local_unnamed_addr !dbg !9 {
+entry:
+  %call = call i32 @_Z3barv(), !dbg !14
+  %call1 = call i32 @_Z3barv(), !dbg !14
+  %add = add nsw i32 %call, %call1, !dbg !14
+  %call2 = call i32 @_Z3barv(), !dbg !14
+  %call4 = call i32 @_Z3barv(), !dbg !14
+  %call6 = call i32 @_Z3barv(), !dbg !14
+  %call8 = call i32 @_Z3barv(), !dbg !14
+  %call10 = call i32 @_Z3barv(), !dbg !14
+  %call12 = call i32 @_Z3barv(), !dbg !14
+  %call14 = call i32 @_Z3barv(), !dbg !14
+  %call16 = call i32 @_Z3barv(), !dbg !14
+  %call18 = call i32 @_Z3barv(), !dbg !14
+  %call20 = call i32 @_Z3barv(), !dbg !14
+  %call22 = call i32 @_Z3barv(), !dbg !14
+  %call24 = call i32 @_Z3barv(), !dbg !14
+  %call26 = call i32 @_Z3barv(), !dbg !14
+  %call28 = call i32 @_Z3barv(), !dbg !14
+  %call30 = call i32 @_Z3barv(), !dbg !14
+  call void @llvm.dbg.value(metadata !DIArgList(i32 %add, i32 %call30, i32 %call28, i32 %call26, i32 %call24, i32 %call22, i32 %call20, i32 %call18, i32 %call16, i32 %call14, i32 %call12, i32 %call10, i32 %call8, i32 %call6, i32 %call4, i32 %call2), metadata !15, metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 15, DW_OP_plus, DW_OP_LLVM_arg, 14, DW_OP_plus, DW_OP_LLVM_arg, 13, DW_OP_plus, DW_OP_LLVM_arg, 12, DW_OP_plus, DW_OP_LLVM_arg, 11, DW_OP_plus, DW_OP_LLVM_arg, 10, DW_OP_plus, DW_OP_LLVM_arg, 9, DW_OP_plus, DW_OP_LLVM_arg, 8, DW_OP_plus, DW_OP_LLVM_arg, 7, DW_OP_plus, DW_OP_LLVM_arg, 6, DW_OP_plus, DW_OP_LLVM_arg, 5, DW_OP_plus, DW_OP_LLVM_arg, 4, DW_OP_plus, DW_OP_LLVM_arg, 3, DW_OP_plus, DW_OP_LLVM_arg, 2, DW_OP_plus, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_stack_value)), !dbg !16
+  %call32 = call i32 @_Z3barv(), !dbg !17
+  ret i32 %call32, !dbg !17
+}
+
+declare dso_local i32 @_Z3barv() local_unnamed_addr
+
+declare void @llvm.dbg.value(metadata, metadata, metadata)
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5, !6, !7}
+!llvm.ident = !{!8}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 13.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "limit-arglist-size.cpp", directory: "/")
+!2 = !{}
+!3 = !{i32 7, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{i32 7, !"uwtable", i32 1}
+!7 = !{i32 7, !"frame-pointer", i32 2}
+!8 = !{!"clang version 13.0.0"}
+!9 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !10, file: !10, line: 3, type: !11, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
+!10 = !DIFile(filename: "./limit-arglist-size.cpp", directory: "/")
+!11 = !DISubroutineType(types: !12)
+!12 = !{!13}
+!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!14 = !DILocation(line: 4, scope: !9)
+!15 = !DILocalVariable(name: "v16", scope: !9, file: !10, line: 4, type: !13)
+!16 = !DILocation(line: 0, scope: !9)
+!17 = !DILocation(line: 5, scope: !9)


        


More information about the llvm-commits mailing list