[llvm] [SampleFDO] Improve stale profile matching by diff algorithm (PR #87375)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 26 20:50:49 PDT 2024
================
@@ -122,15 +122,153 @@ void SampleProfileMatcher::findProfileAnchors(
}
}
+MyersDiff::DiffResult
+MyersDiff::longestCommonSequence(const std::vector<Anchor> &A,
+ const std::vector<Anchor> &B) const {
+ int32_t N = A.size(), M = B.size(), Max = N + M;
+ auto Index = [&](int32_t I) { return I + Max; };
+
+ DiffResult Diff;
+ if (Max == 0)
+ return Diff;
+
+ // Backtrack the SES result.
+ auto Backtrack = [&](const std::vector<std::vector<int32_t>> &Trace,
+ const std::vector<Anchor> &A,
+ const std::vector<Anchor> &B) {
+ int32_t X = N, Y = M;
+ for (int32_t D = Trace.size() - 1; X > 0 || Y > 0; D--) {
+ const auto &P = Trace[D];
+ int32_t K = X - Y;
+ int32_t PrevK = K;
+ if (K == -D || (K != D && P[Index(K - 1)] < P[Index(K + 1)]))
+ PrevK = K + 1;
+ else
+ PrevK = K - 1;
+
+ int32_t PrevX = P[Index(PrevK)];
+ int32_t PrevY = PrevX - PrevK;
+ while (X > PrevX && Y > PrevY) {
+ X--;
+ Y--;
+ Diff.addEqualLocations(A[X].Loc, B[Y].Loc);
+ }
+
+ if (D == 0)
+ break;
+
+ if (Y == PrevY) {
+ X--;
+#ifndef NDEBUG
+ Diff.addInsertion(A[X].Loc);
+#endif
+ } else if (X == PrevX) {
+ Y--;
+#ifndef NDEBUG
+ Diff.addDeletion(B[Y].Loc);
+#endif
+ }
+ X = PrevX;
+ Y = PrevY;
+ }
+ };
+
+ // The greedy LCS/SES algorithm.
+ std::vector<int32_t> V(2 * Max + 1, -1);
+ V[Index(1)] = 0;
+ std::vector<std::vector<int32_t>> Trace;
+ for (int32_t D = 0; D <= Max; D++) {
+ Trace.push_back(V);
+ for (int32_t K = -D; K <= D; K += 2) {
+ int32_t X = 0, Y = 0;
+ if (K == -D || (K != D && V[Index(K - 1)] < V[Index(K + 1)]))
+ X = V[Index(K + 1)];
+ else
+ X = V[Index(K - 1)] + 1;
+ Y = X - K;
+ while (X < N && Y < M && A[X] == B[Y])
----------------
WenleiHe wrote:
It looks like the reason you convert `ProfileAnchors` and `IRAnchors` into `std::vector<Anchor>` is to remove indirect calls and allow random access by indexing. Looking at how `std::vector<Anchor>`, I don't really see real random access (it's always sequential through `X++` and `Y++`). Can you simply use `ProfileAnchors` and `IRAnchors` directly but through an iterator/access that skips indirect call locations?
https://github.com/llvm/llvm-project/pull/87375
More information about the llvm-commits
mailing list