summaryrefslogtreecommitdiffstats
path: root/opt.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2017-09-17 10:49:00 -0400
committerTavian Barnes <tavianator@tavianator.com>2017-09-17 10:49:00 -0400
commit86d790e134d5a12e569e1d78804bc5a54ca9ed25 (patch)
tree5c1d85cf208760553a675be13af19e029e5f48c0 /opt.c
parent768f8a6111ee25a1035d572e58e14c31d7bf5e23 (diff)
downloadbfs-86d790e134d5a12e569e1d78804bc5a54ca9ed25.tar.xz
opt: Move some aggressive optimizations back to -O4
Diffstat (limited to 'opt.c')
-rw-r--r--opt.c28
1 files changed, 18 insertions, 10 deletions
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;
}
}