aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolás Venturo <nicolas.venturo@gmail.com>2018-06-15 01:29:42 +0800
committerNicolás Venturo <nicolas.venturo@gmail.com>2018-06-15 22:27:39 +0800
commit172e208c6aa70956389ce7efb90b64ac32140588 (patch)
tree515665335cd23ee51fb6c1c8e81e9bd2aaf4af85
parentdc5cd3e1e7db933493fe1b0dc12e5ecdf2a50ed7 (diff)
downloaddexon-solidity-172e208c6aa70956389ce7efb90b64ac32140588.tar
dexon-solidity-172e208c6aa70956389ce7efb90b64ac32140588.tar.gz
dexon-solidity-172e208c6aa70956389ce7efb90b64ac32140588.tar.bz2
dexon-solidity-172e208c6aa70956389ce7efb90b64ac32140588.tar.lz
dexon-solidity-172e208c6aa70956389ce7efb90b64ac32140588.tar.xz
dexon-solidity-172e208c6aa70956389ce7efb90b64ac32140588.tar.zst
dexon-solidity-172e208c6aa70956389ce7efb90b64ac32140588.zip
Add TruthyAnd Peephole optimization
-rw-r--r--Changelog.md1
-rw-r--r--libevmasm/PeepholeOptimiser.cpp19
-rw-r--r--test/libevmasm/Optimiser.cpp12
3 files changed, 31 insertions, 1 deletions
diff --git a/Changelog.md b/Changelog.md
index 4389fbd9..b48433d6 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -15,6 +15,7 @@ Breaking Changes:
``implements``, ``macro``, ``mutable``, ``override``, ``partial``, ``promise``, ``reference``, ``sealed``,
``sizeof``, ``supports``, ``typedef`` and ``unchecked``.
* General: Remove assembly instruction aliases ``sha3`` and ``suicide``
+ * Optimizer: Remove the no-op ``PUSH1 0 NOT AND`` sequence.
* Parser: Disallow trailing dots that are not followed by a number.
* Type Checker: Disallow arithmetic operations for boolean variables.
* Type Checker: Disallow conversions between ``bytesX`` and ``uintY`` of different size.
diff --git a/libevmasm/PeepholeOptimiser.cpp b/libevmasm/PeepholeOptimiser.cpp
index 8a39de24..6d8e1df6 100644
--- a/libevmasm/PeepholeOptimiser.cpp
+++ b/libevmasm/PeepholeOptimiser.cpp
@@ -249,6 +249,23 @@ struct TagConjunctions: SimplePeepholeOptimizerMethod<TagConjunctions, 3>
}
};
+struct TruthyAnd: SimplePeepholeOptimizerMethod<TruthyAnd, 3>
+{
+ static bool applySimple(
+ AssemblyItem const& _push,
+ AssemblyItem const& _not,
+ AssemblyItem const& _and,
+ std::back_insert_iterator<AssemblyItems>
+ )
+ {
+ return (
+ _push.type() == Push && _push.data() == 0 &&
+ _not == Instruction::NOT &&
+ _and == Instruction::AND
+ );
+ }
+};
+
/// Removes everything after a JUMP (or similar) until the next JUMPDEST.
struct UnreachableCode
{
@@ -305,7 +322,7 @@ bool PeepholeOptimiser::optimise()
{
OptimiserState state {m_items, 0, std::back_inserter(m_optimisedItems)};
while (state.i < m_items.size())
- applyMethods(state, PushPop(), OpPop(), DoublePush(), DoubleSwap(), CommutativeSwap(), SwapComparison(), JumpToNext(), UnreachableCode(), TagConjunctions(), Identity());
+ applyMethods(state, PushPop(), OpPop(), DoublePush(), DoubleSwap(), CommutativeSwap(), SwapComparison(), JumpToNext(), UnreachableCode(), TagConjunctions(), TruthyAnd(), Identity());
if (m_optimisedItems.size() < m_items.size() || (
m_optimisedItems.size() == m_items.size() && (
eth::bytesRequired(m_optimisedItems, 3) < eth::bytesRequired(m_items, 3) ||
diff --git a/test/libevmasm/Optimiser.cpp b/test/libevmasm/Optimiser.cpp
index 4b399a14..8e4946c3 100644
--- a/test/libevmasm/Optimiser.cpp
+++ b/test/libevmasm/Optimiser.cpp
@@ -967,6 +967,18 @@ BOOST_AUTO_TEST_CASE(peephole_swap_comparison)
}
}
+BOOST_AUTO_TEST_CASE(peephole_truthy_and)
+{
+ AssemblyItems items{
+ u256(0),
+ Instruction::NOT,
+ Instruction::AND
+ };
+ PeepholeOptimiser peepOpt(items);
+ BOOST_REQUIRE(peepOpt.optimise());
+ BOOST_CHECK(items.empty());
+}
+
BOOST_AUTO_TEST_CASE(jumpdest_removal)
{
AssemblyItems items{