Skip to content

Conversation

@chapuni
Copy link
Contributor

@chapuni chapuni commented Feb 2, 2025

Introduce ID and InvalidID. Then DecisionByStmt can have three states.

  • Not assigned if the Stmt(Expr) doesn't exist.
  • When DecisionByStmt[Expr] exists:
    • Invalid and should be ignored if ID == Invalid.
    • Valid if ID != Invalid. Other member will be filled in the Mapper.

To resolve the error, rename mcdc-error-nests.cpp -> mcdc-nested-expr.cpp at first.

- `func_condop`
  A corner case that contains close decisions.
- `func_expect`
  Uses `__builtin_expect`. (#124565)
- `func_lnot`
  Contains logical not(s) `!` among MC/DC binary operators. (#124563)

mcdc-single-cond.cpp is for #95336.
Introduce `ID` and `InvalidID`. Then `DecisionByStmt` can have three
states.

* Not assigned if the Stmt(Expr) doesn't exist.
* When `DecisionByStmt[Expr]` exists:
  * Invalid and should be ignored if `ID == Invalid`.
  * Valid if `ID != Invalid`. Other member will be filled in the
    Mapper.
@chapuni chapuni requested review from evodius96 and ornata February 2, 2025 13:31
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:codegen IR generation bugs: mangling, exceptions, etc. labels Feb 2, 2025
@llvmbot
Copy link
Member

llvmbot commented Feb 2, 2025

@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-codegen

Author: NAKAMURA Takumi (chapuni)

Changes

Introduce ID and InvalidID. Then DecisionByStmt can have three states.

  • Not assigned if the Stmt(Expr) doesn't exist.
  • When DecisionByStmt[Expr] exists:
    • Invalid and should be ignored if ID == Invalid.
    • Valid if ID != Invalid. Other member will be filled in the Mapper.

Full diff: https://github.com/llvm/llvm-project/pull/125408.diff

3 Files Affected:

  • (modified) clang/lib/CodeGen/CodeGenPGO.cpp (+1-1)
  • (modified) clang/lib/CodeGen/CoverageMappingGen.cpp (+2-4)
  • (modified) clang/lib/CodeGen/MCDCState.h (+15-1)
diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp
index 792373839107f0a..0331ff83e633f75 100644
--- a/clang/lib/CodeGen/CodeGenPGO.cpp
+++ b/clang/lib/CodeGen/CodeGenPGO.cpp
@@ -310,7 +310,7 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
           }
 
           // Otherwise, allocate the Decision.
-          MCDCState.DecisionByStmt[BinOp].BitmapIdx = 0;
+          MCDCState.DecisionByStmt[BinOp].ID = MCDCState.DecisionByStmt.size();
         }
         return true;
       }
diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp
index f09157771d2b5c0..4dbc0c70e34d60b 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -2197,10 +2197,8 @@ struct CounterCoverageMappingBuilder
 
     // Update the state for CodeGenPGO
     assert(MCDCState.DecisionByStmt.contains(E));
-    MCDCState.DecisionByStmt[E] = {
-        MCDCState.BitmapBits, // Top
-        std::move(Builder.Indices),
-    };
+    MCDCState.DecisionByStmt[E].update(MCDCState.BitmapBits, // Top
+                                       std::move(Builder.Indices));
 
     auto DecisionParams = mcdc::DecisionParameters{
         MCDCState.BitmapBits += NumTVs, // Tail
diff --git a/clang/lib/CodeGen/MCDCState.h b/clang/lib/CodeGen/MCDCState.h
index e0dd28ff90ed124..0b6f5f28235f43a 100644
--- a/clang/lib/CodeGen/MCDCState.h
+++ b/clang/lib/CodeGen/MCDCState.h
@@ -16,6 +16,8 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ProfileData/Coverage/MCDCTypes.h"
+#include <cassert>
+#include <limits>
 
 namespace clang {
 class Stmt;
@@ -30,8 +32,20 @@ struct State {
   unsigned BitmapBits = 0;
 
   struct Decision {
+    using IndicesTy = llvm::SmallVector<std::array<int, 2>>;
+    static constexpr auto InvalidID = std::numeric_limits<unsigned>::max();
+
     unsigned BitmapIdx;
-    llvm::SmallVector<std::array<int, 2>> Indices;
+    IndicesTy Indices;
+    unsigned ID = InvalidID;
+
+    bool isValid() const { return ID != InvalidID; }
+
+    void update(unsigned I, IndicesTy &&X) {
+      assert(ID != InvalidID);
+      BitmapIdx = I;
+      Indices = std::move(X);
+    }
   };
 
   llvm::DenseMap<const Stmt *, Decision> DecisionByStmt;

bool isValid() const { return ID != InvalidID; }

void update(unsigned I, IndicesTy &&X) {
assert(ID != InvalidID);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just use isValid()?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, how expensive is this? Would it make sense for this to be a real error in release builds as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It shouldn't be the real error. I suppose it the expectation here.

I can update this. IIRC, I implemented isValid later.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:codegen IR generation bugs: mangling, exceptions, etc. clang Clang issues not falling into any other category coverage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants