[llvm] r305304 - Align definition of DW_OP_plus with DWARF spec [1/3]

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 13 09:54:44 PDT 2017


Author: fhahn
Date: Tue Jun 13 11:54:44 2017
New Revision: 305304

URL: http://llvm.org/viewvc/llvm-project?rev=305304&view=rev
Log:
Align definition of DW_OP_plus with DWARF spec [1/3]

Summary:
This patch is part of 3 patches that together form a single patch, but must be introduced in stages in order not to break things.
 
The way that LLVM interprets DW_OP_plus in DIExpression nodes is basically that of the DW_OP_plus_uconst operator since LLVM expects an unsigned constant operand. This unnecessarily restricts the DW_OP_plus operator, preventing it from being used to describe the evaluation of runtime values on the expression stack. These patches try to align the semantics of DW_OP_plus and DW_OP_minus with that of the DWARF definition, which pops two elements off the expression stack, performs the operation and pushes the result back on the stack.
 
This is done in three stages:
• The first patch (LLVM) adds support for DW_OP_plus_uconst.
• The second patch (Clang) contains changes all its uses from DW_OP_plus to DW_OP_plus_uconst.
• The third patch (LLVM) changes the semantics of DW_OP_plus and DW_OP_minus to be in line with its DWARF meaning. This patch includes the bitcode upgrade from legacy DIExpressions.

Patch by Sander de Smalen.

Reviewers: pcc, echristo, aprantl

Reviewed By: aprantl

Subscribers: fhahn, aprantl, javed.absar, llvm-commits

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

Modified:
    llvm/trunk/docs/LangRef.rst
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
    llvm/trunk/lib/IR/DebugInfoMetadata.cpp
    llvm/trunk/test/Assembler/diexpression.ll
    llvm/trunk/unittests/IR/MetadataTest.cpp

Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=305304&r1=305303&r2=305304&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Tue Jun 13 11:54:44 2017
@@ -4405,6 +4405,7 @@ The current supported vocabulary is limi
 
 - ``DW_OP_deref`` dereferences the top of the expression stack.
 - ``DW_OP_plus, 93`` adds ``93`` to the working expression.
+- ``DW_OP_plus_uconst, 93`` adds ``93`` to the working expression.
 - ``DW_OP_LLVM_fragment, 16, 8`` specifies the offset and size (``16`` and ``8``
   here, respectively) of the variable fragment from the working expression. Note
   that contrary to DW_OP_bit_piece, the offset is describing the the location
@@ -4427,6 +4428,7 @@ combined with a concrete location.
 
     !0 = !DIExpression(DW_OP_deref)
     !1 = !DIExpression(DW_OP_plus, 3)
+    !1 = !DIExpression(DW_OP_plus_uconst, 3)
     !2 = !DIExpression(DW_OP_bit_piece, 3, 7)
     !3 = !DIExpression(DW_OP_deref, DW_OP_plus, 3, DW_OP_LLVM_fragment, 3, 7)
     !4 = !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef)

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp?rev=305304&r1=305303&r2=305304&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp Tue Jun 13 11:54:44 2017
@@ -248,6 +248,12 @@ bool DwarfExpression::addMachineRegExpre
   assert(Reg.Size == 0 && "subregister has same size as superregister");
 
   // Pattern-match combinations for which more efficient representations exist.
+  // [Reg, DW_OP_plus_uconst, Offset] --> [DW_OP_breg, Offset].
+  if (Op && (Op->getOp() == dwarf::DW_OP_plus_uconst)) {
+    SignedOffset = Op->getArg(0);
+    ExprCursor.take();
+  }
+
   // [Reg, Offset, DW_OP_plus] --> [DW_OP_breg, Offset].
   // [Reg, Offset, DW_OP_minus] --> [DW_OP_breg, -Offset].
   // If Reg is a subregister we need to mask it out before subtracting.
@@ -321,6 +327,7 @@ void DwarfExpression::addExpression(DIEx
       return;
     }
     case dwarf::DW_OP_plus:
+    case dwarf::DW_OP_plus_uconst:
       assert(LocationKind != Register);
       emitOp(dwarf::DW_OP_plus_uconst);
       emitUnsigned(Op->getArg(0));

Modified: llvm/trunk/lib/IR/DebugInfoMetadata.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/DebugInfoMetadata.cpp?rev=305304&r1=305303&r2=305304&view=diff
==============================================================================
--- llvm/trunk/lib/IR/DebugInfoMetadata.cpp (original)
+++ llvm/trunk/lib/IR/DebugInfoMetadata.cpp Tue Jun 13 11:54:44 2017
@@ -599,6 +599,7 @@ unsigned DIExpression::ExprOperand::getS
     return 3;
   case dwarf::DW_OP_constu:
   case dwarf::DW_OP_plus:
+  case dwarf::DW_OP_plus_uconst:
   case dwarf::DW_OP_minus:
     return 2;
   default:
@@ -641,6 +642,7 @@ bool DIExpression::isValid() const {
       break;
     }
     case dwarf::DW_OP_constu:
+    case dwarf::DW_OP_plus_uconst:
     case dwarf::DW_OP_plus:
     case dwarf::DW_OP_minus:
     case dwarf::DW_OP_deref:
@@ -679,7 +681,8 @@ bool DIExpression::extractIfOffset(int64
   }
   if (getNumElements() != 2)
     return false;
-  if (Elements[0] == dwarf::DW_OP_plus) {
+  if (Elements[0] == dwarf::DW_OP_plus ||
+      Elements[0] == dwarf::DW_OP_plus_uconst) {
     Offset = Elements[1];
     return true;
   }

Modified: llvm/trunk/test/Assembler/diexpression.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/diexpression.ll?rev=305304&r1=305303&r2=305304&view=diff
==============================================================================
--- llvm/trunk/test/Assembler/diexpression.ll (original)
+++ llvm/trunk/test/Assembler/diexpression.ll Tue Jun 13 11:54:44 2017
@@ -1,8 +1,8 @@
 ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
 ; RUN: verify-uselistorder %s
 
-; CHECK: !named = !{!0, !1, !2, !3, !4, !5}
-!named = !{!0, !1, !2, !3, !4, !5}
+; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6}
+!named = !{!0, !1, !2, !3, !4, !5, !6}
 
 ; CHECK:      !0 = !DIExpression()
 ; CHECK-NEXT: !1 = !DIExpression(DW_OP_deref)
@@ -10,9 +10,11 @@
 ; 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)
+; CHECK-NEXT: !6 = !DIExpression(DW_OP_plus_uconst, 3)
 !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)
+!6 = !DIExpression(DW_OP_plus_uconst, 3)

Modified: llvm/trunk/unittests/IR/MetadataTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/MetadataTest.cpp?rev=305304&r1=305303&r2=305304&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/MetadataTest.cpp (original)
+++ llvm/trunk/unittests/IR/MetadataTest.cpp Tue Jun 13 11:54:44 2017
@@ -2043,6 +2043,7 @@ TEST_F(DIExpressionTest, isValid) {
 
   // Valid constructions.
   EXPECT_VALID(dwarf::DW_OP_plus, 6);
+  EXPECT_VALID(dwarf::DW_OP_plus_uconst, 6);
   EXPECT_VALID(dwarf::DW_OP_deref);
   EXPECT_VALID(dwarf::DW_OP_LLVM_fragment, 3, 7);
   EXPECT_VALID(dwarf::DW_OP_plus, 6, dwarf::DW_OP_deref);
@@ -2054,6 +2055,7 @@ TEST_F(DIExpressionTest, isValid) {
   // Invalid constructions.
   EXPECT_INVALID(~0u);
   EXPECT_INVALID(dwarf::DW_OP_plus);
+  EXPECT_INVALID(dwarf::DW_OP_plus_uconst);
   EXPECT_INVALID(dwarf::DW_OP_LLVM_fragment);
   EXPECT_INVALID(dwarf::DW_OP_LLVM_fragment, 3);
   EXPECT_INVALID(dwarf::DW_OP_LLVM_fragment, 3, 7, dwarf::DW_OP_plus, 3);




More information about the llvm-commits mailing list