From 60b51a3bda3f3fc220a2fa56de5f86c4bac35f2e Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Tue, 24 Jan 2023 17:08:58 -0500 Subject: opt: Move always_{true,false} out of the parser --- src/opt.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'src/opt.c') diff --git a/src/opt.c b/src/opt.c index 934a4b4..c80d584 100644 --- a/src/opt.c +++ b/src/opt.c @@ -45,6 +45,7 @@ #include "ctx.h" #include "diag.h" #include "eval.h" +#include "exec.h" #include "expr.h" #include "pwcache.h" #include @@ -799,6 +800,15 @@ static struct bfs_expr *optimize_empty(struct opt_state *state, struct bfs_expr return expr; } +/** Optimize -{exec,ok}{,dir}. */ +static struct bfs_expr *optimize_exec(struct opt_state *state, struct bfs_expr *expr) { + if (expr->exec->flags & BFS_EXEC_MULTI) { + expr->always_true = true; + } + + return expr; +} + /** Optimize -gid. */ static struct bfs_expr *optimize_gid(struct opt_state *state, struct bfs_expr *expr) { struct range *range = &state->facts_when_true.ranges[GID_RANGE]; @@ -891,6 +901,34 @@ static bfs_eval_fn *const opt_pure[] = { eval_xattrname, }; +/** + * Table of always-true expressions. + */ +static bfs_eval_fn *const opt_always_true[] = { + eval_fls, + eval_fprint, + eval_fprint0, + eval_fprintf, + eval_fprintx, + eval_prune, + eval_true, + + // Non-returning + eval_exit, + eval_quit, +}; + +/** + * Table of always-false expressions. + */ +static bfs_eval_fn *const opt_always_false[] = { + eval_false, + + // Non-returning + eval_exit, + eval_quit, +}; + /** * Table of simple predicates. */ @@ -940,6 +978,7 @@ static const struct { // Primaries {eval_access, optimize_access}, {eval_empty, optimize_empty}, + {eval_exec, optimize_exec}, {eval_gid, optimize_gid}, {eval_samefile, optimize_samefile}, {eval_type, optimize_type}, @@ -964,6 +1003,20 @@ static struct bfs_expr *optimize_expr_lookup(struct opt_state *state, struct bfs } } + for (size_t i = 0; i < BFS_COUNTOF(opt_always_true); ++i) { + if (opt_always_true[i] == expr->eval_fn) { + expr->always_true = true; + break; + } + } + + for (size_t i = 0; i < BFS_COUNTOF(opt_always_false); ++i) { + if (opt_always_false[i] == expr->eval_fn) { + expr->always_false = true; + break; + } + } + for (size_t i = 0; i < BFS_COUNTOF(opt_preds); ++i) { if (opt_preds[i].eval_fn == expr->eval_fn) { infer_pred_facts(state, opt_preds[i].pred); @@ -1026,9 +1079,11 @@ static struct bfs_expr *optimize_expr_recursive(struct opt_state *state, struct } if (expr->always_true) { + expr->probability = 1.0; set_facts_impossible(&state->facts_when_false); } if (expr->always_false) { + expr->probability = 0.0; set_facts_impossible(&state->facts_when_true); } -- cgit v1.2.3