]> granicus.if.org Git - llvm/commitdiff
[DebugInfo] Make legal and emit DW_OP_swap and DW_OP_xderef
authorKonstantin Zhuravlyov <kzhuravl_dev@outlook.com>
Wed, 8 Mar 2017 00:28:57 +0000 (00:28 +0000)
committerKonstantin Zhuravlyov <kzhuravl_dev@outlook.com>
Wed, 8 Mar 2017 00:28:57 +0000 (00:28 +0000)
Differential Revision: https://reviews.llvm.org/D29672

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297247 91177308-0d34-0410-b5e6-96231b3b80d8

docs/LangRef.rst
lib/CodeGen/AsmPrinter/DwarfExpression.cpp
lib/IR/DebugInfoMetadata.cpp
test/Assembler/diexpression.ll
test/Verifier/diexpression-swap.ll [new file with mode: 0644]

index 9bf70c8afcdcaa48d7cdc87043a72a088d96db01..cf09a89db33b194c84b9cf37c4f84bf7974ec79a 100644 (file)
@@ -4377,6 +4377,10 @@ The current supported vocabulary is limited:
 - ``DW_OP_plus, 93`` adds ``93`` to the working expression.
 - ``DW_OP_bit_piece, 16, 8`` specifies the offset and size (``16`` and ``8``
   here, respectively) of the variable piece from the working expression.
+- ``DW_OP_swap`` swaps top two stack entries.
+- ``DW_OP_xderef`` provides extended dereference mechanism. The entry at the top
+  of the stack is treated as an address. The second stack entry is treated as an
+  address space identifier.
 
 .. code-block:: text
 
@@ -4384,6 +4388,7 @@ The current supported vocabulary is limited:
     !1 = !DIExpression(DW_OP_plus, 3)
     !2 = !DIExpression(DW_OP_bit_piece, 3, 7)
     !3 = !DIExpression(DW_OP_deref, DW_OP_plus, 3, DW_OP_bit_piece, 3, 7)
+    !4 = !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef)
 
 DIObjCProperty
 """"""""""""""
index c584e5a92da61256f7bc61f45a80dd96259ce339..43c98442d8b2dba290c03f4e5cca3ca5445ad615 100644 (file)
@@ -273,6 +273,12 @@ void DwarfExpression::AddExpression(DIExpressionCursor &&ExprCursor,
     case dwarf::DW_OP_stack_value:
       AddStackValue();
       break;
+    case dwarf::DW_OP_swap:
+      EmitOp(dwarf::DW_OP_swap);
+      break;
+    case dwarf::DW_OP_xderef:
+      EmitOp(dwarf::DW_OP_xderef);
+      break;
     default:
       llvm_unreachable("unhandled opcode found in expression");
     }
index 3fe2872183de0a7829d5ff477c307bfa7b107e91..54cc52f0626c30eb998d752a44ae0c0d0af35a1b 100644 (file)
@@ -612,10 +612,23 @@ bool DIExpression::isValid() const {
         return false;
       break;
     }
+    case dwarf::DW_OP_swap: {
+      // Must be more than one implicit element on the stack.
+
+      // FIXME: A better way to implement this would be to add a local variable
+      // that keeps track of the stack depth and introduce something like a
+      // DW_LLVM_OP_implicit_location as a placeholder for the location this
+      // DIExpression is attached to, or else pass the number of implicit stack
+      // elements into isValid.
+      if (getNumElements() == 1)
+        return false;
+      break;
+    }
     case dwarf::DW_OP_constu:
     case dwarf::DW_OP_plus:
     case dwarf::DW_OP_minus:
     case dwarf::DW_OP_deref:
+    case dwarf::DW_OP_xderef:
       break;
     }
   }
index dd69c0edecc2484f56bda9b3ef68ae565c238e2b..c2fa3ee14c23482cee863b6c3479b8e6054cbff4 100644 (file)
@@ -1,16 +1,18 @@
 ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
 ; RUN: verify-uselistorder %s
 
-; CHECK: !named = !{!0, !1, !2, !3, !4}
-!named = !{!0, !1, !2, !3, !4}
+; CHECK: !named = !{!0, !1, !2, !3, !4, !5}
+!named = !{!0, !1, !2, !3, !4, !5}
 
 ; CHECK:      !0 = !DIExpression()
 ; CHECK-NEXT: !1 = !DIExpression(DW_OP_deref)
 ; CHECK-NEXT: !2 = !DIExpression(DW_OP_plus, 3)
 ; CHECK-NEXT: !3 = !DIExpression(DW_OP_LLVM_fragment, 3, 7)
 ; CHECK-NEXT: !4 = !DIExpression(DW_OP_deref, DW_OP_plus, 3, DW_OP_LLVM_fragment, 3, 7)
+; CHECK-NEXT: !5 = !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef)
 !0 = !DIExpression()
 !1 = !DIExpression(DW_OP_deref)
 !2 = !DIExpression(DW_OP_plus, 3)
 !3 = !DIExpression(DW_OP_LLVM_fragment, 3, 7)
 !4 = !DIExpression(DW_OP_deref, DW_OP_plus, 3, DW_OP_LLVM_fragment, 3, 7)
+!5 = !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef)
diff --git a/test/Verifier/diexpression-swap.ll b/test/Verifier/diexpression-swap.ll
new file mode 100644 (file)
index 0000000..b227c54
--- /dev/null
@@ -0,0 +1,5 @@
+; RUN: not opt -S < %s 2>&1 | FileCheck %s
+
+!named = !{!0}
+; CHECK: invalid expression
+!0 = !DIExpression(DW_OP_swap)