[clang] [clang][bytecode] Special-case ConstantExpr in if conditions (PR #130294)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 7 07:20:23 PST 2025
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/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.
>From 92313a47fb18193b58af5900c661ea1393a3f5db Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Fri, 7 Mar 2025 16:18:27 +0100
Subject: [PATCH] [clang][bytecode] Special-case ConstantExpr in if conditions
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.
---
clang/lib/AST/ByteCode/Compiler.cpp | 50 ++++++++++++++++-------------
1 file changed, 28 insertions(+), 22 deletions(-)
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 281fb7e14a57d..971a8f3bd95f7 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -5167,6 +5167,12 @@ bool Compiler<Emitter>::visitReturnStmt(const ReturnStmt *RS) {
}
template <class Emitter> bool Compiler<Emitter>::visitIfStmt(const IfStmt *IS) {
+ auto visitChildStmt = [&](const Stmt *S) -> bool {
+ LocalScope<Emitter> SScope(this);
+ if (!visitStmt(S))
+ return false;
+ return SScope.destroyLocals();
+ };
if (auto *CondInit = IS->getInit())
if (!visitStmt(CondInit))
return false;
@@ -5175,7 +5181,22 @@ template <class Emitter> bool Compiler<Emitter>::visitIfStmt(const IfStmt *IS) {
if (!visitDeclStmt(CondDecl))
return false;
- // Compile condition.
+ // Save ourselves compiling some code and the jumps, etc. if the condition is
+ // stataically known to be either true or false. We could look at more cases
+ // here, but I think all the ones that actually happen are using a
+ // ConstantExpr.
+ if (const auto *CE = dyn_cast_if_present<ConstantExpr>(IS->getCond());
+ CE && CE->hasAPValueResult() &&
+ CE->getResultAPValueKind() == APValue::ValueKind::Int) {
+ APSInt Value = CE->getResultAsAPSInt();
+ if (Value.getBoolValue())
+ return visitChildStmt(IS->getThen());
+ else if (const Stmt *Else = IS->getElse())
+ return visitChildStmt(Else);
+ return true;
+ }
+
+ // Otherwise, compile the condition.
if (IS->isNonNegatedConsteval()) {
if (!this->emitIsConstantContext(IS))
return false;
@@ -5194,35 +5215,20 @@ template <class Emitter> bool Compiler<Emitter>::visitIfStmt(const IfStmt *IS) {
LabelTy LabelEnd = this->getLabel();
if (!this->jumpFalse(LabelElse))
return false;
- {
- LocalScope<Emitter> ThenScope(this);
- if (!visitStmt(IS->getThen()))
- return false;
- if (!ThenScope.destroyLocals())
- return false;
- }
+ if (!visitChildStmt(IS->getThen()))
+ return false;
if (!this->jump(LabelEnd))
return false;
this->emitLabel(LabelElse);
- {
- LocalScope<Emitter> ElseScope(this);
- if (!visitStmt(Else))
- return false;
- if (!ElseScope.destroyLocals())
- return false;
- }
+ if (!visitChildStmt(Else))
+ return false;
this->emitLabel(LabelEnd);
} else {
LabelTy LabelEnd = this->getLabel();
if (!this->jumpFalse(LabelEnd))
return false;
- {
- LocalScope<Emitter> ThenScope(this);
- if (!visitStmt(IS->getThen()))
- return false;
- if (!ThenScope.destroyLocals())
- return false;
- }
+ if (!visitChildStmt(IS->getThen()))
+ return false;
this->emitLabel(LabelEnd);
}
More information about the cfe-commits
mailing list