LCOV - code coverage report
Current view: top level - lib/CodeGen/AsmPrinter - DwarfExpression.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 27 27 100.0 %
Date: 2017-09-14 15:23:50 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       79860 :   DIExpressionCursor(const DIExpression *Expr) {
      42       25109 :     if (!Expr) {
      43             :       assert(Start == End);
      44             :       return;
      45             :     }
      46       25411 :     Start = Expr->expr_op_begin();
      47       25411 :     End = Expr->expr_op_end();
      48             :   }
      49             : 
      50             :   DIExpressionCursor(ArrayRef<uint64_t> Expr)
      51        1780 :       : Start(Expr.begin()), End(Expr.end()) {}
      52             : 
      53             :   DIExpressionCursor(const DIExpressionCursor &) = default;
      54             : 
      55             :   /// Consume one operation.
      56             :   Optional<DIExpression::ExprOperand> take() {
      57        5202 :     if (Start == End)
      58             :       return None;
      59        7803 :     return *(Start++);
      60             :   }
      61             : 
      62             :   /// Consume N operations.
      63          18 :   void consume(unsigned N) { std::advance(Start, N); }
      64             : 
      65             :   /// Return the current operation.
      66             :   Optional<DIExpression::ExprOperand> peek() const {
      67       57354 :     if (Start == End)
      68             :       return None;
      69        2969 :     return *(Start);
      70             :   }
      71             : 
      72             :   /// Return the next operation.
      73          22 :   Optional<DIExpression::ExprOperand> peekNext() const {
      74          44 :     if (Start == End)
      75             :       return None;
      76             : 
      77          22 :     auto Next = Start.getNext();
      78          44 :     if (Next == End)
      79             :       return None;
      80             : 
      81          22 :     return *Next;
      82             :   }
      83             : 
      84             :   /// Determine whether there are any operations left in this expression.
      85       31360 :   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       14007 :     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         805 :     SubRegisterSizeInBits = SizeInBits;
     126         805 :     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       29402 :   ~DwarfExpression() = default;
     198             : 
     199             : public:
     200       29402 :   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             :   /// Lock this down to become a memory location description.
     215             :   void setMemoryLocationKind() {
     216             :     assert(LocationKind == Unknown);
     217        1590 :     LocationKind = Memory;
     218             :   }
     219             : 
     220             :   /// Emit a machine register location. As an optimization this may also consume
     221             :   /// the prefix of a DwarfExpression if a more efficient representation for
     222             :   /// combining the register location and the first operation exists.
     223             :   ///
     224             :   /// \param FragmentOffsetInBits     If this is one fragment out of a
     225             :   /// fragmented
     226             :   ///                                 location, this is the offset of the
     227             :   ///                                 fragment inside the entire variable.
     228             :   /// \return                         false if no DWARF register exists
     229             :   ///                                 for MachineReg.
     230             :   bool addMachineRegExpression(const TargetRegisterInfo &TRI,
     231             :                                DIExpressionCursor &Expr, unsigned MachineReg,
     232             :                                unsigned FragmentOffsetInBits = 0);
     233             : 
     234             :   /// Emit all remaining operations in the DIExpressionCursor.
     235             :   ///
     236             :   /// \param FragmentOffsetInBits     If this is one fragment out of multiple
     237             :   ///                                 locations, this is the offset of the
     238             :   ///                                 fragment inside the entire variable.
     239             :   void addExpression(DIExpressionCursor &&Expr,
     240             :                      unsigned FragmentOffsetInBits = 0);
     241             : 
     242             :   /// If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to
     243             :   /// the fragment described by \c Expr.
     244             :   void addFragmentOffset(const DIExpression *Expr);
     245             : };
     246             : 
     247             : /// DwarfExpression implementation for .debug_loc entries.
     248       25442 : class DebugLocDwarfExpression final : public DwarfExpression {
     249             :   ByteStreamer &BS;
     250             : 
     251             :   void emitOp(uint8_t Op, const char *Comment = nullptr) override;
     252             :   void emitSigned(int64_t Value) override;
     253             :   void emitUnsigned(uint64_t Value) override;
     254             :   bool isFrameRegister(const TargetRegisterInfo &TRI,
     255             :                        unsigned MachineReg) override;
     256             : 
     257             : public:
     258             :   DebugLocDwarfExpression(unsigned DwarfVersion, ByteStreamer &BS)
     259       25442 :       : DwarfExpression(DwarfVersion), BS(BS) {}
     260             : };
     261             : 
     262             : /// DwarfExpression implementation for singular DW_AT_location.
     263        3960 : class DIEDwarfExpression final : public DwarfExpression {
     264             : const AsmPrinter &AP;
     265             :   DwarfUnit &DU;
     266             :   DIELoc &DIE;
     267             : 
     268             :   void emitOp(uint8_t Op, const char *Comment = nullptr) override;
     269             :   void emitSigned(int64_t Value) override;
     270             :   void emitUnsigned(uint64_t Value) override;
     271             :   bool isFrameRegister(const TargetRegisterInfo &TRI,
     272             :                        unsigned MachineReg) override;
     273             : public:
     274             :   DIEDwarfExpression(const AsmPrinter &AP, DwarfUnit &DU, DIELoc &DIE);
     275             : 
     276             :   DIELoc *finalize() {
     277        1949 :     DwarfExpression::finalize();
     278        1949 :     return &DIE;
     279             :   }
     280             : };
     281             : 
     282             : } // end namespace llvm
     283             : 
     284             : #endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H

Generated by: LCOV version 1.13