diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2019-03-20 18:29:16 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2019-03-20 18:29:16 -0400 |
commit | 344f9c2f844b20a8ba206595c28429a196383e23 (patch) | |
tree | 03981ef52bab3196c43fbc87e30549cf19f5eb68 | |
parent | 2e10b1d55bccbbe3de811df91a70772978e76abf (diff) | |
download | bfs-344f9c2f844b20a8ba206595c28429a196383e23.tar.xz |
opt: Replace -a -false/-o -true with -not when possible
-rw-r--r-- | opt.c | 17 | ||||
-rwxr-xr-x | tests.sh | 7 | ||||
-rw-r--r-- | tests/test_and_false_or_true.out | 1 |
3 files changed, 25 insertions, 0 deletions
@@ -50,6 +50,7 @@ static char *fake_and_arg = "-a"; static char *fake_or_arg = "-o"; +static char *fake_not_arg = "!"; /** * A contrained integer range. @@ -433,6 +434,14 @@ static struct expr *optimize_and_expr(const struct opt_state *state, struct expr } else if (lhs->always_false) { debug_opt(state, "-O1: short-circuit: %e <==> %e\n", expr, lhs); return extract_child_expr(expr, &expr->lhs); + } else if (lhs->always_true && rhs == &expr_false) { + debug_opt(state, "-O1: strength reduction: %e <==> ", expr); + struct expr *ret = extract_child_expr(expr, &expr->lhs); + ret = negate_expr(ret, &fake_not_arg); + if (ret) { + debug_opt(state, "%e\n", ret); + } + return ret; } else if (optlevel >= 2 && lhs->pure && rhs == &expr_false) { debug_opt(state, "-O2: purity: %e <==> %e\n", expr, rhs); return extract_child_expr(expr, &expr->rhs); @@ -493,6 +502,14 @@ static struct expr *optimize_or_expr(const struct opt_state *state, struct expr } else if (rhs == &expr_false) { debug_opt(state, "-O1: disjunctive syllogism: %e <==> %e\n", expr, lhs); return extract_child_expr(expr, &expr->lhs); + } else if (lhs->always_false && rhs == &expr_true) { + debug_opt(state, "-O1: strength reduction: %e <==> ", expr); + struct expr *ret = extract_child_expr(expr, &expr->lhs); + ret = negate_expr(ret, &fake_not_arg); + if (ret) { + debug_opt(state, "%e\n", ret); + } + return ret; } else if (optlevel >= 2 && lhs->pure && rhs == &expr_true) { debug_opt(state, "-O2: purity: %e <==> %e\n", expr, rhs); return extract_child_expr(expr, &expr->rhs); @@ -609,6 +609,7 @@ gnu_tests=( test_and_purity test_not_reachability test_comma_reachability + test_and_false_or_true ) bfs_tests=( @@ -2003,6 +2004,12 @@ function test_de_morgan_or() { bfs_diff basic \( \! -name 'foo' -o \! -type f \) } +function test_and_false_or_true() { + # Test (-a lhs(always_true) false) <==> (! lhs), + # (-a lhs(always_false) true) <==> (! lhs) + bfs_diff basic -prune -false -o -true +} + function test_data_flow_depth() { bfs_diff basic -depth +1 -depth -4 } diff --git a/tests/test_and_false_or_true.out b/tests/test_and_false_or_true.out new file mode 100644 index 0000000..15a13db --- /dev/null +++ b/tests/test_and_false_or_true.out @@ -0,0 +1 @@ +basic |