LCOV - code coverage report
Current view: top level - lib/CodeGen/AsmPrinter - DwarfExpression.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 21 21 100.0 %
Date: 2018-06-17 00:07:59 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- llvm/CodeGen/DwarfExpression.h - Dwarf Compile Unit ------*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This file contains support for writing dwarf compile unit.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H
      15             : #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H
      16             : 
      17             : #include "llvm/ADT/ArrayRef.h"
      18             : #include "llvm/ADT/None.h"
      19             : #include "llvm/ADT/Optional.h"
      20             : #include "llvm/ADT/SmallVector.h"
      21             : #include "llvm/IR/DebugInfoMetadata.h"
      22             : #include <cassert>
      23             : #include <cstdint>
      24             : #include <iterator>
      25             : 
      26             : namespace llvm {
      27             : 
      28             : class AsmPrinter;
      29             : class APInt;
      30             : class ByteStreamer;
      31             : class DwarfUnit;
      32             : class DIELoc;
      33             : class TargetRegisterInfo;
      34             : 
      35             : /// Holds a DIExpression and keeps track of how many operands have been consumed
      36             : /// so far.
      37             : class DIExpressionCursor {
      38             :   DIExpression::expr_op_iterator Start, End;
      39             : 
      40             : public:
      41       94790 :   DIExpressionCursor(const DIExpression *Expr) {
      42       55647 :     if (!Expr) {
      43             :       assert(Start == End);
      44             :       return;
      45             :     }
      46       55651 :     Start = Expr->expr_op_begin();
      47       55651 :     End = Expr->expr_op_end();
      48             :   }
      49             : 
      50             :   DIExpressionCursor(ArrayRef<uint64_t> Expr)
      51             :       : Start(Expr.begin()), End(Expr.end()) {}
      52             : 
      53             :   DIExpressionCursor(const DIExpressionCursor &) = default;
      54             : 
      55             :   /// Consume one operation.
      56             :   Optional<DIExpression::ExprOperand> take() {
      57       74025 :     if (Start == End)
      58             :       return None;
      59             :     return *(Start++);
      60             :   }
      61             : 
      62             :   /// Consume N operations.
      63             :   void consume(unsigned N) { std::advance(Start, N); }
      64             : 
      65             :   /// Return the current operation.
      66             :   Optional<DIExpression::ExprOperand> peek() const {
      67      270749 :     if (Start == End)
      68             :       return None;
      69             :     return *(Start);
      70             :   }
      71             : 
      72             :   /// Return the next operation.
      73         225 :   Optional<DIExpression::ExprOperand> peekNext() const {
      74         225 :     if (Start == End)
      75             :       return None;
      76             : 
      77         225 :     auto Next = Start.getNext();
      78         225 :     if (Next == End)
      79             :       return None;
      80             : 
      81             :     return *Next;
      82             :   }
      83             : 
      84             :   /// Determine whether there are any operations left in this expression.
      85             :   operator bool() const { return Start != End; }
      86             : 
      87             :   DIExpression::expr_op_iterator begin() const { return Start; }
      88             :   DIExpression::expr_op_iterator end() const { return End; }
      89             : 
      90             :   /// Retrieve the fragment information, if any.
      91             :   Optional<DIExpression::FragmentInfo> getFragmentInfo() const {
      92      133615 :     return DIExpression::getFragmentInfo(Start, End);
      93             :   }
      94             : };
      95             : 
      96             : /// Base class containing the logic for constructing DWARF expressions
      97             : /// independently of whether they are emitted into a DIE or into a .debug_loc
      98             : /// entry.
      99             : class DwarfExpression {
     100             : protected:
     101             :   /// Holds information about all subregisters comprising a register location.
     102             :   struct Register {
     103             :     int DwarfRegNo;
     104             :     unsigned Size;
     105             :     const char *Comment;
     106             :   };
     107             : 
     108             :   /// The register location, if any.
     109             :   SmallVector<Register, 2> DwarfRegs;
     110             : 
     111             :   /// Current Fragment Offset in Bits.
     112             :   uint64_t OffsetInBits = 0;
     113             :   unsigned DwarfVersion;
     114             : 
     115             :   /// Sometimes we need to add a DW_OP_bit_piece to describe a subregister. 
     116             :   unsigned SubRegisterSizeInBits = 0;
     117             :   unsigned SubRegisterOffsetInBits = 0;
     118             : 
     119             :   /// The kind of location description being produced.
     120             :   enum { Unknown = 0, Register, Memory, Implicit } LocationKind = Unknown;
     121             : 
     122             :   /// Push a DW_OP_piece / DW_OP_bit_piece for emitting later, if one is needed
     123             :   /// to represent a subregister.
     124             :   void setSubRegisterPiece(unsigned SizeInBits, unsigned OffsetInBits) {
     125         966 :     SubRegisterSizeInBits = SizeInBits;
     126         966 :     SubRegisterOffsetInBits = OffsetInBits;
     127             :   }
     128             : 
     129             :   /// Add masking operations to stencil out a subregister.
     130             :   void maskSubRegister();
     131             : 
     132             :   /// Output a dwarf operand and an optional assembler comment.
     133             :   virtual void emitOp(uint8_t Op, const char *Comment = nullptr) = 0;
     134             : 
     135             :   /// Emit a raw signed value.
     136             :   virtual void emitSigned(int64_t Value) = 0;
     137             : 
     138             :   /// Emit a raw unsigned value.
     139             :   virtual void emitUnsigned(uint64_t Value) = 0;
     140             : 
     141             :   /// Return whether the given machine register is the frame register in the
     142             :   /// current function.
     143             :   virtual bool isFrameRegister(const TargetRegisterInfo &TRI, unsigned MachineReg) = 0;
     144             : 
     145             :   /// Emit a DW_OP_reg operation. Note that this is only legal inside a DWARF
     146             :   /// register location description.
     147             :   void addReg(int DwarfReg, const char *Comment = nullptr);
     148             : 
     149             :   /// Emit a DW_OP_breg operation.
     150             :   void addBReg(int DwarfReg, int Offset);
     151             : 
     152             :   /// Emit DW_OP_fbreg <Offset>.
     153             :   void addFBReg(int Offset);
     154             : 
     155             :   /// Emit a partial DWARF register operation.
     156             :   ///
     157             :   /// \param MachineReg           The register number.
     158             :   /// \param MaxSize              If the register must be composed from
     159             :   ///                             sub-registers this is an upper bound
     160             :   ///                             for how many bits the emitted DW_OP_piece
     161             :   ///                             may cover.
     162             :   ///
     163             :   /// If size and offset is zero an operation for the entire register is
     164             :   /// emitted: Some targets do not provide a DWARF register number for every
     165             :   /// register.  If this is the case, this function will attempt to emit a DWARF
     166             :   /// register by emitting a fragment of a super-register or by piecing together
     167             :   /// multiple subregisters that alias the register.
     168             :   ///
     169             :   /// \return false if no DWARF register exists for MachineReg.
     170             :   bool addMachineReg(const TargetRegisterInfo &TRI, unsigned MachineReg,
     171             :                      unsigned MaxSize = ~1U);
     172             : 
     173             :   /// Emit a DW_OP_piece or DW_OP_bit_piece operation for a variable fragment.
     174             :   /// \param OffsetInBits    This is an optional offset into the location that
     175             :   /// is at the top of the DWARF stack.
     176             :   void addOpPiece(unsigned SizeInBits, unsigned OffsetInBits = 0);
     177             : 
     178             :   /// Emit a shift-right dwarf operation.
     179             :   void addShr(unsigned ShiftBy);
     180             : 
     181             :   /// Emit a bitwise and dwarf operation.
     182             :   void addAnd(unsigned Mask);
     183             : 
     184             :   /// Emit a DW_OP_stack_value, if supported.
     185             :   ///
     186             :   /// The proper way to describe a constant value is DW_OP_constu <const>,
     187             :   /// DW_OP_stack_value.  Unfortunately, DW_OP_stack_value was not available
     188             :   /// until DWARF 4, so we will continue to generate DW_OP_constu <const> for
     189             :   /// DWARF 2 and DWARF 3. Technically, this is incorrect since DW_OP_const
     190             :   /// <const> actually describes a value at a constant addess, not a constant
     191             :   /// value.  However, in the past there was no better way to describe a
     192             :   /// constant value, so the producers and consumers started to rely on
     193             :   /// heuristics to disambiguate the value vs. location status of the
     194             :   /// expression.  See PR21176 for more details.
     195             :   void addStackValue();
     196             : 
     197      137154 :   ~DwarfExpression() = default;
     198             : 
     199             : public:
     200      274308 :   DwarfExpression(unsigned DwarfVersion) : DwarfVersion(DwarfVersion) {}
     201             : 
     202             :   /// This needs to be called last to commit any pending changes.
     203             :   void finalize();
     204             : 
     205             :   /// Emit a signed constant.
     206             :   void addSignedConstant(int64_t Value);
     207             : 
     208             :   /// Emit an unsigned constant.
     209             :   void addUnsignedConstant(uint64_t Value);
     210             : 
     211             :   /// Emit an unsigned constant.
     212             :   void addUnsignedConstant(const APInt &Value);
     213             : 
     214             :   bool isMemoryLocation() const { return LocationKind == Memory; }
     215             :   bool isUnknownLocation() const { return LocationKind == Unknown; }
     216             : 
     217             :   /// Lock this down to become a memory location description.
     218             :   void setMemoryLocationKind() {
     219             :     assert(LocationKind == Unknown);
     220       73806 :     LocationKind = Memory;
     221             :   }
     222             : 
     223             :   /// Emit a machine register location. As an optimization this may also consume
     224             :   /// the prefix of a DwarfExpression if a more efficient representation for
     225             :   /// combining the register location and the first operation exists.
     226             :   ///
     227             :   /// \param FragmentOffsetInBits     If this is one fragment out of a
     228             :   /// fragmented
     229             :   ///                                 location, this is the offset of the
     230             :   ///                                 fragment inside the entire variable.
     231             :   /// \return                         false if no DWARF register exists
     232             :   ///                                 for MachineReg.
     233             :   bool addMachineRegExpression(const TargetRegisterInfo &TRI,
     234             :                                DIExpressionCursor &Expr, unsigned MachineReg,
     235             :                                unsigned FragmentOffsetInBits = 0);
     236             : 
     237             :   /// Emit all remaining operations in the DIExpressionCursor.
     238             :   ///
     239             :   /// \param FragmentOffsetInBits     If this is one fragment out of multiple
     240             :   ///                                 locations, this is the offset of the
     241             :   ///                                 fragment inside the entire variable.
     242             :   void addExpression(DIExpressionCursor &&Expr,
     243             :                      unsigned FragmentOffsetInBits = 0);
     244             : 
     245             :   /// If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to
     246             :   /// the fragment described by \c Expr.
     247             :   void addFragmentOffset(const DIExpression *Expr);
     248             : };
     249             : 
     250             : /// DwarfExpression implementation for .debug_loc entries.
     251       26404 : class DebugLocDwarfExpression final : public DwarfExpression {
     252             :   ByteStreamer &BS;
     253             : 
     254             :   void emitOp(uint8_t Op, const char *Comment = nullptr) override;
     255             :   void emitSigned(int64_t Value) override;
     256             :   void emitUnsigned(uint64_t Value) override;
     257             :   bool isFrameRegister(const TargetRegisterInfo &TRI,
     258             :                        unsigned MachineReg) override;
     259             : 
     260             : public:
     261             :   DebugLocDwarfExpression(unsigned DwarfVersion, ByteStreamer &BS)
     262       52808 :       : DwarfExpression(DwarfVersion), BS(BS) {}
     263             : };
     264             : 
     265             : /// DwarfExpression implementation for singular DW_AT_location.
     266        3124 : class DIEDwarfExpression final : public DwarfExpression {
     267             : const AsmPrinter &AP;
     268             :   DwarfUnit &DU;
     269             :   DIELoc &DIE;
     270             : 
     271             :   void emitOp(uint8_t Op, const char *Comment = nullptr) override;
     272             :   void emitSigned(int64_t Value) override;
     273             :   void emitUnsigned(uint64_t Value) override;
     274             :   bool isFrameRegister(const TargetRegisterInfo &TRI,
     275             :                        unsigned MachineReg) override;
     276             : public:
     277             :   DIEDwarfExpression(const AsmPrinter &AP, DwarfUnit &DU, DIELoc &DIE);
     278             : 
     279             :   DIELoc *finalize() {
     280      110716 :     DwarfExpression::finalize();
     281      110716 :     return &DIE;
     282             :   }
     283             : };
     284             : 
     285             : } // end namespace llvm
     286             : 
     287             : #endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H

Generated by: LCOV version 1.13