From 25160bfc26cd5ae4b5104625caba41c1533614ba Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 25 Oct 2016 12:38:37 +0100 Subject: [PATCH 1/7] Add optimiser rule for SUB with 0 --- libevmasm/ExpressionClasses.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libevmasm/ExpressionClasses.cpp b/libevmasm/ExpressionClasses.cpp index e32b2da21..cb3272528 100644 --- a/libevmasm/ExpressionClasses.cpp +++ b/libevmasm/ExpressionClasses.cpp @@ -245,17 +245,18 @@ Rules::Rules() // invariants involving known constants {{Instruction::ADD, {X, 0}}, [=]{ return X; }}, + {{Instruction::SUB, {X, 0}}, [=]{ return X; }}, {{Instruction::MUL, {X, 1}}, [=]{ return X; }}, {{Instruction::DIV, {X, 1}}, [=]{ return X; }}, {{Instruction::SDIV, {X, 1}}, [=]{ return X; }}, {{Instruction::OR, {X, 0}}, [=]{ return X; }}, {{Instruction::XOR, {X, 0}}, [=]{ return X; }}, {{Instruction::AND, {X, ~u256(0)}}, [=]{ return X; }}, + {{Instruction::AND, {X, 0}}, [=]{ return u256(0); }}, {{Instruction::MUL, {X, 0}}, [=]{ return u256(0); }}, {{Instruction::DIV, {X, 0}}, [=]{ return u256(0); }}, {{Instruction::MOD, {X, 0}}, [=]{ return u256(0); }}, {{Instruction::MOD, {0, X}}, [=]{ return u256(0); }}, - {{Instruction::AND, {X, 0}}, [=]{ return u256(0); }}, {{Instruction::OR, {X, ~u256(0)}}, [=]{ return ~u256(0); }}, {{Instruction::EQ, {X, 0}}, [=]() -> Pattern { return {Instruction::ISZERO, {X}}; } }, // operations involving an expression and itself From b8bba6622013a6c0969392a4096a3a7384b8cf62 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 9 Nov 2016 02:22:54 +0000 Subject: [PATCH 2/7] Replace XOR/ISZERO with EQ --- libevmasm/ExpressionClasses.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libevmasm/ExpressionClasses.cpp b/libevmasm/ExpressionClasses.cpp index cb3272528..29fb6dbc0 100644 --- a/libevmasm/ExpressionClasses.cpp +++ b/libevmasm/ExpressionClasses.cpp @@ -288,6 +288,10 @@ Rules::Rules() {Instruction::ISZERO, {{Instruction::ISZERO, {{Instruction::ISZERO, {X}}}}}}, [=]() -> Pattern { return {Instruction::ISZERO, {X}}; } }); + m_rules.push_back({ + {Instruction::ISZERO, {{Instruction::XOR, {X, Y}}}}, + [=]() -> Pattern { return { Instruction::EQ, {X, Y} }; } + }); // Associative operations for (auto const& opFun: vector>>{ {Instruction::ADD, plus()}, From 3fdef92911ea1824f7a84ce556fec48e23a314ad Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 9 Nov 2016 02:25:44 +0000 Subject: [PATCH 3/7] Replace XOR with self with 0 --- libevmasm/ExpressionClasses.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libevmasm/ExpressionClasses.cpp b/libevmasm/ExpressionClasses.cpp index 29fb6dbc0..bb71be2e7 100644 --- a/libevmasm/ExpressionClasses.cpp +++ b/libevmasm/ExpressionClasses.cpp @@ -262,6 +262,7 @@ Rules::Rules() // operations involving an expression and itself {{Instruction::AND, {X, X}}, [=]{ return X; }}, {{Instruction::OR, {X, X}}, [=]{ return X; }}, + {{Instruction::XOR, {X, X}}, [=]{ return u256(0); }}, {{Instruction::SUB, {X, X}}, [=]{ return u256(0); }}, {{Instruction::EQ, {X, X}}, [=]{ return u256(1); }}, {{Instruction::LT, {X, X}}, [=]{ return u256(0); }}, From 8d0b80f944c42e871e42c320dfabf92c707ed9b7 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 9 Nov 2016 11:28:53 +0000 Subject: [PATCH 4/7] Add test for SUB with 0 optimisation --- test/libsolidity/SolidityOptimizer.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/test/libsolidity/SolidityOptimizer.cpp b/test/libsolidity/SolidityOptimizer.cpp index a53a26384..90caaab07 100644 --- a/test/libsolidity/SolidityOptimizer.cpp +++ b/test/libsolidity/SolidityOptimizer.cpp @@ -1304,6 +1304,28 @@ BOOST_AUTO_TEST_CASE(invalid_state_at_control_flow_join) compareVersions("test()"); } +BOOST_AUTO_TEST_CASE(cse_sub_zero) +{ + checkCSE({ + u256(0), + u256(5), + Instruction::SUB + }, { + u256(5) + }); + + checkCSE({ + u256(5), + u256(0), + Instruction::SUB + }, { + u256(5), + u256(0), + Instruction::SUB + }); +} + + BOOST_AUTO_TEST_SUITE_END() } From 4ff89dda1d9d81170b65775b33c1cfbd7e5e6b48 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 14 Nov 2016 13:22:55 +0100 Subject: [PATCH 5/7] Update SolidityOptimizer.cpp --- test/libsolidity/SolidityOptimizer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/libsolidity/SolidityOptimizer.cpp b/test/libsolidity/SolidityOptimizer.cpp index 90caaab07..00a636fde 100644 --- a/test/libsolidity/SolidityOptimizer.cpp +++ b/test/libsolidity/SolidityOptimizer.cpp @@ -1308,18 +1308,18 @@ BOOST_AUTO_TEST_CASE(cse_sub_zero) { checkCSE({ u256(0), - u256(5), + Instruction::DUP2, Instruction::SUB }, { u256(5) }); checkCSE({ - u256(5), + Instruction::DUP2, u256(0), Instruction::SUB }, { - u256(5), + Instruction::DUP2, u256(0), Instruction::SUB }); From df4b405f9c1cd3ebfd2787b5f1f6925cabf789d3 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Mon, 24 Oct 2016 17:33:57 +0200 Subject: [PATCH 6/7] Add more optimization rules --- libevmasm/ExpressionClasses.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libevmasm/ExpressionClasses.cpp b/libevmasm/ExpressionClasses.cpp index bb71be2e7..d5ccd7e3c 100644 --- a/libevmasm/ExpressionClasses.cpp +++ b/libevmasm/ExpressionClasses.cpp @@ -255,6 +255,7 @@ Rules::Rules() {{Instruction::AND, {X, 0}}, [=]{ return u256(0); }}, {{Instruction::MUL, {X, 0}}, [=]{ return u256(0); }}, {{Instruction::DIV, {X, 0}}, [=]{ return u256(0); }}, + {{Instruction::DIV, {0, X}}, [=]{ return u256(0); }}, {{Instruction::MOD, {X, 0}}, [=]{ return u256(0); }}, {{Instruction::MOD, {0, X}}, [=]{ return u256(0); }}, {{Instruction::OR, {X, ~u256(0)}}, [=]{ return ~u256(0); }}, @@ -272,6 +273,11 @@ Rules::Rules() {{Instruction::MOD, {X, X}}, [=]{ return u256(0); }}, {{Instruction::NOT, {{Instruction::NOT, {X}}}}, [=]{ return X; }}, + {{Instruction::XOR, {{{X}, {Instruction::XOR, {X, Y}}}}}, [=]{ return Y; }}, + {{Instruction::OR, {{{X}, {Instruction::AND, {X, Y}}}}}, [=]{ return X; }}, + {{Instruction::AND, {{{X}, {Instruction::OR, {X, Y}}}}}, [=]{ return X; }}, + {{Instruction::AND, {{{X}, {Instruction::NOT, {X}}}}}, [=]{ return u256(0); }}, + {{Instruction::OR, {{{X}, {Instruction::NOT, {X}}}}}, [=]{ return ~u256(0); }}, }; // Double negation of opcodes with binary result for (auto const& op: vector{ From 9a6a5f219b74097c1a11278aad07df1ffd60ff45 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 30 Nov 2016 11:18:33 +0000 Subject: [PATCH 7/7] Fix sub-0 optimiser test --- test/libsolidity/SolidityOptimizer.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/libsolidity/SolidityOptimizer.cpp b/test/libsolidity/SolidityOptimizer.cpp index 00a636fde..89c89adcf 100644 --- a/test/libsolidity/SolidityOptimizer.cpp +++ b/test/libsolidity/SolidityOptimizer.cpp @@ -1311,16 +1311,17 @@ BOOST_AUTO_TEST_CASE(cse_sub_zero) Instruction::DUP2, Instruction::SUB }, { - u256(5) + Instruction::DUP1 }); checkCSE({ - Instruction::DUP2, + Instruction::DUP1, u256(0), Instruction::SUB }, { - Instruction::DUP2, u256(0), + Instruction::DUP2, + Instruction::SWAP1, Instruction::SUB }); }