9#ifndef LLVM_LIB_CODEGEN_LIVEDEBUGVALUES_INSTRREFBASEDLDV_H
10#define LLVM_LIB_CODEGEN_LIVEDEBUGVALUES_INSTRREFBASEDLDV_H
39using VarAndLoc = std::pair<DebugVariable, const DILocation *>;
52 auto It = VarToIdx.
find(Var);
65 return ItPair.first->second;
86 LocIdx() : Location(UINT_MAX) {}
89#define NUM_LOC_BITS 24
114 return Location <
Other.Location;
125 std::make_pair(
Other.SpillBase,
Other.SpillOffset);
130 std::make_tuple(
Other.SpillBase,
Other.SpillOffset.getFixed(),
131 Other.SpillOffset.getScalable());
157 static_assert(
sizeof(u) == 8,
"Badly packed ValueIDNum?");
165 u.s = {
Block, Inst, Loc};
175 bool isPHI()
const {
return u.s.InstNo == 0; }
190 return u.Value ==
Other.u.Value;
195 std::string
asString(
const std::string &mlocname)
const {
196 return Twine(
"Value{bb: ")
252 Storage.reserve(NumBBs);
253 for (
int i = 0; i != NumBBs; ++i)
260 return (*
this)[
MBB.getNumber()];
266 auto &TablePtr = Storage[MBBNum];
267 assert(TablePtr &&
"Trying to access a deleted table");
276 return Storage[
MBB.getNumber()] !=
nullptr;
281 Storage[
MBB.getNumber()].reset();
307 return !(*
this ==
Other);
321 assert(
MI.getDebugExpression()->getNumLocationOperands() == 0 ||
322 MI.isDebugValueList() ||
MI.isUndefDebugValue());
339 return !(*
this ==
Other);
423 static_assert(
sizeof(
DbgOpID) == 4,
"DbgOpID should fit within 4 bytes.");
465 return insertConstOp(
Op.MO);
466 return insertValueOp(
Op.ID);
474 return DbgOp(ConstOps[
ID.getIndex()]);
475 return DbgOp(ValueOps[
ID.getIndex()]);
487 auto ExistingIt = ConstOpToID.
find(MO);
488 if (ExistingIt != ConstOpToID.
end())
489 return ExistingIt->second;
491 ConstOpToID.
insert(std::make_pair(MO,
ID));
496 auto ExistingIt = ValueOpToID.
find(VID);
497 if (ExistingIt != ValueOpToID.
end())
498 return ExistingIt->second;
500 ValueOpToID.
insert(std::make_pair(VID,
ID));
548 static_assert(
sizeof(
DbgValue) <= 64,
549 "DbgValue should fit within 64 bytes.");
555#define DEBUG_TYPE "LiveDebugValues"
557 LLVM_DEBUG(
dbgs() <<
"Found DbgValue with more than maximum allowed "
563 this->DbgOps[
Idx] = DbgOps[
Idx];
575 "Empty DbgValue constructor must pass in Undef kind");
611 return DbgOps[
Index];
620 "Incorrect number of Debug Operands for this DbgValue.");
621 OpCount = NewIDs.
size();
623 DbgOps[
Idx] = NewIDs[
Idx];
789 return !(*
this ==
Other);
818 unsigned SlotNo = Spill.id() - 1;
829 unsigned SlotNo = Spill.id() - 1;
861 Location.Value = {
CurBB, 0, Location.Idx};
871 Location.Value = Locs[Location.Idx.asU64()];
916 if (
Index.isIllegal())
924 return !
Index.isIllegal();
1034 std::pair<const DILocalVariable *, DIExpression::FragmentInfo>;
1071 MI.getDebugLoc()->getInlinedAt());
1079 auto Result =
Vars.insert(std::make_pair(VarID, Rec));
1081 Result.first->second = Rec;
1082 Scopes[VarID] =
MI.getDebugLoc().get();
1094 for (
auto FragmentInfo : Overlaps->second) {
1098 std::optional<DIExpression::FragmentInfo> OptFragmentInfo = FragmentInfo;
1100 OptFragmentInfo = std::nullopt;
1109 auto Result =
Vars.insert(std::make_pair(OverlappedID, Rec));
1111 Result.first->second = Rec;
1112 Scopes[OverlappedID] = Loc;
1125 friend class ::InstrRefLDVTest;
1146 using InValueT = std::pair<MachineBasicBlock *, DbgValue *>;
1184 unsigned CurBB = -1;
1209 using InstAndNum = std::pair<const MachineInstr *, unsigned>;
1213 std::map<uint64_t, InstAndNum> DebugInstrNumToInstr;
1216 class DebugPHIRecord {
1224 std::optional<ValueIDNum> ValueRead;
1227 std::optional<LocIdx> ReadLoc;
1229 operator unsigned()
const {
return InstrNum; }
1259 bool AdjustsStackInCalls =
false;
1267 std::optional<SpillLocationNo> isSpillInstruction(
const MachineInstr &
MI,
1281 std::optional<SpillLocationNo> isRestoreInstruction(
const MachineInstr &
MI,
1287 std::optional<SpillLocationNo>
1293 std::optional<ValueIDNum> getValueForInstrRef(
unsigned InstNo,
unsigned OpNo,
1385 void placePHIsForSingleVarDefinition(
1436 void buildVLocValueMap(
const DILocation *DILoc,
1464 std::optional<ValueIDNum> pickOperandPHILoc(
1471 bool emitTransfers();
1502 unsigned InputDbgValLimit)
override;
1518 if (!
MI.hasOneMemOperand())
1520 auto *MemOperand = *
MI.memoperands_begin();
1521 return MemOperand->isStore() &&
1522 MemOperand->getPseudoValue() &&
1524 && !MemOperand->getPseudoValue()->isAliased(MFI);
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< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
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)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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 MachineBasicBlock *, DbgValue * > LiveIdxT
Live in/out structure for the variable values: a per-block map of variables to their values.
DenseMap< const LexicalScope *, const DILocation * > ScopeToDILocT
Mapping from lexical scopes to a DILocation in that scope.
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.
InstrRefBasedLDV()
Default construct and initialize the pass.
DenseMap< const DILocalVariable *, SmallSet< FragmentInfo, 4 > > VarToFragments
std::optional< DIExpression::FragmentInfo > OptFragmentInfo
bool hasFoldedStackStore(const MachineInstr &MI)
bool isCalleeSaved(LocIdx L) const
DenseMap< const LexicalScope *, SmallPtrSet< MachineBasicBlock *, 4 > > ScopeToAssignBlocksT
Mapping from lexical scopes to blocks where variables in that scope are assigned.
bool isCalleeSavedReg(Register R) const
LLVM_DUMP_METHOD void dump_mloc_transfer(const MLocTransferMap &mloc_transfer) const
DenseMap< const LexicalScope *, SmallSet< DebugVariableID, 4 > > ScopeToVarsT
Mapping from lexical scopes to variables in that scope.
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 MakeTombstoneLoc()
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?
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.
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()
LocIdx trackRegister(unsigned ID)
Create a LocIdx for an untracked register ID.
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
void defVar(const MachineInstr &MI, const DbgValueProperties &Properties, const SmallVectorImpl< DbgOpID > &DebugOps)
MapVector< DebugVariableID, DbgValue > Vars
Map DebugVariable to the latest Value it's defined to have.
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)
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 ValueIDNum EmptyValue
ValueIDNum(uint64_t Block, uint64_t Inst, LocIdx Loc)
struct LiveDebugValues::ValueIDNum::@458::@459 s
bool operator!=(const ValueIDNum &Other) const
static ValueIDNum TombstoneValue
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...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
DbgVariableFragmentInfo FragmentInfo
static 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...
uint64_t getNumLocationOperands() const
Return the number of unique location operands referred to (via DW_OP_LLVM_arg) in this expression; th...
This class represents an Operation in the Expression.
Identifies a unique instance of a variable.
static bool isDefaultFragment(const FragmentInfo F)
const DILocation * getInlinedAt() const
FragmentInfo getFragmentOrDefault() const
const DILocalVariable * getVariable() const
iterator find(const_arg_type_t< KeyT > Val)
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
StorageT::size_type size() const
LexicalScopes - This class provides interface to collect and use lexical scoping information from mac...
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.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
This class implements a map that also provides access to all stored values in a deterministic order.
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.
static StackOffset getScalable(int64_t Scalable)
static StackOffset getFixed(int64_t Fixed)
StringRef - 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...
Target-Independent Code Generator Pass Configuration Options.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
TypeSize getRegSizeInBits(const TargetRegisterClass &RC) const
Return the size in bits of a register from class RC.
unsigned getSubRegIdxSize(unsigned Idx) const
Get the size of the bit range covered by a sub-register index.
unsigned getSubRegIdxOffset(unsigned Idx) const
Get the offset of the bit range covered by a sub-register index.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
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...
LLVM Value Representation.
A range adaptor for a pair of iterators.
std::pair< DebugVariable, const DILocation * > VarAndLoc
std::pair< const DILocalVariable *, DIExpression::FragmentInfo > FragmentOfVar
Types for recording sets of variable fragments that overlap.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
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.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&... Ranges)
Concatenated range across two or more ranges.
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)
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.
A DbgOp whose ID (if any) has resolved to an actual location, LocIdx.
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 LocIdx getTombstoneKey()
static bool isEqual(const LocIdx &A, const LocIdx &B)
static unsigned getHashValue(const LocIdx &Loc)
static LocIdx getEmptyKey()
static ValueIDNum getTombstoneKey()
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...