[clang] 50d112c - [MC/DC] Prune MCDCLogOpStack and use CGF.isMCDCDecisionExpr. NFC (#125410)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 13 05:09:12 PST 2026
Author: NAKAMURA Takumi
Date: 2026-01-13T22:09:07+09:00
New Revision: 50d112c396eaa326df316bc4b920fb721c0bc4f9
URL: https://github.com/llvm/llvm-project/commit/50d112c396eaa326df316bc4b920fb721c0bc4f9
DIFF: https://github.com/llvm/llvm-project/commit/50d112c396eaa326df316bc4b920fb721c0bc4f9.diff
LOG: [MC/DC] Prune MCDCLogOpStack and use CGF.isMCDCDecisionExpr. NFC (#125410)
`MCDCLogOpStack` is used only for detection of the Decision root. It can
be detected with `MCDC::State::DecisionByStmt`.
Added:
Modified:
clang/lib/CodeGen/CGExprScalar.cpp
clang/lib/CodeGen/CodeGenFunction.cpp
clang/lib/CodeGen/CodeGenFunction.h
clang/lib/CodeGen/CodeGenPGO.cpp
clang/lib/CodeGen/CodeGenPGO.h
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 6fd94752f5126..e48d316d337b0 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -5385,11 +5385,9 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) {
CGF.incrementProfileCounter(E);
// If the top of the logical operator nest, reset the MCDC temp to 0.
- if (CGF.MCDCLogOpStack.empty())
+ if (CGF.isMCDCDecisionExpr(E))
CGF.maybeResetMCDCCondBitmap(E);
- CGF.MCDCLogOpStack.push_back(E);
-
Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
// If we're generating for profiling or coverage, generate a branch to a
@@ -5409,9 +5407,8 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) {
} else
CGF.markStmtMaybeUsed(E->getRHS());
- CGF.MCDCLogOpStack.pop_back();
// If the top of the logical operator nest, update the MCDC bitmap.
- if (CGF.MCDCLogOpStack.empty())
+ if (CGF.isMCDCDecisionExpr(E))
CGF.maybeUpdateMCDCTestVectorBitmap(E);
// ZExt result to int or bool.
@@ -5426,11 +5423,9 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) {
}
// If the top of the logical operator nest, reset the MCDC temp to 0.
- if (CGF.MCDCLogOpStack.empty())
+ if (CGF.isMCDCDecisionExpr(E))
CGF.maybeResetMCDCCondBitmap(E);
- CGF.MCDCLogOpStack.push_back(E);
-
llvm::BasicBlock *ContBlock = CGF.createBasicBlock("land.end");
llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("land.rhs");
@@ -5481,9 +5476,8 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) {
// Insert an entry into the phi node for the edge with the value of RHSCond.
PN->addIncoming(RHSCond, RHSBlock);
- CGF.MCDCLogOpStack.pop_back();
// If the top of the logical operator nest, update the MCDC bitmap.
- if (CGF.MCDCLogOpStack.empty())
+ if (CGF.isMCDCDecisionExpr(E))
CGF.maybeUpdateMCDCTestVectorBitmap(E);
// Artificial location to preserve the scope information
@@ -5528,11 +5522,9 @@ Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) {
CGF.incrementProfileCounter(E);
// If the top of the logical operator nest, reset the MCDC temp to 0.
- if (CGF.MCDCLogOpStack.empty())
+ if (CGF.isMCDCDecisionExpr(E))
CGF.maybeResetMCDCCondBitmap(E);
- CGF.MCDCLogOpStack.push_back(E);
-
Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
// If we're generating for profiling or coverage, generate a branch to a
@@ -5552,9 +5544,8 @@ Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) {
} else
CGF.markStmtMaybeUsed(E->getRHS());
- CGF.MCDCLogOpStack.pop_back();
// If the top of the logical operator nest, update the MCDC bitmap.
- if (CGF.MCDCLogOpStack.empty())
+ if (CGF.isMCDCDecisionExpr(E))
CGF.maybeUpdateMCDCTestVectorBitmap(E);
// ZExt result to int or bool.
@@ -5569,11 +5560,9 @@ Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) {
}
// If the top of the logical operator nest, reset the MCDC temp to 0.
- if (CGF.MCDCLogOpStack.empty())
+ if (CGF.isMCDCDecisionExpr(E))
CGF.maybeResetMCDCCondBitmap(E);
- CGF.MCDCLogOpStack.push_back(E);
-
llvm::BasicBlock *ContBlock = CGF.createBasicBlock("lor.end");
llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("lor.rhs");
@@ -5624,9 +5613,8 @@ Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) {
CGF.EmitBlock(ContBlock);
PN->addIncoming(RHSCond, RHSBlock);
- CGF.MCDCLogOpStack.pop_back();
// If the top of the logical operator nest, update the MCDC bitmap.
- if (CGF.MCDCLogOpStack.empty())
+ if (CGF.isMCDCDecisionExpr(E))
CGF.maybeUpdateMCDCTestVectorBitmap(E);
// ZExt result to int.
@@ -5792,8 +5780,8 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
}
// If the top of the logical operator nest, reset the MCDC temp to 0.
- if (CGF.MCDCLogOpStack.empty())
- CGF.maybeResetMCDCCondBitmap(condExpr);
+ if (auto E = CGF.stripCond(condExpr); CGF.isMCDCDecisionExpr(E))
+ CGF.maybeResetMCDCCondBitmap(E);
llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true");
llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false");
@@ -5808,8 +5796,8 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
// If the top of the logical operator nest, update the MCDC bitmap for the
// ConditionalOperator prior to visiting its LHS and RHS blocks, since they
// may also contain a boolean expression.
- if (CGF.MCDCLogOpStack.empty())
- CGF.maybeUpdateMCDCTestVectorBitmap(condExpr);
+ if (auto E = CGF.stripCond(condExpr); CGF.isMCDCDecisionExpr(E))
+ CGF.maybeUpdateMCDCTestVectorBitmap(E);
if (llvm::EnableSingleByteCoverage)
CGF.incrementProfileCounter(lhsExpr);
@@ -5828,8 +5816,8 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
// If the top of the logical operator nest, update the MCDC bitmap for the
// ConditionalOperator prior to visiting its LHS and RHS blocks, since they
// may also contain a boolean expression.
- if (CGF.MCDCLogOpStack.empty())
- CGF.maybeUpdateMCDCTestVectorBitmap(condExpr);
+ if (auto E = CGF.stripCond(condExpr); CGF.isMCDCDecisionExpr(E))
+ CGF.maybeUpdateMCDCTestVectorBitmap(E);
if (llvm::EnableSingleByteCoverage)
CGF.incrementProfileCounter(rhsExpr);
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 6c0589be32913..10f2ff0184c1c 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -1895,8 +1895,6 @@ void CodeGenFunction::EmitBranchOnBoolExpr(
if (const BinaryOperator *CondBOp = dyn_cast<BinaryOperator>(Cond)) {
// Handle X && Y in a condition.
if (CondBOp->getOpcode() == BO_LAnd) {
- MCDCLogOpStack.push_back(CondBOp);
-
// If we have "1 && X", simplify the code. "0 && X" would have constant
// folded if the case was simple enough.
bool ConstantBool = false;
@@ -1906,7 +1904,6 @@ void CodeGenFunction::EmitBranchOnBoolExpr(
incrementProfileCounter(CondBOp);
EmitBranchToCounterBlock(CondBOp->getRHS(), BO_LAnd, TrueBlock,
FalseBlock, TrueCount, LH);
- MCDCLogOpStack.pop_back();
return;
}
@@ -1917,7 +1914,6 @@ void CodeGenFunction::EmitBranchOnBoolExpr(
// br(X && 1) -> br(X).
EmitBranchToCounterBlock(CondBOp->getLHS(), BO_LAnd, TrueBlock,
FalseBlock, TrueCount, LH, CondBOp);
- MCDCLogOpStack.pop_back();
return;
}
@@ -1947,13 +1943,10 @@ void CodeGenFunction::EmitBranchOnBoolExpr(
EmitBranchToCounterBlock(CondBOp->getRHS(), BO_LAnd, TrueBlock,
FalseBlock, TrueCount, LH);
eval.end(*this);
- MCDCLogOpStack.pop_back();
return;
}
if (CondBOp->getOpcode() == BO_LOr) {
- MCDCLogOpStack.push_back(CondBOp);
-
// If we have "0 || X", simplify the code. "1 || X" would have constant
// folded if the case was simple enough.
bool ConstantBool = false;
@@ -1963,7 +1956,6 @@ void CodeGenFunction::EmitBranchOnBoolExpr(
incrementProfileCounter(CondBOp);
EmitBranchToCounterBlock(CondBOp->getRHS(), BO_LOr, TrueBlock,
FalseBlock, TrueCount, LH);
- MCDCLogOpStack.pop_back();
return;
}
@@ -1974,7 +1966,6 @@ void CodeGenFunction::EmitBranchOnBoolExpr(
// br(X || 0) -> br(X).
EmitBranchToCounterBlock(CondBOp->getLHS(), BO_LOr, TrueBlock,
FalseBlock, TrueCount, LH, CondBOp);
- MCDCLogOpStack.pop_back();
return;
}
// Emit the LHS as a conditional. If the LHS conditional is true, we
@@ -2007,7 +1998,6 @@ void CodeGenFunction::EmitBranchOnBoolExpr(
RHSCount, LH);
eval.end(*this);
- MCDCLogOpStack.pop_back();
return;
}
}
@@ -2094,7 +2084,7 @@ void CodeGenFunction::EmitBranchOnBoolExpr(
// If not at the top of the logical operator nest, update MCDC temp with the
// boolean result of the evaluated condition.
- if (!MCDCLogOpStack.empty()) {
+ {
const Expr *MCDCBaseExpr = Cond;
// When a nested ConditionalOperator (ternary) is encountered in a boolean
// expression, MC/DC tracks the result of the ternary, and this is tied to
@@ -2104,7 +2094,9 @@ void CodeGenFunction::EmitBranchOnBoolExpr(
if (ConditionalOp)
MCDCBaseExpr = ConditionalOp;
- maybeUpdateMCDCCondBitmap(MCDCBaseExpr, CondV);
+ if (isMCDCBranchExpr(stripCond(MCDCBaseExpr)) &&
+ !isMCDCDecisionExpr(stripCond(Cond)))
+ maybeUpdateMCDCCondBitmap(MCDCBaseExpr, CondV);
}
llvm::MDNode *Weights = nullptr;
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 13c8f2002aad9..caf68f28d4661 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -303,9 +303,6 @@ class CodeGenFunction : public CodeGenTypeCache {
/// nest would extend.
SmallVector<llvm::CanonicalLoopInfo *, 4> OMPLoopNestStack;
- /// Stack to track the Logical Operator recursion nest for MC/DC.
- SmallVector<const BinaryOperator *, 16> MCDCLogOpStack;
-
/// Stack to track the controlled convergence tokens.
SmallVector<llvm::ConvergenceControlInst *, 4> ConvergenceTokenStack;
@@ -1703,6 +1700,9 @@ class CodeGenFunction : public CodeGenTypeCache {
return (BOp && BOp->isLogicalOp());
}
+ bool isMCDCDecisionExpr(const Expr *E) const;
+ bool isMCDCBranchExpr(const Expr *E) const;
+
/// Zero-init the MCDC temp value.
void maybeResetMCDCCondBitmap(const Expr *E);
diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp
index 359b4e00a9b57..9cd53208f8abd 100644
--- a/clang/lib/CodeGen/CodeGenPGO.cpp
+++ b/clang/lib/CodeGen/CodeGenPGO.cpp
@@ -1561,6 +1561,12 @@ void CodeGenFunction::maybeCreateMCDCCondBitmap() {
MCDCCondBitmapAddr = CreateIRTemp(getContext().UnsignedIntTy, "mcdc.addr");
}
}
+bool CodeGenFunction::isMCDCDecisionExpr(const Expr *E) const {
+ return PGO->isMCDCDecisionExpr(E);
+}
+bool CodeGenFunction::isMCDCBranchExpr(const Expr *E) const {
+ return PGO->isMCDCBranchExpr(E);
+}
void CodeGenFunction::maybeResetMCDCCondBitmap(const Expr *E) {
if (isMCDCCoverageEnabled() && isBinaryLogicalOp(E)) {
PGO->emitMCDCCondBitmapReset(Builder, E, MCDCCondBitmapAddr);
diff --git a/clang/lib/CodeGen/CodeGenPGO.h b/clang/lib/CodeGen/CodeGenPGO.h
index da386f41c0aea..05cb9d497b91e 100644
--- a/clang/lib/CodeGen/CodeGenPGO.h
+++ b/clang/lib/CodeGen/CodeGenPGO.h
@@ -111,6 +111,20 @@ class CodeGenPGO {
public:
std::pair<bool, bool> getIsCounterPair(const Stmt *S) const;
+
+ bool isMCDCDecisionExpr(const Expr *E) const {
+ if (!RegionMCDCState)
+ return false;
+ auto I = RegionMCDCState->DecisionByStmt.find(E);
+ if (I == RegionMCDCState->DecisionByStmt.end())
+ return false;
+ return I->second.isValid();
+ }
+
+ bool isMCDCBranchExpr(const Expr *E) const {
+ return (RegionMCDCState && RegionMCDCState->BranchByStmt.contains(E));
+ }
+
void emitCounterSetOrIncrement(CGBuilderTy &Builder, const Stmt *S,
bool UseFalsePath, bool UseBoth,
llvm::Value *StepV);
More information about the cfe-commits
mailing list