diff options
author | Adrian Prantl <aprantl@apple.com> | 2014-08-01 22:11:58 +0000 |
---|---|---|
committer | Adrian Prantl <aprantl@apple.com> | 2014-08-01 22:11:58 +0000 |
commit | b1416837f97cd1ec212673fb90fab0fb7df6c442 (patch) | |
tree | 22c532dbd53626600d03903704c6911f00e3d9af /llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp | |
parent | 4184c79975256bbb9d3eec1622b99361770a6644 (diff) | |
download | bcm5719-llvm-b1416837f97cd1ec212673fb90fab0fb7df6c442.tar.gz bcm5719-llvm-b1416837f97cd1ec212673fb90fab0fb7df6c442.zip |
Debug info: Infrastructure to support debug locations for fragmented
variables (for example, by-value struct arguments passed in registers, or
large integer values split across several smaller registers).
On the IR level, this adds a new type of complex address operation OpPiece
to DIVariable that describes size and offset of a variable fragment.
On the DWARF emitter level, all pieces describing the same variable are
collected, sorted and emitted as DWARF expressions using the DW_OP_piece
and DW_OP_bit_piece operators.
http://reviews.llvm.org/D3373
rdar://problem/15928306
What this patch doesn't do / Future work:
- This patch only adds the backend machinery to make this work, patches
that change SROA and SelectionDAG's type legalizer to actually create
such debug info will follow. (http://reviews.llvm.org/D2680)
- Making the DIVariable complex expressions into an argument of dbg.value
will reduce the memory footprint of the debug metadata.
- The sorting/uniquing of pieces should be moved into DebugLocEntry,
to facilitate the merging of multi-piece entries.
llvm-svn: 214576
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp | 27 |
1 files changed, 12 insertions, 15 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp index 02cd12be045..987c0955a0b 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp @@ -214,13 +214,10 @@ static void emitDwarfRegOpIndirect(ByteStreamer &Streamer, int Reg, int Offset, Streamer.EmitInt8(dwarf::DW_OP_deref, "DW_OP_deref"); } -/// Emit a dwarf register operation for describing -/// - a small value occupying only part of a register or -/// - a small register representing only part of a value. -static void emitDwarfOpPiece(ByteStreamer &Streamer, unsigned SizeInBits, - unsigned OffsetInBits) { - assert(SizeInBits > 0 && "zero-sized piece"); - unsigned SizeOfByte = 8; +void AsmPrinter::EmitDwarfOpPiece(ByteStreamer &Streamer, unsigned SizeInBits, + unsigned OffsetInBits) const { + assert(SizeInBits > 0 && "piece has size zero"); + const unsigned SizeOfByte = 8; if (OffsetInBits > 0 || SizeInBits % SizeOfByte) { Streamer.EmitInt8(dwarf::DW_OP_bit_piece, "DW_OP_bit_piece"); Streamer.EmitULEB128(SizeInBits, Twine(SizeInBits)); @@ -255,7 +252,7 @@ void AsmPrinter::EmitDwarfRegOpPiece(ByteStreamer &Streamer, // If this is a valid register number, emit it. if (Reg >= 0) { emitDwarfRegOp(Streamer, Reg); - emitDwarfOpPiece(Streamer, PieceSizeInBits, PieceOffsetInBits); + EmitDwarfOpPiece(Streamer, PieceSizeInBits, PieceOffsetInBits); return; } @@ -266,19 +263,19 @@ void AsmPrinter::EmitDwarfRegOpPiece(ByteStreamer &Streamer, if (Reg >= 0) { unsigned Idx = TRI->getSubRegIndex(*SR, MLoc.getReg()); unsigned Size = TRI->getSubRegIdxSize(Idx); - unsigned Offset = TRI->getSubRegIdxOffset(Idx); + unsigned RegOffset = TRI->getSubRegIdxOffset(Idx); OutStreamer.AddComment("super-register"); emitDwarfRegOp(Streamer, Reg); - if (PieceOffsetInBits == Offset) { - emitDwarfOpPiece(Streamer, Size, Offset); + if (PieceOffsetInBits == RegOffset) { + EmitDwarfOpPiece(Streamer, Size, RegOffset); } else { // If this is part of a variable in a sub-register at a // non-zero offset, we need to manually shift the value into // place, since the DW_OP_piece describes the part of the // variable, not the position of the subregister. - emitDwarfOpPiece(Streamer, Size, PieceOffsetInBits); - if (Offset) - emitDwarfOpShr(Streamer, Offset); + if (RegOffset) + emitDwarfOpShr(Streamer, RegOffset); + EmitDwarfOpPiece(Streamer, Size, PieceOffsetInBits); } return; } @@ -312,7 +309,7 @@ void AsmPrinter::EmitDwarfRegOpPiece(ByteStreamer &Streamer, if (Reg >= 0 && Intersection.any()) { OutStreamer.AddComment("sub-register"); emitDwarfRegOp(Streamer, Reg); - emitDwarfOpPiece(Streamer, Size, Offset == CurPos ? 0 : Offset); + EmitDwarfOpPiece(Streamer, Size, Offset == CurPos ? 0 : Offset); CurPos = Offset + Size; // Mark it as emitted. |