1343171Sdim//===- llvm/CodeGen/DbgEntityHistoryCalculator.h ----------------*- C++ -*-===//
2343171Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6343171Sdim//
7343171Sdim//===----------------------------------------------------------------------===//
8343171Sdim
9343171Sdim#ifndef LLVM_CODEGEN_DBGVALUEHISTORYCALCULATOR_H
10343171Sdim#define LLVM_CODEGEN_DBGVALUEHISTORYCALCULATOR_H
11343171Sdim
12343171Sdim#include "llvm/ADT/MapVector.h"
13353358Sdim#include "llvm/ADT/PointerIntPair.h"
14343171Sdim#include "llvm/ADT/SmallVector.h"
15343171Sdim#include "llvm/IR/DebugInfoMetadata.h"
16343171Sdim#include <utility>
17343171Sdim
18343171Sdimnamespace llvm {
19343171Sdim
20343171Sdimclass DILocalVariable;
21343171Sdimclass MachineFunction;
22343171Sdimclass MachineInstr;
23343171Sdimclass TargetRegisterInfo;
24343171Sdim
25353358Sdim/// For each user variable, keep a list of instruction ranges where this
26353358Sdim/// variable is accessible. The variables are listed in order of appearance.
27343171Sdimclass DbgValueHistoryMap {
28343171Sdimpublic:
29353358Sdim  /// Index in the entry vector.
30353358Sdim  typedef size_t EntryIndex;
31353358Sdim
32353358Sdim  /// Special value to indicate that an entry is valid until the end of the
33353358Sdim  /// function.
34353358Sdim  static const EntryIndex NoEntry = std::numeric_limits<EntryIndex>::max();
35353358Sdim
36353358Sdim  /// Specifies a change in a variable's debug value history.
37353358Sdim  ///
38353358Sdim  /// There exist two types of entries:
39353358Sdim  ///
40353358Sdim  /// * Debug value entry:
41353358Sdim  ///
42353358Sdim  ///   A new debug value becomes live. If the entry's \p EndIndex is \p NoEntry,
43353358Sdim  ///   the value is valid until the end of the function. For other values, the
44353358Sdim  ///   index points to the entry in the entry vector that ends this debug
45353358Sdim  ///   value. The ending entry can either be an overlapping debug value, or
46353358Sdim  ///   an instruction that clobbers the value.
47353358Sdim  ///
48353358Sdim  /// * Clobbering entry:
49353358Sdim  ///
50353358Sdim  ///   This entry's instruction clobbers one or more preceding
51353358Sdim  ///   register-described debug values that have their end index
52353358Sdim  ///   set to this entry's position in the entry vector.
53353358Sdim  class Entry {
54353358Sdim  public:
55353358Sdim    enum EntryKind { DbgValue, Clobber };
56353358Sdim
57353358Sdim    Entry(const MachineInstr *Instr, EntryKind Kind)
58353358Sdim        : Instr(Instr, Kind), EndIndex(NoEntry) {}
59353358Sdim
60353358Sdim    const MachineInstr *getInstr() const { return Instr.getPointer(); }
61353358Sdim    EntryIndex getEndIndex() const { return EndIndex; }
62353358Sdim    EntryKind getEntryKind() const { return Instr.getInt(); }
63353358Sdim
64353358Sdim    bool isClobber() const { return getEntryKind() == Clobber; }
65353358Sdim    bool isDbgValue() const { return getEntryKind() == DbgValue; }
66353358Sdim    bool isClosed() const { return EndIndex != NoEntry; }
67353358Sdim
68353358Sdim    void endEntry(EntryIndex EndIndex);
69353358Sdim
70353358Sdim  private:
71353358Sdim    PointerIntPair<const MachineInstr *, 1, EntryKind> Instr;
72353358Sdim    EntryIndex EndIndex;
73353358Sdim  };
74353358Sdim  using Entries = SmallVector<Entry, 4>;
75343171Sdim  using InlinedEntity = std::pair<const DINode *, const DILocation *>;
76353358Sdim  using EntriesMap = MapVector<InlinedEntity, Entries>;
77343171Sdim
78343171Sdimprivate:
79353358Sdim  EntriesMap VarEntries;
80343171Sdim
81343171Sdimpublic:
82353358Sdim  bool startDbgValue(InlinedEntity Var, const MachineInstr &MI,
83353358Sdim                     EntryIndex &NewIndex);
84353358Sdim  EntryIndex startClobber(InlinedEntity Var, const MachineInstr &MI);
85343171Sdim
86353358Sdim  Entry &getEntry(InlinedEntity Var, EntryIndex Index) {
87353358Sdim    auto &Entries = VarEntries[Var];
88353358Sdim    return Entries[Index];
89353358Sdim  }
90343171Sdim
91353358Sdim  bool empty() const { return VarEntries.empty(); }
92353358Sdim  void clear() { VarEntries.clear(); }
93353358Sdim  EntriesMap::const_iterator begin() const { return VarEntries.begin(); }
94353358Sdim  EntriesMap::const_iterator end() const { return VarEntries.end(); }
95343171Sdim
96343171Sdim#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
97343171Sdim  LLVM_DUMP_METHOD void dump() const;
98343171Sdim#endif
99343171Sdim};
100343171Sdim
101343171Sdim/// For each inlined instance of a source-level label, keep the corresponding
102343171Sdim/// DBG_LABEL instruction. The DBG_LABEL instruction could be used to generate
103343171Sdim/// a temporary (assembler) label before it.
104343171Sdimclass DbgLabelInstrMap {
105343171Sdimpublic:
106343171Sdim  using InlinedEntity = std::pair<const DINode *, const DILocation *>;
107343171Sdim  using InstrMap = MapVector<InlinedEntity, const MachineInstr *>;
108343171Sdim
109343171Sdimprivate:
110343171Sdim  InstrMap LabelInstr;
111343171Sdim
112343171Sdimpublic:
113343171Sdim  void  addInstr(InlinedEntity Label, const MachineInstr &MI);
114343171Sdim
115343171Sdim  bool empty() const { return LabelInstr.empty(); }
116343171Sdim  void clear() { LabelInstr.clear(); }
117343171Sdim  InstrMap::const_iterator begin() const { return LabelInstr.begin(); }
118343171Sdim  InstrMap::const_iterator end() const { return LabelInstr.end(); }
119343171Sdim};
120343171Sdim
121343171Sdimvoid calculateDbgEntityHistory(const MachineFunction *MF,
122343171Sdim                               const TargetRegisterInfo *TRI,
123343171Sdim                               DbgValueHistoryMap &DbgValues,
124343171Sdim                               DbgLabelInstrMap &DbgLabels);
125343171Sdim
126343171Sdim} // end namespace llvm
127343171Sdim
128343171Sdim#endif // LLVM_CODEGEN_DBGVALUEHISTORYCALCULATOR_H
129