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/IR/DebugInfoMetadata.h" 16 #include <utility> 17 18 namespace llvm { 19 20 class DILocalVariable; 21 class MachineFunction; 22 class MachineInstr; 23 class TargetRegisterInfo; 24 25 /// For each user variable, keep a list of instruction ranges where this 26 /// variable is accessible. The variables are listed in order of appearance. 27 class DbgValueHistoryMap { 28 public: 29 /// Index in the entry vector. 30 typedef size_t EntryIndex; 31 32 /// Special value to indicate that an entry is valid until the end of the 33 /// function. 34 static const EntryIndex NoEntry = std::numeric_limits<EntryIndex>::max(); 35 36 /// Specifies a change in a variable's debug value history. 37 /// 38 /// There exist two types of entries: 39 /// 40 /// * Debug value entry: 41 /// 42 /// A new debug value becomes live. If the entry's \p EndIndex is \p NoEntry, 43 /// the value is valid until the end of the function. For other values, the 44 /// index points to the entry in the entry vector that ends this debug 45 /// value. The ending entry can either be an overlapping debug value, or 46 /// an instruction that clobbers the value. 47 /// 48 /// * Clobbering entry: 49 /// 50 /// This entry's instruction clobbers one or more preceding 51 /// register-described debug values that have their end index 52 /// set to this entry's position in the entry vector. 53 class Entry { 54 public: 55 enum EntryKind { DbgValue, Clobber }; 56 57 Entry(const MachineInstr *Instr, EntryKind Kind) 58 : Instr(Instr, Kind), EndIndex(NoEntry) {} 59 60 const MachineInstr *getInstr() const { return Instr.getPointer(); } 61 EntryIndex getEndIndex() const { return EndIndex; } 62 EntryKind getEntryKind() const { return Instr.getInt(); } 63 64 bool isClobber() const { return getEntryKind() == Clobber; } 65 bool isDbgValue() const { return getEntryKind() == DbgValue; } 66 bool isClosed() const { return EndIndex != NoEntry; } 67 68 void endEntry(EntryIndex EndIndex); 69 70 private: 71 PointerIntPair<const MachineInstr *, 1, EntryKind> Instr; 72 EntryIndex EndIndex; 73 }; 74 using Entries = SmallVector<Entry, 4>; 75 using InlinedEntity = std::pair<const DINode *, const DILocation *>; 76 using EntriesMap = MapVector<InlinedEntity, Entries>; 77 78 private: 79 EntriesMap VarEntries; 80 81 public: 82 bool startDbgValue(InlinedEntity Var, const MachineInstr &MI, 83 EntryIndex &NewIndex); 84 EntryIndex startClobber(InlinedEntity Var, const MachineInstr &MI); 85 86 Entry &getEntry(InlinedEntity Var, EntryIndex Index) { 87 auto &Entries = VarEntries[Var]; 88 return Entries[Index]; 89 } 90 91 bool empty() const { return VarEntries.empty(); } 92 void clear() { VarEntries.clear(); } 93 EntriesMap::const_iterator begin() const { return VarEntries.begin(); } 94 EntriesMap::const_iterator end() const { return VarEntries.end(); } 95 96 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 97 LLVM_DUMP_METHOD void dump() const; 98 #endif 99 }; 100 101 /// For each inlined instance of a source-level label, keep the corresponding 102 /// DBG_LABEL instruction. The DBG_LABEL instruction could be used to generate 103 /// a temporary (assembler) label before it. 104 class DbgLabelInstrMap { 105 public: 106 using InlinedEntity = std::pair<const DINode *, const DILocation *>; 107 using InstrMap = MapVector<InlinedEntity, const MachineInstr *>; 108 109 private: 110 InstrMap LabelInstr; 111 112 public: 113 void addInstr(InlinedEntity Label, const MachineInstr &MI); 114 115 bool empty() const { return LabelInstr.empty(); } 116 void clear() { LabelInstr.clear(); } 117 InstrMap::const_iterator begin() const { return LabelInstr.begin(); } 118 InstrMap::const_iterator end() const { return LabelInstr.end(); } 119 }; 120 121 void calculateDbgEntityHistory(const MachineFunction *MF, 122 const TargetRegisterInfo *TRI, 123 DbgValueHistoryMap &DbgValues, 124 DbgLabelInstrMap &DbgLabels); 125 126 } // end namespace llvm 127 128 #endif // LLVM_CODEGEN_DBGVALUEHISTORYCALCULATOR_H 129