From 0fda589a19715e72355cae119e0e9d63314b1128 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Tue, 3 Dec 2024 12:47:20 -0700 Subject: [PATCH] ZAM optimization now removes hook calls to hooks without any bodies --- src/Expr.h | 1 + src/script_opt/Expr.cc | 24 +++++++++++++++++++++++- src/script_opt/Stmt.cc | 9 ++++----- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/Expr.h b/src/Expr.h index ffd325de50..78576758a9 100644 --- a/src/Expr.h +++ b/src/Expr.h @@ -1458,6 +1458,7 @@ protected: bool IsFoldableBiF() const; bool AllConstArgs() const; bool CheckForBuiltin() const; + bool IsEmptyHook() const; ExprPtr TransformToBuiltin(); ExprPtr func; diff --git a/src/script_opt/Expr.cc b/src/script_opt/Expr.cc index 861468b91d..8cc2eefeaf 100644 --- a/src/script_opt/Expr.cc +++ b/src/script_opt/Expr.cc @@ -2249,7 +2249,7 @@ ExprPtr CallExpr::Inline(Inliner* inl) { bool CallExpr::IsReduced(Reducer* c) const { return func->IsSingleton(c) && args->IsReduced(c) && ! WillTransform(c); } -bool CallExpr::WillTransform(Reducer* c) const { return CheckForBuiltin() || IsFoldableBiF(); } +bool CallExpr::WillTransform(Reducer* c) const { return CheckForBuiltin() || IsFoldableBiF() || IsEmptyHook(); } bool CallExpr::HasReducedOps(Reducer* c) const { if ( WillTransform(c) ) @@ -2280,6 +2280,12 @@ ExprPtr CallExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { if ( ! func->IsSingleton(c) ) func = func->ReduceToSingleton(c, red_stmt); + if ( IsEmptyHook() ) { + // Reduce the arguments to pick up any side effects they include. + (void)args->Reduce(c, red_stmt); + return with_location_of(make_intrusive(val_mgr->True()), this); + } + StmtPtr red2_stmt = args->ReduceToSingletons(c); red_stmt = MergeStmts(red_stmt, std::move(red2_stmt)); @@ -2357,6 +2363,22 @@ ExprPtr CallExpr::TransformToBuiltin() { return with_location_of(make_intrusive(kf, this_ptr), this); } +bool CallExpr::IsEmptyHook() const { + if ( func->Tag() != EXPR_NAME ) + return false; + + auto func_id = func->AsNameExpr()->IdPtr(); + auto func_val = func_id->GetVal(); + + if ( ! func_val || ! func_id->IsGlobal() ) + return false; + + if ( func_id->GetType()->AsFuncType()->Flavor() != FUNC_FLAVOR_HOOK ) + return false; + + return ! func_val->AsFuncVal()->Get()->HasBodies(); +} + ExprPtr LambdaExpr::Duplicate() { return SetSucc(new LambdaExpr(this)); } bool LambdaExpr::IsReduced(Reducer* c) const { diff --git a/src/script_opt/Stmt.cc b/src/script_opt/Stmt.cc index 8ef72c60b4..95ef0a5cec 100644 --- a/src/script_opt/Stmt.cc +++ b/src/script_opt/Stmt.cc @@ -119,7 +119,7 @@ StmtPtr ExprStmt::DoReduce(Reducer* c) { auto t = e->Tag(); - if ( t == EXPR_NOP ) + if ( t == EXPR_NOP || t == EXPR_CONST ) return TransformMe(make_intrusive(), c); if ( c->Optimizing() ) { @@ -138,10 +138,9 @@ StmtPtr ExprStmt::DoReduce(Reducer* c) { StmtPtr red_e_stmt; - if ( t == EXPR_CALL ) - // A bare call. If we reduce it regularly, if - // it has a non-void type it'll generate an - // assignment to a temporary. + if ( t == EXPR_CALL && ! e->WillTransform(c) ) + // A bare call. If we reduce it regularly, if it has a non-void + // type it'll generate an assignment to a temporary. red_e_stmt = e->ReduceToSingletons(c); else { e = e->Reduce(c, red_e_stmt);