From ff09e21191e1a536a0c889a3e9a010aba1d495c4 Mon Sep 17 00:00:00 2001 From: cgyurgyik Date: Tue, 5 Jan 2021 18:46:59 -0500 Subject: [PATCH 1/3] Logical operators. --- examples/lvn.py | 11 ++++++++++ examples/test/lvn/logical-operators.bril | 26 ++++++++++++++++++++++++ examples/test/lvn/logical-operators.out | 21 +++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 examples/test/lvn/logical-operators.bril create mode 100644 examples/test/lvn/logical-operators.out diff --git a/examples/lvn.py b/examples/lvn.py index cf7f834bc..b298de78a 100644 --- a/examples/lvn.py +++ b/examples/lvn.py @@ -199,6 +199,9 @@ def _lookup(value2num, value): 'le': lambda a, b: a <= b, 'ne': lambda a, b: a != b, 'eq': lambda a, b: a == b, + 'or': lambda a, b: a or b, + 'and': lambda a, b: a and b, + 'not': lambda a: not a } @@ -212,6 +215,14 @@ def _fold(num2const, value): # Equivalent arguments may be evaluated for equality. # E.g. `eq x x`, where `x` is not a constant evaluates to `true`. return value.op != 'ne' + + if value.op in {'and', 'or'} and any(v in num2const for v in value.args): + # Short circuiting the logical operators `and` and `or` for two cases: + # (1) `and x c0` -> false, where `c0` a constant that evaluates to `false`. + # (2) `or x c1` -> true, where `c1` a constant that evaluates to `true`. + const_value = num2const[value.args[0]] if value.args[0] in num2const else num2const[value.args[1]] + if (value.op == 'and' and not const_value) or (value.op == 'or' and const_value): + return const_value return None except ZeroDivisionError: # If we hit a dynamic error, bail! return None diff --git a/examples/test/lvn/logical-operators.bril b/examples/test/lvn/logical-operators.bril new file mode 100644 index 000000000..88f5701ef --- /dev/null +++ b/examples/test/lvn/logical-operators.bril @@ -0,0 +1,26 @@ +# ARGS: -f + +@main(arg1: bool, arg2: bool) { + t: int = const true; + f: int = const false; + + constant_fold1: bool = and f t; + constant_fold2: bool = and t f; + constant_fold3: bool = or t f; + constant_fold4: bool = or f t; + constant_fold5: bool = not t; + constant_fold6: bool = not f; + + should_fold1: bool = and f arg1; + should_fold2: bool = and arg1 f; + should_fold3: bool = or t arg1; + should_fold4: bool = or arg1 t; + + no_fold1: bool = and t arg1; + no_fold2: bool = and arg1 t; + no_fold3: bool = or f arg1; + no_fold4: bool = or arg1 f; + no_fold5: bool = and arg1 arg2; + no_fold6: bool = or arg1 arg2; + no_fold7: bool = not arg1; +} diff --git a/examples/test/lvn/logical-operators.out b/examples/test/lvn/logical-operators.out new file mode 100644 index 000000000..12028ea58 --- /dev/null +++ b/examples/test/lvn/logical-operators.out @@ -0,0 +1,21 @@ +@main(arg1: bool, arg2: bool) { + t: int = const true; + f: int = const false; + constant_fold1: bool = const false; + constant_fold2: bool = const false; + constant_fold3: bool = const true; + constant_fold4: bool = const true; + constant_fold5: bool = const false; + constant_fold6: bool = const true; + should_fold1: bool = const false; + should_fold2: bool = const false; + should_fold3: bool = const true; + should_fold4: bool = const true; + no_fold1: bool = and t arg1; + no_fold2: bool = and arg1 t; + no_fold3: bool = or f arg1; + no_fold4: bool = or arg1 f; + no_fold5: bool = and arg1 arg2; + no_fold6: bool = or arg1 arg2; + no_fold7: bool = not arg1; +} From e124274a5ead46fe1b8632faa72270370fb46630 Mon Sep 17 00:00:00 2001 From: cgyurgyik Date: Tue, 5 Jan 2021 18:55:13 -0500 Subject: [PATCH 2/3] shorter name --- examples/lvn.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/lvn.py b/examples/lvn.py index b298de78a..84b95641d 100644 --- a/examples/lvn.py +++ b/examples/lvn.py @@ -220,9 +220,9 @@ def _fold(num2const, value): # Short circuiting the logical operators `and` and `or` for two cases: # (1) `and x c0` -> false, where `c0` a constant that evaluates to `false`. # (2) `or x c1` -> true, where `c1` a constant that evaluates to `true`. - const_value = num2const[value.args[0]] if value.args[0] in num2const else num2const[value.args[1]] - if (value.op == 'and' and not const_value) or (value.op == 'or' and const_value): - return const_value + const_val = num2const[value.args[0]] if value.args[0] in num2const else num2const[value.args[1]] + if (value.op == 'and' and not const_val) or (value.op == 'or' and const_val): + return const_val return None except ZeroDivisionError: # If we hit a dynamic error, bail! return None From 5cbe70ea21f85f5ac248746514e5d4a8ad6455e7 Mon Sep 17 00:00:00 2001 From: cgyurgyik Date: Tue, 5 Jan 2021 18:56:15 -0500 Subject: [PATCH 3/3] Do python stuff correct --- examples/lvn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/lvn.py b/examples/lvn.py index 84b95641d..5b3428930 100644 --- a/examples/lvn.py +++ b/examples/lvn.py @@ -220,7 +220,7 @@ def _fold(num2const, value): # Short circuiting the logical operators `and` and `or` for two cases: # (1) `and x c0` -> false, where `c0` a constant that evaluates to `false`. # (2) `or x c1` -> true, where `c1` a constant that evaluates to `true`. - const_val = num2const[value.args[0]] if value.args[0] in num2const else num2const[value.args[1]] + const_val = num2const[value.args[0] if value.args[0] in num2const else value.args[1]] if (value.op == 'and' and not const_val) or (value.op == 'or' and const_val): return const_val return None