Go to the documentation of this file.
34 #define DEBUG_TYPE "dwarfdebug"
48 if (
MI.getDebugExpression()->isEntryValue())
52 return MI.getDebugOperand(0).isReg() ?
MI.getDebugOperand(0).getReg()
73 unsigned Position = 0;
76 InstNumberMap[&
MI] =
MI.isMetaInstruction() ? Position : ++Position;
81 assert(A->getParent() &&
B->getParent() &&
"Operands must have a parent");
82 assert(A->getMF() ==
B->getMF() &&
83 "Operands must be in the same MachineFunction");
84 return InstNumberMap.lookup(A) < InstNumberMap.lookup(
B);
92 assert(
MI.isDebugValue() &&
"not a DBG_VALUE");
93 auto &
Entries = VarEntries[Var];
96 Entries.back().getInstr()->isIdenticalTo(
MI)) {
98 <<
"\t" <<
Entries.back().getInstr() <<
"\t" <<
MI
109 auto &
Entries = VarEntries[Var];
134 for (
auto RangesI = Ranges.
begin(), RangesE = Ranges.
end();
135 RangesI != RangesE; ++RangesI) {
136 if (EndMI && Ordering.
isBefore(EndMI, RangesI->first))
138 if (EndMI && !Ordering.
isBefore(RangesI->second, EndMI))
140 if (Ordering.
isBefore(StartMI, RangesI->second))
158 for (
auto &
Record : VarEntries) {
159 auto &HistoryMapEntries =
Record.second;
160 if (HistoryMapEntries.empty())
167 if (
const DILocation *InlinedAt = Entity.second) {
179 (
Scope->getScopeNode() ==
Scope->getScopeNode()->getSubprogram()) &&
191 ReferenceCount.
assign(HistoryMapEntries.size(), 0);
196 for (
auto EI = HistoryMapEntries.begin(), EE = HistoryMapEntries.end();
197 EI != EE; ++EI, ++StartIndex) {
199 if (!EI->isDbgValue())
206 ReferenceCount[EndIndex] += 1;
211 if (ReferenceCount[StartIndex] > 0)
216 ? HistoryMapEntries[EndIndex].getInstr()
220 if (
auto R =
intersects(StartMI, EndMI, ScopeRanges, Ordering)) {
232 ReferenceCount[EndIndex] -= 1;
241 for (
size_t i = 0;
i < HistoryMapEntries.size(); ++
i)
242 if (ReferenceCount[
i] <= 0 && HistoryMapEntries[
i].isClobber())
250 Offsets.assign(HistoryMapEntries.size(), 0);
251 size_t CurOffset = 0;
252 auto ToRemoveItr =
ToRemove.begin();
253 for (
size_t EntryIdx = *ToRemoveItr; EntryIdx < HistoryMapEntries.size();
256 if (ToRemoveItr !=
ToRemove.end() && *ToRemoveItr == EntryIdx) {
265 for (
auto &
Entry : HistoryMapEntries)
271 for (
auto Itr =
ToRemove.rbegin(), End =
ToRemove.rend(); Itr != End; ++Itr)
272 HistoryMapEntries.erase(HistoryMapEntries.begin() + *Itr);
284 if (
MI->getOperand(0).isReg() &&
MI->getOperand(0).getReg() == 0)
294 assert(
MI.isDebugLabel() &&
"not a DBG_LABEL");
295 LabelInstr[Label] = &
MI;
302 using RegDescribedVarsMap = std::map<unsigned, SmallVector<InlinedEntity, 1>>;
308 using DbgValueEntriesMap = std::map<InlinedEntity, SmallSet<EntryIndex, 1>>;
315 const auto &
I = RegVars.find(RegNo);
316 assert(RegNo != 0U &&
I != RegVars.end());
317 auto &VarSet =
I->second;
319 assert(VarPos != VarSet.end());
320 VarSet.erase(VarPos);
330 auto &VarSet = RegVars[RegNo];
332 VarSet.push_back(Var);
339 DbgValueEntriesMap &LiveEntries,
345 for (
auto Index : LiveEntries[Var]) {
347 assert(Entry.isDbgValue() &&
"Not a DBG_VALUE in LiveEntries");
349 IndicesToErase.push_back(
Index);
350 Entry.endEntry(ClobberIndex);
355 for (
auto Index : IndicesToErase)
356 LiveEntries[Var].erase(
Index);
361 RegDescribedVarsMap &RegVars,
362 DbgValueEntriesMap &LiveEntries,
372 for (
auto Index : LiveEntries[Var]) {
374 assert(Entry.isDbgValue() &&
"Not a DBG_VALUE in LiveEntries");
378 IndicesToErase.push_back(
Index);
379 Entry.endEntry(NewIndex);
382 TrackedRegs[
Reg] |= !Overlaps;
388 if (!TrackedRegs.
count(NewReg))
390 LiveEntries[Var].insert(NewIndex);
391 TrackedRegs[NewReg] =
true;
395 for (
auto I : TrackedRegs)
400 for (
auto Index : IndicesToErase)
401 LiveEntries[Var].erase(
Index);
402 LiveEntries[Var].insert(NewIndex);
409 RegDescribedVarsMap::iterator
I,
411 DbgValueEntriesMap &LiveEntries,
415 for (
const auto &Var :
I->second)
424 DbgValueEntriesMap &LiveEntries,
426 const auto &
I = RegVars.find(RegNo);
427 if (
I == RegVars.end())
439 RegDescribedVarsMap RegVars;
440 DbgValueEntriesMap LiveEntries;
441 for (
const auto &
MBB : *MF) {
442 for (
const auto &
MI :
MBB) {
443 if (
MI.isDebugValue()) {
444 assert(
MI.getNumOperands() > 1 &&
"Invalid DBG_VALUE instruction!");
450 "Expected inlined-at fields to agree");
454 }
else if (
MI.isDebugLabel()) {
455 assert(
MI.getNumOperands() == 1 &&
"Invalid DBG_LABEL instruction!");
456 const DILabel *RawLabel =
MI.getDebugLabel();
458 "Expected inlined-at fields to agree");
468 if (
MI.isMetaInstruction())
474 if (MO.isReg() && MO.isDef() && MO.getReg()) {
477 if (
MI.isCall() && MO.getReg() == SP)
488 else if (MO.getReg() != FrameReg ||
495 }
else if (MO.isRegMask()) {
500 for (
auto It : RegVars) {
501 unsigned int Reg = It.first;
503 MO.clobbersPhysReg(
Reg))
504 RegsToClobber.push_back(
Reg);
507 for (
unsigned Reg : RegsToClobber) {
519 for (
auto &Pair : LiveEntries) {
520 if (Pair.second.empty())
540 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
542 dbgs() <<
"DbgValueHistoryMap:\n";
543 for (
const auto &VarRangePair : *
this) {
553 dbgs() << Location->getFilename() <<
":" << Location->getLine() <<
":"
554 << Location->getColumn();
556 dbgs() <<
"<unknown location>";
561 const auto &
Entry =
E.value();
562 dbgs() <<
" Entry[" <<
E.index() <<
"]: ";
564 dbgs() <<
"Debug value\n";
566 dbgs() <<
"Clobber\n";
570 dbgs() <<
" - Valid until end of function\n";
static void clobberRegEntries(InlinedEntity Var, unsigned RegNo, const MachineInstr &ClobberingInstr, DbgValueEntriesMap &LiveEntries, DbgValueHistoryMap &HistMap)
Create a clobbering entry and end all open debug value entries for Var that are described by RegNo us...
void initialize(const MachineFunction &MF)
Register getStackPointerRegisterToSaveRestore() const
If a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save...
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This class represents lattice values for constants.
static Register isDescribedByReg(const MachineInstr &MI)
For each inlined instance of a source-level label, keep the corresponding DBG_LABEL instruction.
Specifies a change in a variable's debug value history.
LexicalScope - This class is used to track scope information.
detail::enumerator< R > enumerate(R &&TheRange)
Given an input range, returns a new range whose values are are pair (A,B) such that A is the 0-based ...
ReachingDefAnalysis InstSet & ToRemove
size_t EntryIndex
Index in the entry vector.
static Optional< ArrayRef< InsnRange >::iterator > intersects(const MachineInstr *StartMI, const MachineInstr *EndMI, const ArrayRef< InsnRange > &Ranges, const InstructionOrdering &Ordering)
Check if the instruction range [StartMI, EndMI] intersects any instruction range in Ranges.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
llvm::DenseMapBase< SmallDenseMap< KeyT, ValueT, 4, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::count size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
unsigned const TargetRegisterInfo * TRI
bool startDbgValue(InlinedEntity Var, const MachineInstr &MI, EntryIndex &NewIndex)
EntryIndex getEndIndex() const
bool isValidLocationForIntrinsic(const DILocation *DL) const
Check that a location is valid for this label.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
const MachineInstr * getInstr() const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
void calculateDbgEntityHistory(const MachineFunction *MF, const TargetRegisterInfo *TRI, DbgValueHistoryMap &DbgValues, DbgLabelInstrMap &DbgLabels)
bool isBefore(const MachineInstr *A, const MachineInstr *B) const
Check if instruction A comes before B, where A and B both belong to the MachineFunction passed to ini...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
MachineOperand class - Representation of each machine instruction operand.
std::pair< const DINode *, const DILocation * > InlinedEntity
bool isValidLocationForIntrinsic(const DILocation *DL) const
Check that a location is valid for this variable.
bool hasNonEmptyLocation(const Entries &Entries) const
Test whether a vector of entries features any non-empty locations.
Record instruction ordering so we can query their relative positions within a function.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
EntryIndex startClobber(InlinedEntity Var, const MachineInstr &MI)
LLVM_DUMP_METHOD void dump() const
static void handleNewDebugValue(InlinedEntity Var, const MachineInstr &DV, RegDescribedVarsMap &RegVars, DbgValueEntriesMap &LiveEntries, DbgValueHistoryMap &HistMap)
Add a new debug value for Var. Closes all overlapping debug values.
const DIExpression * getDebugExpression() const
Return the complex address expression referenced by this DBG_VALUE instruction.
Representation of each machine instruction.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
virtual Register getFrameRegister(const MachineFunction &MF) const =0
Debug information queries.
static const EntryIndex NoEntry
Special value to indicate that an entry is valid until the end of the function.
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void endEntry(EntryIndex EndIndex)
Entry & getEntry(InlinedEntity Var, EntryIndex Index)
void trimLocationRanges(const MachineFunction &MF, LexicalScopes &LScopes, const InstructionOrdering &Ordering)
Drop location ranges which exist entirely outside each variable's scope.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
Wrapper class representing virtual and physical registers.
For each user variable, keep a list of instruction ranges where this variable is accessible.
void addInstr(InlinedEntity Label, const MachineInstr &MI)
void assign(size_type NumElts, ValueParamT Elt)
LexicalScope * findInlinedScope(const DILocalScope *N, const DILocation *IA)
findInlinedScope - Find an inlined scope for the given scope/inlined-at.
LexicalScope * findLexicalScope(const DILocation *DL)
findLexicalScope - Find lexical scope, either regular or inlined, for the given DebugLoc.
void sort(IteratorTy Start, IteratorTy End)
std::pair< const DINode *, const DILocation * > InlinedEntity
virtual const TargetLowering * getTargetLowering() const
static void dropRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo, InlinedEntity Var)
static void addRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo, InlinedEntity Var)
LexicalScopes - This class provides interface to collect and use lexical scoping information from mac...
static void clobberRegisterUses(RegDescribedVarsMap &RegVars, RegDescribedVarsMap::iterator I, DbgValueHistoryMap &HistMap, DbgValueEntriesMap &LiveEntries, const MachineInstr &ClobberingInstr)
MCRegAliasIterator enumerates all registers aliasing Reg.
reference emplace_back(ArgTypes &&... Args)
static bool fragmentsOverlap(const FragmentInfo &A, const FragmentInfo &B)
Check if fragments overlap between a pair of FragmentInfos.