From: Konstantin Zhuravlyov Date: Wed, 8 Mar 2017 00:28:57 +0000 (+0000) Subject: [DebugInfo] Make legal and emit DW_OP_swap and DW_OP_xderef X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=df032da7f1a1df65433f504223f4c4cf7a620332;p=llvm [DebugInfo] Make legal and emit DW_OP_swap and DW_OP_xderef Differential Revision: https://reviews.llvm.org/D29672 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297247 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/docs/LangRef.rst b/docs/LangRef.rst index 9bf70c8afcd..cf09a89db33 100644 --- a/docs/LangRef.rst +++ b/docs/LangRef.rst @@ -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 """""""""""""" diff --git a/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/lib/CodeGen/AsmPrinter/DwarfExpression.cpp index c584e5a92da..43c98442d8b 100644 --- a/lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -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"); } diff --git a/lib/IR/DebugInfoMetadata.cpp b/lib/IR/DebugInfoMetadata.cpp index 3fe2872183d..54cc52f0626 100644 --- a/lib/IR/DebugInfoMetadata.cpp +++ b/lib/IR/DebugInfoMetadata.cpp @@ -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; } } diff --git a/test/Assembler/diexpression.ll b/test/Assembler/diexpression.ll index dd69c0edecc..c2fa3ee14c2 100644 --- a/test/Assembler/diexpression.ll +++ b/test/Assembler/diexpression.ll @@ -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 index 00000000000..b227c54bfa8 --- /dev/null +++ b/test/Verifier/diexpression-swap.ll @@ -0,0 +1,5 @@ +; RUN: not opt -S < %s 2>&1 | FileCheck %s + +!named = !{!0} +; CHECK: invalid expression +!0 = !DIExpression(DW_OP_swap)