Refactor: Pull out single value optimisation.

This commit is contained in:
chriseth 2019-05-14 13:12:51 +02:00
parent 563aec1df5
commit 37fb3cd2fd
2 changed files with 39 additions and 24 deletions

View File

@ -44,39 +44,45 @@ unsigned ConstantOptimisationMethod::optimiseConstants(
map<u256, AssemblyItems> pendingReplacements;
for (auto it: pushes)
{
AssemblyItem const& item = it.first;
if (item.data() < 0x100)
continue;
u256 value = it.first.data();
Params params;
params.multiplicity = it.second;
params.isCreation = _isCreation;
params.runs = _runs;
params.evmVersion = _evmVersion;
LiteralMethod lit(params, item.data());
bigint literalGas = lit.gasNeeded();
CodeCopyMethod copy(params, item.data());
bigint copyGas = copy.gasNeeded();
ComputeMethod compute(params, item.data());
bigint computeGas = compute.gasNeeded();
AssemblyItems replacement;
if (copyGas < literalGas && copyGas < computeGas)
{
replacement = copy.execute(_assembly);
optimisations++;
}
else if (computeGas < literalGas && computeGas <= copyGas)
{
replacement = compute.execute(_assembly);
optimisations++;
}
if (!replacement.empty())
pendingReplacements[item.data()] = replacement;
AssemblyItems replacement = optimiseSingleConstant(value, params, _assembly);
if (replacement.empty())
continue;
pendingReplacements[value] = move(replacement);
optimisations++;
}
if (!pendingReplacements.empty())
replaceConstants(_items, pendingReplacements);
return optimisations;
}
AssemblyItems ConstantOptimisationMethod::optimiseSingleConstant(
u256 const& _value,
Params const& _params,
Assembly& _assembly
)
{
if (_value < 0x100)
return {};
LiteralMethod lit(_params, _value);
bigint literalGas = lit.gasNeeded();
CodeCopyMethod copy(_params, _value);
bigint copyGas = copy.gasNeeded();
ComputeMethod compute(_params, _value);
bigint computeGas = compute.gasNeeded();
if (copyGas < literalGas && copyGas < computeGas)
return copy.execute(_assembly);
else if (computeGas < literalGas && computeGas <= copyGas)
return compute.execute(_assembly);
return {};
}
bigint ConstantOptimisationMethod::simpleRunGas(AssemblyItems const& _items)
{
bigint gas = 0;

View File

@ -57,8 +57,6 @@ public:
);
protected:
/// This is the public API for the optimiser methods, but it doesn't need to be exposed to the caller.
struct Params
{
bool isCreation; ///< Whether this is called during contract creation or runtime.
@ -67,6 +65,17 @@ protected:
langutil::EVMVersion evmVersion; ///< Version of the EVM
};
/// Computes the replacement for a single constant.
/// This can already modify @a _assembly by adding a data item,
/// but the return value still has to be inserted.
static AssemblyItems optimiseSingleConstant(
u256 const& _value,
Params const& _params,
Assembly& _assembly
);
/// This is the public API for the optimiser methods, but it doesn't need to be exposed to the caller.
explicit ConstantOptimisationMethod(Params const& _params, u256 const& _value):
m_params(_params), m_value(_value) {}
virtual ~ConstantOptimisationMethod() = default;