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?= <tbae...@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); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits