summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2016-06-07 19:16:31 -0400
committerTavian Barnes <tavianator@tavianator.com>2016-06-07 19:16:31 -0400
commit6528f13b22941bb46bff3644f15a596187046b91 (patch)
tree2c3167f7ba913c72022124d8119c0545b63c08f8
parentf7ecc531ace37997e08f4c64503e428780f6a228 (diff)
downloadbfs-6528f13b22941bb46bff3644f15a596187046b91.tar.xz
Remove redundant pure expressions from the top level.
-rw-r--r--parse.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/parse.c b/parse.c
index 2c02c83..c65d61f 100644
--- a/parse.c
+++ b/parse.c
@@ -1620,6 +1620,33 @@ static struct expr *parse_expr(struct parser_state *state) {
}
/**
+ * Apply top-level optimizations.
+ */
+static struct expr *optimize_whole_expr(const struct parser_state *state, struct expr *expr) {
+ int optlevel = state->cmdline->optlevel;
+
+ if (optlevel >= 2) {
+ while ((expr->eval == eval_and || expr->eval == eval_or || expr->eval == eval_comma)
+ && expr->rhs->pure) {
+ debug_opt(state, "-O2: top-level purity: %e <==> %e\n", expr, expr->lhs);
+
+ struct expr *old = expr;
+ expr = old->lhs;
+ old->lhs = NULL;
+ free_expr(old);
+ }
+ }
+
+ if (optlevel >= 3 && expr->pure && expr != &expr_false) {
+ debug_opt(state, "-O3: top-level purity: %e <==> %e\n", expr, &expr_false);
+ free_expr(expr);
+ expr = &expr_false;
+ }
+
+ return expr;
+}
+
+/**
* Dump the parsed form of the command line, for debugging.
*/
static void dump_cmdline(const struct cmdline *cmdline) {
@@ -1738,11 +1765,7 @@ struct cmdline *parse_cmdline(int argc, char *argv[]) {
}
}
- if (cmdline->optlevel >= 3 && cmdline->expr->pure && cmdline->expr != &expr_false) {
- debug_opt(&state, "-O3: top-level purity: %e <==> %e\n", cmdline->expr, &expr_false);
- free_expr(cmdline->expr);
- cmdline->expr = &expr_false;
- }
+ cmdline->expr = optimize_whole_expr(&state, cmdline->expr);
if (cmdline->nroots == 0) {
if (!cmdline_add_root(cmdline, ".")) {