summaryrefslogtreecommitdiffstats
path: root/src/opt.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2023-01-24 16:51:33 -0500
committerTavian Barnes <tavianator@tavianator.com>2023-01-24 16:51:33 -0500
commitb922add3a5597020a0ad5357b5fc390b3fae709f (patch)
treea8b7ddb627811b8137b3a30c0addafb9b0494386 /src/opt.c
parent0c0dbcbcdf04e55c2805eb71aecd968ea2ffe1a0 (diff)
downloadbfs-b922add3a5597020a0ad5357b5fc390b3fae709f.tar.xz
opt: Use a table for simple range comparisons
Diffstat (limited to 'src/opt.c')
-rw-r--r--src/opt.c38
1 files changed, 24 insertions, 14 deletions
diff --git a/src/opt.c b/src/opt.c
index a33ffea..50fcd20 100644
--- a/src/opt.c
+++ b/src/opt.c
@@ -789,8 +789,6 @@ static struct bfs_expr *optimize_access(struct opt_state *state, struct bfs_expr
/** Optimize -gid. */
static struct bfs_expr *optimize_gid(struct opt_state *state, struct bfs_expr *expr) {
- infer_icmp_facts(state, expr, GID_RANGE);
-
struct range *range = &state->facts_when_true.ranges[GID_RANGE];
if (range->min == range->max) {
gid_t gid = range->min;
@@ -805,8 +803,6 @@ static struct bfs_expr *optimize_gid(struct opt_state *state, struct bfs_expr *e
/** Optimize -uid. */
static struct bfs_expr *optimize_uid(struct opt_state *state, struct bfs_expr *expr) {
- infer_icmp_facts(state, expr, UID_RANGE);
-
struct range *range = &state->facts_when_true.ranges[UID_RANGE];
if (range->min == range->max) {
uid_t uid = range->min;
@@ -860,6 +856,23 @@ static const struct {
{eval_xattr, XATTR_PRED},
};
+/**
+ * Table of simple range comparisons.
+ */
+static const struct {
+ /** The evaluation function this optimizer applies to. */
+ bfs_eval_fn *eval_fn;
+ /** The corresponding range. */
+ enum range_type range;
+} opt_ranges[] = {
+ {eval_depth, DEPTH_RANGE},
+ {eval_gid, GID_RANGE},
+ {eval_inum, INUM_RANGE},
+ {eval_links, LINKS_RANGE},
+ {eval_size, SIZE_RANGE},
+ {eval_uid, UID_RANGE},
+};
+
/** Signature for custom optimizer functions. */
typedef struct bfs_expr *bfs_opt_fn(struct opt_state *state, struct bfs_expr *expr);
@@ -896,6 +909,13 @@ static struct bfs_expr *optimize_expr_lookup(struct opt_state *state, struct bfs
}
}
+ for (size_t i = 0; i < BFS_COUNTOF(opt_ranges); ++i) {
+ if (opt_ranges[i].eval_fn == expr->eval_fn) {
+ infer_icmp_facts(state, expr, opt_ranges[i].range);
+ break;
+ }
+ }
+
for (size_t i = 0; i < BFS_COUNTOF(opt_fns); ++i) {
if (opt_fns[i].eval_fn == expr->eval_fn) {
return opt_fns[i].opt_fn(state, expr);
@@ -923,16 +943,6 @@ static struct bfs_expr *optimize_expr_recursive(struct opt_state *state, struct
facts_union(state->facts_when_impure, state->facts_when_impure, &state->facts);
}
- if (expr->eval_fn == eval_depth) {
- infer_icmp_facts(state, expr, DEPTH_RANGE);
- } else if (expr->eval_fn == eval_inum) {
- infer_icmp_facts(state, expr, INUM_RANGE);
- } else if (expr->eval_fn == eval_links) {
- infer_icmp_facts(state, expr, LINKS_RANGE);
- } else if (expr->eval_fn == eval_size) {
- infer_icmp_facts(state, expr, SIZE_RANGE);
- }
-
expr = optimize_expr_lookup(state, expr);
if (!expr) {
return NULL;