From 284827f32bd8d06ca1ab8a949bf96088612b1504 Mon Sep 17 00:00:00 2001 From: David Stenberg Date: Tue, 15 Oct 2019 11:14:35 +0000 Subject: [DebugInfo] Add interface for pre-calculating the size of emitted DWARF Summary: DWARF's DW_OP_entry_value operation has two operands; the first is a ULEB128 operand that specifies the size of the second operand, which is a DWARF block. This means that we need to be able to pre-calculate and emit the size of DWARF expressions before emitting them. There is currently no interface for doing this in DwarfExpression, so this patch introduces that. When implementing this I initially thought about running through DwarfExpression's emission two times; first with a temporary buffer to emit the expression, in order to being able to calculate the size of that emitted data. However, DwarfExpression is a quite complex state machine, so I decided against that, as it seemed like the two runs could get out of sync, resulting in incorrect size operands. Therefore I have implemented this in a way that we only have to run DwarfExpression once. The idea is to emit DWARF to a temporary buffer, for which it is possible to query the size. The data in the temporary buffer can then be emitted to DwarfExpression's main output. In the case of DIEDwarfExpression, a temporary DIE is used. The values are all allocated using the same BumpPtrAllocator as for all other DIEs, and the values are then transferred to the real value list. In the case of DebugLocDwarfExpression, the temporary buffer is implemented using a BufferByteStreamer which emits to a buffer in the DwarfExpression object. Reviewers: aprantl, vsk, NikolaPrica, djtodoro Reviewed By: aprantl Subscribers: hiraditya, llvm-commits Tags: #debug-info, #llvm Differential Revision: https://reviews.llvm.org/D67768 llvm-svn: 374879 --- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 36 +++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) (limited to 'llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp') diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 82c8b955e13..7d7cadcce17 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -170,26 +170,26 @@ static const char *const DbgTimerDescription = "DWARF Debug Writer"; static constexpr unsigned ULEB128PadSize = 4; void DebugLocDwarfExpression::emitOp(uint8_t Op, const char *Comment) { - BS.EmitInt8( + getActiveStreamer().EmitInt8( Op, Comment ? Twine(Comment) + " " + dwarf::OperationEncodingString(Op) : dwarf::OperationEncodingString(Op)); } void DebugLocDwarfExpression::emitSigned(int64_t Value) { - BS.EmitSLEB128(Value, Twine(Value)); + getActiveStreamer().EmitSLEB128(Value, Twine(Value)); } void DebugLocDwarfExpression::emitUnsigned(uint64_t Value) { - BS.EmitULEB128(Value, Twine(Value)); + getActiveStreamer().EmitULEB128(Value, Twine(Value)); } void DebugLocDwarfExpression::emitData1(uint8_t Value) { - BS.EmitInt8(Value, Twine(Value)); + getActiveStreamer().EmitInt8(Value, Twine(Value)); } void DebugLocDwarfExpression::emitBaseTypeRef(uint64_t Idx) { assert(Idx < (1ULL << (ULEB128PadSize * 7)) && "Idx wont fit"); - BS.EmitULEB128(Idx, Twine(Idx), ULEB128PadSize); + getActiveStreamer().EmitULEB128(Idx, Twine(Idx), ULEB128PadSize); } bool DebugLocDwarfExpression::isFrameRegister(const TargetRegisterInfo &TRI, @@ -198,6 +198,32 @@ bool DebugLocDwarfExpression::isFrameRegister(const TargetRegisterInfo &TRI, return false; } +void DebugLocDwarfExpression::enableTemporaryBuffer() { + assert(!IsBuffering && "Already buffering?"); + if (!TmpBuf) + TmpBuf = std::make_unique(OutBS.GenerateComments); + IsBuffering = true; +} + +void DebugLocDwarfExpression::disableTemporaryBuffer() { IsBuffering = false; } + +unsigned DebugLocDwarfExpression::getTemporaryBufferSize() { + return TmpBuf ? TmpBuf->Bytes.size() : 0; +} + +void DebugLocDwarfExpression::commitTemporaryBuffer() { + if (!TmpBuf) + return; + for (auto Byte : enumerate(TmpBuf->Bytes)) { + const char *Comment = (Byte.index() < TmpBuf->Comments.size()) + ? TmpBuf->Comments[Byte.index()].c_str() + : ""; + OutBS.EmitInt8(Byte.value(), Comment); + } + TmpBuf->Bytes.clear(); + TmpBuf->Comments.clear(); +} + const DIType *DbgVariable::getType() const { return getVariable()->getType(); } -- cgit v1.2.3