From 4a5a7f975d1cdcd182da1490fb6badd5f39ea54c Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Fri, 16 Jun 2023 15:21:32 -0700 Subject: [PATCH] bug fixes for script optimization intermediate forms --- auxil/gen-zam | 2 +- src/Stmt.h | 1 + src/Type.cc | 5 ++++- src/script_opt/Expr.cc | 27 ++++++++++++++++++++------- src/script_opt/Stmt.cc | 15 ++++++++++----- 5 files changed, 36 insertions(+), 14 deletions(-) diff --git a/auxil/gen-zam b/auxil/gen-zam index 16841c9584..f62a0215f0 160000 --- a/auxil/gen-zam +++ b/auxil/gen-zam @@ -1 +1 @@ -Subproject commit 16841c95849d4d82f239bfb0c46bc217af368da2 +Subproject commit f62a0215f063bc768d7e85b4a49faeb07ca3cb14 diff --git a/src/Stmt.h b/src/Stmt.h index dc1a33a45b..0e69a2e086 100644 --- a/src/Stmt.h +++ b/src/Stmt.h @@ -450,6 +450,7 @@ public: ReturnStmt(ExprPtr e, bool ignored); // Optimization-related: + bool IsReduced(Reducer* c) const override; StmtPtr DoReduce(Reducer* c) override; bool NoFlowAfter(bool ignore_break) const override { return true; } diff --git a/src/Type.cc b/src/Type.cc index c07a7b5fec..469a7ba6fd 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -788,9 +788,12 @@ bool FuncType::CheckArgs(const std::vector& args, bool is_init, bool do if ( my_args.size() != args.size() ) { if ( do_warn ) + { Warn(util::fmt("Wrong number of arguments for function. Expected %zu, got %zu.", args.size(), my_args.size())); - const_cast(this)->reported_error = true; + const_cast(this)->reported_error = true; + } + return false; } diff --git a/src/script_opt/Expr.cc b/src/script_opt/Expr.cc index b2e9880056..d0663fae05 100644 --- a/src/script_opt/Expr.cc +++ b/src/script_opt/Expr.cc @@ -1851,7 +1851,12 @@ ExprPtr AssignExpr::ReduceToSingleton(Reducer* c, StmtPtr& red_stmt) if ( val ) return make_intrusive(val); - return op1->AsRefExprPtr()->GetOp1(); + auto lhs = op1->AsRefExprPtr()->GetOp1(); + StmtPtr lhs_stmt; + auto new_op1 = lhs->ReduceToSingleton(c, lhs_stmt); + red_stmt = MergeStmts(red_stmt, lhs_stmt); + + return new_op1; } ExprPtr IndexSliceAssignExpr::Duplicate() @@ -2368,7 +2373,14 @@ bool CallExpr::HasReducedOps(Reducer* c) const if ( ! func->IsSingleton(c) ) return NonReduced(this); - return args->HasReducedOps(c); + // We don't use args->HasReducedOps() here because for ListExpr's + // the method has some special-casing that isn't germane for calls. + + for ( const auto& expr : args->Exprs() ) + if ( ! expr->IsSingleton(c) ) + return false; + + return true; } ExprPtr CallExpr::Reduce(Reducer* c, StmtPtr& red_stmt) @@ -2386,9 +2398,7 @@ ExprPtr CallExpr::Reduce(Reducer* c, StmtPtr& red_stmt) if ( ! func->IsSingleton(c) ) func = func->ReduceToSingleton(c, red_stmt); - StmtPtr red2_stmt; - // We assume that ListExpr won't transform itself fundamentally. - (void)args->Reduce(c, red2_stmt); + StmtPtr red2_stmt = args->ReduceToSingletons(c); // ### could check here for (1) pure function, and (2) all // arguments constants, and call it to fold right now. @@ -2558,11 +2568,14 @@ StmtPtr ListExpr::ReduceToSingletons(Reducer* c) loop_over_list(exprs, i) { - if ( exprs[i]->IsSingleton(c) ) + auto& e_i = exprs[i]; + + if ( e_i->IsSingleton(c) ) continue; StmtPtr e_stmt; - auto old = exprs.replace(i, exprs[i]->Reduce(c, e_stmt).release()); + auto new_e_i = e_i->ReduceToSingleton(c, e_stmt); + auto old = exprs.replace(i, new_e_i.release()); Unref(old); if ( e_stmt ) diff --git a/src/script_opt/Stmt.cc b/src/script_opt/Stmt.cc index 5ffdda0f28..9d49adf316 100644 --- a/src/script_opt/Stmt.cc +++ b/src/script_opt/Stmt.cc @@ -646,21 +646,26 @@ StmtPtr ReturnStmt::Duplicate() ReturnStmt::ReturnStmt(ExprPtr arg_e, bool ignored) : ExprStmt(STMT_RETURN, std::move(arg_e)) { } +bool ReturnStmt::IsReduced(Reducer* c) const + { + if ( ! e || e->IsSingleton(c) ) + return true; + + return NonReduced(e.get()); + } + StmtPtr ReturnStmt::DoReduce(Reducer* c) { if ( ! e ) return ThisPtr(); if ( c->Optimizing() ) - { e = c->OptExpr(e); - return ThisPtr(); - } - if ( ! e->IsSingleton(c) ) + else if ( ! e->IsSingleton(c) ) { StmtPtr red_e_stmt; - e = e->Reduce(c, red_e_stmt); + e = e->ReduceToSingleton(c, red_e_stmt); if ( red_e_stmt ) {