summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/AsmPrinter
diff options
context:
space:
mode:
authorAdrian Prantl <aprantl@apple.com>2017-03-16 17:14:56 +0000
committerAdrian Prantl <aprantl@apple.com>2017-03-16 17:14:56 +0000
commit981f03e6a2202cdc2e245e1c6d5cec70d0dfdbf6 (patch)
tree89d4b4390b13dbd18b4c7814845fb94c4c6d1865 /llvm/lib/CodeGen/AsmPrinter
parent9f3585dad39f1c6f9b0eeb830254925797b36f36 (diff)
downloadbcm5719-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')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp31
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h7
2 files changed, 35 insertions, 3 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) {
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
index 01f66fa7eac..2f5a701499d 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
@@ -99,6 +99,9 @@ protected:
SubRegisterOffsetInBits = OffsetInBits;
}
+ /// Add masking operations to stencil out a subregister.
+ void maskSubRegister();
+
public:
DwarfExpression(unsigned DwarfVersion) : DwarfVersion(DwarfVersion) {}
virtual ~DwarfExpression() {};
@@ -126,8 +129,10 @@ public:
/// is at the top of the DWARF stack.
void AddOpPiece(unsigned SizeInBits, unsigned OffsetInBits = 0);
- /// Emit a shift-right dwarf expression.
+ /// Emit a shift-right dwarf operation.
void AddShr(unsigned ShiftBy);
+ /// Emit a bitwise and dwarf operation.
+ void AddAnd(unsigned Mask);
/// Emit a DW_OP_stack_value, if supported.
///
OpenPOWER on IntegriCloud