[llvm-branch-commits] [llvm] 104a9f9 - [Debuginfo][DW_OP_implicit_pointer] (1/7) Support for DW_OP_LLVM_implicit_pointer

Alok Kumar Sharma via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Jan 15 01:20:55 PST 2021


Author: Alok Kumar Sharma
Date: 2021-01-15T14:45:04+05:30
New Revision: 104a9f99ccab9d6dbc07a70f569246c23feaf4c1

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

LOG: [Debuginfo][DW_OP_implicit_pointer] (1/7) Support for DW_OP_LLVM_implicit_pointer

New dwarf operator DW_OP_LLVM_implicit_pointer is introduced (present only in LLVM IR)
This operator is required as it is different than DWARF operator
DW_OP_implicit_pointer in representation and specification (number
and types of operands) and later can not be used as multiple level.

Reviewed By: aprantl

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

Added: 
    llvm/test/DebugInfo/X86/LLVM_implicit_pointer.ll

Modified: 
    llvm/docs/LangRef.rst
    llvm/include/llvm/BinaryFormat/Dwarf.h
    llvm/lib/BinaryFormat/Dwarf.cpp
    llvm/lib/IR/DebugInfoMetadata.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 5a4c652c3603..a6f6e8281a72 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -5284,6 +5284,33 @@ The current supported opcode vocabulary is limited:
   of the stack. This opcode can be used to calculate bounds of fortran assumed
   rank array which has rank known at run time and current dimension number is
   implicitly first element of the stack.
+- ``DW_OP_LLVM_implicit_pointer`` It specifies the dereferenced value. It can
+  be used to represent pointer variables which are optimized out but the value
+  it points to is known. This operator is required as it is 
diff erent than DWARF
+  operator DW_OP_implicit_pointer in representation and specification (number
+  and types of operands) and later can not be used as multiple level.
+
+.. code-block:: text
+
+    IR for "*ptr = 4;"
+    --------------
+    call void @llvm.dbg.value(metadata i32 4, metadata !17, metadata !20)
+    !17 = !DILocalVariable(name: "ptr1", scope: !12, file: !3, line: 5,
+                           type: !18)
+    !18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64)
+    !19 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+    !20 = !DIExpression(DW_OP_LLVM_implicit_pointer))
+
+    IR for "**ptr = 4;"
+    --------------
+    call void @llvm.dbg.value(metadata i32 4, metadata !17, metadata !21)
+    !17 = !DILocalVariable(name: "ptr1", scope: !12, file: !3, line: 5,
+                           type: !18)
+    !18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64)
+    !19 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !20, size: 64)
+    !20 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+    !21 = !DIExpression(DW_OP_LLVM_implicit_pointer,
+                        DW_OP_LLVM_implicit_pointer))
 
 DWARF specifies three kinds of simple location descriptions: Register, memory,
 and implicit location descriptions.  Note that a location description is

diff  --git a/llvm/include/llvm/BinaryFormat/Dwarf.h b/llvm/include/llvm/BinaryFormat/Dwarf.h
index 75b8b2647b95..cafc5be686bc 100644
--- a/llvm/include/llvm/BinaryFormat/Dwarf.h
+++ b/llvm/include/llvm/BinaryFormat/Dwarf.h
@@ -120,10 +120,11 @@ enum LocationAtom {
 #include "llvm/BinaryFormat/Dwarf.def"
   DW_OP_lo_user = 0xe0,
   DW_OP_hi_user = 0xff,
-  DW_OP_LLVM_fragment = 0x1000,    ///< Only used in LLVM metadata.
-  DW_OP_LLVM_convert = 0x1001,     ///< Only used in LLVM metadata.
-  DW_OP_LLVM_tag_offset = 0x1002,  ///< Only used in LLVM metadata.
-  DW_OP_LLVM_entry_value = 0x1003, ///< Only used in LLVM metadata.
+  DW_OP_LLVM_fragment = 0x1000,         ///< Only used in LLVM metadata.
+  DW_OP_LLVM_convert = 0x1001,          ///< Only used in LLVM metadata.
+  DW_OP_LLVM_tag_offset = 0x1002,       ///< Only used in LLVM metadata.
+  DW_OP_LLVM_entry_value = 0x1003,      ///< Only used in LLVM metadata.
+  DW_OP_LLVM_implicit_pointer = 0x1004, ///< Only used in LLVM metadata.
 };
 
 enum TypeKind : uint8_t {

diff  --git a/llvm/lib/BinaryFormat/Dwarf.cpp b/llvm/lib/BinaryFormat/Dwarf.cpp
index 29028709d378..e4747369f3e3 100644
--- a/llvm/lib/BinaryFormat/Dwarf.cpp
+++ b/llvm/lib/BinaryFormat/Dwarf.cpp
@@ -151,6 +151,8 @@ StringRef llvm::dwarf::OperationEncodingString(unsigned Encoding) {
     return "DW_OP_LLVM_tag_offset";
   case DW_OP_LLVM_entry_value:
     return "DW_OP_LLVM_entry_value";
+  case DW_OP_LLVM_implicit_pointer:
+    return "DW_OP_LLVM_implicit_pointer";
   }
 }
 
@@ -163,6 +165,7 @@ unsigned llvm::dwarf::getOperationEncoding(StringRef OperationEncodingString) {
       .Case("DW_OP_LLVM_fragment", DW_OP_LLVM_fragment)
       .Case("DW_OP_LLVM_tag_offset", DW_OP_LLVM_tag_offset)
       .Case("DW_OP_LLVM_entry_value", DW_OP_LLVM_entry_value)
+      .Case("DW_OP_LLVM_implicit_pointer", DW_OP_LLVM_implicit_pointer)
       .Default(0);
 }
 

diff  --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index 22eca57da31f..77bba9f7ed0e 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -1114,6 +1114,7 @@ bool DIExpression::isValid() const {
       return I->get() == expr_op_begin()->get() && I->getArg(0) == 1 &&
              getNumElements() == 2;
     }
+    case dwarf::DW_OP_LLVM_implicit_pointer:
     case dwarf::DW_OP_LLVM_convert:
     case dwarf::DW_OP_LLVM_tag_offset:
     case dwarf::DW_OP_constu:

diff  --git a/llvm/test/DebugInfo/X86/LLVM_implicit_pointer.ll b/llvm/test/DebugInfo/X86/LLVM_implicit_pointer.ll
new file mode 100644
index 000000000000..904a4530d19f
--- /dev/null
+++ b/llvm/test/DebugInfo/X86/LLVM_implicit_pointer.ll
@@ -0,0 +1,87 @@
+; Round trip test for DW_OP_LLVM_implicit_pointer metadata
+
+; RUN: llvm-as < %s | llvm-dis | FileCheck %s
+
+;---------------------------
+;static const char *b = "opq";
+;volatile int v;
+;int main() {
+;  int var = 4;
+;  int *ptr1;
+;  int **ptr2;
+;
+;  v++;
+;  ptr1 = &var;
+;  ptr2 = &ptr1;
+;  v++;
+;
+;  return *ptr1 - 5 + **ptr2;
+;}
+;---------------------------
+
+; ModuleID = 'LLVM_implicit_pointer.c'
+source_filename = "LLVM_implicit_pointer.c"
+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"
+
+ at v = dso_local global i32 0, align 4, !dbg !0
+
+; Function Attrs: nofree norecurse nounwind uwtable
+define dso_local i32 @main() local_unnamed_addr !dbg !12 {
+entry:
+; CHECK: call void @llvm.dbg.value(metadata i32 4, metadata [[VAR:![0-9]+]], metadata !DIExpression())
+  call void @llvm.dbg.value(metadata i32 4, metadata !16, metadata !DIExpression()), !dbg !21
+  %0 = load volatile i32, i32* @v, align 4, !dbg !22, !tbaa !23
+  %inc = add nsw i32 %0, 1, !dbg !22
+  store volatile i32 %inc, i32* @v, align 4, !dbg !22, !tbaa !23
+
+; CHECK: call void @llvm.dbg.value(metadata i32 4, metadata [[PTR1:![0-9]+]], metadata !DIExpression(DW_OP_LLVM_implicit_pointer))
+  call void @llvm.dbg.value(metadata i32 4, metadata !17, metadata !DIExpression(DW_OP_LLVM_implicit_pointer)), !dbg !21
+
+; CHECK: call void @llvm.dbg.value(metadata i32 4, metadata [[PTR2:![0-9]+]], metadata !DIExpression(DW_OP_LLVM_implicit_pointer, DW_OP_LLVM_implicit_pointer))
+  call void @llvm.dbg.value(metadata i32 4, metadata !19, metadata !DIExpression(DW_OP_LLVM_implicit_pointer, DW_OP_LLVM_implicit_pointer)), !dbg !21
+  %1 = load volatile i32, i32* @v, align 4, !dbg !27, !tbaa !23
+  %inc1 = add nsw i32 %1, 1, !dbg !27
+  store volatile i32 %inc1, i32* @v, align 4, !dbg !27, !tbaa !23
+  ret i32 3, !dbg !28
+}
+
+; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
+declare void @llvm.dbg.value(metadata, metadata, metadata) #1
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!8, !9, !10}
+!llvm.ident = !{!11}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "v", scope: !2, file: !3, line: 2, type: !6, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 12.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, splitDebugInlining: false, nameTableKind: None)
+!3 = !DIFile(filename: "LLVM_implicit_pointer.c", directory: "/dir", checksumkind: CSK_MD5, checksum: "218aaa8dc9f04b056b56d944d06383dd")
+!4 = !{}
+!5 = !{!0}
+!6 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !7)
+!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!8 = !{i32 7, !"Dwarf Version", i32 5}
+!9 = !{i32 2, !"Debug Info Version", i32 3}
+!10 = !{i32 1, !"wchar_size", i32 4}
+!11 = !{!"clang version 12.0.0"}
+!12 = distinct !DISubprogram(name: "main", scope: !3, file: !3, line: 3, type: !13, scopeLine: 3, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !15)
+!13 = !DISubroutineType(types: !14)
+!14 = !{!7}
+!15 = !{!16, !17, !19}
+; CHECK: [[VAR]] = !DILocalVariable(name: "var"
+!16 = !DILocalVariable(name: "var", scope: !12, file: !3, line: 4, type: !7)
+; CHECK: [[PTR1]] = !DILocalVariable(name: "ptr1"
+!17 = !DILocalVariable(name: "ptr1", scope: !12, file: !3, line: 5, type: !18)
+!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64)
+; CHECK: [[PTR2]] = !DILocalVariable(name: "ptr2"
+!19 = !DILocalVariable(name: "ptr2", scope: !12, file: !3, line: 6, type: !20)
+!20 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !18, size: 64)
+!21 = !DILocation(line: 0, scope: !12)
+!22 = !DILocation(line: 8, column: 4, scope: !12)
+!23 = !{!24, !24, i64 0}
+!24 = !{!"int", !25, i64 0}
+!25 = !{!"omnipotent char", !26, i64 0}
+!26 = !{!"Simple C/C++ TBAA"}
+!27 = !DILocation(line: 11, column: 4, scope: !12)
+!28 = !DILocation(line: 13, column: 3, scope: !12)


        


More information about the llvm-branch-commits mailing list