Skip to content

Commit 12d4769

Browse files
Revert "[MemProf] Streamline and avoid unnecessary context id duplication (#107918)" (#108652)
This reverts commit 524a028, but manually so that follow on PR108086 / ae5f1a7 is retained (NFC patch to convert tuple to a struct).
1 parent 52b48a7 commit 12d4769

File tree

1 file changed

+34
-58
lines changed

1 file changed

+34
-58
lines changed

llvm/lib/Transforms/IPO/MemProfContextDisambiguation.cpp

Lines changed: 34 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,23 +1479,13 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::updateStackNodes() {
14791479
// of length, and within each length, lexicographically by stack id. The
14801480
// latter is so that we can specially handle calls that have identical stack
14811481
// id sequences (either due to cloning or artificially because of the MIB
1482-
// context pruning). Those with the same Ids are then sorted by function to
1483-
// facilitate efficiently mapping them to the same context node.
1484-
// Because the functions are pointers, to ensure a stable sort first assign
1485-
// each function pointer to its first index in the Calls array, and then use
1486-
// that to sort by.
1487-
DenseMap<const FuncTy *, unsigned> FuncToIndex;
1488-
for (const auto &[Idx, CallCtxInfo] : enumerate(Calls))
1489-
FuncToIndex.insert({CallCtxInfo.Func, Idx});
1490-
std::stable_sort(
1491-
Calls.begin(), Calls.end(),
1492-
[&FuncToIndex](const CallContextInfo &A, const CallContextInfo &B) {
1493-
return A.StackIds.size() > B.StackIds.size() ||
1494-
(A.StackIds.size() == B.StackIds.size() &&
1495-
(A.StackIds < B.StackIds ||
1496-
(A.StackIds == B.StackIds &&
1497-
FuncToIndex[A.Func] < FuncToIndex[B.Func])));
1498-
});
1482+
// context pruning).
1483+
std::stable_sort(Calls.begin(), Calls.end(),
1484+
[](const CallContextInfo &A, const CallContextInfo &B) {
1485+
return A.StackIds.size() > B.StackIds.size() ||
1486+
(A.StackIds.size() == B.StackIds.size() &&
1487+
A.StackIds < B.StackIds);
1488+
});
14991489

15001490
// Find the node for the last stack id, which should be the same
15011491
// across all calls recorded for this id, and is the id for this
@@ -1513,35 +1503,18 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::updateStackNodes() {
15131503
DenseSet<uint32_t> LastNodeContextIds = LastNode->getContextIds();
15141504
assert(!LastNodeContextIds.empty());
15151505

1516-
#ifndef NDEBUG
1517-
// Save the set of functions seen for a particular set of the same stack
1518-
// ids. This is used to ensure that they have been correctly sorted to be
1519-
// adjacent in the Calls list, since we rely on that to efficiently place
1520-
// all such matching calls onto the same context node.
1521-
DenseSet<const FuncTy *> MatchingIdsFuncSet;
1522-
#endif
1506+
// Map from function to the first call from the below list (with matching
1507+
// stack ids) found in that function. Note that calls from different
1508+
// functions can have the same stack ids because this is the list of stack
1509+
// ids that had (possibly pruned) nodes after building the graph from the
1510+
// allocation MIBs.
1511+
DenseMap<const FuncTy *, CallInfo> FuncToCallMap;
15231512

15241513
for (unsigned I = 0; I < Calls.size(); I++) {
15251514
auto &[Call, Ids, Func, SavedContextIds] = Calls[I];
15261515
assert(SavedContextIds.empty());
15271516
assert(LastId == Ids.back());
15281517

1529-
#ifndef NDEBUG
1530-
// If this call has a different set of ids than the last one, clear the
1531-
// set used to ensure they are sorted properly.
1532-
if (I > 0 && Ids != Calls[I - 1].StackIds)
1533-
MatchingIdsFuncSet.clear();
1534-
else
1535-
// If the prior call had the same stack ids this set would not be empty.
1536-
// Check if we already have a call that "matches" because it is located
1537-
// in the same function. If the Calls list was sorted properly we should
1538-
// not encounter this situation as all such entries should be adjacent
1539-
// and processed in bulk further below.
1540-
assert(!MatchingIdsFuncSet.contains(Func));
1541-
1542-
MatchingIdsFuncSet.insert(Func);
1543-
#endif
1544-
15451518
// First compute the context ids for this stack id sequence (the
15461519
// intersection of the context ids of the corresponding nodes).
15471520
// Start with the remaining saved ids for the last node.
@@ -1610,27 +1583,23 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::updateStackNodes() {
16101583
continue;
16111584
}
16121585

1586+
// If the prior call had the same stack ids this map would not be empty.
1587+
// Check if we already have a call that "matches" because it is located
1588+
// in the same function.
1589+
if (FuncToCallMap.contains(Func)) {
1590+
// Record the matching call found for this call, and skip it. We
1591+
// will subsequently combine it into the same node.
1592+
CallToMatchingCall[Call] = FuncToCallMap[Func];
1593+
continue;
1594+
}
1595+
16131596
// Check if the next set of stack ids is the same (since the Calls vector
16141597
// of tuples is sorted by the stack ids we can just look at the next one).
1615-
// If so, save them in the CallToMatchingCall map so that they get
1616-
// assigned to the same context node, and skip them.
16171598
bool DuplicateContextIds = false;
1618-
for (unsigned J = I + 1; J < Calls.size(); J++) {
1619-
auto &CallCtxInfo = Calls[J];
1599+
if (I + 1 < Calls.size()) {
1600+
auto &CallCtxInfo = Calls[I + 1];
16201601
auto &NextIds = CallCtxInfo.StackIds;
1621-
if (NextIds != Ids)
1622-
break;
1623-
auto *NextFunc = CallCtxInfo.Func;
1624-
if (NextFunc != Func) {
1625-
// We have another Call with the same ids but that cannot share this
1626-
// node, must duplicate ids for it.
1627-
DuplicateContextIds = true;
1628-
break;
1629-
}
1630-
auto &NextCall = CallCtxInfo.Call;
1631-
CallToMatchingCall[NextCall] = Call;
1632-
// Update I so that it gets incremented correctly to skip this call.
1633-
I = J;
1602+
DuplicateContextIds = Ids == NextIds;
16341603
}
16351604

16361605
// If we don't have duplicate context ids, then we can assign all the
@@ -1654,7 +1623,14 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::updateStackNodes() {
16541623
set_subtract(LastNodeContextIds, StackSequenceContextIds);
16551624
if (LastNodeContextIds.empty())
16561625
break;
1657-
}
1626+
// No longer possibly in a sequence of calls with duplicate stack ids,
1627+
// clear the map.
1628+
FuncToCallMap.clear();
1629+
} else
1630+
// Record the call with its function, so we can locate it the next time
1631+
// we find a call from this function when processing the calls with the
1632+
// same stack ids.
1633+
FuncToCallMap[Func] = Call;
16581634
}
16591635
}
16601636

0 commit comments

Comments
 (0)