Skip to content

Commit

Permalink
Merge pull request #115 from cgyurgyik/log-op
Browse files Browse the repository at this point in the history
[LVN] Add logical operators to foldable, a few special cases.
  • Loading branch information
sampsyo committed Jan 6, 2021
2 parents 51c368a + 5cbe70e commit dbbd8e8
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 0 deletions.
11 changes: 11 additions & 0 deletions examples/lvn.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
}


Expand All @@ -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_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
except ZeroDivisionError: # If we hit a dynamic error, bail!
return None
Expand Down
26 changes: 26 additions & 0 deletions examples/test/lvn/logical-operators.bril
Original file line number Diff line number Diff line change
@@ -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;
}
21 changes: 21 additions & 0 deletions examples/test/lvn/logical-operators.out
Original file line number Diff line number Diff line change
@@ -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;
}

0 comments on commit dbbd8e8

Please sign in to comment.