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_DBGVALUEHISTORYCALCULATOR_H 10 #define LLVM_CODEGEN_DBGVALUEHISTORYCALCULATOR_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); clear()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 Entry(const MachineInstr * Instr,EntryKind Kind)79 Entry(const MachineInstr *Instr, EntryKind Kind) 80 : Instr(Instr, Kind), EndIndex(NoEntry) {} 81 getInstr()82 const MachineInstr *getInstr() const { return Instr.getPointer(); } getEndIndex()83 EntryIndex getEndIndex() const { return EndIndex; } getEntryKind()84 EntryKind getEntryKind() const { return Instr.getInt(); } 85 isClobber()86 bool isClobber() const { return getEntryKind() == Clobber; } isDbgValue()87 bool isDbgValue() const { return getEntryKind() == DbgValue; } isClosed()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 getEntry(InlinedEntity Var,EntryIndex Index)108 Entry &getEntry(InlinedEntity Var, EntryIndex Index) { 109 auto &Entries = VarEntries[Var]; 110 return Entries[Index]; 111 } 112 113 /// Drop location ranges which exist entirely outside each variable's scope. 114 void trimLocationRanges(const MachineFunction &MF, LexicalScopes &LScopes, 115 const InstructionOrdering &Ordering); empty()116 bool empty() const { return VarEntries.empty(); } clear()117 void clear() { VarEntries.clear(); } begin()118 EntriesMap::const_iterator begin() const { return VarEntries.begin(); } end()119 EntriesMap::const_iterator end() const { return VarEntries.end(); } 120 121 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 122 LLVM_DUMP_METHOD void dump() const; 123 #endif 124 }; 125 126 /// For each inlined instance of a source-level label, keep the corresponding 127 /// DBG_LABEL instruction. The DBG_LABEL instruction could be used to generate 128 /// a temporary (assembler) label before it. 129 class DbgLabelInstrMap { 130 public: 131 using InlinedEntity = std::pair<const DINode *, const DILocation *>; 132 using InstrMap = MapVector<InlinedEntity, const MachineInstr *>; 133 134 private: 135 InstrMap LabelInstr; 136 137 public: 138 void addInstr(InlinedEntity Label, const MachineInstr &MI); 139 empty()140 bool empty() const { return LabelInstr.empty(); } clear()141 void clear() { LabelInstr.clear(); } begin()142 InstrMap::const_iterator begin() const { return LabelInstr.begin(); } end()143 InstrMap::const_iterator end() const { return LabelInstr.end(); } 144 }; 145 146 void calculateDbgEntityHistory(const MachineFunction *MF, 147 const TargetRegisterInfo *TRI, 148 DbgValueHistoryMap &DbgValues, 149 DbgLabelInstrMap &DbgLabels); 150 151 } // end namespace llvm 152 153 #endif // LLVM_CODEGEN_DBGVALUEHISTORYCALCULATOR_H 154