• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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