From d136e7dc95eb91644242308a4d58d0e79a82823a Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 20 Apr 2020 15:47:58 +0200 Subject: [PATCH] Rules for optimizing idempotency for bitwise operations. --- Changelog.md | 1 + libevmasm/RuleList.h | 23 +++++++++++++++++++ .../expressionSimplifier/idempotency.yul | 15 ++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 test/libyul/yulOptimizerTests/expressionSimplifier/idempotency.yul diff --git a/Changelog.md b/Changelog.md index 4baf84ebb..6a7042e6f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,6 +6,7 @@ Language Features: Compiler Features: + * Optimizer: Simplify repeated AND and OR operations. Bugfixes: * SMTChecker: Fix internal error when fixed points are used. diff --git a/libevmasm/RuleList.h b/libevmasm/RuleList.h index 812c67002..cd6eda81d 100644 --- a/libevmasm/RuleList.h +++ b/libevmasm/RuleList.h @@ -232,6 +232,28 @@ std::vector> simplificationRuleListPart4( }; } +template +std::vector> simplificationRuleListPart4_5( + Pattern, + Pattern, + Pattern, + Pattern X, + Pattern Y +) +{ + using Builtins = typename Pattern::Builtins; + return std::vector>{ + // idempotent operations + {Builtins::AND(Builtins::AND(X, Y), Y), [=]{ return Builtins::AND(X, Y); }, true}, + {Builtins::AND(Y, Builtins::AND(X, Y)), [=]{ return Builtins::AND(X, Y); }, true}, + {Builtins::AND(Builtins::AND(Y, X), Y), [=]{ return Builtins::AND(Y, X); }, true}, + {Builtins::AND(Y, Builtins::AND(Y, X)), [=]{ return Builtins::AND(Y, X); }, true}, + {Builtins::OR(Builtins::OR(X, Y), Y), [=]{ return Builtins::OR(X, Y); }, true}, + {Builtins::OR(Y, Builtins::OR(X, Y)), [=]{ return Builtins::OR(X, Y); }, true}, + {Builtins::OR(Builtins::OR(Y, X), Y), [=]{ return Builtins::OR(Y, X); }, true}, + {Builtins::OR(Y, Builtins::OR(Y, X)), [=]{ return Builtins::OR(Y, X); }, true}, + }; +} template std::vector> simplificationRuleListPart5( @@ -663,6 +685,7 @@ std::vector> simplificationRuleList( rules += simplificationRuleListPart2(A, B, C, W, X); rules += simplificationRuleListPart3(A, B, C, W, X); rules += simplificationRuleListPart4(A, B, C, W, X); + rules += simplificationRuleListPart4_5(A, B, C, W, X); rules += simplificationRuleListPart5(A, B, C, W, X); rules += simplificationRuleListPart6(A, B, C, W, X); rules += simplificationRuleListPart7(A, B, C, W, X); diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/idempotency.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/idempotency.yul new file mode 100644 index 000000000..78d51db73 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/idempotency.yul @@ -0,0 +1,15 @@ +{ + let x := calldataload(0) + let z := calldataload(1) + let t := and(and(x, z), x) + let w := or(or(x, z), x) +} +// ---- +// step: expressionSimplifier +// +// { +// let x := calldataload(0) +// let z := calldataload(1) +// let t := and(x, z) +// let w := or(x, z) +// }