aboutsummaryrefslogtreecommitdiffstats
path: root/libevmasm/ConstantOptimiser.h
diff options
context:
space:
mode:
authorDimitry <winsvega@mail.ru>2016-03-21 16:55:45 +0800
committerDimitry <winsvega@mail.ru>2016-03-21 16:55:45 +0800
commitb50e65437ebad535af29e84156b8b1af71f61c3d (patch)
treef2594fc7b539e5848f4fc08ebcfafedab90e00b5 /libevmasm/ConstantOptimiser.h
parent2fe6037b9bc42946dafbf0f870ca59546712d14c (diff)
downloaddexon-solidity-b50e65437ebad535af29e84156b8b1af71f61c3d.tar.gz
dexon-solidity-b50e65437ebad535af29e84156b8b1af71f61c3d.tar.zst
dexon-solidity-b50e65437ebad535af29e84156b8b1af71f61c3d.zip
move libevmasm
Diffstat (limited to 'libevmasm/ConstantOptimiser.h')
-rw-r--r--libevmasm/ConstantOptimiser.h155
1 files changed, 155 insertions, 0 deletions
diff --git a/libevmasm/ConstantOptimiser.h b/libevmasm/ConstantOptimiser.h
new file mode 100644
index 00000000..64cb66bb
--- /dev/null
+++ b/libevmasm/ConstantOptimiser.h
@@ -0,0 +1,155 @@
+/*
+ This file is part of cpp-ethereum.
+
+ cpp-ethereum 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.
+
+ cpp-ethereum 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file ConstantOptimiser.cpp
+ * @author Christian <c@ethdev.com>
+ * @date 2015
+ */
+
+#pragma once
+
+#include <vector>
+#include <libdevcore/CommonData.h>
+#include <libdevcore/CommonIO.h>
+#include <libethcore/ChainOperationParams.h>
+
+namespace dev
+{
+namespace eth
+{
+
+class AssemblyItem;
+using AssemblyItems = std::vector<AssemblyItem>;
+class Assembly;
+
+// TODO: FIXME: HOMESTEAD: XXX: @chfast populate m_schedule from an ExtVMFace instance via ExtVMFace::evmSchedule.
+
+/**
+ * Abstract base class for one way to change how constants are represented in the code.
+ */
+class ConstantOptimisationMethod
+{
+public:
+ /// Tries to optimised how constants are represented in the source code and modifies
+ /// @a _assembly and its @a _items.
+ /// @returns zero if no optimisations could be performed.
+ static unsigned optimiseConstants(
+ bool _isCreation,
+ size_t _runs,
+ Assembly& _assembly,
+ AssemblyItems& _items
+ );
+
+ struct Params
+ {
+ bool isCreation; ///< Whether this is called during contract creation or runtime.
+ size_t runs; ///< Estimated number of calls per opcode oven the lifetime of the contract.
+ size_t multiplicity; ///< Number of times the constant appears in the code.
+ };
+
+ explicit ConstantOptimisationMethod(Params const& _params, u256 const& _value):
+ m_params(_params), m_value(_value) {}
+ virtual bigint gasNeeded() = 0;
+ virtual void execute(Assembly& _assembly, AssemblyItems& _items) = 0;
+
+protected:
+ size_t dataSize() const { return std::max<size_t>(1, dev::bytesRequired(m_value)); }
+
+ /// @returns the run gas for the given items ignoring special gas costs
+ static bigint simpleRunGas(AssemblyItems const& _items);
+ /// @returns the gas needed to store the given data literally
+ bigint dataGas(bytes const& _data) const;
+ /// @returns the gas needed to store the value literally
+ bigint dataGas() const { return dataGas(toCompactBigEndian(m_value, 1)); }
+ static size_t bytesRequired(AssemblyItems const& _items);
+ /// @returns the combined estimated gas usage taking @a m_params into account.
+ bigint combineGas(
+ bigint const& _runGas,
+ bigint const& _repeatedDataGas,
+ bigint const& _uniqueDataGas
+ )
+ {
+ // _runGas is not multiplied by _multiplicity because the runs are "per opcode"
+ return m_params.runs * _runGas + m_params.multiplicity * _repeatedDataGas + _uniqueDataGas;
+ }
+
+ /// Replaces the constant by the code given in @a _replacement.
+ void replaceConstants(AssemblyItems& _items, AssemblyItems const& _replacement) const;
+
+ Params m_params;
+ u256 const& m_value;
+ EVMSchedule m_schedule;
+};
+
+/**
+ * Optimisation method that pushes the constant to the stack literally. This is the default method,
+ * i.e. executing it does not alter the Assembly.
+ */
+class LiteralMethod: public ConstantOptimisationMethod
+{
+public:
+ explicit LiteralMethod(Params const& _params, u256 const& _value):
+ ConstantOptimisationMethod(_params, _value) {}
+ virtual bigint gasNeeded() override;
+ virtual void execute(Assembly&, AssemblyItems&) override {}
+
+ EVMSchedule m_schedule;
+};
+
+/**
+ * Method that stores the data in the .data section of the code and copies it to the stack.
+ */
+class CodeCopyMethod: public ConstantOptimisationMethod
+{
+public:
+ explicit CodeCopyMethod(Params const& _params, u256 const& _value);
+ virtual bigint gasNeeded() override;
+ virtual void execute(Assembly& _assembly, AssemblyItems& _items) override;
+
+protected:
+ AssemblyItems m_copyRoutine;
+ EVMSchedule m_schedule;
+};
+
+/**
+ * Method that tries to compute the constant.
+ */
+class ComputeMethod: public ConstantOptimisationMethod
+{
+public:
+ explicit ComputeMethod(Params const& _params, u256 const& _value):
+ ConstantOptimisationMethod(_params, _value)
+ {
+ m_routine = findRepresentation(m_value);
+ }
+
+ virtual bigint gasNeeded() override { return gasNeeded(m_routine); }
+ virtual void execute(Assembly&, AssemblyItems& _items) override
+ {
+ replaceConstants(_items, m_routine);
+ }
+
+protected:
+ /// Tries to recursively find a way to compute @a _value.
+ AssemblyItems findRepresentation(u256 const& _value);
+ bigint gasNeeded(AssemblyItems const& _routine);
+
+ AssemblyItems m_routine;
+ EVMSchedule m_schedule;
+};
+
+}
+}