mirror of
https://github.com/zeek/zeek.git
synced 2025-10-04 23:58:20 +00:00
hooks for ZAM optimization of calls to particular functions
This commit is contained in:
parent
4b39e1f5f5
commit
e38053ee3c
2 changed files with 89 additions and 6 deletions
|
@ -151,6 +151,13 @@ bool Expr::IsReducedConditional(Reducer* c) const {
|
|||
|
||||
case EXPR_NAME: return IsReduced(c);
|
||||
|
||||
case EXPR_CALL: {
|
||||
if ( ! HasReducedOps(c) )
|
||||
return false;
|
||||
|
||||
return IsZAM_BuiltInCond(static_cast<const CallExpr*>(this));
|
||||
}
|
||||
|
||||
case EXPR_IN: {
|
||||
auto op1 = GetOp1();
|
||||
auto op2 = GetOp2();
|
||||
|
@ -276,6 +283,19 @@ ExprPtr Expr::ReduceToConditional(Reducer* c, StmtPtr& red_stmt) {
|
|||
|
||||
return Reduce(c, red_stmt);
|
||||
|
||||
case EXPR_CALL: {
|
||||
auto ce = static_cast<CallExpr*>(this);
|
||||
red_stmt = ce->ReduceToSingletons(c);
|
||||
|
||||
if ( IsZAM_BuiltInCond(ce) )
|
||||
return ThisPtr();
|
||||
|
||||
StmtPtr red_stmt2;
|
||||
auto res = Reduce(c, red_stmt2);
|
||||
red_stmt = MergeStmts(red_stmt, red_stmt2);
|
||||
return res;
|
||||
}
|
||||
|
||||
case EXPR_IN: {
|
||||
// This is complicated because there are lots of forms
|
||||
// of "in" expressions, and we're only interested in
|
||||
|
@ -2069,9 +2089,14 @@ ExprPtr CallExpr::Inline(Inliner* inl) {
|
|||
return ThisPtr();
|
||||
}
|
||||
|
||||
bool CallExpr::IsReduced(Reducer* c) const { return func->IsSingleton(c) && args->IsReduced(c); }
|
||||
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::HasReducedOps(Reducer* c) const {
|
||||
if ( WillTransform(c) )
|
||||
return false;
|
||||
|
||||
if ( ! func->IsSingleton(c) )
|
||||
return NonReduced(this);
|
||||
|
||||
|
@ -2090,7 +2115,6 @@ ExprPtr CallExpr::Reduce(Reducer* c, StmtPtr& red_stmt) {
|
|||
func = c->UpdateExpr(func);
|
||||
auto e = c->UpdateExpr(args);
|
||||
args = e->AsListExprPtr();
|
||||
return ThisPtr();
|
||||
}
|
||||
|
||||
red_stmt = nullptr;
|
||||
|
@ -2100,12 +2124,22 @@ ExprPtr CallExpr::Reduce(Reducer* c, StmtPtr& red_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.
|
||||
|
||||
red_stmt = MergeStmts(red_stmt, std::move(red2_stmt));
|
||||
|
||||
if ( GetType()->Tag() == TYPE_VOID )
|
||||
if ( CheckForBuiltin() ) {
|
||||
StmtPtr red3_stmt;
|
||||
auto res = TransformToBuiltin()->Reduce(c, red3_stmt);
|
||||
red_stmt = MergeStmts(red_stmt, std::move(red3_stmt));
|
||||
return res;
|
||||
}
|
||||
|
||||
if ( IsFoldableBiF() ) {
|
||||
auto res = Eval(nullptr);
|
||||
ASSERT(res);
|
||||
return with_location_of(make_intrusive<ConstExpr>(res), this);
|
||||
}
|
||||
|
||||
if ( c->Optimizing() || GetType()->Tag() == TYPE_VOID )
|
||||
return ThisPtr();
|
||||
else
|
||||
return AssignToTemporary(c, red_stmt);
|
||||
|
@ -2122,6 +2156,49 @@ StmtPtr CallExpr::ReduceToSingletons(Reducer* c) {
|
|||
return MergeStmts(func_stmt, args_stmt);
|
||||
}
|
||||
|
||||
bool CallExpr::IsFoldableBiF() const {
|
||||
if ( IsAggr(type) )
|
||||
return false;
|
||||
|
||||
if ( ! AllConstArgs() )
|
||||
return false;
|
||||
|
||||
if ( func->Tag() != EXPR_NAME )
|
||||
return false;
|
||||
|
||||
return is_foldable(func->AsNameExpr()->Id()->Name());
|
||||
}
|
||||
|
||||
bool CallExpr::AllConstArgs() const {
|
||||
for ( auto e : Args()->Exprs() )
|
||||
if ( e->Tag() != EXPR_CONST )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static std::map<std::string, ScriptOptBuiltinExpr::SOBuiltInTag> known_funcs = {
|
||||
{"id_string", ScriptOptBuiltinExpr::FUNC_ID_STRING}};
|
||||
|
||||
bool CallExpr::CheckForBuiltin() const {
|
||||
if ( func->Tag() != EXPR_NAME )
|
||||
return false;
|
||||
|
||||
auto f_id = func->AsNameExpr()->Id();
|
||||
|
||||
auto kf = known_funcs.find(f_id->Name());
|
||||
if ( kf == known_funcs.end() )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ExprPtr CallExpr::TransformToBuiltin() {
|
||||
auto kf = known_funcs[func->AsNameExpr()->Id()->Name()];
|
||||
CallExprPtr this_ptr = {NewRef{}, this};
|
||||
return with_location_of(make_intrusive<ScriptOptBuiltinExpr>(kf, this_ptr), this);
|
||||
}
|
||||
|
||||
ExprPtr LambdaExpr::Duplicate() { return SetSucc(new LambdaExpr(this)); }
|
||||
|
||||
bool LambdaExpr::IsReduced(Reducer* c) const {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue