Skip to content

Commit d6a4828

Browse files
authored
[clang][bytecode] Special-case ConstantExpr in if conditions (#130294)
This happens a lot with `if constexpr` with a condition based on a template param. In those cases, the condition is a ConstantExpr with a value already set, so we can use that and ignore the other branch.
1 parent db5e401 commit d6a4828

File tree

1 file changed

+28
-22
lines changed

1 file changed

+28
-22
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5167,6 +5167,12 @@ bool Compiler<Emitter>::visitReturnStmt(const ReturnStmt *RS) {
51675167
}
51685168

51695169
template <class Emitter> bool Compiler<Emitter>::visitIfStmt(const IfStmt *IS) {
5170+
auto visitChildStmt = [&](const Stmt *S) -> bool {
5171+
LocalScope<Emitter> SScope(this);
5172+
if (!visitStmt(S))
5173+
return false;
5174+
return SScope.destroyLocals();
5175+
};
51705176
if (auto *CondInit = IS->getInit())
51715177
if (!visitStmt(CondInit))
51725178
return false;
@@ -5175,7 +5181,22 @@ template <class Emitter> bool Compiler<Emitter>::visitIfStmt(const IfStmt *IS) {
51755181
if (!visitDeclStmt(CondDecl))
51765182
return false;
51775183

5178-
// Compile condition.
5184+
// Save ourselves compiling some code and the jumps, etc. if the condition is
5185+
// stataically known to be either true or false. We could look at more cases
5186+
// here, but I think all the ones that actually happen are using a
5187+
// ConstantExpr.
5188+
if (const auto *CE = dyn_cast_if_present<ConstantExpr>(IS->getCond());
5189+
CE && CE->hasAPValueResult() &&
5190+
CE->getResultAPValueKind() == APValue::ValueKind::Int) {
5191+
APSInt Value = CE->getResultAsAPSInt();
5192+
if (Value.getBoolValue())
5193+
return visitChildStmt(IS->getThen());
5194+
else if (const Stmt *Else = IS->getElse())
5195+
return visitChildStmt(Else);
5196+
return true;
5197+
}
5198+
5199+
// Otherwise, compile the condition.
51795200
if (IS->isNonNegatedConsteval()) {
51805201
if (!this->emitIsConstantContext(IS))
51815202
return false;
@@ -5194,35 +5215,20 @@ template <class Emitter> bool Compiler<Emitter>::visitIfStmt(const IfStmt *IS) {
51945215
LabelTy LabelEnd = this->getLabel();
51955216
if (!this->jumpFalse(LabelElse))
51965217
return false;
5197-
{
5198-
LocalScope<Emitter> ThenScope(this);
5199-
if (!visitStmt(IS->getThen()))
5200-
return false;
5201-
if (!ThenScope.destroyLocals())
5202-
return false;
5203-
}
5218+
if (!visitChildStmt(IS->getThen()))
5219+
return false;
52045220
if (!this->jump(LabelEnd))
52055221
return false;
52065222
this->emitLabel(LabelElse);
5207-
{
5208-
LocalScope<Emitter> ElseScope(this);
5209-
if (!visitStmt(Else))
5210-
return false;
5211-
if (!ElseScope.destroyLocals())
5212-
return false;
5213-
}
5223+
if (!visitChildStmt(Else))
5224+
return false;
52145225
this->emitLabel(LabelEnd);
52155226
} else {
52165227
LabelTy LabelEnd = this->getLabel();
52175228
if (!this->jumpFalse(LabelEnd))
52185229
return false;
5219-
{
5220-
LocalScope<Emitter> ThenScope(this);
5221-
if (!visitStmt(IS->getThen()))
5222-
return false;
5223-
if (!ThenScope.destroyLocals())
5224-
return false;
5225-
}
5230+
if (!visitChildStmt(IS->getThen()))
5231+
return false;
52265232
this->emitLabel(LabelEnd);
52275233
}
52285234

0 commit comments

Comments
 (0)