From 344f9c2f844b20a8ba206595c28429a196383e23 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Wed, 20 Mar 2019 18:29:16 -0400 Subject: opt: Replace -a -false/-o -true with -not when possible --- opt.c | 17 +++++++++++++++++ tests.sh | 7 +++++++ tests/test_and_false_or_true.out | 1 + 3 files changed, 25 insertions(+) create mode 100644 tests/test_and_false_or_true.out diff --git a/opt.c b/opt.c index dd98ca0..fd2dc3c 100644 --- a/opt.c +++ b/opt.c @@ -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); diff --git a/tests.sh b/tests.sh index 2df3448..a219812 100755 --- a/tests.sh +++ b/tests.sh @@ -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 -- cgit v1.2.3