Values.push_back(std::move(Val));
}
- /// \brief Attempt to merge this DebugLocEntry with Next and return
- /// true if the merge was successful. Entries can be merged if they
- /// share the same Loc/Constant and if Next immediately follows this
- /// Entry.
- bool Merge(const DebugLocEntry &Next) {
- // If this and Next are describing different pieces of the same
- // variable, merge them by appending next's values to the current
- // list of values.
+ /// \brief If this and Next are describing different pieces of the same
+ // variable, merge them by appending Next's values to the current
+ // list of values.
+ // Return true if the merge was successful.
+ bool MergeValues(const DebugLocEntry &Next) {
if (Begin == Next.Begin && Values.size() > 0 && Next.Values.size() > 0) {
DIVariable Var(Values[0].Variable);
DIVariable NextVar(Next.Values[0].Variable);
return true;
}
}
+ return false;
+ }
+
+ /// \brief Attempt to merge this DebugLocEntry with Next and return
+ /// true if the merge was successful. Entries can be merged if they
+ /// share the same Loc/Constant and if Next immediately follows this
+ /// 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;
auto Value = getDebugLocValue(Begin);
DebugLocEntry Loc(StartLabel, EndLabel, Value);
- if (DebugLoc.empty() || !DebugLoc.back().Merge(Loc)) {
- // Add all values from still valid non-overlapping pieces.
+ bool couldMerge = false;
+
+ // If this is a piece, it may belong to the current DebugLocEntry.
+ if (DIVar.isVariablePiece()) {
+ // Add this value to the list of open ranges.
+ OpenRanges.push_back(std::make_pair(DIVar, Value));
+
+ // Attempt to add the piece to the last entry.
+ if (!DebugLoc.empty())
+ if (DebugLoc.back().MergeValues(Loc))
+ couldMerge = true;
+ }
+
+ if (!couldMerge) {
+ // Need to add a new DebugLocEntry. Add all values from still
+ // valid non-overlapping pieces.
for (auto Range : OpenRanges)
Loc.addValue(Range.second);
DebugLoc.push_back(std::move(Loc));
}
- // Add this value to the list of open ranges.
- if (DIVar.isVariablePiece())
- OpenRanges.push_back(std::make_pair(DIVar, Value));
+
+ // Attempt to coalesce the ranges of two otherwise identical
+ // DebugLocEntries.
+ auto CurEntry = DebugLoc.rbegin();
+ auto PrevEntry = std::next(CurEntry);
+ if (PrevEntry != DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry))
+ DebugLoc.pop_back();
DEBUG(dbgs() << "Values:\n";
- for (auto Value : DebugLoc.back().getValues())
+ for (auto Value : CurEntry->getValues())
Value.getVariable()->dump();
dbgs() << "-----\n");
}