mirror of
https://github.com/zeek/zeek.git
synced 2025-10-06 16:48:19 +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
|
@ -1381,6 +1381,7 @@ public:
|
||||||
ExprPtr Inline(Inliner* inl) override;
|
ExprPtr Inline(Inliner* inl) override;
|
||||||
|
|
||||||
bool IsReduced(Reducer* c) const override;
|
bool IsReduced(Reducer* c) const override;
|
||||||
|
bool WillTransform(Reducer* c) const override;
|
||||||
bool HasReducedOps(Reducer* c) const override;
|
bool HasReducedOps(Reducer* c) const override;
|
||||||
ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override;
|
ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override;
|
||||||
StmtPtr ReduceToSingletons(Reducer* c) override;
|
StmtPtr ReduceToSingletons(Reducer* c) override;
|
||||||
|
@ -1388,6 +1389,11 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void ExprDescribe(ODesc* d) const override;
|
void ExprDescribe(ODesc* d) const override;
|
||||||
|
|
||||||
|
bool IsFoldableBiF() const;
|
||||||
|
bool AllConstArgs() const;
|
||||||
|
bool CheckForBuiltin() const;
|
||||||
|
ExprPtr TransformToBuiltin();
|
||||||
|
|
||||||
ExprPtr func;
|
ExprPtr func;
|
||||||
ListExprPtr args;
|
ListExprPtr args;
|
||||||
bool in_when;
|
bool in_when;
|
||||||
|
|
|
@ -151,6 +151,13 @@ bool Expr::IsReducedConditional(Reducer* c) const {
|
||||||
|
|
||||||
case EXPR_NAME: return IsReduced(c);
|
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: {
|
case EXPR_IN: {
|
||||||
auto op1 = GetOp1();
|
auto op1 = GetOp1();
|
||||||
auto op2 = GetOp2();
|
auto op2 = GetOp2();
|
||||||
|
@ -276,6 +283,19 @@ ExprPtr Expr::ReduceToConditional(Reducer* c, StmtPtr& red_stmt) {
|
||||||
|
|
||||||
return Reduce(c, 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: {
|
case EXPR_IN: {
|
||||||
// This is complicated because there are lots of forms
|
// This is complicated because there are lots of forms
|
||||||
// of "in" expressions, and we're only interested in
|
// of "in" expressions, and we're only interested in
|
||||||
|
@ -2069,9 +2089,14 @@ ExprPtr CallExpr::Inline(Inliner* inl) {
|
||||||
return ThisPtr();
|
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 {
|
bool CallExpr::HasReducedOps(Reducer* c) const {
|
||||||
|
if ( WillTransform(c) )
|
||||||
|
return false;
|
||||||
|
|
||||||
if ( ! func->IsSingleton(c) )
|
if ( ! func->IsSingleton(c) )
|
||||||
return NonReduced(this);
|
return NonReduced(this);
|
||||||
|
|
||||||
|
@ -2090,7 +2115,6 @@ ExprPtr CallExpr::Reduce(Reducer* c, StmtPtr& red_stmt) {
|
||||||
func = c->UpdateExpr(func);
|
func = c->UpdateExpr(func);
|
||||||
auto e = c->UpdateExpr(args);
|
auto e = c->UpdateExpr(args);
|
||||||
args = e->AsListExprPtr();
|
args = e->AsListExprPtr();
|
||||||
return ThisPtr();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
red_stmt = nullptr;
|
red_stmt = nullptr;
|
||||||
|
@ -2100,12 +2124,22 @@ ExprPtr CallExpr::Reduce(Reducer* c, StmtPtr& red_stmt) {
|
||||||
|
|
||||||
StmtPtr red2_stmt = args->ReduceToSingletons(c);
|
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));
|
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();
|
return ThisPtr();
|
||||||
else
|
else
|
||||||
return AssignToTemporary(c, red_stmt);
|
return AssignToTemporary(c, red_stmt);
|
||||||
|
@ -2122,6 +2156,49 @@ StmtPtr CallExpr::ReduceToSingletons(Reducer* c) {
|
||||||
return MergeStmts(func_stmt, args_stmt);
|
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)); }
|
ExprPtr LambdaExpr::Duplicate() { return SetSucc(new LambdaExpr(this)); }
|
||||||
|
|
||||||
bool LambdaExpr::IsReduced(Reducer* c) const {
|
bool LambdaExpr::IsReduced(Reducer* c) const {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue