llvm.org GIT mirror llvm / 10ccfa6
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305304 91177308-0d34-0410-b5e6-96231b3b80d8 Florian Hahn 2 years ago
5 changed file(s) with 19 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
44044404
44054405 - ``DW_OP_deref`` dereferences the top of the expression stack.
44064406 - ``DW_OP_plus, 93`` adds ``93`` to the working expression.
4407 - ``DW_OP_plus_uconst, 93`` adds ``93`` to the working expression.
44074408 - ``DW_OP_LLVM_fragment, 16, 8`` specifies the offset and size (``16`` and ``8``
44084409 here, respectively) of the variable fragment from the working expression. Note
44094410 that contrary to DW_OP_bit_piece, the offset is describing the the location
44264427
44274428 !0 = !DIExpression(DW_OP_deref)
44284429 !1 = !DIExpression(DW_OP_plus, 3)
4430 !1 = !DIExpression(DW_OP_plus_uconst, 3)
44294431 !2 = !DIExpression(DW_OP_bit_piece, 3, 7)
44304432 !3 = !DIExpression(DW_OP_deref, DW_OP_plus, 3, DW_OP_LLVM_fragment, 3, 7)
44314433 !4 = !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef)
247247 assert(Reg.Size == 0 && "subregister has same size as superregister");
248248
249249 // Pattern-match combinations for which more efficient representations exist.
250 // [Reg, DW_OP_plus_uconst, Offset] --> [DW_OP_breg, Offset].
251 if (Op && (Op->getOp() == dwarf::DW_OP_plus_uconst)) {
252 SignedOffset = Op->getArg(0);
253 ExprCursor.take();
254 }
255
250256 // [Reg, Offset, DW_OP_plus] --> [DW_OP_breg, Offset].
251257 // [Reg, Offset, DW_OP_minus] --> [DW_OP_breg, -Offset].
252258 // If Reg is a subregister we need to mask it out before subtracting.
320326 return;
321327 }
322328 case dwarf::DW_OP_plus:
329 case dwarf::DW_OP_plus_uconst:
323330 assert(LocationKind != Register);
324331 emitOp(dwarf::DW_OP_plus_uconst);
325332 emitUnsigned(Op->getArg(0));
598598 return 3;
599599 case dwarf::DW_OP_constu:
600600 case dwarf::DW_OP_plus:
601 case dwarf::DW_OP_plus_uconst:
601602 case dwarf::DW_OP_minus:
602603 return 2;
603604 default:
640641 break;
641642 }
642643 case dwarf::DW_OP_constu:
644 case dwarf::DW_OP_plus_uconst:
643645 case dwarf::DW_OP_plus:
644646 case dwarf::DW_OP_minus:
645647 case dwarf::DW_OP_deref:
678680 }
679681 if (getNumElements() != 2)
680682 return false;
681 if (Elements[0] == dwarf::DW_OP_plus) {
683 if (Elements[0] == dwarf::DW_OP_plus ||
684 Elements[0] == dwarf::DW_OP_plus_uconst) {
682685 Offset = Elements[1];
683686 return true;
684687 }
0 ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
11 ; RUN: verify-uselistorder %s
22
3 ; CHECK: !named = !{!0, !1, !2, !3, !4, !5}
4 !named = !{!0, !1, !2, !3, !4, !5}
3 ; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6}
4 !named = !{!0, !1, !2, !3, !4, !5, !6}
55
66 ; CHECK: !0 = !DIExpression()
77 ; CHECK-NEXT: !1 = !DIExpression(DW_OP_deref)
99 ; CHECK-NEXT: !3 = !DIExpression(DW_OP_LLVM_fragment, 3, 7)
1010 ; CHECK-NEXT: !4 = !DIExpression(DW_OP_deref, DW_OP_plus, 3, DW_OP_LLVM_fragment, 3, 7)
1111 ; CHECK-NEXT: !5 = !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef)
12 ; CHECK-NEXT: !6 = !DIExpression(DW_OP_plus_uconst, 3)
1213 !0 = !DIExpression()
1314 !1 = !DIExpression(DW_OP_deref)
1415 !2 = !DIExpression(DW_OP_plus, 3)
1516 !3 = !DIExpression(DW_OP_LLVM_fragment, 3, 7)
1617 !4 = !DIExpression(DW_OP_deref, DW_OP_plus, 3, DW_OP_LLVM_fragment, 3, 7)
1718 !5 = !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef)
19 !6 = !DIExpression(DW_OP_plus_uconst, 3)
20422042
20432043 // Valid constructions.
20442044 EXPECT_VALID(dwarf::DW_OP_plus, 6);
2045 EXPECT_VALID(dwarf::DW_OP_plus_uconst, 6);
20452046 EXPECT_VALID(dwarf::DW_OP_deref);
20462047 EXPECT_VALID(dwarf::DW_OP_LLVM_fragment, 3, 7);
20472048 EXPECT_VALID(dwarf::DW_OP_plus, 6, dwarf::DW_OP_deref);
20532054 // Invalid constructions.
20542055 EXPECT_INVALID(~0u);
20552056 EXPECT_INVALID(dwarf::DW_OP_plus);
2057 EXPECT_INVALID(dwarf::DW_OP_plus_uconst);
20562058 EXPECT_INVALID(dwarf::DW_OP_LLVM_fragment);
20572059 EXPECT_INVALID(dwarf::DW_OP_LLVM_fragment, 3);
20582060 EXPECT_INVALID(dwarf::DW_OP_LLVM_fragment, 3, 7, dwarf::DW_OP_plus, 3);