From 59803f35895d14ae95a64ca95197276667507464 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Mon, 28 Jul 2025 11:22:28 -0700 Subject: [PATCH] working for folding & for loops - not enough win though --- src/Expr.h | 2 ++ src/script_opt/Expr.cc | 35 ++++++++++++++++++++++++++++++----- src/script_opt/Reduce.cc | 11 +++++++++++ src/script_opt/Reduce.h | 4 ++++ src/script_opt/Stmt.cc | 2 ++ 5 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/Expr.h b/src/Expr.h index 9745445c9f..69fd3bd00a 100644 --- a/src/Expr.h +++ b/src/Expr.h @@ -1568,6 +1568,8 @@ public: ExprPtr Duplicate() override; ExprPtr Inline(Inliner* inl) override; + ValPtr FoldVal() const override; + bool IsReduced(Reducer* c) const override; bool HasReducedOps(Reducer* c) const override; ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override; diff --git a/src/script_opt/Expr.cc b/src/script_opt/Expr.cc index bc8fa55248..d37160e5ef 100644 --- a/src/script_opt/Expr.cc +++ b/src/script_opt/Expr.cc @@ -473,11 +473,18 @@ ExprPtr UnaryExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { if ( ! op->IsSingleton(c) ) op = op->ReduceToSingleton(c, red_stmt); - auto op_val = op->FoldVal(); - if ( op_val ) { - auto fold = Fold(op_val.get()); - if ( fold->GetType()->Tag() != TYPE_OPAQUE ) - return TransformMe(make_intrusive(fold), c, red_stmt); + if ( tag != EXPR_VECTOR_CONSTRUCTOR && tag != EXPR_TABLE_CONSTRUCTOR && tag != EXPR_RECORD_CONSTRUCTOR ) { + auto op_val = op->FoldVal(); + if ( ! op_val ) { + op_val = c->EvalIfGlobalAggrConstant(op); + if ( op_val ) + printf("unary w/ global aggr fold: %s\n", obj_desc(this).c_str()); + } + if ( op_val ) { + auto fold = Fold(op_val.get()); + if ( fold->GetType()->Tag() != TYPE_OPAQUE ) + return TransformMe(make_intrusive(fold), c, red_stmt); + } } if ( c->Optimizing() ) @@ -522,7 +529,13 @@ ExprPtr BinaryExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { // We can turn the list into a ListVal. op1_fold_val = op1->Eval(nullptr); + if ( ! op1_fold_val ) + op1_fold_val = c->EvalIfGlobalAggrConstant(op1); + auto op2_fold_val = op2->FoldVal(); + if ( ! op2_fold_val ) + op2_fold_val = c->EvalIfGlobalAggrConstant(op2); + if ( op1_fold_val && op2_fold_val ) { auto fold = Fold(op1_fold_val.get(), op2_fold_val.get()); if ( fold->GetType()->Tag() != TYPE_OPAQUE ) @@ -2480,6 +2493,18 @@ ExprPtr ListExpr::Inline(Inliner* inl) { return ThisPtr(); } +ValPtr ListExpr::FoldVal() const { + std::vector vals; + vals.reserve(exprs.length()); + loop_over_list(exprs, i) { + auto v = exprs[i]->FoldVal(); + if ( ! v ) + return nullptr; + vals.push_back(std::move(v)); + } + return make_intrusive(cast_intrusive(type), std::move(vals)); +} + bool ListExpr::IsReduced(Reducer* c) const { for ( const auto& expr : exprs ) if ( ! expr->IsSingleton(c) ) { diff --git a/src/script_opt/Reduce.cc b/src/script_opt/Reduce.cc index 44afdafd4a..171050ee48 100644 --- a/src/script_opt/Reduce.cc +++ b/src/script_opt/Reduce.cc @@ -634,6 +634,17 @@ ConstExprPtr Reducer::Fold(ExprPtr e) { return c; } +ValPtr Reducer::EvalIfGlobalAggrConstant(ExprPtr e) const { + if ( e->Tag() != EXPR_NAME ) + return nullptr; + + auto id = e->AsNameExpr()->Id(); + if ( id->IsGlobal() && pfs->ConstAggrGlobals().count(id) > 0 ) + return id->GetVal(); + + return nullptr; +} + void Reducer::FoldedTo(ExprPtr e, ConstExprPtr c) { c->SetLocationInfo(e->GetLocationInfo()); om.AddObj(e.get()); diff --git a/src/script_opt/Reduce.h b/src/script_opt/Reduce.h index b69e4e0229..eaa85e3b80 100644 --- a/src/script_opt/Reduce.h +++ b/src/script_opt/Reduce.h @@ -145,6 +145,10 @@ public: // (which must have constant operands). ConstExprPtr Fold(ExprPtr e); + // If the given expression refers to a global that's both (1) an aggregate + // value, and (2) constant then returns its constant value, nil otherwise. + ValPtr EvalIfGlobalAggrConstant(ExprPtr e) const; + // Notes that the given expression has been folded to the given constant. void FoldedTo(ExprPtr orig, ConstExprPtr c); diff --git a/src/script_opt/Stmt.cc b/src/script_opt/Stmt.cc index 62acce3441..6807422622 100644 --- a/src/script_opt/Stmt.cc +++ b/src/script_opt/Stmt.cc @@ -619,6 +619,8 @@ StmtPtr ForStmt::DoReduce(Reducer* c) { e = c->OptExpr(e); else { e = e->Reduce(c, red_e_stmt); + if ( c->EvalIfGlobalAggrConstant(e) ) + printf("for loop opt: %s\n", obj_desc(this).c_str()); c->UpdateIDs(loop_vars); if ( value_var )