9#ifndef LLVM_LIB_CODEGEN_LIVEDEBUGVALUES_INSTRREFBASEDLDV_H
10#define LLVM_LIB_CODEGEN_LIVEDEBUGVALUES_INSTRREFBASEDLDV_H
40using VarAndLoc = std::pair<DebugVariable, const DILocation *>;
53 auto It = VarToIdx.find(Var);
54 assert(It != VarToIdx.end());
59 unsigned Size = VarToIdx.size();
60 auto ItPair = VarToIdx.insert({Var,
Size});
62 IdxToVar.push_back({Var,
Loc});
66 return ItPair.first->second;
87 LocIdx() : Location(UINT_MAX) {}
90#define NUM_LOC_BITS 24
97 bool isIllegal()
const {
return Location == UINT_MAX; }
103 bool operator==(
const LocIdx &L)
const {
return Location == L.Location; }
107 bool operator!=(
const LocIdx &L)
const {
return !(*
this == L); }
110 return Location <
Other.Location;
121 std::make_pair(
Other.SpillBase,
Other.SpillOffset);
126 std::make_tuple(
Other.SpillBase,
Other.SpillOffset.getFixed(),
127 Other.SpillOffset.getScalable());
153 static_assert(
sizeof(u) == 8,
"Badly packed ValueIDNum?");
171 bool isPHI()
const {
return u.s.InstNo == 0; }
186 return u.Value ==
Other.u.Value;
191 std::string
asString(
const std::string &mlocname)
const {
192 return Twine(
"Value{bb: ")
243 Storage.reserve(NumBBs);
244 for (
int i = 0; i != NumBBs; ++i)
251 return (*
this)[
MBB.getNumber()];
257 auto &TablePtr = Storage[MBBNum];
258 assert(TablePtr &&
"Trying to access a deleted table");
267 return Storage[
MBB.getNumber()] !=
nullptr;
272 Storage[
MBB.getNumber()].reset();
298 return !(*
this ==
Other);
312 assert(
MI.getDebugExpression()->getNumLocationOperands() == 0 ||
313 MI.isDebugValueList() ||
MI.isUndefDebugValue());
330 return !(*
this ==
Other);
386 return MO.isIdenticalTo(
Other.MO);
414 static_assert(
sizeof(
DbgOpID) == 4,
"DbgOpID should fit within 4 bytes.");
456 return insertConstOp(
Op.MO);
457 return insertValueOp(
Op.ID);
465 return DbgOp(ConstOps[
ID.getIndex()]);
466 return DbgOp(ValueOps[
ID.getIndex()]);
478 auto [It, Inserted] = ConstOpToID.
try_emplace(MO,
true, ConstOps.
size());
484 auto [It, Inserted] = ValueOpToID.
try_emplace(VID,
false, ValueOps.
size());
533 static_assert(
sizeof(
DbgValue) <= 64,
534 "DbgValue should fit within 64 bytes.");
540#define DEBUG_TYPE "LiveDebugValues"
542 LLVM_DEBUG(
dbgs() <<
"Found DbgValue with more than maximum allowed "
547 for (
unsigned Idx = 0; Idx < DbgOps.size(); ++Idx)
548 this->DbgOps[Idx] = DbgOps[Idx];
560 "Empty DbgValue constructor must pass in Undef kind");
596 return DbgOps[Index];
605 "Incorrect number of Debug Operands for this DbgValue.");
606 OpCount = NewIDs.
size();
607 for (
unsigned Idx = 0; Idx < NewIDs.
size(); ++Idx)
608 DbgOps[Idx] = NewIDs[Idx];
766 : ValueMap(ValueMap), Idx(Idx) {}
770 return Idx ==
Other.Idx;
774 return !(*
this ==
Other);
795 unsigned short Size =
TRI.getSubRegIdxSize(SpillSubReg);
796 unsigned short Offs =
TRI.getSubRegIdxOffset(SpillSubReg);
804 unsigned SlotNo = Spill.id() - 1;
815 unsigned SlotNo = Spill.id() - 1;
847 Location.Value = {
CurBB, 0, Location.Idx};
857 Location.Value = Locs[Location.Idx.asU64()];
902 if (Index.isIllegal())
910 return !Index.isIllegal();
1021 std::pair<const DILocalVariable *, DIExpression::FragmentInfo>;
1058 MI.getDebugLoc()->getInlinedAt());
1079 for (
auto FragmentInfo : Overlaps->second) {
1083 std::optional<DIExpression::FragmentInfo> OptFragmentInfo = FragmentInfo;
1085 OptFragmentInfo = std::nullopt;
1094 Vars.insert_or_assign(OverlappedID, Rec);
1108 friend class ::InstrRefLDVTest;
1129 using InValueT = std::pair<MachineBasicBlock *, DbgValue *>;
1166 unsigned CurBB = -1;
1191 using InstAndNum = std::pair<const MachineInstr *, unsigned>;
1195 std::map<uint64_t, InstAndNum> DebugInstrNumToInstr;
1198 class DebugPHIRecord {
1206 std::optional<ValueIDNum> ValueRead;
1209 std::optional<LocIdx> ReadLoc;
1211 operator unsigned()
const {
return InstrNum; }
1241 bool AdjustsStackInCalls =
false;
1249 std::optional<SpillLocationNo> isSpillInstruction(
const MachineInstr &
MI,
1263 std::optional<SpillLocationNo> isRestoreInstruction(
const MachineInstr &
MI,
1269 std::optional<SpillLocationNo>
1275 std::optional<ValueIDNum> getValueForInstrRef(
unsigned InstNo,
unsigned OpNo,
1367 void placePHIsForSingleVarDefinition(
1448 std::optional<ValueIDNum> pickOperandPHILoc(
1455 bool emitTransfers();
1475 bool depthFirstVLocAndEmit(
1480 bool ShouldEmitDebugEntryValues);
1483 bool ShouldEmitDebugEntryValues,
unsigned InputBBLimit,
1484 unsigned InputDbgValLimit)
override;
1500 if (!
MI.hasOneMemOperand())
1502 auto *MemOperand = *
MI.memoperands_begin();
1503 return MemOperand->isStore() &&
1504 MemOperand->getPseudoValue() &&
1506 && !MemOperand->getPseudoValue()->isAliased(MFI);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static cl::opt< unsigned > MaxNumBlocks("debug-ata-max-blocks", cl::init(10000), cl::desc("Maximum num basic blocks before debug info dropped"), cl::Hidden)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
#define LLVM_ABI_FOR_TEST
This file defines the DenseMap class.
const HexagonInstrInfo * TII
This file implements an indexed map.
static cl::opt< unsigned > InputBBLimit("livedebugvalues-input-bb-limit", cl::desc("Maximum input basic blocks before DBG_VALUE limit applies"), cl::init(10000), cl::Hidden)
Register const TargetRegisterInfo * TRI
Promote Memory to Register
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
Class storing the complete set of values that are observed by DbgValues within the current function.
DbgOp find(DbgOpID ID) const
Returns the DbgOp associated with ID.
DbgOpID insert(DbgOp Op)
If Op does not already exist in this map, it is inserted and the corresponding DbgOpID is returned.
Meta qualifiers for a value.
bool operator==(const DbgValueProperties &Other) const
DbgValueProperties(const DIExpression *DIExpr, bool Indirect, bool IsVariadic)
const DIExpression * DIExpr
DbgValueProperties(const MachineInstr &MI)
Extract properties from an existing DBG_VALUE instruction.
bool isJoinable(const DbgValueProperties &Other) const
unsigned getLocationOpCount() const
bool operator!=(const DbgValueProperties &Other) const
Class recording the (high level) value of a variable.
int BlockNo
For a NoVal or VPHI DbgValue, which block it was generated in.
DbgValueProperties Properties
Qualifiers for the ValueIDNum above.
ArrayRef< DbgOpID > getDbgOpIDs() const
void setDbgOpIDs(ArrayRef< DbgOpID > NewIDs)
bool hasJoinableLocOps(const DbgValue &Other) const
void dump(const MLocTracker *MTrack=nullptr, const DbgOpIDMap *OpStore=nullptr) const
bool isUnjoinedPHI() const
DbgValue(ArrayRef< DbgOpID > DbgOps, const DbgValueProperties &Prop)
DbgOpID getDbgOpID(unsigned Index) const
DbgValue(unsigned BlockNo, const DbgValueProperties &Prop, KindT Kind)
bool operator!=(const DbgValue &Other) const
DbgValue(const DbgValueProperties &Prop, KindT Kind)
KindT Kind
Discriminator for whether this is a constant or an in-program value.
unsigned getLocationOpCount() const
bool operator==(const DbgValue &Other) const
bool hasIdenticalValidLocOps(const DbgValue &Other) const
Mapping from DebugVariable to/from a unique identifying number.
const VarAndLoc & lookupDVID(DebugVariableID ID) const
DebugVariableID insertDVID(DebugVariable &Var, const DILocation *Loc)
DebugVariableID getDVID(const DebugVariable &Var) const
DenseMap< const LexicalScope *, const DILocation * > ScopeToDILocT
Mapping from lexical scopes to a DILocation in that scope.
DenseMap< const DILocalVariable *, SmallSet< FragmentInfo, 4 > > VarToFragments
std::optional< LocIdx > findLocationForMemOperand(const MachineInstr &MI)
std::pair< MachineBasicBlock *, DbgValue * > InValueT
Type for a live-in value: the predecessor block, and its value.
DebugVariableMap & getDVMap()
std::pair< DebugVariableID, DbgValue > VarAndLoc
SmallVector< SmallVector< VarAndLoc, 8 >, 8 > LiveInsT
Vector (per block) of a collection (inner smallvector) of live-ins.
LLVM_ABI_FOR_TEST InstrRefBasedLDV()
Default construct and initialize the pass.
DenseMap< const LexicalScope *, SmallPtrSet< MachineBasicBlock *, 4 > > ScopeToAssignBlocksT
Mapping from lexical scopes to blocks where variables in that scope are assigned.
DIExpression::FragmentInfo FragmentInfo
DenseMap< const LexicalScope *, SmallSet< DebugVariableID, 4 > > ScopeToVarsT
Mapping from lexical scopes to variables in that scope.
std::optional< DIExpression::FragmentInfo > OptFragmentInfo
SmallDenseMap< const MachineBasicBlock *, DbgValue *, 16 > LiveIdxT
Live in/out structure for the variable values: a per-block map of variables to their values.
SmallDenseMap< LocIdx, ValueIDNum > MLocTransferMap
Machine location/value transfer function, a mapping of which locations are assigned which new values.
bool hasFoldedStackStore(const MachineInstr &MI)
bool isCalleeSaved(LocIdx L) const
bool isCalleeSavedReg(Register R) const
LLVM_DUMP_METHOD void dump_mloc_transfer(const MLocTransferMap &mloc_transfer) const
unsigned operator()(const LocIdx &L) const
Handle-class for a particular "location".
bool operator!=(const LocIdx &L) const
bool operator<(const LocIdx &Other) const
static LocIdx MakeIllegalLoc()
bool operator!=(unsigned L) const
bool operator==(unsigned L) const
bool operator==(const LocIdx &L) const
value_type(LocIdx Idx, ValueIDNum &Value)
ValueIDNum & Value
Read-only index of this location.
Iterator for locations and the values they contain.
bool operator!=(const MLocIterator &Other) const
MLocIterator(LocToValueType &ValueMap, LocIdx Idx)
bool operator==(const MLocIterator &Other) const
Tracker for what values are in machine locations.
unsigned getLocSizeInBits(LocIdx L) const
How large is this location (aka, how wide is a value defined there?).
bool isRegisterTracked(Register R)
Is register R currently tracked by MLocTracker?
LLVM_ABI_FOR_TEST std::optional< SpillLocationNo > getOrTrackSpillLoc(SpillLoc L)
Find LocIdx for SpillLoc L, creating a new one if it's not tracked.
void loadFromArray(ValueTable &Locs, unsigned NewCurBB)
Load values for each location from array of ValueIDNums.
IndexedMap< unsigned, LocIdxToIndexFunctor > LocIdxToLocID
Inverse map of LocIDToLocIdx.
unsigned getSpillIDWithIdx(SpillLocationNo Spill, unsigned Idx)
Given a spill number, and a slot within the spill, calculate the ID number for that location.
unsigned getLocID(SpillLocationNo Spill, unsigned SpillSubReg)
Produce location ID number for a spill position.
iterator_range< MLocIterator > locations()
Return a range over all locations currently tracked.
unsigned getLocID(SpillLocationNo Spill, StackSlotPos Idx)
Produce location ID number for a spill position.
SmallSet< Register, 8 > SPAliases
When clobbering register masks, we chose to not believe the machine model and don't clobber SP.
unsigned getLocID(Register Reg)
Produce location ID number for a Register.
const TargetLowering & TLI
const TargetRegisterInfo & TRI
unsigned NumRegs
Cached local copy of the number of registers the target has.
unsigned getNumLocs() const
DenseMap< StackSlotPos, unsigned > StackSlotIdxes
Map from a size/offset pair describing a position in a stack slot, to a numeric identifier for that p...
LocIdx lookupOrTrackRegister(unsigned ID)
void setReg(Register R, ValueIDNum ValueID)
Set a register to a value number.
SpillLocationNo locIDToSpill(unsigned ID) const
Return the spill number that a location ID corresponds to.
void reset()
Wipe any un-necessary location records after traversing a block.
DenseMap< unsigned, StackSlotPos > StackIdxesToPos
Inverse of StackSlotIdxes.
std::string IDAsString(const ValueIDNum &Num) const
void writeRegMask(const MachineOperand *MO, unsigned CurBB, unsigned InstID)
Record a RegMask operand being executed.
std::pair< unsigned short, unsigned short > StackSlotPos
Pair for describing a position within a stack slot – first the size in bits, then the offset.
const TargetInstrInfo & TII
bool isSpill(LocIdx Idx) const
Return true if Idx is a spill machine location.
LocIdx getRegMLoc(Register R)
Determine the LocIdx of an existing register.
MachineInstrBuilder emitLoc(const SmallVectorImpl< ResolvedDbgOp > &DbgOps, const DebugVariable &Var, const DILocation *DILoc, const DbgValueProperties &Properties)
Create a DBG_VALUE based on debug operands DbgOps.
void wipeRegister(Register R)
Reset a register value to zero / empty.
void setMLoc(LocIdx L, ValueIDNum Num)
Set a locaiton to a certain value.
LocToValueType LocIdxToIDNum
Map of LocIdxes to the ValueIDNums that they store.
std::vector< LocIdx > LocIDToLocIdx
"Map" of machine location IDs (i.e., raw register or spill number) to the LocIdx key / number for tha...
void clear()
Clear all data.
IndexedMap< ValueIDNum, LocIdxToIndexFunctor > LocToValueType
IndexedMap type, mapping from LocIdx to ValueIDNum.
SmallVector< std::pair< const MachineOperand *, unsigned >, 32 > Masks
Collection of register mask operands that have been observed.
unsigned NumSlotIdxes
Number of slot indexes the target has – distinct segments of a stack slot that can take on the value ...
UniqueVector< SpillLoc > SpillLocs
Unique-ification of spill.
ValueIDNum readMLoc(LocIdx L)
Read the value of a particular location.
void setMPhis(unsigned NewCurBB)
Reset all locations to contain a PHI value at the designated block.
ValueIDNum readReg(Register R)
void defReg(Register R, unsigned BB, unsigned Inst)
Record a definition of the specified register at the given block / inst.
LLVM_DUMP_METHOD void dump()
LLVM_ABI_FOR_TEST LocIdx trackRegister(unsigned ID)
Create a LocIdx for an untracked register ID.
LLVM_ABI_FOR_TEST MLocTracker(MachineFunction &MF, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const TargetLowering &TLI)
LLVM_DUMP_METHOD void dump_mloc_map()
StackSlotPos locIDToSpillIdx(unsigned ID) const
Returns the spill-slot size/offs that a location ID corresponds to.
LocIdx getSpillMLoc(unsigned SpillID)
std::string LocIdxToName(LocIdx Idx) const
Thin wrapper around an integer – designed to give more type safety to spill location numbers.
bool operator==(const SpillLocationNo &Other) const
bool operator!=(const SpillLocationNo &Other) const
bool operator<(const SpillLocationNo &Other) const
SpillLocationNo(unsigned SpillNo)
Collection of DBG_VALUEs observed when traversing a block.
const OverlapMap & OverlappingFragments
SmallDenseMap< DebugVariableID, const DILocation *, 8 > Scopes
SmallMapVector< DebugVariableID, DbgValue, 8 > Vars
Map DebugVariable to the latest Value it's defined to have.
void defVar(const MachineInstr &MI, const DbgValueProperties &Properties, const SmallVectorImpl< DbgOpID > &DebugOps)
void considerOverlaps(const DebugVariable &Var, const DILocation *Loc)
VLocTracker(DebugVariableMap &DVMap, const OverlapMap &O, const DIExpression *EmptyExpr)
DebugVariableMap & DVMap
Ref to function-wide map of DebugVariable <=> ID-numbers.
DbgValueProperties EmptyProperties
Unique identifier for a value defined by an instruction, as a value type.
uint64_t LocNo
The Instruction where the def happens.
ValueIDNum(uint64_t Block, uint64_t Inst, uint64_t Loc)
struct LiveDebugValues::ValueIDNum::@122243371010332366363270357367014132366357004151::@211331010212204211312147341360354163043131005174 s
bool operator==(const ValueIDNum &Other) const
bool operator<(const ValueIDNum &Other) const
static ValueIDNum fromU64(uint64_t v)
std::string asString(const std::string &mlocname) const
static LLVM_ABI_FOR_TEST ValueIDNum EmptyValue
ValueIDNum(uint64_t Block, uint64_t Inst, LocIdx Loc)
bool operator!=(const ValueIDNum &Other) const
uint64_t getBlock() const
uint64_t InstNo
The block where the def happens.
Tracker for converting machine value locations and variable values into variable locations (the outpu...
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
DbgVariableFragmentInfo FragmentInfo
static LLVM_ABI bool isEqualExpression(const DIExpression *FirstExpr, bool FirstIndirect, const DIExpression *SecondExpr, bool SecondIndirect)
Determines whether two debug values should produce equivalent DWARF expressions, using their DIExpres...
Identifies a unique instance of a variable.
static bool isDefaultFragment(const FragmentInfo F)
const DILocation * getInlinedAt() const
FragmentInfo getFragmentOrDefault() const
const DILocalVariable * getVariable() const
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
This class provides interface to collect and use lexical scoping information from machine instruction...
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
Represent a constant reference to a string, i.e.
Information about stack frame layout on the target.
TargetInstrInfo - Interface to description of machine instruction set.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM_ABI std::string str() const
Return the twine contents as a std::string.
Twine concat(const Twine &Suffix) const
UniqueVector - This class produces a sequential ID number (base 1) for each unique entry that is adde...
A range adaptor for a pair of iterators.
DenseMap< FragmentOfVar, SmallVector< DIExpression::FragmentInfo, 1 > > OverlapMap
SmallVector< ValueIDNum, 0 > ValueTable
Type for a table of values in a block.
std::pair< const DILocalVariable *, DIExpression::FragmentInfo > FragmentOfVar
Types for recording sets of variable fragments that overlap.
std::pair< DebugVariable, const DILocation * > VarAndLoc
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
std::tuple< const DIScope *, const DIScope *, const DILocalVariable * > VarID
A unique key that represents a debug variable.
hash_code hash_value(const FixedPointSemantics &Val)
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&...Ranges)
Returns a concatenated range across two or more ranges.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
DWARFExpression::Operation Op
bool equal(L &&LRange, R &&RRange)
Wrapper function around std::equal to detect if pair-wise elements between two ranges are the same.
An ID used in the DbgOpIDMap (below) to lookup a stored DbgOp.
bool operator==(const DbgOpID &Other) const
bool operator!=(const DbgOpID &Other) const
void dump(const MLocTracker *MTrack, const DbgOpIDMap *OpStore) const
uint32_t getIndex() const
DbgOpID(bool IsConst, uint32_t Index)
static LLVM_ABI_FOR_TEST DbgOpID UndefID
struct IsConstIndexPair ID
TODO: Might pack better if we changed this to a Struct of Arrays, since MachineOperand is width 32,...
void dump(const MLocTracker *MTrack) const
A collection of ValueTables, one per BB in a function, with convenient accessor methods.
ValueTable & operator[](int MBBNum) const
Returns the ValueTable associated with the MachineBasicBlock whose number is MBBNum.
void ejectTableForBlock(const MachineBasicBlock &MBB)
Frees the memory of the ValueTable associated with MBB.
ValueTable & tableForEntryMBB() const
Returns the ValueTable associated with the entry MachineBasicBlock.
FuncValueTable(int NumBBs, int NumLocs)
ValueTable & operator[](const MachineBasicBlock &MBB) const
Returns the ValueTable associated with MBB.
bool hasTableFor(MachineBasicBlock &MBB) const
Returns true if the ValueTable associated with MBB has not been freed.
ResolvedDbgOp(MachineOperand MO)
ResolvedDbgOp(LocIdx Loc)
bool operator==(const ResolvedDbgOp &Other) const
void dump(const MLocTracker *MTrack) const
bool operator<(const SpillLoc &Other) const
bool operator==(const SpillLoc &Other) const
static bool isEqual(const LocIdx &A, const LocIdx &B)
static unsigned getHashValue(const LocIdx &Loc)
static LocIdx getEmptyKey()
static ValueIDNum getEmptyKey()
static unsigned getHashValue(const ValueIDNum &Val)
static bool isEqual(const ValueIDNum &A, const ValueIDNum &B)
An information struct used to provide DenseMap with the various necessary components for a given valu...
A MapVector that performs no allocations if smaller than a certain size.