diff options
Diffstat (limited to 'opt.c')
-rw-r--r-- | opt.c | 28 |
1 files changed, 18 insertions, 10 deletions
@@ -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; } } |