summaryrefslogtreecommitdiffstats
path: root/opt.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2020-06-07 14:04:20 -0400
committerTavian Barnes <tavianator@tavianator.com>2020-06-07 15:16:10 -0400
commit1bce3b33acbfcfbfa03f1174d6e00c125cd8625d (patch)
tree9cb9efd81d667b711845878310afb39183cae847 /opt.c
parentfaee855b1e886dacc999e1dccf7f8e2c750f33c6 (diff)
downloadbfs-1bce3b33acbfcfbfa03f1174d6e00c125cd8625d.tar.xz
Implement -exclude, a special form for convenient exclusions
Fixes #8.
Diffstat (limited to 'opt.c')
-rw-r--r--opt.c57
1 files changed, 43 insertions, 14 deletions
diff --git a/opt.c b/opt.c
index 820f421..6a62790 100644
--- a/opt.c
+++ b/opt.c
@@ -803,6 +803,13 @@ static struct expr *optimize_expr_recursive(struct opt_state *state, struct expr
state->facts_when_true = state->facts;
state->facts_when_false = state->facts;
+ if (facts_are_impossible(&state->facts)) {
+ debug_opt(state, 2, "reachability: %pe --> %pe\n", expr, &expr_false);
+ free_expr(expr);
+ expr = &expr_false;
+ goto done;
+ }
+
if (!expr->rhs && !expr->pure) {
facts_union(state->facts_when_impure, state->facts_when_impure, &state->facts);
}
@@ -953,6 +960,29 @@ static bool reorder_expr_recursive(const struct opt_state *state, struct expr *e
return ret;
}
+/**
+ * Optimize a top-level expression.
+ */
+static struct expr *optimize_expr(struct opt_state *state, struct expr *expr) {
+ struct opt_facts saved_impure = *state->facts_when_impure;
+
+ expr = optimize_expr_recursive(state, expr);
+ if (!expr) {
+ return NULL;
+ }
+
+ if (state->cmdline->optlevel >= 3 && reorder_expr_recursive(state, expr)) {
+ // Re-do optimizations to account for the new ordering
+ *state->facts_when_impure = saved_impure;
+ expr = optimize_expr_recursive(state, expr);
+ if (!expr) {
+ return NULL;
+ }
+ }
+
+ return expr;
+}
+
int optimize_cmdline(struct cmdline *cmdline) {
struct opt_facts facts_when_impure;
set_facts_impossible(&facts_when_impure);
@@ -963,32 +993,31 @@ int optimize_cmdline(struct cmdline *cmdline) {
};
facts_init(&state.facts);
- struct range *depth = &state.facts.ranges[DEPTH_RANGE];
- depth->min = cmdline->mindepth;
- depth->max = cmdline->maxdepth;
+ cmdline->exclude = optimize_expr(&state, cmdline->exclude);
+ if (!cmdline->exclude) {
+ return -1;
+ }
- int optlevel = cmdline->optlevel;
+ // Only non-excluded files are evaluated
+ state.facts = state.facts_when_false;
+
+ struct range *depth = &state.facts.ranges[DEPTH_RANGE];
+ constrain_min(depth, cmdline->mindepth);
+ constrain_max(depth, cmdline->maxdepth);
- cmdline->expr = optimize_expr_recursive(&state, cmdline->expr);
+ cmdline->expr = optimize_expr(&state, cmdline->expr);
if (!cmdline->expr) {
return -1;
}
- if (optlevel >= 3 && reorder_expr_recursive(&state, cmdline->expr)) {
- // Re-do optimizations to account for the new ordering
- set_facts_impossible(&facts_when_impure);
- cmdline->expr = optimize_expr_recursive(&state, cmdline->expr);
- if (!cmdline->expr) {
- return -1;
- }
- }
-
cmdline->expr = ignore_result(&state, cmdline->expr);
const struct range *depth_when_impure = &facts_when_impure.ranges[DEPTH_RANGE];
long long mindepth = depth_when_impure->min;
long long maxdepth = depth_when_impure->max;
+ int optlevel = cmdline->optlevel;
+
if (optlevel >= 2 && mindepth > cmdline->mindepth) {
if (mindepth > INT_MAX) {
mindepth = INT_MAX;