summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/AsmPrinter
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp12
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp25
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp7
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp146
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h13
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp5
6 files changed, 122 insertions, 86 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 5d099be7740..b18dd7d0067 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -834,9 +834,9 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
OS << " <- ";
// The second operand is only an offset if it's an immediate.
- bool Deref = MI->getOperand(0).isReg() && MI->getOperand(1).isImm();
- int64_t Offset = Deref ? MI->getOperand(1).getImm() : 0;
-
+ bool Deref = false;
+ bool MemLoc = MI->getOperand(0).isReg() && MI->getOperand(1).isImm();
+ int64_t Offset = MemLoc ? MI->getOperand(1).getImm() : 0;
for (unsigned i = 0; i < Expr->getNumElements(); ++i) {
uint64_t Op = Expr->getElement(i);
if (Op == dwarf::DW_OP_LLVM_fragment) {
@@ -844,7 +844,7 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
break;
} else if (Deref) {
// We currently don't support extra Offsets or derefs after the first
- // one. Bail out early instead of emitting an incorrect comment
+ // one. Bail out early instead of emitting an incorrect comment.
OS << " [complex expression]";
AP.OutStreamer->emitRawComment(OS.str());
return true;
@@ -899,12 +899,12 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
AP.OutStreamer->emitRawComment(OS.str());
return true;
}
- if (Deref)
+ if (MemLoc || Deref)
OS << '[';
OS << PrintReg(Reg, AP.MF->getSubtarget().getRegisterInfo());
}
- if (Deref)
+ if (MemLoc || Deref)
OS << '+' << Offset << ']';
// NOTE: Want this comment at start of line, don't emit with AddComment.
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index a550ff2fb90..4a092ffbdc0 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -547,18 +547,19 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
for (auto &Fragment : DV.getFrameIndexExprs()) {
unsigned FrameReg = 0;
+ const DIExpression *Expr = Fragment.Expr;
const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
int Offset = TFI->getFrameIndexReference(*Asm->MF, Fragment.FI, FrameReg);
- DwarfExpr.addFragmentOffset(Fragment.Expr);
+ DwarfExpr.addFragmentOffset(Expr);
SmallVector<uint64_t, 8> Ops;
Ops.push_back(dwarf::DW_OP_plus);
Ops.push_back(Offset);
- Ops.push_back(dwarf::DW_OP_deref);
- Ops.append(Fragment.Expr->elements_begin(), Fragment.Expr->elements_end());
- DIExpressionCursor Expr(Ops);
- DwarfExpr.addMachineRegExpression(
- *Asm->MF->getSubtarget().getRegisterInfo(), Expr, FrameReg);
- DwarfExpr.addExpression(std::move(Expr));
+ Ops.append(Expr->elements_begin(), Expr->elements_end());
+ DIExpressionCursor Cursor(Ops);
+ DwarfExpr.addMachineLocExpression(
+ *Asm->MF->getSubtarget().getRegisterInfo(), Cursor,
+ MachineLocation(FrameReg));
+ DwarfExpr.addExpression(std::move(Cursor));
}
addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
@@ -781,14 +782,13 @@ void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute,
DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
SmallVector<uint64_t, 8> Ops;
- if (Location.isIndirect()) {
+ if (Location.isIndirect() && Location.getOffset()) {
Ops.push_back(dwarf::DW_OP_plus);
Ops.push_back(Location.getOffset());
- Ops.push_back(dwarf::DW_OP_deref);
}
DIExpressionCursor Cursor(Ops);
const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
- if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
+ if (!DwarfExpr.addMachineLocExpression(TRI, Cursor, Location))
return;
DwarfExpr.addExpression(std::move(Cursor));
@@ -809,15 +809,14 @@ void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die,
DwarfExpr.addFragmentOffset(DIExpr);
SmallVector<uint64_t, 8> Ops;
- if (Location.isIndirect()) {
+ if (Location.isIndirect() && Location.getOffset()) {
Ops.push_back(dwarf::DW_OP_plus);
Ops.push_back(Location.getOffset());
- Ops.push_back(dwarf::DW_OP_deref);
}
Ops.append(DIExpr->elements_begin(), DIExpr->elements_end());
DIExpressionCursor Cursor(Ops);
const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
- if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
+ if (!DwarfExpr.addMachineLocExpression(TRI, Cursor, Location))
return;
DwarfExpr.addExpression(std::move(Cursor));
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index af90f6f60a1..b5a99aa5545 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -1517,18 +1517,15 @@ static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
DwarfExpr.addUnsignedConstant(Value.getInt());
} else if (Value.isLocation()) {
MachineLocation Location = Value.getLoc();
-
SmallVector<uint64_t, 8> Ops;
- // FIXME: Should this condition be Location.isIndirect() instead?
- if (Location.getOffset()) {
+ if (Location.isIndirect() && Location.getOffset()) {
Ops.push_back(dwarf::DW_OP_plus);
Ops.push_back(Location.getOffset());
- Ops.push_back(dwarf::DW_OP_deref);
}
Ops.append(DIExpr->elements_begin(), DIExpr->elements_end());
DIExpressionCursor Cursor(Ops);
const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo();
- if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
+ if (!DwarfExpr.addMachineLocExpression(TRI, Cursor, Location))
return;
return DwarfExpr.addExpression(std::move(Cursor));
} else if (Value.isConstantFP()) {
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index debe88f3b1e..d21288f4b81 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -23,9 +23,12 @@
using namespace llvm;
void DwarfExpression::addReg(int DwarfReg, const char *Comment) {
- assert(DwarfReg >= 0 && "invalid negative dwarf register number");
- if (DwarfReg < 32) {
- emitOp(dwarf::DW_OP_reg0 + DwarfReg, Comment);
+ assert(DwarfReg >= 0 && "invalid negative dwarf register number");
+ assert((LocationKind == Unknown || LocationKind == Register) &&
+ "location description already locked down");
+ LocationKind = Register;
+ if (DwarfReg < 32) {
+ emitOp(dwarf::DW_OP_reg0 + DwarfReg, Comment);
} else {
emitOp(dwarf::DW_OP_regx, Comment);
emitUnsigned(DwarfReg);
@@ -34,6 +37,7 @@ void DwarfExpression::addReg(int DwarfReg, const char *Comment) {
void DwarfExpression::addBReg(int DwarfReg, int Offset) {
assert(DwarfReg >= 0 && "invalid negative dwarf register number");
+ assert(LocationKind != Register && "location description already locked down");
if (DwarfReg < 32) {
emitOp(dwarf::DW_OP_breg0 + DwarfReg);
} else {
@@ -156,18 +160,23 @@ void DwarfExpression::addStackValue() {
}
void DwarfExpression::addSignedConstant(int64_t Value) {
+ assert(LocationKind == Implicit || LocationKind == Unknown);
+ LocationKind = Implicit;
emitOp(dwarf::DW_OP_consts);
emitSigned(Value);
- addStackValue();
}
void DwarfExpression::addUnsignedConstant(uint64_t Value) {
+ assert(LocationKind == Implicit || LocationKind == Unknown);
+ LocationKind = Implicit;
emitOp(dwarf::DW_OP_constu);
emitUnsigned(Value);
- addStackValue();
}
void DwarfExpression::addUnsignedConstant(const APInt &Value) {
+ assert(LocationKind == Implicit || LocationKind == Unknown);
+ LocationKind = Implicit;
+
unsigned Size = Value.getBitWidth();
const uint64_t *Data = Value.getRawData();
@@ -178,15 +187,20 @@ void DwarfExpression::addUnsignedConstant(const APInt &Value) {
addUnsignedConstant(*Data++);
if (Offset == 0 && Size <= 64)
break;
- addOpPiece(std::min(Size-Offset, 64u), Offset);
+ addStackValue();
+ addOpPiece(std::min(Size - Offset, 64u), Offset);
Offset += 64;
}
}
-bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
+bool DwarfExpression::addMachineLocExpression(const TargetRegisterInfo &TRI,
DIExpressionCursor &ExprCursor,
- unsigned MachineReg,
+ MachineLocation Loc,
unsigned FragmentOffsetInBits) {
+ if (Loc.isIndirect())
+ LocationKind = Memory;
+
+ unsigned MachineReg = Loc.getReg();
auto Fragment = ExprCursor.getFragmentInfo();
if (!addMachineReg(TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U))
return false;
@@ -206,7 +220,7 @@ bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
}
// Handle simple register locations.
- if (!HasComplexExpression) {
+ if (LocationKind != Memory && !HasComplexExpression) {
for (auto &Reg : DwarfRegs) {
if (Reg.DwarfRegNo >= 0)
addReg(Reg.DwarfRegNo, Reg.Comment);
@@ -216,62 +230,58 @@ bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
return true;
}
+ // FIXME:
+ // Don't emit locations that cannot be expressed without DW_OP_stack_value.
+
assert(DwarfRegs.size() == 1);
auto Reg = DwarfRegs[0];
- bool FBReg = isFrameRegister(TRI, MachineReg);
+ bool FBReg = isFrameRegister(TRI, MachineReg);
+ int SignedOffset = 0;
assert(Reg.Size == 0 && "subregister has same size as superregister");
// Pattern-match combinations for which more efficient representations exist.
- switch (Op->getOp()) {
- default: {
- if (FBReg)
- addFBReg(0);
- else
- addReg(Reg.DwarfRegNo, 0);
- break;
+ // [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.
+ if (Op && ((Op->getOp() == dwarf::DW_OP_plus) ||
+ (Op->getOp() == dwarf::DW_OP_minus && !SubRegisterSizeInBits))) {
+ int Offset = Op->getArg(0);
+ SignedOffset = (Op->getOp() == dwarf::DW_OP_plus) ? Offset : -Offset;
+ ExprCursor.take();
}
- case dwarf::DW_OP_plus:
- case dwarf::DW_OP_minus: {
- // [DW_OP_reg,Offset,DW_OP_plus, DW_OP_deref] --> [DW_OP_breg, Offset].
- // [DW_OP_reg,Offset,DW_OP_minus,DW_OP_deref] --> [DW_OP_breg,-Offset].
- auto N = ExprCursor.peekNext();
- if (N && N->getOp() == dwarf::DW_OP_deref) {
- int Offset = Op->getArg(0);
- int SignedOffset = (Op->getOp() == dwarf::DW_OP_plus) ? Offset : -Offset;
- if (FBReg)
- addFBReg(SignedOffset);
- else
- addBReg(Reg.DwarfRegNo, SignedOffset);
+ if (FBReg)
+ addFBReg(SignedOffset);
+ else
+ addBReg(Reg.DwarfRegNo, SignedOffset);
+ DwarfRegs.clear();
+ return true;
+}
- ExprCursor.consume(2);
+/// Assuming a well-formed expression, match "DW_OP_deref* DW_OP_LLVM_fragment?".
+static bool isMemoryLocation(DIExpressionCursor ExprCursor) {
+ while (ExprCursor) {
+ auto Op = ExprCursor.take();
+ switch (Op->getOp()) {
+ case dwarf::DW_OP_deref:
+ case dwarf::DW_OP_LLVM_fragment:
break;
+ default:
+ return false;
}
- addReg(Reg.DwarfRegNo, 0);
- break;
- }
- case dwarf::DW_OP_deref:
- // [DW_OP_reg,DW_OP_deref] --> [DW_OP_breg].
- if (FBReg)
- addFBReg(0);
- else
- addBReg(Reg.DwarfRegNo, 0);
- ExprCursor.take();
- break;
}
- DwarfRegs.clear();
return true;
}
void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor,
unsigned FragmentOffsetInBits) {
+ // If we need to mask out a subregister, do it now, unless the next
+ // operation would emit an OpPiece anyway.
+ auto N = ExprCursor.peek();
+ if (SubRegisterSizeInBits && N && (N->getOp() != dwarf::DW_OP_LLVM_fragment))
+ maskSubRegister();
+
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);
@@ -281,50 +291,74 @@ void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor,
// location.
assert(OffsetInBits >= FragmentOffset && "fragment offset not added?");
- // If \a addMachineReg already emitted DW_OP_piece operations to represent
+ // If addMachineReg already emitted DW_OP_piece operations to represent
// a super-register by splicing together sub-registers, subtract the size
// of the pieces that was already emitted.
SizeInBits -= OffsetInBits - FragmentOffset;
- // If \a addMachineReg requested a DW_OP_bit_piece to stencil out a
+ // If addMachineReg requested a DW_OP_bit_piece to stencil out a
// sub-register that is smaller than the current fragment's size, use it.
if (SubRegisterSizeInBits)
SizeInBits = std::min<unsigned>(SizeInBits, SubRegisterSizeInBits);
-
+
+ // Emit a DW_OP_stack_value for implicit location descriptions.
+ if (LocationKind == Implicit)
+ addStackValue();
+
+ // Emit the DW_OP_piece.
addOpPiece(SizeInBits, SubRegisterOffsetInBits);
setSubRegisterPiece(0, 0);
- break;
+ // Reset the location description kind.
+ LocationKind = Unknown;
+ return;
}
case dwarf::DW_OP_plus:
+ assert(LocationKind != Register);
emitOp(dwarf::DW_OP_plus_uconst);
emitUnsigned(Op->getArg(0));
break;
case dwarf::DW_OP_minus:
- // There is no OP_minus_uconst.
+ assert(LocationKind != Register);
+ // There is no DW_OP_minus_uconst.
emitOp(dwarf::DW_OP_constu);
emitUnsigned(Op->getArg(0));
emitOp(dwarf::DW_OP_minus);
break;
- case dwarf::DW_OP_deref:
- emitOp(dwarf::DW_OP_deref);
+ case dwarf::DW_OP_deref: {
+ assert(LocationKind != Register);
+ if (LocationKind != Memory && isMemoryLocation(ExprCursor))
+ // Turning this into a memory location description makes the deref
+ // implicit.
+ LocationKind = Memory;
+ else
+ emitOp(dwarf::DW_OP_deref);
break;
+ }
case dwarf::DW_OP_constu:
+ assert(LocationKind != Register);
emitOp(dwarf::DW_OP_constu);
emitUnsigned(Op->getArg(0));
break;
case dwarf::DW_OP_stack_value:
- addStackValue();
+ assert(LocationKind == Unknown || LocationKind == Implicit);
+ LocationKind = Implicit;
break;
case dwarf::DW_OP_swap:
+ assert(LocationKind != Register);
emitOp(dwarf::DW_OP_swap);
break;
case dwarf::DW_OP_xderef:
+ assert(LocationKind != Register);
emitOp(dwarf::DW_OP_xderef);
break;
default:
llvm_unreachable("unhandled opcode found in expression");
}
}
+
+ if (LocationKind == Implicit)
+ // Turn this into an implicit location description.
+ addStackValue();
}
/// add masking operations to stencil out a subregister.
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
index e8dc211eb3c..00734fd6843 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
@@ -16,6 +16,7 @@
#include "llvm/IR/DebugInfo.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/MC/MachineLocation.h"
namespace llvm {
@@ -102,6 +103,9 @@ protected:
unsigned SubRegisterSizeInBits = 0;
unsigned SubRegisterOffsetInBits = 0;
+ /// The kind of location description being produced.
+ enum { Unknown = 0, Register, Memory, Implicit } LocationKind = Unknown;
+
/// Push a DW_OP_piece / DW_OP_bit_piece for emitting later, if one is needed
/// to represent a subregister.
void setSubRegisterPiece(unsigned SizeInBits, unsigned OffsetInBits) {
@@ -109,6 +113,8 @@ protected:
SubRegisterOffsetInBits = OffsetInBits;
}
+ void setMemoryLocationKind();
+
/// Add masking operations to stencil out a subregister.
void maskSubRegister();
@@ -122,7 +128,8 @@ protected:
/// current function.
virtual bool isFrameRegister(const TargetRegisterInfo &TRI, unsigned MachineReg) = 0;
- /// Emit a DW_OP_reg operation.
+ /// Emit a DW_OP_reg operation. Note that this is only legal inside a DWARF
+ /// register location description.
void addReg(int DwarfReg, const char *Comment = nullptr);
/// Emit a DW_OP_breg operation.
void addBReg(int DwarfReg, int Offset);
@@ -194,8 +201,8 @@ public:
/// fragment inside the entire variable.
/// \return false if no DWARF register exists
/// for MachineReg.
- bool addMachineRegExpression(const TargetRegisterInfo &TRI,
- DIExpressionCursor &Expr, unsigned MachineReg,
+ bool addMachineLocExpression(const TargetRegisterInfo &TRI,
+ DIExpressionCursor &Expr, MachineLocation Loc,
unsigned FragmentOffsetInBits = 0);
/// Emit all remaining operations in the DIExpressionCursor.
///
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index 89ab4a3c1ce..f5dccd17295 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -474,10 +474,9 @@ void DwarfUnit::addBlockByrefAddress(const DbgVariable &DV, DIE &Die,
DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
SmallVector<uint64_t, 9> Ops;
- if (Location.isIndirect()) {
+ if (Location.isIndirect() && Location.getOffset()) {
Ops.push_back(dwarf::DW_OP_plus);
Ops.push_back(Location.getOffset());
- Ops.push_back(dwarf::DW_OP_deref);
}
// If we started with a pointer to the __Block_byref... struct, then
// the first thing we need to do is dereference the pointer (DW_OP_deref).
@@ -506,7 +505,7 @@ void DwarfUnit::addBlockByrefAddress(const DbgVariable &DV, DIE &Die,
DIExpressionCursor Cursor(Ops);
const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
- if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
+ if (!DwarfExpr.addMachineLocExpression(TRI, Cursor, Location))
return;
DwarfExpr.addExpression(std::move(Cursor));
OpenPOWER on IntegriCloud