@@ -5167,6 +5167,12 @@ bool Compiler<Emitter>::visitReturnStmt(const ReturnStmt *RS) {
51675167}
51685168
51695169template <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