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 v1.2.3 From b6ffb6c8b7a581e1c3d0e7882be0d1606cc37509 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Thu, 24 Nov 2016 18:21:57 +0100 Subject: libevmasm: generalize ADDPOP optimization into ADDMODPOP etc --- libevmasm/PeepholeOptimiser.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libevmasm/PeepholeOptimiser.cpp b/libevmasm/PeepholeOptimiser.cpp index 104d9769..901e310e 100644 --- a/libevmasm/PeepholeOptimiser.cpp +++ b/libevmasm/PeepholeOptimiser.cpp @@ -68,14 +68,15 @@ struct AddPop { Instruction i0 = _in[0].instruction(); if (instructionInfo(i0).ret == 1 && - instructionInfo(i0).args == 2 && !SemanticInformation::invalidatesMemory(i0) && - !SemanticInformation::invalidatesStorage(i0) + !SemanticInformation::invalidatesStorage(i0) && + !SemanticInformation::altersControlFlow(i0) && + !instructionInfo(i0).sideEffects ) { - *_out = Instruction::POP; - *_out = Instruction::POP; - return true; + for (int j = 0; j < instructionInfo(i0).args; j++) + *_out = Instruction::POP; + return true; } } return false; -- cgit v1.2.3