From 17bcabb6cfb42a3983ecb79768d44622507ce292 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 29 Mar 2018 12:10:39 +0100 Subject: Remove useless SWAP1 in front of commutative operations --- libevmasm/PeepholeOptimiser.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'libevmasm/PeepholeOptimiser.cpp') diff --git a/libevmasm/PeepholeOptimiser.cpp b/libevmasm/PeepholeOptimiser.cpp index 168d1109..30646545 100644 --- a/libevmasm/PeepholeOptimiser.cpp +++ b/libevmasm/PeepholeOptimiser.cpp @@ -154,6 +154,25 @@ struct DoublePush: SimplePeepholeOptimizerMethod } }; +struct CommutativeSwap: SimplePeepholeOptimizerMethod +{ + static bool applySimple(AssemblyItem const& _swap, AssemblyItem const& _op, std::back_insert_iterator _out) + { + // Remove SWAP1 if following instruction is commutative + if ( + _swap.type() == Operation && + _swap.instruction() == Instruction::SWAP1 && + SemanticInformation::isCommutativeOperation(_op) + ) + { + *_out = _op; + return true; + } + else + return false; + } +}; + struct JumpToNext: SimplePeepholeOptimizerMethod { static size_t applySimple( @@ -260,7 +279,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(), JumpToNext(), UnreachableCode(), TagConjunctions(), Identity()); + applyMethods(state, PushPop(), OpPop(), DoublePush(), DoubleSwap(), CommutativeSwap(), JumpToNext(), UnreachableCode(), TagConjunctions(), Identity()); if (m_optimisedItems.size() < m_items.size() || ( m_optimisedItems.size() == m_items.size() && ( eth::bytesRequired(m_optimisedItems, 3) < eth::bytesRequired(m_items, 3) || -- cgit v1.2.3 From 02ea0e547f3faa687f9c986ca9a0201b995846c0 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 4 Apr 2018 15:28:15 +0200 Subject: Replace comparison operators with opposites if preceded by SWAP1 --- libevmasm/PeepholeOptimiser.cpp | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'libevmasm/PeepholeOptimiser.cpp') diff --git a/libevmasm/PeepholeOptimiser.cpp b/libevmasm/PeepholeOptimiser.cpp index 30646545..8a39de24 100644 --- a/libevmasm/PeepholeOptimiser.cpp +++ b/libevmasm/PeepholeOptimiser.cpp @@ -173,6 +173,32 @@ struct CommutativeSwap: SimplePeepholeOptimizerMethod } }; +struct SwapComparison: SimplePeepholeOptimizerMethod +{ + static bool applySimple(AssemblyItem const& _swap, AssemblyItem const& _op, std::back_insert_iterator _out) + { + map swappableOps{ + { Instruction::LT, Instruction::GT }, + { Instruction::GT, Instruction::LT }, + { Instruction::SLT, Instruction::SGT }, + { Instruction::SGT, Instruction::SLT } + }; + + if ( + _swap.type() == Operation && + _swap.instruction() == Instruction::SWAP1 && + _op.type() == Operation && + swappableOps.count(_op.instruction()) + ) + { + *_out = swappableOps.at(_op.instruction()); + return true; + } + else + return false; + } +}; + struct JumpToNext: SimplePeepholeOptimizerMethod { static size_t applySimple( @@ -279,7 +305,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(), JumpToNext(), UnreachableCode(), TagConjunctions(), Identity()); + applyMethods(state, PushPop(), OpPop(), DoublePush(), DoubleSwap(), CommutativeSwap(), SwapComparison(), JumpToNext(), UnreachableCode(), TagConjunctions(), Identity()); if (m_optimisedItems.size() < m_items.size() || ( m_optimisedItems.size() == m_items.size() && ( eth::bytesRequired(m_optimisedItems, 3) < eth::bytesRequired(m_items, 3) || -- cgit v1.2.3