perf(optimiser): eliminate absorbing arithmetic and bitwise expressions
3 files changed, +14 −1
- src/Examples.thy modified +8 −0
- src/Model.thy modified +5 −1
- tests/native.py modified +1 −0
src/Examples.thy modified
| @@ -35,6 +35,14 @@ lemma neutral_bits: | ||
| 35 | 35 | "optimise (Binary And (Binary Xor (Input Y) (Literal 0)) (Literal (-1))) = Input Y" |
| 36 | 36 | by eval |
| 37 | 37 | |
| 38 | +lemma absorbing_arithmetic: | |
| 39 | + "optimise (Binary Mul (Input X) (Literal 0)) = Literal 0" | |
| 40 | + by eval | |
| 41 | + | |
| 42 | +lemma absorbing_bits: | |
| 43 | + "optimise (Binary Or (Binary And (Input Y) (Literal 0)) (Literal (-1))) = Literal (-1)" | |
| 44 | + by eval | |
| 45 | + | |
| 38 | 46 | lemma dead_branch: |
| 39 | 47 | "optimise (Cond (Literal 0) (Input X) (Input Y)) = Input Y" |
| 40 | 48 | by eval |
src/Model.thy modified
| @@ -49,7 +49,11 @@ fun fold_binary :: "operator \<Rightarrow> expression \<Rightarrow> expression \ | ||
| 49 | 49 | else if b = Literal 1 \<and> op = Mul then a |
| 50 | 50 | else if a = Literal 1 \<and> op = Mul then b |
| 51 | 51 | else if b = Literal (-1) \<and> op = And then a |
| 52 | - else if a = Literal (-1) \<and> op = And then b else Binary op a b)" | |
| 52 | + else if a = Literal (-1) \<and> op = And then b | |
| 53 | + else if b = Literal 0 \<and> op \<in> {Mul,And} then Literal 0 | |
| 54 | + else if a = Literal 0 \<and> op \<in> {Mul,And,Shl,Shr} then Literal 0 | |
| 55 | + else if b = Literal (-1) \<and> op = Or then Literal (-1) | |
| 56 | + else if a = Literal (-1) \<and> op = Or then Literal (-1) else Binary op a b)" | |
| 53 | 57 | |
| 54 | 58 | fun fold_cond :: "expression \<Rightarrow> expression \<Rightarrow> expression \<Rightarrow> expression" where |
| 55 | 59 | "fold_cond (Literal c) a b = (if c = 0 then b else a)" |
tests/native.py modified
| @@ -67,6 +67,7 @@ def main(): | ||
| 67 | 67 | cases = [(op, "x", "y") for op in OPERATORS] |
| 68 | 68 | cases += [(op, "x", 0) for op in ("+", "-", "or", "xor", "shl", "shr")] |
| 69 | 69 | cases += [("*", "x", 1), ("*", 1, "x"), ("and", "x", MASK)] |
| 70 | + cases += [("*", "x", 0), ("and", "x", 0), ("shl", 0, "y"), ("shr", 0, "y"), ("or", "x", MASK)] | |
| 70 | 71 | cases += [("let", "a", ("+", "x", 3), ("+", "y", ("let", "b", "t", ("*", "a", "b")))), |
| 71 | 72 | ("let", "x", "y", ("if", "t", ("+", "x", 1), ("-", "x", 1)))] |
| 72 | 73 | cases += [generate(rng, 5, ["x", "y", "t"]) for _ in range(117)] |