From 86d790e134d5a12e569e1d78804bc5a54ca9ed25 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Sun, 17 Sep 2017 10:49:00 -0400 Subject: opt: Move some aggressive optimizations back to -O4 --- eval.c | 9 +-------- opt.c | 28 ++++++++++++++++++---------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/eval.c b/eval.c index 5196b57..08d2643 100644 --- a/eval.c +++ b/eval.c @@ -1091,7 +1091,7 @@ static enum bftw_action cmdline_callback(struct BFTW *ftwbuf, void *ptr) { goto done; } - if (ftwbuf->depth >= cmdline->maxdepth) { + if (cmdline->maxdepth < 0 || ftwbuf->depth >= cmdline->maxdepth) { state.action = BFTW_SKIP_SUBTREE; } @@ -1216,13 +1216,6 @@ int eval_cmdline(const struct cmdline *cmdline) { return EXIT_SUCCESS; } - if (cmdline->optlevel >= 4 && cmdline->expr->eval == eval_false) { - if (cmdline->debug & DEBUG_OPT) { - fputs("-O4: skipping evaluation of top-level -false\n", stderr); - } - return EXIT_SUCCESS; - } - int nopenfd = infer_fdlimit(cmdline); struct callback_args args = { diff --git a/opt.c b/opt.c index 26aec0b..717af90 100644 --- a/opt.c +++ b/opt.c @@ -462,7 +462,7 @@ fail: } /** Optimize an expression in an ignored-result context. */ -static struct expr *ignore_result(const struct opt_state *state, struct expr *expr) { +static struct expr *ignore_result(const struct opt_state *state, struct expr *expr, int purelevel) { int optlevel = state->cmdline->optlevel; if (optlevel >= 1) { @@ -470,18 +470,18 @@ static struct expr *ignore_result(const struct opt_state *state, struct expr *ex if (expr->eval == eval_not) { debug_opt(state, "-O1: ignored result: %e --> %e\n", expr, expr->rhs); expr = extract_child_expr(expr, &expr->rhs); - } else if (optlevel >= 2 + } else if (optlevel >= purelevel && (expr->eval == eval_and || expr->eval == eval_or || expr->eval == eval_comma) && expr->rhs->pure) { - debug_opt(state, "-O2: ignored result: %e --> %e\n", expr, expr->lhs); + debug_opt(state, "-O%d: ignored result: %e --> %e\n", purelevel, expr, expr->lhs); expr = extract_child_expr(expr, &expr->lhs); } else { break; } } - if (optlevel >= 2 && expr->pure && expr != &expr_false) { - debug_opt(state, "-O2: ignored result: %e --> %e\n", expr, &expr_false); + if (optlevel >= purelevel && expr->pure && expr != &expr_false) { + debug_opt(state, "-O%d: ignored result: %e --> %e\n", purelevel, expr, &expr_false); free_expr(expr); expr = &expr_false; } @@ -499,7 +499,7 @@ static struct expr *optimize_comma_expr(const struct opt_state *state, struct ex int optlevel = state->cmdline->optlevel; if (optlevel >= 1) { - lhs = expr->lhs = ignore_result(state, lhs); + lhs = expr->lhs = ignore_result(state, lhs, 2); if (expr_never_returns(lhs)) { debug_opt(state, "-O1: reachability: %e <==> %e\n", expr, lhs); @@ -621,16 +621,24 @@ int optimize_cmdline(struct cmdline *cmdline) { return -1; } - cmdline->expr = ignore_result(&state, cmdline->expr); + cmdline->expr = ignore_result(&state, cmdline->expr, 4); - if (cmdline->optlevel >= 2) { + int minlevel = 2; + if (facts_impossible(&facts_when_impure)) { + // If we've detected that all side effects are unreachable, the + // following optimization will skip the entire traversal, so + // only do it at -O4 + minlevel = 4; + } + + if (cmdline->optlevel >= minlevel) { if (facts_when_impure.mindepth > cmdline->mindepth) { - debug_opt(&state, "-O2: data flow: mindepth --> %d\n"); + debug_opt(&state, "-O%d: data flow: mindepth --> %d\n", minlevel, facts_when_impure.mindepth); cmdline->mindepth = facts_when_impure.mindepth; } if (facts_when_impure.maxdepth < cmdline->maxdepth) { - debug_opt(&state, "-O2: data flow: maxdepth --> %d\n"); + debug_opt(&state, "-O%d: data flow: maxdepth --> %d\n", minlevel, facts_when_impure.maxdepth); cmdline->maxdepth = facts_when_impure.maxdepth; } } -- cgit v1.2.3