From c0fe5fbe9b474a9cd0db10db5e4410e7950d9a93 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Thu, 24 Nov 2016 12:17:29 +0100 Subject: libevmasm: Add another peephole optimization --- libevmasm/AssemblyItem.h | 2 +- libevmasm/PeepholeOptimiser.cpp | 29 +++++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/libevmasm/AssemblyItem.h b/libevmasm/AssemblyItem.h index 2bc28dbd..b5bd3ed8 100644 --- a/libevmasm/AssemblyItem.h +++ b/libevmasm/AssemblyItem.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with solidity. If not, see . */ -/** @file Assembly.h +/** @file AssemblyItem.h * @author Gav Wood * @date 2014 */ diff --git a/libevmasm/PeepholeOptimiser.cpp b/libevmasm/PeepholeOptimiser.cpp index e93db9ac..104d9769 100644 --- a/libevmasm/PeepholeOptimiser.cpp +++ b/libevmasm/PeepholeOptimiser.cpp @@ -15,7 +15,7 @@ along with solidity. If not, see . */ /** - * @file PeepholeOptimiser.h + * @file PeepholeOptimiser.cpp * Performs local optimising code changes to assembly. */ @@ -57,6 +57,31 @@ struct PushPop } }; +struct AddPop +{ + static size_t windowSize() { return 2; } + static bool apply(AssemblyItems::const_iterator _in, std::back_insert_iterator _out) + { + if (_in[1] == Instruction::POP && + _in[0].type() == Operation + ) + { + Instruction i0 = _in[0].instruction(); + if (instructionInfo(i0).ret == 1 && + instructionInfo(i0).args == 2 && + !SemanticInformation::invalidatesMemory(i0) && + !SemanticInformation::invalidatesStorage(i0) + ) + { + *_out = Instruction::POP; + *_out = Instruction::POP; + return true; + } + } + return false; + } +}; + struct DoubleSwap { static size_t windowSize() { return 2; } @@ -136,7 +161,7 @@ bool PeepholeOptimiser::optimise() { OptimiserState state {m_items, 0, std::back_inserter(m_optimisedItems)}; while (state.i < m_items.size()) - applyMethods(state, PushPop(), DoubleSwap(), JumpToNext(), TagConjunctions(), Identity()); + applyMethods(state, PushPop(), AddPop(), DoubleSwap(), JumpToNext(), TagConjunctions(), Identity()); if (m_optimisedItems.size() < m_items.size()) { m_items = std::move(m_optimisedItems); -- cgit