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);
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   /// 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);
empty()120   bool empty() const { return VarEntries.empty(); }
clear()121   void clear() { VarEntries.clear(); }
begin()122   EntriesMap::const_iterator begin() const { return VarEntries.begin(); }
end()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 
empty()144   bool empty() const { return LabelInstr.empty(); }
clear()145   void clear() { LabelInstr.clear(); }
begin()146   InstrMap::const_iterator begin() const { return LabelInstr.begin(); }
end()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