diff options
author | Adrian Prantl <aprantl@apple.com> | 2017-03-16 17:14:56 +0000 |
---|---|---|
committer | Adrian Prantl <aprantl@apple.com> | 2017-03-16 17:14:56 +0000 |
commit | 981f03e6a2202cdc2e245e1c6d5cec70d0dfdbf6 (patch) | |
tree | 89d4b4390b13dbd18b4c7814845fb94c4c6d1865 /llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp | |
parent | 9f3585dad39f1c6f9b0eeb830254925797b36f36 (diff) | |
download | bcm5719-llvm-981f03e6a2202cdc2e245e1c6d5cec70d0dfdbf6.tar.gz bcm5719-llvm-981f03e6a2202cdc2e245e1c6d5cec70d0dfdbf6.zip |
PR32288: More efficient encoding for DWARF expr subregister access.
Citing http://bugs.llvm.org/show_bug.cgi?id=32288
The DWARF generated by LLVM includes this location:
0x55 0x93 0x04 DW_OP_reg5 DW_OP_piece(4) When GCC's DWARF is simply
0x55 (DW_OP_reg5) without the DW_OP_piece. I believe it's reasonable
to assume the DWARF consumer knows which part of a register
logically holds the value (low bytes, high bytes, how many bytes,
etc) for a primitive value like an integer.
This patch gets rid of the redundant DW_OP_piece when a subregister is
at offset 0. It also adds previously missing subregister masking when
a subregister is followed by another operation.
(This reapplies r297960 with two additional testcase updates).
rdar://problem/31069390
https://reviews.llvm.org/D31010
llvm-svn: 297965
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp index 43c98442d8b..caf0bc0f258 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -66,6 +66,12 @@ void DwarfExpression::AddShr(unsigned ShiftBy) { EmitOp(dwarf::DW_OP_shr); } +void DwarfExpression::AddAnd(unsigned Mask) { + EmitOp(dwarf::DW_OP_constu); + EmitUnsigned(Mask); + EmitOp(dwarf::DW_OP_and); +} + bool DwarfExpression::AddMachineRegIndirect(const TargetRegisterInfo &TRI, unsigned MachineReg, int Offset) { if (isFrameRegister(TRI, MachineReg)) { @@ -230,6 +236,12 @@ void DwarfExpression::AddExpression(DIExpressionCursor &&ExprCursor, unsigned FragmentOffsetInBits) { while (ExprCursor) { auto Op = ExprCursor.take(); + + // If we need to mask out a subregister, do it now, unless the next + // operation would emit an OpPiece anyway. + if (SubRegisterSizeInBits && Op->getOp() != dwarf::DW_OP_LLVM_fragment) + maskSubRegister(); + switch (Op->getOp()) { case dwarf::DW_OP_LLVM_fragment: { unsigned SizeInBits = Op->getArg(1); @@ -285,9 +297,24 @@ void DwarfExpression::AddExpression(DIExpressionCursor &&ExprCursor, } } +/// Add masking operations to stencil out a subregister. +void DwarfExpression::maskSubRegister() { + assert(SubRegisterSizeInBits && "no subregister was registered"); + if (SubRegisterOffsetInBits > 0) + AddShr(SubRegisterOffsetInBits); + uint64_t Mask = (1UL << SubRegisterSizeInBits) - 1; + AddAnd(Mask); +} + + void DwarfExpression::finalize() { - if (SubRegisterSizeInBits) - AddOpPiece(SubRegisterSizeInBits, SubRegisterOffsetInBits); + // Emit any outstanding DW_OP_piece operations to mask out subregisters. + if (SubRegisterSizeInBits == 0) + return; + // Don't emit a DW_OP_piece for a subregister at offset 0. + if (SubRegisterOffsetInBits == 0) + return; + AddOpPiece(SubRegisterSizeInBits, SubRegisterOffsetInBits); } void DwarfExpression::addFragmentOffset(const DIExpression *Expr) { |