Home | History | Annotate | Line # | Download | only in CodeGen
      1 //===- llvm/CodeGen/DbgEntityHistoryCalculator.h ----------------*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 
      9 #ifndef LLVM_CODEGEN_DBGENTITYHISTORYCALCULATOR_H
     10 #define LLVM_CODEGEN_DBGENTITYHISTORYCALCULATOR_H
     11 
     12 #include "llvm/ADT/MapVector.h"
     13 #include "llvm/ADT/PointerIntPair.h"
     14 #include "llvm/ADT/SmallVector.h"
     15 #include "llvm/CodeGen/LexicalScopes.h"
     16 #include <utility>
     17 
     18 namespace llvm {
     19 
     20 class DILocalVariable;
     21 class DILocation;
     22 class DINode;
     23 class MachineFunction;
     24 class MachineInstr;
     25 class TargetRegisterInfo;
     26 
     27 /// Record instruction ordering so we can query their relative positions within
     28 /// a function. Meta instructions are given the same ordinal as the preceding
     29 /// non-meta instruction. Class state is invalid if MF is modified after
     30 /// calling initialize.
     31 class InstructionOrdering {
     32 public:
     33   void initialize(const MachineFunction &MF);
     34   void clear() { InstNumberMap.clear(); }
     35 
     36   /// Check if instruction \p A comes before \p B, where \p A and \p B both
     37   /// belong to the MachineFunction passed to initialize().
     38   bool isBefore(const MachineInstr *A, const MachineInstr *B) const;
     39 
     40 private:
     41   /// Each instruction is assigned an order number.
     42   DenseMap<const MachineInstr *, unsigned> InstNumberMap;
     43 };
     44 
     45 /// For each user variable, keep a list of instruction ranges where this
     46 /// variable is accessible. The variables are listed in order of appearance.
     47 class DbgValueHistoryMap {
     48 public:
     49   /// Index in the entry vector.
     50   typedef size_t EntryIndex;
     51 
     52   /// Special value to indicate that an entry is valid until the end of the
     53   /// function.
     54   static const EntryIndex NoEntry = std::numeric_limits<EntryIndex>::max();
     55 
     56   /// Specifies a change in a variable's debug value history.
     57   ///
     58   /// There exist two types of entries:
     59   ///
     60   /// * Debug value entry:
     61   ///
     62   ///   A new debug value becomes live. If the entry's \p EndIndex is \p NoEntry,
     63   ///   the value is valid until the end of the function. For other values, the
     64   ///   index points to the entry in the entry vector that ends this debug
     65   ///   value. The ending entry can either be an overlapping debug value, or
     66   ///   an instruction that clobbers the value.
     67   ///
     68   /// * Clobbering entry:
     69   ///
     70   ///   This entry's instruction clobbers one or more preceding
     71   ///   register-described debug values that have their end index
     72   ///   set to this entry's position in the entry vector.
     73   class Entry {
     74     friend DbgValueHistoryMap;
     75 
     76   public:
     77     enum EntryKind { DbgValue, Clobber };
     78 
     79     Entry(const MachineInstr *Instr, EntryKind Kind)
     80         : Instr(Instr, Kind), EndIndex(NoEntry) {}
     81 
     82     const MachineInstr *getInstr() const { return Instr.getPointer(); }
     83     EntryIndex getEndIndex() const { return EndIndex; }
     84     EntryKind getEntryKind() const { return Instr.getInt(); }
     85 
     86     bool isClobber() const { return getEntryKind() == Clobber; }
     87     bool isDbgValue() const { return getEntryKind() == DbgValue; }
     88     bool isClosed() const { return EndIndex != NoEntry; }
     89 
     90     void endEntry(EntryIndex EndIndex);
     91 
     92   private:
     93     PointerIntPair<const MachineInstr *, 1, EntryKind> Instr;
     94     EntryIndex EndIndex;
     95   };
     96   using Entries = SmallVector<Entry, 4>;
     97   using InlinedEntity = std::pair<const DINode *, const DILocation *>;
     98   using EntriesMap = MapVector<InlinedEntity, Entries>;
     99 
    100 private:
    101   EntriesMap VarEntries;
    102 
    103 public:
    104   bool startDbgValue(InlinedEntity Var, const MachineInstr &MI,
    105                      EntryIndex &NewIndex);
    106   EntryIndex startClobber(InlinedEntity Var, const MachineInstr &MI);
    107 
    108   Entry &getEntry(InlinedEntity Var, EntryIndex Index) {
    109     auto &Entries = VarEntries[Var];
    110     return Entries[Index];
    111   }
    112 
    113   /// Test whether a vector of entries features any non-empty locations. It
    114   /// could have no entries, or only DBG_VALUE $noreg entries.
    115   bool hasNonEmptyLocation(const Entries &Entries) const;
    116 
    117   /// Drop location ranges which exist entirely outside each variable's scope.
    118   void trimLocationRanges(const MachineFunction &MF, LexicalScopes &LScopes,
    119                           const InstructionOrdering &Ordering);
    120   bool empty() const { return VarEntries.empty(); }
    121   void clear() { VarEntries.clear(); }
    122   EntriesMap::const_iterator begin() const { return VarEntries.begin(); }
    123   EntriesMap::const_iterator end() const { return VarEntries.end(); }
    124 
    125 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
    126   LLVM_DUMP_METHOD void dump() const;
    127 #endif
    128 };
    129 
    130 /// For each inlined instance of a source-level label, keep the corresponding
    131 /// DBG_LABEL instruction. The DBG_LABEL instruction could be used to generate
    132 /// a temporary (assembler) label before it.
    133 class DbgLabelInstrMap {
    134 public:
    135   using InlinedEntity = std::pair<const DINode *, const DILocation *>;
    136   using InstrMap = MapVector<InlinedEntity, const MachineInstr *>;
    137 
    138 private:
    139   InstrMap LabelInstr;
    140 
    141 public:
    142   void  addInstr(InlinedEntity Label, const MachineInstr &MI);
    143 
    144   bool empty() const { return LabelInstr.empty(); }
    145   void clear() { LabelInstr.clear(); }
    146   InstrMap::const_iterator begin() const { return LabelInstr.begin(); }
    147   InstrMap::const_iterator end() const { return LabelInstr.end(); }
    148 };
    149 
    150 void calculateDbgEntityHistory(const MachineFunction *MF,
    151                                const TargetRegisterInfo *TRI,
    152                                DbgValueHistoryMap &DbgValues,
    153                                DbgLabelInstrMap &DbgLabels);
    154 
    155 } // end namespace llvm
    156 
    157 #endif // LLVM_CODEGEN_DBGENTITYHISTORYCALCULATOR_H
    158