From 1bce3b33acbfcfbfa03f1174d6e00c125cd8625d Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Sun, 7 Jun 2020 14:04:20 -0400 Subject: Implement -exclude, a special form for convenient exclusions Fixes #8. --- opt.c | 57 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 14 deletions(-) (limited to 'opt.c') 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; -- cgit v1.2.3