[llvm] r374879 - [DebugInfo] Add interface for pre-calculating the size of emitted DWARF
David Blaikie via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 28 16:14:09 PDT 2019
On Tue, Oct 15, 2019 at 4:12 AM David Stenberg via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> Author: dstenb
> Date: Tue Oct 15 04:14:35 2019
> New Revision: 374879
>
> URL: http://llvm.org/viewvc/llvm-project?rev=374879&view=rev
> Log:
> [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.
"temporary" and "BumpPtrAllocator" are a bit antithetical - this produces a
sort of reachable memory leak? Should that be revisited/maybe a different
allocation scheme used?
> 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
>
> Modified:
> llvm/trunk/include/llvm/CodeGen/DIE.h
> llvm/trunk/lib/CodeGen/AsmPrinter/ByteStreamer.h
> llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
> llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h
> llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
>
> Modified: llvm/trunk/include/llvm/CodeGen/DIE.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/DIE.h?rev=374879&r1=374878&r2=374879&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/DIE.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/DIE.h Tue Oct 15 04:14:35 2019
> @@ -550,6 +550,14 @@ public:
> return *static_cast<T *>(Last ? Last->Next.getPointer() : nullptr);
> }
>
> + void takeNodes(IntrusiveBackList<T> &Other) {
> + for (auto &N : Other) {
> + N.Next.setPointerAndInt(&N, true);
> + push_back(N);
> + }
> + Other.Last = nullptr;
> + }
> +
> class const_iterator;
> class iterator
> : public iterator_facade_base<iterator, std::forward_iterator_tag,
> T> {
> @@ -685,6 +693,10 @@ public:
> return addValue(Alloc, DIEValue(Attribute, Form,
> std::forward<T>(Value)));
> }
>
> + /// Take ownership of the nodes in \p Other, and append them to the
> back of
> + /// the list.
> + void takeValues(DIEValueList &Other) { List.takeNodes(Other.List); }
> +
> value_range values() {
> return make_range(value_iterator(List.begin()),
> value_iterator(List.end()));
> }
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/ByteStreamer.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/ByteStreamer.h?rev=374879&r1=374878&r2=374879&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/ByteStreamer.h (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/ByteStreamer.h Tue Oct 15 04:14:35
> 2019
> @@ -75,16 +75,16 @@ private:
> SmallVectorImpl<char> &Buffer;
> std::vector<std::string> &Comments;
>
> +public:
> /// Only verbose textual output needs comments. This will be set to
> /// true for that case, and false otherwise. If false, comments passed
> in to
> /// the emit methods will be ignored.
> - bool GenerateComments;
> + const bool GenerateComments;
>
> -public:
> BufferByteStreamer(SmallVectorImpl<char> &Buffer,
> - std::vector<std::string> &Comments,
> - bool GenerateComments)
> - : Buffer(Buffer), Comments(Comments),
> GenerateComments(GenerateComments) {}
> + std::vector<std::string> &Comments, bool
> GenerateComments)
> + : Buffer(Buffer), Comments(Comments),
> GenerateComments(GenerateComments) {
> + }
> void EmitInt8(uint8_t Byte, const Twine &Comment) override {
> Buffer.push_back(Byte);
> if (GenerateComments)
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=374879&r1=374878&r2=374879&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue Oct 15 04:14:35
> 2019
> @@ -170,26 +170,26 @@ static const char *const DbgTimerDescrip
> 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::isFrameReg
> return false;
> }
>
> +void DebugLocDwarfExpression::enableTemporaryBuffer() {
> + assert(!IsBuffering && "Already buffering?");
> + if (!TmpBuf)
> + TmpBuf = std::make_unique<TempBuffer>(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();
> }
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h?rev=374879&r1=374878&r2=374879&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h Tue Oct 15
> 04:14:35 2019
> @@ -13,6 +13,7 @@
> #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H
> #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H
>
> +#include "ByteStreamer.h"
> #include "llvm/ADT/ArrayRef.h"
> #include "llvm/ADT/None.h"
> #include "llvm/ADT/Optional.h"
> @@ -26,7 +27,6 @@ namespace llvm {
>
> class AsmPrinter;
> class APInt;
> -class ByteStreamer;
> class DwarfCompileUnit;
> class DIELoc;
> class TargetRegisterInfo;
> @@ -95,6 +95,13 @@ public:
> /// Base class containing the logic for constructing DWARF expressions
> /// independently of whether they are emitted into a DIE or into a
> .debug_loc
> /// entry.
> +///
> +/// Some DWARF operations, e.g. DW_OP_entry_value, need to calculate the
> size
> +/// of a succeeding DWARF block before the latter is emitted to the
> output.
> +/// To handle such cases, data can conditionally be emitted to a temporary
> +/// buffer, which can later on be committed to the main output. The size
> of the
> +/// temporary buffer is queryable, allowing for the size of the data to be
> +/// emitted before the data is committed.
> class DwarfExpression {
> protected:
> /// Holds information about all subregisters comprising a register
> location.
> @@ -178,6 +185,22 @@ protected:
>
> virtual void emitBaseTypeRef(uint64_t Idx) = 0;
>
> + /// Start emitting data to the temporary buffer. The data stored in the
> + /// temporary buffer can be committed to the main output using
> + /// commitTemporaryBuffer().
> + virtual void enableTemporaryBuffer() = 0;
> +
> + /// Disable emission to the temporary buffer. This does not commit data
> + /// in the temporary buffer to the main output.
> + virtual void disableTemporaryBuffer() = 0;
> +
> + /// Return the emitted size, in number of bytes, for the data stored in
> the
> + /// temporary buffer.
> + virtual unsigned getTemporaryBufferSize() = 0;
> +
> + /// Commit the data stored in the temporary buffer to the main output.
> + virtual void commitTemporaryBuffer() = 0;
> +
> /// Emit a normalized unsigned constant.
> void emitConstu(uint64_t Value);
>
> @@ -308,31 +331,62 @@ public:
>
> /// DwarfExpression implementation for .debug_loc entries.
> class DebugLocDwarfExpression final : public DwarfExpression {
> - ByteStreamer &BS;
> +
> + struct TempBuffer {
> + SmallString<32> Bytes;
> + std::vector<std::string> Comments;
> + BufferByteStreamer BS;
> +
> + TempBuffer(bool GenerateComments) : BS(Bytes, Comments,
> GenerateComments) {}
> + };
> +
> + std::unique_ptr<TempBuffer> TmpBuf;
> + BufferByteStreamer &OutBS;
> + bool IsBuffering = false;
> +
> + /// Return the byte streamer that currently is being emitted to.
> + ByteStreamer &getActiveStreamer() { return IsBuffering ? TmpBuf->BS :
> OutBS; }
>
> void emitOp(uint8_t Op, const char *Comment = nullptr) override;
> void emitSigned(int64_t Value) override;
> void emitUnsigned(uint64_t Value) override;
> void emitData1(uint8_t Value) override;
> void emitBaseTypeRef(uint64_t Idx) override;
> +
> + void enableTemporaryBuffer() override;
> + void disableTemporaryBuffer() override;
> + unsigned getTemporaryBufferSize() override;
> + void commitTemporaryBuffer() override;
> +
> bool isFrameRegister(const TargetRegisterInfo &TRI,
> unsigned MachineReg) override;
> -
> public:
> - DebugLocDwarfExpression(unsigned DwarfVersion, ByteStreamer &BS,
> DwarfCompileUnit &CU)
> - : DwarfExpression(DwarfVersion, CU), BS(BS) {}
> + DebugLocDwarfExpression(unsigned DwarfVersion, BufferByteStreamer &BS,
> + DwarfCompileUnit &CU)
> + : DwarfExpression(DwarfVersion, CU), OutBS(BS) {}
> };
>
> /// DwarfExpression implementation for singular DW_AT_location.
> class DIEDwarfExpression final : public DwarfExpression {
> -const AsmPrinter &AP;
> - DIELoc &DIE;
> + const AsmPrinter &AP;
> + DIELoc &OutDIE;
> + DIELoc TmpDIE;
> + bool IsBuffering = false;
> +
> + /// Return the DIE that currently is being emitted to.
> + DIELoc &getActiveDIE() { return IsBuffering ? TmpDIE : OutDIE; }
>
> void emitOp(uint8_t Op, const char *Comment = nullptr) override;
> void emitSigned(int64_t Value) override;
> void emitUnsigned(uint64_t Value) override;
> void emitData1(uint8_t Value) override;
> void emitBaseTypeRef(uint64_t Idx) override;
> +
> + void enableTemporaryBuffer() override;
> + void disableTemporaryBuffer() override;
> + unsigned getTemporaryBufferSize() override;
> + void commitTemporaryBuffer() override;
> +
> bool isFrameRegister(const TargetRegisterInfo &TRI,
> unsigned MachineReg) override;
> public:
> @@ -340,7 +394,7 @@ public:
>
> DIELoc *finalize() {
> DwarfExpression::finalize();
> - return &DIE;
> + return &OutDIE;
> }
> };
>
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp?rev=374879&r1=374878&r2=374879&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp Tue Oct 15 04:14:35
> 2019
> @@ -47,31 +47,42 @@ using namespace llvm;
> #define DEBUG_TYPE "dwarfdebug"
>
> DIEDwarfExpression::DIEDwarfExpression(const AsmPrinter &AP,
> - DwarfCompileUnit &CU,
> - DIELoc &DIE)
> - : DwarfExpression(AP.getDwarfVersion(), CU), AP(AP),
> - DIE(DIE) {}
> + DwarfCompileUnit &CU, DIELoc &DIE)
> + : DwarfExpression(AP.getDwarfVersion(), CU), AP(AP), OutDIE(DIE) {}
>
> void DIEDwarfExpression::emitOp(uint8_t Op, const char* Comment) {
> - CU.addUInt(DIE, dwarf::DW_FORM_data1, Op);
> + CU.addUInt(getActiveDIE(), dwarf::DW_FORM_data1, Op);
> }
>
> void DIEDwarfExpression::emitSigned(int64_t Value) {
> - CU.addSInt(DIE, dwarf::DW_FORM_sdata, Value);
> + CU.addSInt(getActiveDIE(), dwarf::DW_FORM_sdata, Value);
> }
>
> void DIEDwarfExpression::emitUnsigned(uint64_t Value) {
> - CU.addUInt(DIE, dwarf::DW_FORM_udata, Value);
> + CU.addUInt(getActiveDIE(), dwarf::DW_FORM_udata, Value);
> }
>
> void DIEDwarfExpression::emitData1(uint8_t Value) {
> - CU.addUInt(DIE, dwarf::DW_FORM_data1, Value);
> + CU.addUInt(getActiveDIE(), dwarf::DW_FORM_data1, Value);
> }
>
> void DIEDwarfExpression::emitBaseTypeRef(uint64_t Idx) {
> - CU.addBaseTypeRef(DIE, Idx);
> + CU.addBaseTypeRef(getActiveDIE(), Idx);
> }
>
> +void DIEDwarfExpression::enableTemporaryBuffer() {
> + assert(!IsBuffering && "Already buffering?");
> + IsBuffering = true;
> +}
> +
> +void DIEDwarfExpression::disableTemporaryBuffer() { IsBuffering = false; }
> +
> +unsigned DIEDwarfExpression::getTemporaryBufferSize() {
> + return TmpDIE.ComputeSize(&AP);
> +}
> +
> +void DIEDwarfExpression::commitTemporaryBuffer() {
> OutDIE.takeValues(TmpDIE); }
> +
> bool DIEDwarfExpression::isFrameRegister(const TargetRegisterInfo &TRI,
> unsigned MachineReg) {
> return MachineReg == TRI.getFrameRegister(*AP.MF);
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20191028/b3af24ec/attachment.html>
More information about the llvm-commits
mailing list