diff options
Diffstat (limited to 'libevmasm')
-rw-r--r-- | libevmasm/Assembly.cpp | 3 | ||||
-rw-r--r-- | libevmasm/AssemblyItem.cpp | 4 | ||||
-rw-r--r-- | libevmasm/EVMSchedule.h | 62 | ||||
-rw-r--r-- | libevmasm/Instruction.h | 18 | ||||
-rw-r--r-- | libevmasm/PeepholeOptimiser.cpp | 11 | ||||
-rw-r--r-- | libevmasm/SemanticInformation.cpp | 6 |
6 files changed, 34 insertions, 70 deletions
diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index df691e7d..5fab24e1 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -408,7 +408,10 @@ map<u256, u256> Assembly::optimiseInternal( { PeepholeOptimiser peepOpt(m_items); while (peepOpt.optimise()) + { count++; + assertThrow(count < 64000, OptimizerException, "Peephole optimizer seems to be stuck."); + } } // This only modifies PushTags, we have to run again to actually remove code. diff --git a/libevmasm/AssemblyItem.cpp b/libevmasm/AssemblyItem.cpp index cfe91be0..64963021 100644 --- a/libevmasm/AssemblyItem.cpp +++ b/libevmasm/AssemblyItem.cpp @@ -17,8 +17,6 @@ #include <libevmasm/AssemblyItem.h> -#include <libevmasm/SemanticInformation.h> - #include <libdevcore/CommonData.h> #include <libdevcore/FixedHash.h> @@ -112,7 +110,7 @@ bool AssemblyItem::canBeFunctional() const switch (m_type) { case Operation: - return !SemanticInformation::isDupInstruction(*this) && !SemanticInformation::isSwapInstruction(*this); + return !isDupInstruction(instruction()) && !isSwapInstruction(instruction()); case Push: case PushString: case PushTag: diff --git a/libevmasm/EVMSchedule.h b/libevmasm/EVMSchedule.h deleted file mode 100644 index 1695a59c..00000000 --- a/libevmasm/EVMSchedule.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see <http://www.gnu.org/licenses/>. -*/ -/** @file EVMSchedule.h - * @author Gav <i@gavwood.com> - * @author Christian <c@ethdev.com> - * @date 2015 - */ - -#pragma once - -namespace dev -{ -namespace solidity -{ - -struct EVMSchedule -{ - unsigned stackLimit = 1024; - unsigned expGas = 10; - unsigned expByteGas = 10; - unsigned keccak256Gas = 30; - unsigned keccak256WordGas = 6; - unsigned sloadGas = 200; - unsigned sstoreSetGas = 20000; - unsigned sstoreResetGas = 5000; - unsigned sstoreRefundGas = 15000; - unsigned jumpdestGas = 1; - unsigned logGas = 375; - unsigned logDataGas = 8; - unsigned logTopicGas = 375; - unsigned createGas = 32000; - unsigned callGas = 40; - unsigned callStipend = 2300; - unsigned callValueTransferGas = 9000; - unsigned callNewAccountGas = 25000; - unsigned selfdestructRefundGas = 24000; - unsigned memoryGas = 3; - unsigned quadCoeffDiv = 512; - unsigned createDataGas = 200; - unsigned txGas = 21000; - unsigned txCreateGas = 53000; - unsigned txDataZeroGas = 4; - unsigned txDataNonZeroGas = 68; - unsigned copyGas = 3; -}; - -} -} diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h index afbef71d..d9c53900 100644 --- a/libevmasm/Instruction.h +++ b/libevmasm/Instruction.h @@ -197,6 +197,24 @@ enum class Instruction: uint8_t SELFDESTRUCT = 0xff ///< halt execution and register account for later deletion }; +/// @returns true if the instruction is a PUSH +inline bool isPushInstruction(Instruction _inst) +{ + return Instruction::PUSH1 <= _inst && _inst <= Instruction::PUSH32; +} + +/// @returns true if the instruction is a DUP +inline bool isDupInstruction(Instruction _inst) +{ + return Instruction::DUP1 <= _inst && _inst <= Instruction::DUP16; +} + +/// @returns true if the instruction is a SWAP +inline bool isSwapInstruction(Instruction _inst) +{ + return Instruction::SWAP1 <= _inst && _inst <= Instruction::SWAP16; +} + /// @returns the number of PUSH Instruction _inst inline unsigned getPushNumber(Instruction _inst) { diff --git a/libevmasm/PeepholeOptimiser.cpp b/libevmasm/PeepholeOptimiser.cpp index 31fdd317..168d1109 100644 --- a/libevmasm/PeepholeOptimiser.cpp +++ b/libevmasm/PeepholeOptimiser.cpp @@ -249,6 +249,11 @@ void applyMethods(OptimiserState& _state, Method, OtherMethods... _other) applyMethods(_state, _other...); } +size_t numberOfPops(AssemblyItems const& _items) +{ + return std::count(_items.begin(), _items.end(), Instruction::POP); +} + } bool PeepholeOptimiser::optimise() @@ -257,8 +262,10 @@ bool PeepholeOptimiser::optimise() while (state.i < m_items.size()) applyMethods(state, PushPop(), OpPop(), DoublePush(), DoubleSwap(), 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) + m_optimisedItems.size() == m_items.size() && ( + eth::bytesRequired(m_optimisedItems, 3) < eth::bytesRequired(m_items, 3) || + numberOfPops(m_optimisedItems) > numberOfPops(m_items) + ) )) { m_items = std::move(m_optimisedItems); diff --git a/libevmasm/SemanticInformation.cpp b/libevmasm/SemanticInformation.cpp index ceb3fbdd..61a6ccda 100644 --- a/libevmasm/SemanticInformation.cpp +++ b/libevmasm/SemanticInformation.cpp @@ -90,14 +90,14 @@ bool SemanticInformation::isDupInstruction(AssemblyItem const& _item) { if (_item.type() != Operation) return false; - return Instruction::DUP1 <= _item.instruction() && _item.instruction() <= Instruction::DUP16; + return solidity::isDupInstruction(_item.instruction()); } bool SemanticInformation::isSwapInstruction(AssemblyItem const& _item) { if (_item.type() != Operation) return false; - return Instruction::SWAP1 <= _item.instruction() && _item.instruction() <= Instruction::SWAP16; + return solidity::isSwapInstruction(_item.instruction()); } bool SemanticInformation::isJumpInstruction(AssemblyItem const& _item) @@ -198,6 +198,7 @@ bool SemanticInformation::invalidInPureFunctions(Instruction _instruction) case Instruction::ORIGIN: case Instruction::CALLER: case Instruction::CALLVALUE: + case Instruction::GAS: case Instruction::GASPRICE: case Instruction::EXTCODESIZE: case Instruction::EXTCODECOPY: @@ -223,7 +224,6 @@ bool SemanticInformation::invalidInViewFunctions(Instruction _instruction) case Instruction::SSTORE: case Instruction::JUMP: case Instruction::JUMPI: - case Instruction::GAS: case Instruction::LOG0: case Instruction::LOG1: case Instruction::LOG2: |