[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`.
This commit is contained in:
NAKAMURA Takumi 2026-01-13 22:09:07 +09:00 committed by GitHub
parent 017a27cb1a
commit 50d112c396
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 41 additions and 41 deletions

View File

@ -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);

View File

@ -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;

View File

@ -303,9 +303,6 @@ public:
/// 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 @@ public:
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);

View File

@ -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);

View File

@ -111,6 +111,20 @@ private:
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);