123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- llvm/CodeGen/DbgEntityHistoryCalculator.h ----------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CODEGEN_DBGENTITYHISTORYCALCULATOR_H
- #define LLVM_CODEGEN_DBGENTITYHISTORYCALCULATOR_H
- #include "llvm/ADT/MapVector.h"
- #include "llvm/ADT/PointerIntPair.h"
- #include "llvm/ADT/SmallVector.h"
- #include "llvm/CodeGen/MachineInstr.h"
- #include <utility>
- namespace llvm {
- class DILocation;
- class LexicalScopes;
- class DINode;
- class MachineFunction;
- class TargetRegisterInfo;
- /// Record instruction ordering so we can query their relative positions within
- /// a function. Meta instructions are given the same ordinal as the preceding
- /// non-meta instruction. Class state is invalid if MF is modified after
- /// calling initialize.
- class InstructionOrdering {
- public:
- void initialize(const MachineFunction &MF);
- void clear() { InstNumberMap.clear(); }
- /// Check if instruction \p A comes before \p B, where \p A and \p B both
- /// belong to the MachineFunction passed to initialize().
- bool isBefore(const MachineInstr *A, const MachineInstr *B) const;
- private:
- /// Each instruction is assigned an order number.
- DenseMap<const MachineInstr *, unsigned> InstNumberMap;
- };
- /// For each user variable, keep a list of instruction ranges where this
- /// variable is accessible. The variables are listed in order of appearance.
- class DbgValueHistoryMap {
- public:
- /// Index in the entry vector.
- typedef size_t EntryIndex;
- /// Special value to indicate that an entry is valid until the end of the
- /// function.
- static const EntryIndex NoEntry = std::numeric_limits<EntryIndex>::max();
- /// Specifies a change in a variable's debug value history.
- ///
- /// There exist two types of entries:
- ///
- /// * Debug value entry:
- ///
- /// A new debug value becomes live. If the entry's \p EndIndex is \p NoEntry,
- /// the value is valid until the end of the function. For other values, the
- /// index points to the entry in the entry vector that ends this debug
- /// value. The ending entry can either be an overlapping debug value, or
- /// an instruction that clobbers the value.
- ///
- /// * Clobbering entry:
- ///
- /// This entry's instruction clobbers one or more preceding
- /// register-described debug values that have their end index
- /// set to this entry's position in the entry vector.
- class Entry {
- friend DbgValueHistoryMap;
- public:
- enum EntryKind { DbgValue, Clobber };
- Entry(const MachineInstr *Instr, EntryKind Kind)
- : Instr(Instr, Kind), EndIndex(NoEntry) {}
- const MachineInstr *getInstr() const { return Instr.getPointer(); }
- EntryIndex getEndIndex() const { return EndIndex; }
- EntryKind getEntryKind() const { return Instr.getInt(); }
- bool isClobber() const { return getEntryKind() == Clobber; }
- bool isDbgValue() const { return getEntryKind() == DbgValue; }
- bool isClosed() const { return EndIndex != NoEntry; }
- void endEntry(EntryIndex EndIndex);
- private:
- PointerIntPair<const MachineInstr *, 1, EntryKind> Instr;
- EntryIndex EndIndex;
- };
- using Entries = SmallVector<Entry, 4>;
- using InlinedEntity = std::pair<const DINode *, const DILocation *>;
- using EntriesMap = MapVector<InlinedEntity, Entries>;
- private:
- EntriesMap VarEntries;
- public:
- bool startDbgValue(InlinedEntity Var, const MachineInstr &MI,
- EntryIndex &NewIndex);
- EntryIndex startClobber(InlinedEntity Var, const MachineInstr &MI);
- Entry &getEntry(InlinedEntity Var, EntryIndex Index) {
- auto &Entries = VarEntries[Var];
- return Entries[Index];
- }
- /// Test whether a vector of entries features any non-empty locations. It
- /// could have no entries, or only DBG_VALUE $noreg entries.
- bool hasNonEmptyLocation(const Entries &Entries) const;
- /// Drop location ranges which exist entirely outside each variable's scope.
- void trimLocationRanges(const MachineFunction &MF, LexicalScopes &LScopes,
- const InstructionOrdering &Ordering);
- bool empty() const { return VarEntries.empty(); }
- void clear() { VarEntries.clear(); }
- EntriesMap::const_iterator begin() const { return VarEntries.begin(); }
- EntriesMap::const_iterator end() const { return VarEntries.end(); }
- #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
- LLVM_DUMP_METHOD void dump() const;
- #endif
- };
- /// For each inlined instance of a source-level label, keep the corresponding
- /// DBG_LABEL instruction. The DBG_LABEL instruction could be used to generate
- /// a temporary (assembler) label before it.
- class DbgLabelInstrMap {
- public:
- using InlinedEntity = std::pair<const DINode *, const DILocation *>;
- using InstrMap = MapVector<InlinedEntity, const MachineInstr *>;
- private:
- InstrMap LabelInstr;
- public:
- void addInstr(InlinedEntity Label, const MachineInstr &MI);
- bool empty() const { return LabelInstr.empty(); }
- void clear() { LabelInstr.clear(); }
- InstrMap::const_iterator begin() const { return LabelInstr.begin(); }
- InstrMap::const_iterator end() const { return LabelInstr.end(); }
- };
- void calculateDbgEntityHistory(const MachineFunction *MF,
- const TargetRegisterInfo *TRI,
- DbgValueHistoryMap &DbgValues,
- DbgLabelInstrMap &DbgLabels);
- } // end namespace llvm
- #endif // LLVM_CODEGEN_DBGENTITYHISTORYCALCULATOR_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|