Skip to content

Commit

Permalink
[DebugInfo] Make legal and emit DW_OP_swap and DW_OP_xderef
Browse files Browse the repository at this point in the history
Differential Revision: https://reviews.llvm.org/D29672

llvm-svn: 297247
  • Loading branch information
kzhuravl committed Mar 8, 2017
1 parent 33562c2 commit f9b41cd
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 2 deletions.
5 changes: 5 additions & 0 deletions llvm/docs/LangRef.rst
Expand Up @@ -4377,13 +4377,18 @@ 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
!0 = !DIExpression(DW_OP_deref)
!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
""""""""""""""
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
Expand Up @@ -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");
}
Expand Down
13 changes: 13 additions & 0 deletions llvm/lib/IR/DebugInfoMetadata.cpp
Expand Up @@ -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;
}
}
Expand Down
6 changes: 4 additions & 2 deletions llvm/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)
5 changes: 5 additions & 0 deletions llvm/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)

0 comments on commit f9b41cd

Please sign in to comment.