summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h61
1 files changed, 42 insertions, 19 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
index d7ab2091967f..2008aa39ff87 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
@@ -76,6 +76,9 @@ public:
: EntryKind(E_TargetIndexLocation), TIL(Loc) {}
bool isLocation() const { return EntryKind == E_Location; }
+ bool isIndirectLocation() const {
+ return EntryKind == E_Location && Loc.isIndirect();
+ }
bool isTargetIndexLocation() const {
return EntryKind == E_TargetIndexLocation;
}
@@ -116,13 +119,7 @@ class DbgValueLoc {
public:
DbgValueLoc(const DIExpression *Expr, ArrayRef<DbgValueLocEntry> Locs)
: Expression(Expr), ValueLocEntries(Locs.begin(), Locs.end()),
- IsVariadic(true) {
-#ifndef NDEBUG
- // Currently, DBG_VALUE_VAR expressions must use stack_value.
- assert(Expr && Expr->isValid() &&
- is_contained(Locs, dwarf::DW_OP_stack_value));
-#endif
- }
+ IsVariadic(true) {}
DbgValueLoc(const DIExpression *Expr, ArrayRef<DbgValueLocEntry> Locs,
bool IsVariadic)
@@ -133,10 +130,6 @@ public:
!any_of(Locs, [](auto LE) { return LE.isLocation(); }));
if (!IsVariadic) {
assert(ValueLocEntries.size() == 1);
- } else {
- // Currently, DBG_VALUE_VAR expressions must use stack_value.
- assert(Expr && Expr->isValid() &&
- is_contained(Expr->getElements(), dwarf::DW_OP_stack_value));
}
#endif
}
@@ -150,10 +143,31 @@ public:
bool isFragment() const { return getExpression()->isFragment(); }
bool isEntryVal() const { return getExpression()->isEntryValue(); }
bool isVariadic() const { return IsVariadic; }
- const DIExpression *getExpression() const { return Expression; }
- const ArrayRef<DbgValueLocEntry> getLocEntries() const {
- return ValueLocEntries;
+ bool isEquivalent(const DbgValueLoc &Other) const {
+ // Cannot be equivalent with different numbers of entries.
+ if (ValueLocEntries.size() != Other.ValueLocEntries.size())
+ return false;
+ bool ThisIsIndirect =
+ !IsVariadic && ValueLocEntries[0].isIndirectLocation();
+ bool OtherIsIndirect =
+ !Other.IsVariadic && Other.ValueLocEntries[0].isIndirectLocation();
+ // Check equivalence of DIExpressions + Directness together.
+ if (!DIExpression::isEqualExpression(Expression, ThisIsIndirect,
+ Other.Expression, OtherIsIndirect))
+ return false;
+ // Indirectness should have been accounted for in the above check, so just
+ // compare register values directly here.
+ if (ThisIsIndirect || OtherIsIndirect) {
+ DbgValueLocEntry ThisOp = ValueLocEntries[0];
+ DbgValueLocEntry OtherOp = Other.ValueLocEntries[0];
+ return ThisOp.isLocation() && OtherOp.isLocation() &&
+ ThisOp.getLoc().getReg() == OtherOp.getLoc().getReg();
+ }
+ // If neither are indirect, then just compare the loc entries directly.
+ return ValueLocEntries == Other.ValueLocEntries;
}
+ const DIExpression *getExpression() const { return Expression; }
+ ArrayRef<DbgValueLocEntry> getLocEntries() const { return ValueLocEntries; }
friend bool operator==(const DbgValueLoc &, const DbgValueLoc &);
friend bool operator<(const DbgValueLoc &, const DbgValueLoc &);
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
@@ -193,11 +207,15 @@ public:
/// Entry.
bool MergeRanges(const DebugLocEntry &Next) {
// If this and Next are describing the same variable, merge them.
- if ((End == Next.Begin && Values == Next.Values)) {
- End = Next.End;
- return true;
- }
- return false;
+ if (End != Next.Begin)
+ return false;
+ if (Values.size() != Next.Values.size())
+ return false;
+ for (unsigned EntryIdx = 0; EntryIdx < Values.size(); ++EntryIdx)
+ if (!Values[EntryIdx].isEquivalent(Next.Values[EntryIdx]))
+ return false;
+ End = Next.End;
+ return true;
}
const MCSymbol *getBeginSym() const { return Begin; }
@@ -214,6 +232,11 @@ public:
// Sort the pieces by offset.
// Remove any duplicate entries by dropping all but the first.
void sortUniqueValues() {
+ // Values is either 1 item that does not have a fragment, or many items
+ // that all do. No need to sort if the former and also prevents operator<
+ // being called on a non fragment item when _GLIBCXX_DEBUG is defined.
+ if (Values.size() == 1)
+ return;
llvm::sort(Values);
Values.erase(std::unique(Values.begin(), Values.end(),
[](const DbgValueLoc &A, const DbgValueLoc &B) {