[llvm-branch-commits] [llvm] [KeyInstr] Merge atoms in DILocation::getMergedLocation (PR #133480)

Jeremy Morse via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Apr 23 06:18:21 PDT 2025


================
@@ -1243,6 +1243,140 @@ TEST_F(DILocationTest, Merge) {
     auto *M2 = DILocation::getMergedLocation(A2, B);
     EXPECT_EQ(M1, M2);
   }
+
+#ifdef EXPERIMENTAL_KEY_INSTRUCTIONS
+#define EXPECT_ATOM(Loc, Group, Rank)                                          \
+  EXPECT_EQ(Group, M->getAtomGroup());                                         \
+  EXPECT_EQ(Rank, M->getAtomRank());
+#else
+#define EXPECT_ATOM(Loc, Group, Rank)                                          \
+  EXPECT_EQ(0u, M->getAtomGroup());                                            \
+  EXPECT_EQ(0u, M->getAtomRank());                                             \
+  (void)Group;                                                                 \
+  (void)Rank;
+#endif
+  // Identical, including source atom numbers.
+  {
+    auto *A = DILocation::get(Context, 2, 7, N, nullptr, false, 1, 1);
+    auto *B = DILocation::get(Context, 2, 7, N, nullptr, false, 1, 1);
+    auto *M = DILocation::getMergedLocation(A, B);
+    EXPECT_ATOM(M, 1u, 1u);
+    // DILocations are uniqued, so we can check equality by ptr.
+    EXPECT_EQ(M, DILocation::getMergedLocation(A, B));
+  }
+
+  // Identical but different atom ranks (same atom) - choose the lowest nonzero
+  // rank.
+  {
+    auto *A = DILocation::get(Context, 2, 7, N, nullptr, false, 1, 1);
+    auto *B = DILocation::get(Context, 2, 7, N, nullptr, false, 1, 2);
+    auto *M = DILocation::getMergedLocation(A, B);
+    EXPECT_ATOM(M, 1u, 1u);
+    EXPECT_EQ(M, DILocation::getMergedLocation(B, A));
+
+    A = DILocation::get(Context, 2, 7, N, nullptr, false, 1, 0);
+    B = DILocation::get(Context, 2, 7, N, nullptr, false, 1, 2);
+    M = DILocation::getMergedLocation(A, B);
+    EXPECT_ATOM(M, 1u, 2u);
+    EXPECT_EQ(M, DILocation::getMergedLocation(B, A));
+  }
+
+  // Identical but different atom ranks (different atom) - choose the lowest
+  // nonzero rank.
+  {
+    auto *A = DILocation::get(Context, 2, 7, N, nullptr, false, 1, 1);
+    auto *B = DILocation::get(Context, 2, 7, N, nullptr, false, 2, 2);
+    auto *M = DILocation::getMergedLocation(A, B);
+    EXPECT_ATOM(M, 1u, 1u);
+    EXPECT_EQ(M, DILocation::getMergedLocation(B, A));
+
+    A = DILocation::get(Context, 2, 7, N, nullptr, false, 1, 0);
+    B = DILocation::get(Context, 2, 7, N, nullptr, false, 2, 2);
+    M = DILocation::getMergedLocation(A, B);
+    EXPECT_ATOM(M, 2u, 2u);
+    EXPECT_EQ(M, DILocation::getMergedLocation(B, A));
+  }
+
+  // Identical but equal atom rank (different atom) - choose the lowest non-zero
+  // group (arbitrary choice for deterministic behaviour).
+  {
+    auto *A = DILocation::get(Context, 2, 7, N, nullptr, false, 1, 1);
+    auto *B = DILocation::get(Context, 2, 7, N, nullptr, false, 2, 1);
+    auto *M = DILocation::getMergedLocation(A, B);
+    EXPECT_ATOM(M, 1u, 1u);
+    EXPECT_EQ(M, DILocation::getMergedLocation(B, A));
+
+    A = DILocation::get(Context, 2, 7, N, nullptr, false, 0, 1);
+    B = DILocation::get(Context, 2, 7, N, nullptr, false, 2, 1);
+    M = DILocation::getMergedLocation(A, B);
+    EXPECT_ATOM(M, 2u, 1u);
+    EXPECT_EQ(M, DILocation::getMergedLocation(B, A));
+  }
+
+  // Completely different except same atom numbers. Zero out the atoms.
+  {
+    auto *I = DILocation::get(Context, 2, 7, N);
+    auto *A = DILocation::get(Context, 1, 6, S, I, false, 1, 1);
+    auto *B =
+        DILocation::get(Context, 2, 7, getSubprogram(), nullptr, false, 1, 1);
+    auto *M = DILocation::getMergedLocation(A, B);
+    EXPECT_EQ(0u, M->getLine());
+    EXPECT_EQ(0u, M->getColumn());
+    EXPECT_TRUE(isa<DILocalScope>(M->getScope()));
+    EXPECT_EQ(S, M->getScope());
+    EXPECT_EQ(nullptr, M->getInlinedAt());
+  }
+
+  // Same inlined-at chain but different atoms. Choose the lowest
+  // non-zero group (arbitrary choice for deterministic behaviour).
+  {
+    auto *I = DILocation::get(Context, 1, 7, N);
+    auto *F = getSubprogram();
+    auto *A = DILocation::get(Context, 1, 1, F, I, false, 1, 2);
+    auto *B = DILocation::get(Context, 1, 1, F, I, false, 2, 1);
+    auto *M = DILocation::getMergedLocation(A, B);
+    EXPECT_ATOM(M, 2u, 1u);
----------------
jmorse wrote:

No real suggestions; I think the C++17 way might be to invent user-defined-literals and an integer-like object, but that seems like waaayyyy overkill here. Or maybe enum classes? The unit tests will also (IMHO YMMV?) be the only place where literals get fed into this.

An ugly alternative is to put the pattern in the name, i.e. "DILocation::getWithAtomRank", so that every time it appears you're reminded what argument order it should be.

https://github.com/llvm/llvm-project/pull/133480


More information about the llvm-branch-commits mailing list