[llvm] Isolate the final result out of TestVectors (PR #82282)

NAKAMURA Takumi via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 19 14:10:09 PST 2024


https://github.com/chapuni created https://github.com/llvm/llvm-project/pull/82282

To reduce conditional judges in the loop in `findIndependencePairs()`, I have tried a couple of tweaks.

* Isolate the final result
```
using TestVectors = llvm::SmallVector<std::pair<TestVector, CondState>>;
```
The final result is just piggybacked on `TestVector`, so it can be isolated.

* Filter out and sort `ExecVectors` by the final result

It will cost more in constructing `ExecVectors`, but it can eliminate a conditional judgement in the loop.

>From f96be84c25e0c47a23231fe9dcf81ab9216dada2 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4civic at gmail.com>
Date: Mon, 19 Feb 2024 21:14:30 +0900
Subject: [PATCH] using TestVectors = llvm::SmallVector<std::pair<TestVector,
 CondState>>;

---
 .../ProfileData/Coverage/CoverageMapping.h    |  6 ++---
 .../ProfileData/Coverage/CoverageMapping.cpp  | 25 +++++++++++--------
 2 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
index c5c9740f25c2ce..44d58aba7754ad 100644
--- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
+++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
@@ -381,7 +381,7 @@ struct MCDCRecord {
   enum CondState { MCDC_DontCare = -1, MCDC_False = 0, MCDC_True = 1 };
 
   using TestVector = llvm::SmallVector<CondState>;
-  using TestVectors = llvm::SmallVector<TestVector>;
+  using TestVectors = llvm::SmallVector<std::pair<TestVector, CondState>>;
   using BoolVector = llvm::SmallVector<bool>;
   using TVRowPair = std::pair<unsigned, unsigned>;
   using TVPairMap = llvm::DenseMap<unsigned, TVRowPair>;
@@ -422,13 +422,13 @@ struct MCDCRecord {
   /// accessing conditions in the TestVectors requires a translation from a
   /// ordinal position to actual condition ID. This is done via PosToID[].
   CondState getTVCondition(unsigned TestVectorIndex, unsigned Condition) {
-    return TV[TestVectorIndex][PosToID[Condition]];
+    return TV[TestVectorIndex].first[PosToID[Condition]];
   }
 
   /// Return the Result evaluation for an executed test vector.
   /// See MCDCRecordProcessor::RecordTestVector().
   CondState getTVResult(unsigned TestVectorIndex) {
-    return TV[TestVectorIndex][getNumConditions()];
+    return TV[TestVectorIndex].second;
   }
 
   /// Determine whether a given condition (indicated by Condition) is covered
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
index ddce7580729170..e8440fa9fb09f7 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
@@ -257,6 +257,8 @@ class MCDCRecordProcessor {
   /// Actual executed Test Vectors for the boolean expression, based on
   /// ExecutedTestVectorBitmap.
   MCDCRecord::TestVectors ExecVectors;
+  std::array<MCDCRecord::TestVectors, 2> ExecVectorsByCond;
+  unsigned NumExecVectorsF;
 
 public:
   MCDCRecordProcessor(const BitVector &Bitmap,
@@ -291,11 +293,9 @@ class MCDCRecordProcessor {
         continue;
 
       // Copy the completed test vector to the vector of testvectors.
-      ExecVectors.push_back(TV);
-
       // The final value (T,F) is equal to the last non-dontcare state on the
       // path (in a short-circuiting system).
-      ExecVectors.back().push_back(MCDCCond);
+      ExecVectorsByCond[MCDCCond].push_back({TV, MCDCCond});
     }
 
     // Reset back to DontCare.
@@ -310,6 +310,12 @@ class MCDCRecordProcessor {
     // `Index` encodes the bitmask of true values and is initially 0.
     MCDCRecord::TestVector TV(NumConditions, MCDCRecord::MCDC_DontCare);
     buildTestVector(TV, 0, 0);
+
+    auto &[ExecVectorsF, ExecVectorsT] = ExecVectorsByCond;
+    NumExecVectorsF = ExecVectorsF.size();
+    ExecVectors = std::move(ExecVectorsF);
+    ExecVectors.append(std::make_move_iterator(ExecVectorsT.begin()),
+                       std::make_move_iterator(ExecVectorsT.end()));
   }
 
   // Find an independence pair for each condition:
@@ -318,13 +324,12 @@ class MCDCRecordProcessor {
   // - All other conditions' values must be equal or marked as "don't care".
   void findIndependencePairs() {
     unsigned NumTVs = ExecVectors.size();
-    for (unsigned I = 1; I < NumTVs; ++I) {
-      const MCDCRecord::TestVector &A = ExecVectors[I];
-      for (unsigned J = 0; J < I; ++J) {
-        const MCDCRecord::TestVector &B = ExecVectors[J];
-        // Enumerate two execution vectors whose outcomes are different.
-        if (A[NumConditions] == B[NumConditions])
-          continue;
+    for (unsigned I = NumExecVectorsF; I < NumTVs; ++I) {
+      const auto &[A, ACond] = ExecVectors[I];
+      assert(ACond == MCDCRecord::MCDC_True);
+      for (unsigned J = 0; J < NumExecVectorsF; ++J) {
+        const auto &[B, BCond] = ExecVectors[J];
+        assert(BCond == MCDCRecord::MCDC_False);
         unsigned Flip = NumConditions, Idx;
         for (Idx = 0; Idx < NumConditions; ++Idx) {
           MCDCRecord::CondState ACond = A[Idx], BCond = B[Idx];



More information about the llvm-commits mailing list