LCOV - code coverage report
Current view: top level - lib/CodeGen/AsmPrinter - DwarfExpression.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 20 29 69.0 %
Date: 2018-10-20 13:21:21 Functions: 1 7 14.3 %
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       13164 :   DIExpressionCursor(const DIExpression *Expr) {
      42        2370 :     if (!Expr) {
      43             :       assert(Start == End);
      44             :       return;
      45             :     }
      46        2451 :     Start = Expr->expr_op_begin();
      47        2451 :     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       19233 :     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      185247 :     if (Start == End)
      68             :       return None;
      69             :     return *(Start);
      70             :   }
      71             : 
      72             :   /// Return the next operation.
      73         990 :   Optional<DIExpression::ExprOperand> peekNext() const {
      74         990 :     if (Start == End)
      75             :       return None;
      76             : 
      77         990 :     auto Next = Start.getNext();
      78         990 :     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           0 :   DIExpression::expr_op_iterator begin() const { return Start; }
      88           0 :   DIExpression::expr_op_iterator end() const { return End; }
      89             : 
      90             :   /// Retrieve the fragment information, if any.
      91           0 :   Optional<DIExpression::FragmentInfo> getFragmentInfo() const {
      92       97715 :     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           0 :   void setSubRegisterPiece(unsigned SizeInBits, unsigned OffsetInBits) {
     125        3288 :     SubRegisterSizeInBits = SizeInBits;
     126        3288 :     SubRegisterOffsetInBits = OffsetInBits;
     127           0 :   }
     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             :   /// Emit a normalized unsigned constant.
     142             :   void emitConstu(uint64_t Value);
     143             : 
     144             :   /// Return whether the given machine register is the frame register in the
     145             :   /// current function.
     146             :   virtual bool isFrameRegister(const TargetRegisterInfo &TRI, unsigned MachineReg) = 0;
     147             : 
     148             :   /// Emit a DW_OP_reg operation. Note that this is only legal inside a DWARF
     149             :   /// register location description.
     150             :   void addReg(int DwarfReg, const char *Comment = nullptr);
     151             : 
     152             :   /// Emit a DW_OP_breg operation.
     153             :   void addBReg(int DwarfReg, int Offset);
     154             : 
     155             :   /// Emit DW_OP_fbreg <Offset>.
     156             :   void addFBReg(int Offset);
     157             : 
     158             :   /// Emit a partial DWARF register operation.
     159             :   ///
     160             :   /// \param MachineReg           The register number.
     161             :   /// \param MaxSize              If the register must be composed from
     162             :   ///                             sub-registers this is an upper bound
     163             :   ///                             for how many bits the emitted DW_OP_piece
     164             :   ///                             may cover.
     165             :   ///
     166             :   /// If size and offset is zero an operation for the entire register is
     167             :   /// emitted: Some targets do not provide a DWARF register number for every
     168             :   /// register.  If this is the case, this function will attempt to emit a DWARF
     169             :   /// register by emitting a fragment of a super-register or by piecing together
     170             :   /// multiple subregisters that alias the register.
     171             :   ///
     172             :   /// \return false if no DWARF register exists for MachineReg.
     173             :   bool addMachineReg(const TargetRegisterInfo &TRI, unsigned MachineReg,
     174             :                      unsigned MaxSize = ~1U);
     175             : 
     176             :   /// Emit a DW_OP_piece or DW_OP_bit_piece operation for a variable fragment.
     177             :   /// \param OffsetInBits    This is an optional offset into the location that
     178             :   /// is at the top of the DWARF stack.
     179             :   void addOpPiece(unsigned SizeInBits, unsigned OffsetInBits = 0);
     180             : 
     181             :   /// Emit a shift-right dwarf operation.
     182             :   void addShr(unsigned ShiftBy);
     183             : 
     184             :   /// Emit a bitwise and dwarf operation.
     185             :   void addAnd(unsigned Mask);
     186             : 
     187             :   /// Emit a DW_OP_stack_value, if supported.
     188             :   ///
     189             :   /// The proper way to describe a constant value is DW_OP_constu <const>,
     190             :   /// DW_OP_stack_value.  Unfortunately, DW_OP_stack_value was not available
     191             :   /// until DWARF 4, so we will continue to generate DW_OP_constu <const> for
     192             :   /// DWARF 2 and DWARF 3. Technically, this is incorrect since DW_OP_const
     193             :   /// <const> actually describes a value at a constant addess, not a constant
     194             :   /// value.  However, in the past there was no better way to describe a
     195             :   /// constant value, so the producers and consumers started to rely on
     196             :   /// heuristics to disambiguate the value vs. location status of the
     197             :   /// expression.  See PR21176 for more details.
     198             :   void addStackValue();
     199             : 
     200       98289 :   ~DwarfExpression() = default;
     201             : 
     202             : public:
     203      198422 :   DwarfExpression(unsigned DwarfVersion) : DwarfVersion(DwarfVersion) {}
     204             : 
     205             :   /// This needs to be called last to commit any pending changes.
     206             :   void finalize();
     207             : 
     208             :   /// Emit a signed constant.
     209             :   void addSignedConstant(int64_t Value);
     210             : 
     211             :   /// Emit an unsigned constant.
     212             :   void addUnsignedConstant(uint64_t Value);
     213             : 
     214             :   /// Emit an unsigned constant.
     215             :   void addUnsignedConstant(const APInt &Value);
     216             : 
     217             :   bool isMemoryLocation() const { return LocationKind == Memory; }
     218           0 :   bool isUnknownLocation() const { return LocationKind == Unknown; }
     219             : 
     220             :   /// Lock this down to become a memory location description.
     221           0 :   void setMemoryLocationKind() {
     222             :     assert(LocationKind == Unknown);
     223        1666 :     LocationKind = Memory;
     224           0 :   }
     225             : 
     226             :   /// Emit a machine register location. As an optimization this may also consume
     227             :   /// the prefix of a DwarfExpression if a more efficient representation for
     228             :   /// combining the register location and the first operation exists.
     229             :   ///
     230             :   /// \param FragmentOffsetInBits     If this is one fragment out of a
     231             :   /// fragmented
     232             :   ///                                 location, this is the offset of the
     233             :   ///                                 fragment inside the entire variable.
     234             :   /// \return                         false if no DWARF register exists
     235             :   ///                                 for MachineReg.
     236             :   bool addMachineRegExpression(const TargetRegisterInfo &TRI,
     237             :                                DIExpressionCursor &Expr, unsigned MachineReg,
     238             :                                unsigned FragmentOffsetInBits = 0);
     239             : 
     240             :   /// Emit all remaining operations in the DIExpressionCursor.
     241             :   ///
     242             :   /// \param FragmentOffsetInBits     If this is one fragment out of multiple
     243             :   ///                                 locations, this is the offset of the
     244             :   ///                                 fragment inside the entire variable.
     245             :   void addExpression(DIExpressionCursor &&Expr,
     246             :                      unsigned FragmentOffsetInBits = 0);
     247             : 
     248             :   /// If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to
     249             :   /// the fragment described by \c Expr.
     250             :   void addFragmentOffset(const DIExpression *Expr);
     251             : };
     252             : 
     253             : /// DwarfExpression implementation for .debug_loc entries.
     254       85416 : class DebugLocDwarfExpression final : public DwarfExpression {
     255             :   ByteStreamer &BS;
     256             : 
     257             :   void emitOp(uint8_t Op, const char *Comment = nullptr) override;
     258             :   void emitSigned(int64_t Value) override;
     259             :   void emitUnsigned(uint64_t Value) override;
     260             :   bool isFrameRegister(const TargetRegisterInfo &TRI,
     261             :                        unsigned MachineReg) override;
     262             : 
     263             : public:
     264             :   DebugLocDwarfExpression(unsigned DwarfVersion, ByteStreamer &BS)
     265      170832 :       : DwarfExpression(DwarfVersion), BS(BS) {}
     266             : };
     267             : 
     268             : /// DwarfExpression implementation for singular DW_AT_location.
     269           0 : class DIEDwarfExpression final : public DwarfExpression {
     270             : const AsmPrinter &AP;
     271             :   DwarfUnit &DU;
     272             :   DIELoc &DIE;
     273             : 
     274             :   void emitOp(uint8_t Op, const char *Comment = nullptr) override;
     275             :   void emitSigned(int64_t Value) override;
     276             :   void emitUnsigned(uint64_t Value) override;
     277             :   bool isFrameRegister(const TargetRegisterInfo &TRI,
     278             :                        unsigned MachineReg) override;
     279             : public:
     280             :   DIEDwarfExpression(const AsmPrinter &AP, DwarfUnit &DU, DIELoc &DIE);
     281             : 
     282             :   DIELoc *finalize() {
     283        7871 :     DwarfExpression::finalize();
     284        7871 :     return &DIE;
     285             :   }
     286             : };
     287             : 
     288             : } // end namespace llvm
     289             : 
     290             : #endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H

Generated by: LCOV version 1.13