Skip to content

Commit 269a9af

Browse files
committed
[DebugInfo] Make DebugVariable class available in DebugInfoMetadata
The DebugVariable class is a class declared in LiveDebugValues.cpp which is used to uniquely identify a single variable, using its source variable, inline location, and fragment info to do so. This patch moves this class into DebugInfoMetadata.h, making it available in a much broader scope.
1 parent 2dd82a1 commit 269a9af

File tree

4 files changed

+150
-111
lines changed

4 files changed

+150
-111
lines changed

llvm/include/llvm/IR/DebugInfoMetadata.h

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3253,6 +3253,89 @@ class DIMacroFile : public DIMacroNode {
32533253
}
32543254
};
32553255

3256+
/// Identifies a unique instance of a variable.
3257+
///
3258+
/// Storage for identifying a potentially inlined instance of a variable,
3259+
/// or a fragment thereof. This guarantees that exactly one variable instance
3260+
/// may be identified by this class, even when that variable is a fragment of
3261+
/// an aggregate variable and/or there is another inlined instance of the same
3262+
/// source code variable nearby.
3263+
/// This class does not necessarily uniquely identify that variable: it is
3264+
/// possible that a DebugVariable with different parameters may point to the
3265+
/// same variable instance, but not that one DebugVariable points to multiple
3266+
/// variable instances.
3267+
class DebugVariable {
3268+
using FragmentInfo = DIExpression::FragmentInfo;
3269+
3270+
const DILocalVariable *Variable;
3271+
Optional<FragmentInfo> Fragment;
3272+
const DILocation *InlinedAt;
3273+
3274+
/// Fragment that will overlap all other fragments. Used as default when
3275+
/// caller demands a fragment.
3276+
static const FragmentInfo DefaultFragment;
3277+
3278+
public:
3279+
DebugVariable(const DILocalVariable *Var, Optional<FragmentInfo> FragmentInfo,
3280+
const DILocation *InlinedAt)
3281+
: Variable(Var), Fragment(FragmentInfo), InlinedAt(InlinedAt) {}
3282+
3283+
DebugVariable(const DILocalVariable *Var, const DIExpression *DIExpr,
3284+
const DILocation *InlinedAt)
3285+
: Variable(Var),
3286+
Fragment(DIExpr ? DIExpr->getFragmentInfo() : NoneType()),
3287+
InlinedAt(InlinedAt) {}
3288+
3289+
const DILocalVariable *getVariable() const { return Variable; }
3290+
const Optional<FragmentInfo> getFragment() const { return Fragment; }
3291+
const DILocation *getInlinedAt() const { return InlinedAt; }
3292+
3293+
const FragmentInfo getFragmentOrDefault() const {
3294+
return Fragment.getValueOr(DefaultFragment);
3295+
}
3296+
3297+
static bool isDefaultFragment(const FragmentInfo F) {
3298+
return F == DefaultFragment;
3299+
}
3300+
3301+
bool operator==(const DebugVariable &Other) const {
3302+
return std::tie(Variable, Fragment, InlinedAt) ==
3303+
std::tie(Other.Variable, Other.Fragment, Other.InlinedAt);
3304+
}
3305+
3306+
bool operator<(const DebugVariable &Other) const {
3307+
return std::tie(Variable, Fragment, InlinedAt) <
3308+
std::tie(Other.Variable, Other.Fragment, Other.InlinedAt);
3309+
}
3310+
};
3311+
3312+
template <> struct DenseMapInfo<DebugVariable> {
3313+
using FragmentInfo = DIExpression::FragmentInfo;
3314+
3315+
/// Empty key: no key should be generated that has no DILocalVariable.
3316+
static inline DebugVariable getEmptyKey() {
3317+
return DebugVariable(nullptr, NoneType(), nullptr);
3318+
}
3319+
3320+
/// Difference in tombstone is that the Optional is meaningful.
3321+
static inline DebugVariable getTombstoneKey() {
3322+
return DebugVariable(nullptr, {{0, 0}}, nullptr);
3323+
}
3324+
3325+
static unsigned getHashValue(const DebugVariable &D) {
3326+
unsigned HV = 0;
3327+
const Optional<FragmentInfo> Fragment = D.getFragment();
3328+
if (Fragment)
3329+
HV = DenseMapInfo<FragmentInfo>::getHashValue(*Fragment);
3330+
3331+
return hash_combine(D.getVariable(), HV, D.getInlinedAt());
3332+
}
3333+
3334+
static bool isEqual(const DebugVariable &A, const DebugVariable &B) {
3335+
return A == B;
3336+
}
3337+
};
3338+
32563339
} // end namespace llvm
32573340

32583341
#undef DEFINE_MDNODE_GET_UNPACK_IMPL

llvm/lib/CodeGen/LiveDebugValues.cpp

Lines changed: 26 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -144,60 +144,6 @@ class LiveDebugValues : public MachineFunctionPass {
144144
using FragmentInfo = DIExpression::FragmentInfo;
145145
using OptFragmentInfo = Optional<DIExpression::FragmentInfo>;
146146

147-
/// Storage for identifying a potentially inlined instance of a variable,
148-
/// or a fragment thereof.
149-
class DebugVariable {
150-
const DILocalVariable *Variable;
151-
OptFragmentInfo Fragment;
152-
const DILocation *InlinedAt;
153-
154-
/// Fragment that will overlap all other fragments. Used as default when
155-
/// caller demands a fragment.
156-
static const FragmentInfo DefaultFragment;
157-
158-
public:
159-
DebugVariable(const DILocalVariable *Var, OptFragmentInfo &&FragmentInfo,
160-
const DILocation *InlinedAt)
161-
: Variable(Var), Fragment(FragmentInfo), InlinedAt(InlinedAt) {}
162-
163-
DebugVariable(const DILocalVariable *Var, OptFragmentInfo &FragmentInfo,
164-
const DILocation *InlinedAt)
165-
: Variable(Var), Fragment(FragmentInfo), InlinedAt(InlinedAt) {}
166-
167-
DebugVariable(const DILocalVariable *Var, const DIExpression *DIExpr,
168-
const DILocation *InlinedAt)
169-
: DebugVariable(Var, DIExpr->getFragmentInfo(), InlinedAt) {}
170-
171-
DebugVariable(const MachineInstr &MI)
172-
: DebugVariable(MI.getDebugVariable(),
173-
MI.getDebugExpression()->getFragmentInfo(),
174-
MI.getDebugLoc()->getInlinedAt()) {}
175-
176-
const DILocalVariable *getVar() const { return Variable; }
177-
const OptFragmentInfo &getFragment() const { return Fragment; }
178-
const DILocation *getInlinedAt() const { return InlinedAt; }
179-
180-
const FragmentInfo getFragmentDefault() const {
181-
return Fragment.getValueOr(DefaultFragment);
182-
}
183-
184-
static bool isFragmentDefault(FragmentInfo &F) {
185-
return F == DefaultFragment;
186-
}
187-
188-
bool operator==(const DebugVariable &Other) const {
189-
return std::tie(Variable, Fragment, InlinedAt) ==
190-
std::tie(Other.Variable, Other.Fragment, Other.InlinedAt);
191-
}
192-
193-
bool operator<(const DebugVariable &Other) const {
194-
return std::tie(Variable, Fragment, InlinedAt) <
195-
std::tie(Other.Variable, Other.Fragment, Other.InlinedAt);
196-
}
197-
};
198-
199-
friend struct llvm::DenseMapInfo<DebugVariable>;
200-
201147
/// A pair of debug variable and value location.
202148
struct VarLoc {
203149
// The location at which a spilled variable resides. It consists of a
@@ -241,8 +187,9 @@ class LiveDebugValues : public MachineFunctionPass {
241187
} Loc;
242188

243189
VarLoc(const MachineInstr &MI, LexicalScopes &LS)
244-
: Var(MI), Expr(MI.getDebugExpression()), MI(MI),
245-
UVS(MI.getDebugLoc(), LS) {
190+
: Var(MI.getDebugVariable(), MI.getDebugExpression(),
191+
MI.getDebugLoc()->getInlinedAt()),
192+
Expr(MI.getDebugExpression()), MI(MI), UVS(MI.getDebugLoc(), LS) {
246193
static_assert((sizeof(Loc) == sizeof(uint64_t)),
247194
"hash does not cover all members of Loc");
248195
assert(MI.isDebugValue() && "not a DBG_VALUE");
@@ -370,7 +317,8 @@ class LiveDebugValues : public MachineFunctionPass {
370317
llvm_unreachable("Invalid VarLoc in dump method");
371318
}
372319

373-
dbgs() << ", \"" << Var.getVar()->getName() << "\", " << *Expr << ", ";
320+
dbgs() << ", \"" << Var.getVariable()->getName() << "\", " << *Expr
321+
<< ", ";
374322
if (Var.getInlinedAt())
375323
dbgs() << "!" << Var.getInlinedAt()->getMetadataID() << ")\n";
376324
else
@@ -559,46 +507,10 @@ class LiveDebugValues : public MachineFunctionPass {
559507

560508
} // end anonymous namespace
561509

562-
namespace llvm {
563-
564-
template <> struct DenseMapInfo<LiveDebugValues::DebugVariable> {
565-
using DV = LiveDebugValues::DebugVariable;
566-
using OptFragmentInfo = LiveDebugValues::OptFragmentInfo;
567-
using FragmentInfo = LiveDebugValues::FragmentInfo;
568-
569-
// Empty key: no key should be generated that has no DILocalVariable.
570-
static inline DV getEmptyKey() {
571-
return DV(nullptr, OptFragmentInfo(), nullptr);
572-
}
573-
574-
// Difference in tombstone is that the Optional is meaningful
575-
static inline DV getTombstoneKey() {
576-
return DV(nullptr, OptFragmentInfo({0, 0}), nullptr);
577-
}
578-
579-
static unsigned getHashValue(const DV &D) {
580-
unsigned HV = 0;
581-
const OptFragmentInfo &Fragment = D.getFragment();
582-
if (Fragment)
583-
HV = DenseMapInfo<FragmentInfo>::getHashValue(*Fragment);
584-
585-
return hash_combine(D.getVar(), HV, D.getInlinedAt());
586-
}
587-
588-
static bool isEqual(const DV &A, const DV &B) { return A == B; }
589-
};
590-
591-
} // namespace llvm
592-
593510
//===----------------------------------------------------------------------===//
594511
// Implementation
595512
//===----------------------------------------------------------------------===//
596513

597-
const DIExpression::FragmentInfo
598-
LiveDebugValues::DebugVariable::DefaultFragment = {
599-
std::numeric_limits<uint64_t>::max(),
600-
std::numeric_limits<uint64_t>::min()};
601-
602514
char LiveDebugValues::ID = 0;
603515

604516
char &llvm::LiveDebugValuesID = LiveDebugValues::ID;
@@ -636,17 +548,17 @@ void LiveDebugValues::OpenRangesSet::erase(DebugVariable Var) {
636548

637549
// Extract the fragment. Interpret an empty fragment as one that covers all
638550
// possible bits.
639-
FragmentInfo ThisFragment = Var.getFragmentDefault();
551+
FragmentInfo ThisFragment = Var.getFragmentOrDefault();
640552

641553
// There may be fragments that overlap the designated fragment. Look them up
642554
// in the pre-computed overlap map, and erase them too.
643-
auto MapIt = OverlappingFragments.find({Var.getVar(), ThisFragment});
555+
auto MapIt = OverlappingFragments.find({Var.getVariable(), ThisFragment});
644556
if (MapIt != OverlappingFragments.end()) {
645557
for (auto Fragment : MapIt->second) {
646558
LiveDebugValues::OptFragmentInfo FragmentHolder;
647-
if (!DebugVariable::isFragmentDefault(Fragment))
559+
if (!DebugVariable::isDefaultFragment(Fragment))
648560
FragmentHolder = LiveDebugValues::OptFragmentInfo(Fragment);
649-
DoErase({Var.getVar(), FragmentHolder, Var.getInlinedAt()});
561+
DoErase({Var.getVariable(), FragmentHolder, Var.getInlinedAt()});
650562
}
651563
}
652564
}
@@ -669,7 +581,7 @@ void LiveDebugValues::printVarLocInMBB(const MachineFunction &MF,
669581
Out << "MBB: " << BB.getNumber() << ":\n";
670582
for (unsigned VLL : L) {
671583
const VarLoc &VL = VarLocIDs[VLL];
672-
Out << " Var: " << VL.Var.getVar()->getName();
584+
Out << " Var: " << VL.Var.getVariable()->getName();
673585
Out << " MI: ";
674586
VL.dump(TRI, Out);
675587
}
@@ -735,7 +647,7 @@ void LiveDebugValues::emitEntryValues(MachineInstr &MI,
735647
DebugParamMap &DebugEntryVals,
736648
SparseBitVector<> &KillSet) {
737649
for (unsigned ID : KillSet) {
738-
if (!VarLocIDs[ID].Var.getVar()->isParameter())
650+
if (!VarLocIDs[ID].Var.getVariable()->isParameter())
739651
continue;
740652

741653
const MachineInstr *CurrDebugInstr = &VarLocIDs[ID].MI;
@@ -773,7 +685,9 @@ void LiveDebugValues::insertTransferDebugPair(
773685
unsigned LocId = VarLocIDs.insert(VL);
774686

775687
// Close this variable's previous location range.
776-
DebugVariable V(*DebugInstr);
688+
DebugVariable V(DebugInstr->getDebugVariable(),
689+
DebugInstr->getDebugExpression(),
690+
DebugInstr->getDebugLoc()->getInlinedAt());
777691
OpenRanges.erase(V);
778692

779693
// Record the new location as an open range, and a postponed transfer
@@ -1005,12 +919,12 @@ void LiveDebugValues::transferSpillOrRestoreInst(MachineInstr &MI,
1005919
if (TKind == TransferKind::TransferSpill &&
1006920
VarLocIDs[ID].isDescribedByReg() == Reg) {
1007921
LLVM_DEBUG(dbgs() << "Spilling Register " << printReg(Reg, TRI) << '('
1008-
<< VarLocIDs[ID].Var.getVar()->getName() << ")\n");
922+
<< VarLocIDs[ID].Var.getVariable()->getName() << ")\n");
1009923
} else if (TKind == TransferKind::TransferRestore &&
1010924
VarLocIDs[ID].Kind == VarLoc::SpillLocKind &&
1011925
VarLocIDs[ID].Loc.SpillLocation == *Loc) {
1012926
LLVM_DEBUG(dbgs() << "Restoring Register " << printReg(Reg, TRI) << '('
1013-
<< VarLocIDs[ID].Var.getVar()->getName() << ")\n");
927+
<< VarLocIDs[ID].Var.getVariable()->getName() << ")\n");
1014928
} else
1015929
continue;
1016930
insertTransferDebugPair(MI, OpenRanges, Transfers, VarLocIDs, ID, TKind,
@@ -1099,26 +1013,27 @@ bool LiveDebugValues::transferTerminator(MachineBasicBlock *CurMBB,
10991013
void LiveDebugValues::accumulateFragmentMap(MachineInstr &MI,
11001014
VarToFragments &SeenFragments,
11011015
OverlapMap &OverlappingFragments) {
1102-
DebugVariable MIVar(MI);
1103-
FragmentInfo ThisFragment = MIVar.getFragmentDefault();
1016+
DebugVariable MIVar(MI.getDebugVariable(), MI.getDebugExpression(),
1017+
MI.getDebugLoc()->getInlinedAt());
1018+
FragmentInfo ThisFragment = MIVar.getFragmentOrDefault();
11041019

11051020
// If this is the first sighting of this variable, then we are guaranteed
11061021
// there are currently no overlapping fragments either. Initialize the set
11071022
// of seen fragments, record no overlaps for the current one, and return.
1108-
auto SeenIt = SeenFragments.find(MIVar.getVar());
1023+
auto SeenIt = SeenFragments.find(MIVar.getVariable());
11091024
if (SeenIt == SeenFragments.end()) {
11101025
SmallSet<FragmentInfo, 4> OneFragment;
11111026
OneFragment.insert(ThisFragment);
1112-
SeenFragments.insert({MIVar.getVar(), OneFragment});
1027+
SeenFragments.insert({MIVar.getVariable(), OneFragment});
11131028

1114-
OverlappingFragments.insert({{MIVar.getVar(), ThisFragment}, {}});
1029+
OverlappingFragments.insert({{MIVar.getVariable(), ThisFragment}, {}});
11151030
return;
11161031
}
11171032

11181033
// If this particular Variable/Fragment pair already exists in the overlap
11191034
// map, it has already been accounted for.
11201035
auto IsInOLapMap =
1121-
OverlappingFragments.insert({{MIVar.getVar(), ThisFragment}, {}});
1036+
OverlappingFragments.insert({{MIVar.getVariable(), ThisFragment}, {}});
11221037
if (!IsInOLapMap.second)
11231038
return;
11241039

@@ -1136,7 +1051,7 @@ void LiveDebugValues::accumulateFragmentMap(MachineInstr &MI,
11361051
// Mark the previously seen fragment as being overlapped by the current
11371052
// one.
11381053
auto ASeenFragmentsOverlaps =
1139-
OverlappingFragments.find({MIVar.getVar(), ASeenFragment});
1054+
OverlappingFragments.find({MIVar.getVariable(), ASeenFragment});
11401055
assert(ASeenFragmentsOverlaps != OverlappingFragments.end() &&
11411056
"Previously seen var fragment has no vector of overlaps");
11421057
ASeenFragmentsOverlaps->second.push_back(ThisFragment);
@@ -1201,7 +1116,7 @@ bool LiveDebugValues::join(
12011116
if (!InLocsT.empty()) {
12021117
for (auto ID : InLocsT)
12031118
dbgs() << " gathered candidate incoming var: "
1204-
<< VarLocIDs[ID].Var.getVar()->getName() << "\n";
1119+
<< VarLocIDs[ID].Var.getVariable()->getName() << "\n";
12051120
}
12061121
});
12071122

@@ -1216,7 +1131,7 @@ bool LiveDebugValues::join(
12161131
if (!VarLocIDs[ID].dominates(MBB)) {
12171132
KillSet.set(ID);
12181133
LLVM_DEBUG({
1219-
auto Name = VarLocIDs[ID].Var.getVar()->getName();
1134+
auto Name = VarLocIDs[ID].Var.getVariable()->getName();
12201135
dbgs() << " killing " << Name << ", it doesn't dominate MBB\n";
12211136
});
12221137
}

llvm/lib/IR/DebugInfoMetadata.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323

2424
using namespace llvm;
2525

26+
const DIExpression::FragmentInfo DebugVariable::DefaultFragment = {
27+
std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint64_t>::min()};
28+
2629
DILocation::DILocation(LLVMContext &C, StorageType Storage, unsigned Line,
2730
unsigned Column, ArrayRef<Metadata *> MDs,
2831
bool ImplicitCode)

0 commit comments

Comments
 (0)