~james/remy

perf(optimiser): eliminate absorbing arithmetic and bitwise expressions

commit
3e3f52cd4b5a7e127a8a6834b895a5537dcf5b47 browse tree
parent
0c936dff3ac8cddb8c0c8a477151e4a03d4c40b6
author
james <j@cpl0.zip>
signature
Verified ~james signed with a key registered by ~james
date
2026-09-08 11:00 UTC

3 files changed, +14 −1

src/Examples.thy modified

@@ -35,6 +35,14 @@ lemma neutral_bits:
3535 "optimise (Binary And (Binary Xor (Input Y) (Literal 0)) (Literal (-1))) = Input Y"
3636 by eval
3737
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+
3846 lemma dead_branch:
3947 "optimise (Cond (Literal 0) (Input X) (Input Y)) = Input Y"
4048 by eval

src/Model.thy modified

@@ -49,7 +49,11 @@ fun fold_binary :: "operator \<Rightarrow> expression \<Rightarrow> expression \
4949 else if b = Literal 1 \<and> op = Mul then a
5050 else if a = Literal 1 \<and> op = Mul then b
5151 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)"
5357
5458 fun fold_cond :: "expression \<Rightarrow> expression \<Rightarrow> expression \<Rightarrow> expression" where
5559 "fold_cond (Literal c) a b = (if c = 0 then b else a)"

tests/native.py modified

@@ -67,6 +67,7 @@ def main():
6767 cases = [(op, "x", "y") for op in OPERATORS]
6868 cases += [(op, "x", 0) for op in ("+", "-", "or", "xor", "shl", "shr")]
6969 cases += [("*", "x", 1), ("*", 1, "x"), ("and", "x", MASK)]
70+ cases += [("*", "x", 0), ("and", "x", 0), ("shl", 0, "y"), ("shr", 0, "y"), ("or", "x", MASK)]
7071 cases += [("let", "a", ("+", "x", 3), ("+", "y", ("let", "b", "t", ("*", "a", "b")))),
7172 ("let", "x", "y", ("if", "t", ("+", "x", 1), ("-", "x", 1)))]
7273 cases += [generate(rng, 5, ["x", "y", "t"]) for _ in range(117)]