mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Name simplifier.
This commit is contained in:
parent
95a284e526
commit
6101bdf7e2
@ -7,6 +7,8 @@ Compiler Features:
|
|||||||
* SMTChecker: Support shifts.
|
* SMTChecker: Support shifts.
|
||||||
* SMTChecker: Support structs.
|
* SMTChecker: Support structs.
|
||||||
* Yul Optimizer: Prune unused parameters in functions.
|
* Yul Optimizer: Prune unused parameters in functions.
|
||||||
|
* Yul Optimizer: Try to simplify function names.
|
||||||
|
|
||||||
|
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
* Type Checker: Disallow ``virtual`` for modifiers in libraries.
|
* Type Checker: Disallow ``virtual`` for modifiers in libraries.
|
||||||
|
@ -32,7 +32,7 @@ namespace solidity::frontend
|
|||||||
struct OptimiserSettings
|
struct OptimiserSettings
|
||||||
{
|
{
|
||||||
static char constexpr DefaultYulOptimiserSteps[] =
|
static char constexpr DefaultYulOptimiserSteps[] =
|
||||||
"dhfoDgvulfnTUtnIf" // None of these can make stack problems worse
|
"NdhfoDgvulfnTUtnIf" // None of these can make stack problems worse
|
||||||
"["
|
"["
|
||||||
"xarrscLM" // Turn into SSA and simplify
|
"xarrscLM" // Turn into SSA and simplify
|
||||||
"cCTUtTOntnfDIul" // Perform structural simplification
|
"cCTUtTOntnfDIul" // Perform structural simplification
|
||||||
@ -47,7 +47,7 @@ struct OptimiserSettings
|
|||||||
"gvif" // Run full inliner
|
"gvif" // Run full inliner
|
||||||
"CTUcarrLsTOtfDncarrIulc" // SSA plus simplify
|
"CTUcarrLsTOtfDncarrIulc" // SSA plus simplify
|
||||||
"]"
|
"]"
|
||||||
"jmuljuljul VcTOcul jmul"; // Make source short and pretty
|
"jmuljuljul VcTOcul jmulN"; // Make source short and pretty
|
||||||
|
|
||||||
/// No optimisations at all - not recommended.
|
/// No optimisations at all - not recommended.
|
||||||
static OptimiserSettings none()
|
static OptimiserSettings none()
|
||||||
|
@ -127,6 +127,8 @@ add_library(yul
|
|||||||
optimiser/NameDispenser.h
|
optimiser/NameDispenser.h
|
||||||
optimiser/NameDisplacer.cpp
|
optimiser/NameDisplacer.cpp
|
||||||
optimiser/NameDisplacer.h
|
optimiser/NameDisplacer.h
|
||||||
|
optimiser/NameSimplifier.cpp
|
||||||
|
optimiser/NameSimplifier.h
|
||||||
optimiser/OptimiserStep.h
|
optimiser/OptimiserStep.h
|
||||||
optimiser/OptimizerUtilities.cpp
|
optimiser/OptimizerUtilities.cpp
|
||||||
optimiser/OptimizerUtilities.h
|
optimiser/OptimizerUtilities.h
|
||||||
|
122
libyul/optimiser/NameSimplifier.cpp
Normal file
122
libyul/optimiser/NameSimplifier.cpp
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <libyul/optimiser/NameSimplifier.h>
|
||||||
|
#include <libyul/optimiser/NameCollector.h>
|
||||||
|
#include <libyul/AsmData.h>
|
||||||
|
#include <libyul/Dialect.h>
|
||||||
|
#include <libyul/optimiser/OptimizerUtilities.h>
|
||||||
|
|
||||||
|
#include <libsolutil/CommonData.h>
|
||||||
|
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
using namespace solidity::yul;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
NameSimplifier::NameSimplifier(
|
||||||
|
OptimiserStepContext& _context,
|
||||||
|
Block const& _ast
|
||||||
|
):
|
||||||
|
m_context(_context),
|
||||||
|
m_usedNames(_context.reservedIdentifiers)
|
||||||
|
{
|
||||||
|
for (YulString name: m_usedNames)
|
||||||
|
m_translations[name] = name;
|
||||||
|
|
||||||
|
set<YulString> allNames = NameCollector(_ast).names();
|
||||||
|
m_usedNames += allNames;
|
||||||
|
for (YulString name: allNames)
|
||||||
|
findSimplification(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NameSimplifier::operator()(FunctionDefinition& _funDef)
|
||||||
|
{
|
||||||
|
translate(_funDef.name);
|
||||||
|
renameVariables(_funDef.parameters);
|
||||||
|
renameVariables(_funDef.returnVariables);
|
||||||
|
ASTModifier::operator()(_funDef);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NameSimplifier::operator()(VariableDeclaration& _varDecl)
|
||||||
|
{
|
||||||
|
renameVariables(_varDecl.variables);
|
||||||
|
ASTModifier::operator()(_varDecl);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NameSimplifier::renameVariables(vector<TypedName>& _variables)
|
||||||
|
{
|
||||||
|
for (TypedName& typedName: _variables)
|
||||||
|
translate(typedName.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NameSimplifier::operator()(Identifier& _identifier)
|
||||||
|
{
|
||||||
|
translate(_identifier.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NameSimplifier::operator()(FunctionCall& _funCall)
|
||||||
|
{
|
||||||
|
// The visitor on its own does not visit the function name.
|
||||||
|
if (!m_context.dialect.builtin(_funCall.functionName.name))
|
||||||
|
(*this)(_funCall.functionName);
|
||||||
|
ASTModifier::operator()(_funCall);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NameSimplifier::findSimplification(YulString _name)
|
||||||
|
{
|
||||||
|
if (m_translations.count(_name))
|
||||||
|
return;
|
||||||
|
|
||||||
|
string name = _name.str();
|
||||||
|
|
||||||
|
static auto replacements = vector<pair<regex, string>>{
|
||||||
|
{regex("_\\$\\d+"), ""}, // removes AST IDs
|
||||||
|
{regex("(abi_..code.*)_to_.*"), "$1"}, // removes _to... for abi functions
|
||||||
|
{regex("(stringliteral_[0-9a-f][0-9a-f][0-9a-f][0-9a-f])[0-9a-f]*"), "$1"}, // shorten string literal
|
||||||
|
{regex("tuple_t_"), ""},
|
||||||
|
{regex("_memory_ptr"), ""},
|
||||||
|
{regex("_calldata_ptr"), "_calldata"},
|
||||||
|
{regex("_fromStack"), ""},
|
||||||
|
{regex("_storage_storage"), "_storage"},
|
||||||
|
{regex("_memory_memory"), "_memory"},
|
||||||
|
{regex("t_contract\\$_([^_]*)_"), "$1_"},
|
||||||
|
{regex("index_access_t_array"), "index_access"},
|
||||||
|
{regex("[0-9]*_$"), ""}
|
||||||
|
};
|
||||||
|
for (auto const& [pattern, substitute]: replacements)
|
||||||
|
{
|
||||||
|
string candidate = regex_replace(name, pattern, substitute);
|
||||||
|
if (
|
||||||
|
!isRestrictedIdentifier(m_context.dialect, YulString(candidate)) &&
|
||||||
|
!m_usedNames.count(YulString(candidate))
|
||||||
|
)
|
||||||
|
name = candidate;
|
||||||
|
}
|
||||||
|
if (name != _name.str())
|
||||||
|
{
|
||||||
|
m_usedNames.insert(YulString(name));
|
||||||
|
m_translations[_name] = YulString(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NameSimplifier::translate(YulString& _name)
|
||||||
|
{
|
||||||
|
auto it = m_translations.find(_name);
|
||||||
|
if (it != m_translations.end())
|
||||||
|
_name = it->second;
|
||||||
|
}
|
76
libyul/optimiser/NameSimplifier.h
Normal file
76
libyul/optimiser/NameSimplifier.h
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
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/>.
|
||||||
|
*/
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <libyul/AsmDataForward.h>
|
||||||
|
#include <libyul/optimiser/ASTWalker.h>
|
||||||
|
#include <libyul/YulString.h>
|
||||||
|
#include <libyul/optimiser/OptimiserStep.h>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace solidity::yul
|
||||||
|
{
|
||||||
|
|
||||||
|
struct Dialect;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pass to "simplify" all identifier names.
|
||||||
|
*
|
||||||
|
* The purpose of this is to make generated code more readable, but also
|
||||||
|
* to remove AST identifiers that could lead to a different sorting order
|
||||||
|
* and thus influence e.g. the order of function inlining.
|
||||||
|
*
|
||||||
|
* Prerequisites: Disambiguator, FunctionHoister, FunctionGrouper
|
||||||
|
*/
|
||||||
|
class NameSimplifier: public ASTModifier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr char const* name{"NameSimplifier"};
|
||||||
|
static void run(OptimiserStepContext& _context, Block& _ast)
|
||||||
|
{
|
||||||
|
NameSimplifier{_context, _ast}(_ast);
|
||||||
|
}
|
||||||
|
|
||||||
|
using ASTModifier::operator();
|
||||||
|
void operator()(VariableDeclaration& _varDecl) override;
|
||||||
|
void operator()(Identifier& _identifier) override;
|
||||||
|
void operator()(FunctionCall& _funCall) override;
|
||||||
|
void operator()(FunctionDefinition& _funDef) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
NameSimplifier(
|
||||||
|
OptimiserStepContext& _context,
|
||||||
|
Block const& _ast
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Tries to rename a list of variables.
|
||||||
|
void renameVariables(std::vector<TypedName>& _variables);
|
||||||
|
|
||||||
|
void findSimplification(YulString _name);
|
||||||
|
void translate(YulString& _name);
|
||||||
|
|
||||||
|
OptimiserStepContext& m_context;
|
||||||
|
std::set<YulString> m_usedNames;
|
||||||
|
std::map<YulString, YulString> m_translations;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -57,6 +57,7 @@
|
|||||||
#include <libyul/optimiser/LoadResolver.h>
|
#include <libyul/optimiser/LoadResolver.h>
|
||||||
#include <libyul/optimiser/LoopInvariantCodeMotion.h>
|
#include <libyul/optimiser/LoopInvariantCodeMotion.h>
|
||||||
#include <libyul/optimiser/Metrics.h>
|
#include <libyul/optimiser/Metrics.h>
|
||||||
|
#include <libyul/optimiser/NameSimplifier.h>
|
||||||
#include <libyul/backends/evm/ConstantOptimiser.h>
|
#include <libyul/backends/evm/ConstantOptimiser.h>
|
||||||
#include <libyul/AsmAnalysis.h>
|
#include <libyul/AsmAnalysis.h>
|
||||||
#include <libyul/AsmAnalysisInfo.h>
|
#include <libyul/AsmAnalysisInfo.h>
|
||||||
@ -181,6 +182,7 @@ map<string, unique_ptr<OptimiserStep>> const& OptimiserSuite::allSteps()
|
|||||||
LiteralRematerialiser,
|
LiteralRematerialiser,
|
||||||
LoadResolver,
|
LoadResolver,
|
||||||
LoopInvariantCodeMotion,
|
LoopInvariantCodeMotion,
|
||||||
|
NameSimplifier,
|
||||||
RedundantAssignEliminator,
|
RedundantAssignEliminator,
|
||||||
Rematerialiser,
|
Rematerialiser,
|
||||||
SSAReverser,
|
SSAReverser,
|
||||||
@ -218,6 +220,7 @@ map<string, char> const& OptimiserSuite::stepNameToAbbreviationMap()
|
|||||||
{LiteralRematerialiser::name, 'T'},
|
{LiteralRematerialiser::name, 'T'},
|
||||||
{LoadResolver::name, 'L'},
|
{LoadResolver::name, 'L'},
|
||||||
{LoopInvariantCodeMotion::name, 'M'},
|
{LoopInvariantCodeMotion::name, 'M'},
|
||||||
|
{NameSimplifier::name, 'N'},
|
||||||
{RedundantAssignEliminator::name, 'r'},
|
{RedundantAssignEliminator::name, 'r'},
|
||||||
{Rematerialiser::name, 'm'},
|
{Rematerialiser::name, 'm'},
|
||||||
{SSAReverser::name, 'V'},
|
{SSAReverser::name, 'V'},
|
||||||
|
1
test/cmdlineTests/name_simplifier/args
Normal file
1
test/cmdlineTests/name_simplifier/args
Normal file
@ -0,0 +1 @@
|
|||||||
|
--optimize --ir-optimized --metadata-hash none
|
23
test/cmdlineTests/name_simplifier/input.sol
Normal file
23
test/cmdlineTests/name_simplifier/input.sol
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
|
pragma solidity >=0.0;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
// The point of this test is to check that the
|
||||||
|
// AST IDs are removed from the optimized IR
|
||||||
|
// so that they do not have a big effect on the
|
||||||
|
// optimizer if it has a bug that makes it
|
||||||
|
// depen on the actual identifiers.
|
||||||
|
|
||||||
|
struct S { uint x; }
|
||||||
|
struct T { uint[2] y; }
|
||||||
|
|
||||||
|
contract C {
|
||||||
|
S[2] values;
|
||||||
|
T t;
|
||||||
|
|
||||||
|
function sumArray(S[] memory _s) public returns (uint, string memory) {
|
||||||
|
values[0].x = _s[0].x;
|
||||||
|
t.y[0] = _s[1].x;
|
||||||
|
return (t.y[0], "longstringlongstringlongstringlongstringlongstringlongstringlongstringlongstringlongstringlongstring");
|
||||||
|
}
|
||||||
|
}
|
131
test/cmdlineTests/name_simplifier/output
Normal file
131
test/cmdlineTests/name_simplifier/output
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
Optimized IR:
|
||||||
|
/*******************************************************
|
||||||
|
* WARNING *
|
||||||
|
* Solidity to Yul compilation is still EXPERIMENTAL *
|
||||||
|
* It can result in LOSS OF FUNDS or worse *
|
||||||
|
* !USE AT YOUR OWN RISK! *
|
||||||
|
*******************************************************/
|
||||||
|
|
||||||
|
object "C_56" {
|
||||||
|
code {
|
||||||
|
{
|
||||||
|
mstore(64, 128)
|
||||||
|
if callvalue() { revert(0, 0) }
|
||||||
|
let _1 := datasize("C_56_deployed")
|
||||||
|
codecopy(0, dataoffset("C_56_deployed"), _1)
|
||||||
|
return(0, _1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
object "C_56_deployed" {
|
||||||
|
code {
|
||||||
|
{
|
||||||
|
mstore(64, 128)
|
||||||
|
if iszero(lt(calldatasize(), 4))
|
||||||
|
{
|
||||||
|
let _1 := 0
|
||||||
|
if eq(0xf8eddcc6, shr(224, calldataload(_1)))
|
||||||
|
{
|
||||||
|
if callvalue() { revert(_1, _1) }
|
||||||
|
if slt(add(calldatasize(), not(3)), 32) { revert(_1, _1) }
|
||||||
|
let offset := calldataload(4)
|
||||||
|
if gt(offset, 0xffffffffffffffff) { revert(_1, _1) }
|
||||||
|
let value0 := abi_decode_t_array$_t_struct$_S_$dyn(add(4, offset), calldatasize())
|
||||||
|
let value := mload(mload(memory_array_index_access$_t_struct$_S_$dyn(value0, _1)))
|
||||||
|
let _2, _3 := storage_array_index_access$_t_struct$_S_storage(_1, _1)
|
||||||
|
sstore(_2, value)
|
||||||
|
let value_1 := mload(mload(memory_array_index_access$_t_struct$_S_$dyn(value0, 0x01)))
|
||||||
|
let _4, _5 := storage_array_index_access$_t_struct$_S_storage(0x02, _1)
|
||||||
|
update_storage_value_t_uint256_to_t_uint256(_4, _5, value_1)
|
||||||
|
let _6, _7 := storage_array_index_access$_t_struct$_S_storage(0x02, _1)
|
||||||
|
let vloc := extract_from_storage_value_dynamict_uint256(sload(_6), _7)
|
||||||
|
let vloc__24_mpos := convert_t_stringliteral_6490_to_t_string()
|
||||||
|
let memPos := allocateMemory(_1)
|
||||||
|
return(memPos, sub(abi_encode_uint256_t_string(memPos, vloc, vloc__24_mpos), memPos))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
revert(0, 0)
|
||||||
|
}
|
||||||
|
function abi_decode_t_array$_t_struct$_S_$dyn(offset, end) -> array
|
||||||
|
{
|
||||||
|
if iszero(slt(add(offset, 0x1f), end)) { revert(array, array) }
|
||||||
|
let length := calldataload(offset)
|
||||||
|
if gt(length, 0xffffffffffffffff) { revert(array, array) }
|
||||||
|
let _1 := 0x20
|
||||||
|
let _2 := mul(length, _1)
|
||||||
|
array := allocateMemory(add(_2, _1))
|
||||||
|
let dst := array
|
||||||
|
mstore(array, length)
|
||||||
|
dst := add(array, _1)
|
||||||
|
let src := add(offset, _1)
|
||||||
|
if gt(add(add(offset, _2), _1), end) { revert(0, 0) }
|
||||||
|
let i := 0
|
||||||
|
let i_1 := i
|
||||||
|
for { } lt(i_1, length) { i_1 := add(i_1, 1) }
|
||||||
|
{
|
||||||
|
if slt(sub(end, src), _1) { revert(i, i) }
|
||||||
|
let value := allocateMemory(_1)
|
||||||
|
mstore(value, calldataload(src))
|
||||||
|
mstore(dst, value)
|
||||||
|
dst := add(dst, _1)
|
||||||
|
src := add(src, _1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function abi_encode_uint256_t_string(headStart, value0, value1) -> tail
|
||||||
|
{
|
||||||
|
mstore(headStart, value0)
|
||||||
|
let _1 := 32
|
||||||
|
mstore(add(headStart, _1), 64)
|
||||||
|
let length := mload(value1)
|
||||||
|
mstore(add(headStart, 64), length)
|
||||||
|
let i := tail
|
||||||
|
for { } lt(i, length) { i := add(i, _1) }
|
||||||
|
{
|
||||||
|
mstore(add(add(headStart, i), 96), mload(add(add(value1, i), _1)))
|
||||||
|
}
|
||||||
|
if gt(i, length)
|
||||||
|
{
|
||||||
|
mstore(add(add(headStart, length), 96), tail)
|
||||||
|
}
|
||||||
|
tail := add(add(headStart, and(add(length, 31), not(31))), 96)
|
||||||
|
}
|
||||||
|
function allocateMemory(size) -> memPtr
|
||||||
|
{
|
||||||
|
memPtr := mload(64)
|
||||||
|
let newFreePtr := add(memPtr, size)
|
||||||
|
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) }
|
||||||
|
mstore(64, newFreePtr)
|
||||||
|
}
|
||||||
|
function convert_t_stringliteral_6490_to_t_string() -> converted
|
||||||
|
{
|
||||||
|
converted := allocateMemory(160)
|
||||||
|
mstore(converted, 100)
|
||||||
|
mstore(add(converted, 32), "longstringlongstringlongstringlo")
|
||||||
|
mstore(add(converted, 64), "ngstringlongstringlongstringlong")
|
||||||
|
mstore(add(converted, 96), "stringlongstringlongstringlongst")
|
||||||
|
mstore(add(converted, 128), "ring")
|
||||||
|
}
|
||||||
|
function extract_from_storage_value_dynamict_uint256(slot_value, offset) -> value
|
||||||
|
{
|
||||||
|
value := shr(mul(offset, 8), slot_value)
|
||||||
|
}
|
||||||
|
function memory_array_index_access$_t_struct$_S_$dyn(baseRef, index) -> addr
|
||||||
|
{
|
||||||
|
if iszero(lt(index, mload(baseRef))) { invalid() }
|
||||||
|
addr := add(add(baseRef, mul(index, 32)), 32)
|
||||||
|
}
|
||||||
|
function storage_array_index_access$_t_struct$_S_storage(array, index) -> slot, offset
|
||||||
|
{
|
||||||
|
if iszero(lt(index, 0x02)) { invalid() }
|
||||||
|
slot := add(array, index)
|
||||||
|
offset := offset
|
||||||
|
}
|
||||||
|
function update_storage_value_t_uint256_to_t_uint256(slot, offset, value)
|
||||||
|
{
|
||||||
|
let _1 := sload(slot)
|
||||||
|
let shiftBits := mul(offset, 8)
|
||||||
|
let mask := shl(shiftBits, not(0))
|
||||||
|
sstore(slot, or(and(_1, not(mask)), and(shl(shiftBits, value), mask)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -36,16 +36,16 @@ object "Arraysum_33" {
|
|||||||
vloc_i := increment_t_uint256(vloc_i)
|
vloc_i := increment_t_uint256(vloc_i)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
let _3, _4 := storage_array_index_access_t_array$_t_uint256_$dyn_storage(_1, vloc_i)
|
let _3, _4 := storage_array_index_access$_t_uint256_$dyn_storage(_1, vloc_i)
|
||||||
vloc_sum := checked_add_t_uint256(vloc_sum, extract_from_storage_value_dynamict_uint256(sload(_3), _4))
|
vloc_sum := checked_add_t_uint256(vloc_sum, extract_from_storage_value_dynamict_uint256(sload(_3), _4))
|
||||||
}
|
}
|
||||||
let memPos := allocateMemory(_1)
|
let memPos := allocateMemory(_1)
|
||||||
return(memPos, sub(abi_encode_tuple_t_uint256__to_t_uint256__fromStack(memPos, _1), memPos))
|
return(memPos, sub(abi_encode_uint(memPos, _1), memPos))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
revert(0, 0)
|
revert(0, 0)
|
||||||
}
|
}
|
||||||
function abi_encode_tuple_t_uint256__to_t_uint256__fromStack(headStart, value0) -> tail
|
function abi_encode_uint(headStart, value0) -> tail
|
||||||
{
|
{
|
||||||
tail := add(headStart, 32)
|
tail := add(headStart, 32)
|
||||||
mstore(headStart, value0)
|
mstore(headStart, value0)
|
||||||
@ -71,7 +71,7 @@ object "Arraysum_33" {
|
|||||||
if gt(value, not(1)) { revert(ret, ret) }
|
if gt(value, not(1)) { revert(ret, ret) }
|
||||||
ret := add(value, 1)
|
ret := add(value, 1)
|
||||||
}
|
}
|
||||||
function storage_array_index_access_t_array$_t_uint256_$dyn_storage(array, index) -> slot, offset
|
function storage_array_index_access$_t_uint256_$dyn_storage(array, index) -> slot, offset
|
||||||
{
|
{
|
||||||
if iszero(lt(index, sload(array))) { invalid() }
|
if iszero(lt(index, sload(array))) { invalid() }
|
||||||
mstore(slot, array)
|
mstore(slot, array)
|
||||||
|
@ -1081,13 +1081,13 @@
|
|||||||
// let _2 := mload(0)
|
// let _2 := mload(0)
|
||||||
// if slt(sub(_1, _2), 64) { revert(0, 0) }
|
// if slt(sub(_1, _2), 64) { revert(0, 0) }
|
||||||
// sstore(0, and(calldataload(_2), sub(shl(160, 1), 1)))
|
// sstore(0, and(calldataload(_2), sub(shl(160, 1), 1)))
|
||||||
// let x0, x1, x2, x3, x4 := abi_decode_tuple_t_addresst_uint256t_bytes_calldata_ptrt_enum$_Operation_$1949(mload(7), mload(8))
|
// let x0, x1, x2, x3, x4 := abi_decode_addresst_uint256t_bytes_calldatat_enum$_Operation(mload(7), mload(8))
|
||||||
// sstore(x1, x0)
|
// sstore(x1, x0)
|
||||||
// sstore(x3, x2)
|
// sstore(x3, x2)
|
||||||
// sstore(1, x4)
|
// sstore(1, x4)
|
||||||
// pop(abi_encode_tuple_t_bytes32_t_address_t_uint256_t_bytes32_t_enum$_Operation_$1949_t_uint256_t_uint256_t_uint256_t_address_t_address_t_uint256__to_t_bytes32_t_address_t_uint256_t_bytes32_t_uint8_t_uint256_t_uint256_t_uint256_t_address_t_address_t_uint256_(mload(30), mload(31), mload(32), mload(33), mload(34), mload(35), mload(36), mload(37), mload(38), mload(39), mload(40), mload(41)))
|
// pop(abi_encode_bytes32_t_address_t_uint256_t_bytes32_t_enum$_Operation_t_uint256_t_uint256_t_uint256_t_address_t_address_t_uint(mload(30), mload(31), mload(32), mload(33), mload(34), mload(35), mload(36), mload(37), mload(38), mload(39), mload(40), mload(41)))
|
||||||
// }
|
// }
|
||||||
// function abi_decode_tuple_t_addresst_uint256t_bytes_calldata_ptrt_enum$_Operation_$1949(headStart, dataEnd) -> value0, value1, value2, value3, value4
|
// function abi_decode_addresst_uint256t_bytes_calldatat_enum$_Operation(headStart, dataEnd) -> value0, value1, value2, value3, value4
|
||||||
// {
|
// {
|
||||||
// if slt(sub(dataEnd, headStart), 128) { revert(value4, value4) }
|
// if slt(sub(dataEnd, headStart), 128) { revert(value4, value4) }
|
||||||
// value0 := and(calldataload(headStart), sub(shl(160, 1), 1))
|
// value0 := and(calldataload(headStart), sub(shl(160, 1), 1))
|
||||||
@ -1106,7 +1106,7 @@
|
|||||||
// if iszero(lt(_3, 3)) { revert(value4, value4) }
|
// if iszero(lt(_3, 3)) { revert(value4, value4) }
|
||||||
// value4 := _3
|
// value4 := _3
|
||||||
// }
|
// }
|
||||||
// function abi_encode_tuple_t_bytes32_t_address_t_uint256_t_bytes32_t_enum$_Operation_$1949_t_uint256_t_uint256_t_uint256_t_address_t_address_t_uint256__to_t_bytes32_t_address_t_uint256_t_bytes32_t_uint8_t_uint256_t_uint256_t_uint256_t_address_t_address_t_uint256_(headStart, value10, value9, value8, value7, value6, value5, value4, value3, value2, value1, value0) -> tail
|
// function abi_encode_bytes32_t_address_t_uint256_t_bytes32_t_enum$_Operation_t_uint256_t_uint256_t_uint256_t_address_t_address_t_uint(headStart, value10, value9, value8, value7, value6, value5, value4, value3, value2, value1, value0) -> tail
|
||||||
// {
|
// {
|
||||||
// tail := add(headStart, 352)
|
// tail := add(headStart, 352)
|
||||||
// mstore(headStart, value0)
|
// mstore(headStart, value0)
|
||||||
|
@ -473,7 +473,7 @@
|
|||||||
// let i := _1
|
// let i := _1
|
||||||
// for { } lt(i, length) { i := add(i, 1) }
|
// for { } lt(i, length) { i := add(i, 1) }
|
||||||
// {
|
// {
|
||||||
// abi_encode_t_array$_t_contract$_C_$55_$3_memory_to_t_array$_t_address_$3_memory_ptr(mload(srcPtr), pos)
|
// abi_encode_t_array$_C_memory(mload(srcPtr), pos)
|
||||||
// srcPtr := add(srcPtr, 0x20)
|
// srcPtr := add(srcPtr, 0x20)
|
||||||
// pos := add(pos, 0x60)
|
// pos := add(pos, 0x60)
|
||||||
// }
|
// }
|
||||||
@ -483,15 +483,15 @@
|
|||||||
// let offset := calldataload(add(_4, 64))
|
// let offset := calldataload(add(_4, 64))
|
||||||
// let _5 := 0xffffffffffffffff
|
// let _5 := 0xffffffffffffffff
|
||||||
// if gt(offset, _5) { revert(_1, _1) }
|
// if gt(offset, _5) { revert(_1, _1) }
|
||||||
// let value2 := abi_decode_t_array$_t_uint256_$dyn_memory_ptr(add(_4, offset), _3)
|
// let value2 := abi_decode_t_array$_t_uint256_$dyn(add(_4, offset), _3)
|
||||||
// let offset_1 := calldataload(add(_4, 0x60))
|
// let offset_1 := calldataload(add(_4, 0x60))
|
||||||
// if gt(offset_1, _5) { revert(_1, _1) }
|
// if gt(offset_1, _5) { revert(_1, _1) }
|
||||||
// let value3 := abi_decode_t_array$_t_array$_t_uint256_$2_memory_$dyn_memory_ptr(add(_4, offset_1), _3)
|
// let value3 := abi_decode_t_array$_t_array$_t_uint256_memory_$dyn(add(_4, offset_1), _3)
|
||||||
// sstore(calldataload(_4), calldataload(add(_4, 0x20)))
|
// sstore(calldataload(_4), calldataload(add(_4, 0x20)))
|
||||||
// sstore(value2, value3)
|
// sstore(value2, value3)
|
||||||
// sstore(_1, pos)
|
// sstore(_1, pos)
|
||||||
// }
|
// }
|
||||||
// function abi_decode_t_array$_t_array$_t_uint256_$2_memory_$dyn_memory_ptr(offset, end) -> array
|
// function abi_decode_t_array$_t_array$_t_uint256_memory_$dyn(offset, end) -> array
|
||||||
// {
|
// {
|
||||||
// let _1 := 0x1f
|
// let _1 := 0x1f
|
||||||
// if iszero(slt(add(offset, _1), end)) { revert(array, array) }
|
// if iszero(slt(add(offset, _1), end)) { revert(array, array) }
|
||||||
@ -509,7 +509,7 @@
|
|||||||
// {
|
// {
|
||||||
// if iszero(slt(add(src, _1), end)) { revert(0, 0) }
|
// if iszero(slt(add(src, _1), end)) { revert(0, 0) }
|
||||||
// let _4 := 0x2
|
// let _4 := 0x2
|
||||||
// let dst_1 := allocateMemory(array_allocation_size_t_array$_t_uint256_$2_memory(_4))
|
// let dst_1 := allocateMemory(array_allocation_size_t_array$_t_uint256_memory(_4))
|
||||||
// let dst_2 := dst_1
|
// let dst_2 := dst_1
|
||||||
// let src_1 := src
|
// let src_1 := src
|
||||||
// let _5 := add(src, _3)
|
// let _5 := add(src, _3)
|
||||||
@ -526,7 +526,7 @@
|
|||||||
// src := _5
|
// src := _5
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// function abi_decode_t_array$_t_uint256_$dyn_memory_ptr(offset, end) -> array
|
// function abi_decode_t_array$_t_uint256_$dyn(offset, end) -> array
|
||||||
// {
|
// {
|
||||||
// if iszero(slt(add(offset, 0x1f), end)) { revert(array, array) }
|
// if iszero(slt(add(offset, 0x1f), end)) { revert(array, array) }
|
||||||
// let length := calldataload(offset)
|
// let length := calldataload(offset)
|
||||||
@ -545,7 +545,7 @@
|
|||||||
// src := add(src, _1)
|
// src := add(src, _1)
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// function abi_encode_t_array$_t_contract$_C_$55_$3_memory_to_t_array$_t_address_$3_memory_ptr(value, pos)
|
// function abi_encode_t_array$_C_memory(value, pos)
|
||||||
// {
|
// {
|
||||||
// let srcPtr := value
|
// let srcPtr := value
|
||||||
// let i := 0
|
// let i := 0
|
||||||
@ -569,7 +569,7 @@
|
|||||||
// if gt(length, 0xffffffffffffffff) { revert(size, size) }
|
// if gt(length, 0xffffffffffffffff) { revert(size, size) }
|
||||||
// size := add(mul(length, 0x20), 0x20)
|
// size := add(mul(length, 0x20), 0x20)
|
||||||
// }
|
// }
|
||||||
// function array_allocation_size_t_array$_t_uint256_$2_memory(length) -> size
|
// function array_allocation_size_t_array$_t_uint256_memory(length) -> size
|
||||||
// {
|
// {
|
||||||
// if gt(length, 0xffffffffffffffff) { revert(size, size) }
|
// if gt(length, 0xffffffffffffffff) { revert(size, size) }
|
||||||
// size := mul(length, 0x20)
|
// size := mul(length, 0x20)
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
// This function name can be shortened, the other cannot.
|
||||||
|
function nonmstore_(x) {
|
||||||
|
nonmstore_(x)
|
||||||
|
sstore(10, calldataload(2))
|
||||||
|
}
|
||||||
|
function mstore_(x) -> y {
|
||||||
|
let t3_3_ := mstore_(x)
|
||||||
|
y := 8
|
||||||
|
sstore(y, calldataload(y))
|
||||||
|
}
|
||||||
|
let t2_ := mstore_(7)
|
||||||
|
nonmstore_(70)
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// step: fullSuite
|
||||||
|
//
|
||||||
|
// {
|
||||||
|
// {
|
||||||
|
// pop(mstore_(7))
|
||||||
|
// nonmstore(70)
|
||||||
|
// }
|
||||||
|
// function nonmstore(x)
|
||||||
|
// {
|
||||||
|
// nonmstore(x)
|
||||||
|
// sstore(10, calldataload(2))
|
||||||
|
// }
|
||||||
|
// function mstore_(x) -> y
|
||||||
|
// {
|
||||||
|
// pop(mstore_(x))
|
||||||
|
// y := 8
|
||||||
|
// sstore(y, calldataload(y))
|
||||||
|
// }
|
||||||
|
// }
|
@ -36,16 +36,16 @@
|
|||||||
//
|
//
|
||||||
// {
|
// {
|
||||||
// {
|
// {
|
||||||
// let a, b := abi_decode_t_bytes_calldata_ptr(mload(0), mload(1))
|
// let a, b := abi_decode_t_bytes_calldata(mload(0), mload(1))
|
||||||
// let a_1, b_1 := abi_decode_t_bytes_calldata_ptr(a, b)
|
// let a_1, b_1 := abi_decode_t_bytes_calldata(a, b)
|
||||||
// let a_2, b_2 := abi_decode_t_bytes_calldata_ptr(a_1, b_1)
|
// let a_2, b_2 := abi_decode_t_bytes_calldata(a_1, b_1)
|
||||||
// let a_3, b_3 := abi_decode_t_bytes_calldata_ptr(a_2, b_2)
|
// let a_3, b_3 := abi_decode_t_bytes_calldata(a_2, b_2)
|
||||||
// let a_4, b_4 := abi_decode_t_bytes_calldata_ptr(a_3, b_3)
|
// let a_4, b_4 := abi_decode_t_bytes_calldata(a_3, b_3)
|
||||||
// let a_5, b_5 := abi_decode_t_bytes_calldata_ptr(a_4, b_4)
|
// let a_5, b_5 := abi_decode_t_bytes_calldata(a_4, b_4)
|
||||||
// let a_6, b_6 := abi_decode_t_bytes_calldata_ptr(a_5, b_5)
|
// let a_6, b_6 := abi_decode_t_bytes_calldata(a_5, b_5)
|
||||||
// mstore(a_6, b_6)
|
// mstore(a_6, b_6)
|
||||||
// }
|
// }
|
||||||
// function abi_decode_t_bytes_calldata_ptr(offset, end) -> arrayPos, length
|
// function abi_decode_t_bytes_calldata(offset, end) -> arrayPos, length
|
||||||
// {
|
// {
|
||||||
// if iszero(slt(add(offset, 0x1f), end)) { revert(arrayPos, arrayPos) }
|
// if iszero(slt(add(offset, 0x1f), end)) { revert(arrayPos, arrayPos) }
|
||||||
// length := calldataload(offset)
|
// length := calldataload(offset)
|
||||||
|
@ -130,7 +130,7 @@ BOOST_AUTO_TEST_CASE(output_operator_should_create_concise_and_unambiguous_strin
|
|||||||
|
|
||||||
BOOST_TEST(chromosome.length() == allSteps.size());
|
BOOST_TEST(chromosome.length() == allSteps.size());
|
||||||
BOOST_TEST(chromosome.optimisationSteps() == allSteps);
|
BOOST_TEST(chromosome.optimisationSteps() == allSteps);
|
||||||
BOOST_TEST(toString(chromosome) == "flcCUnDvejsxIOoighTLMrmVatpud");
|
BOOST_TEST(toString(chromosome) == "flcCUnDvejsxIOoighTLMNrmVatpud");
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(randomOptimisationStep_should_return_each_step_with_same_probability)
|
BOOST_AUTO_TEST_CASE(randomOptimisationStep_should_return_each_step_with_same_probability)
|
||||||
|
@ -103,10 +103,10 @@ BOOST_AUTO_TEST_CASE(geneAddition_should_iterate_over_gene_positions_and_insert_
|
|||||||
SimulationRNG::reset(1);
|
SimulationRNG::reset(1);
|
||||||
// f c C U n D v e j s
|
// f c C U n D v e j s
|
||||||
BOOST_TEST(mutation01(chromosome) == Chromosome(stripWhitespace(" f c C UC n D v e jx s"))); // 20% more
|
BOOST_TEST(mutation01(chromosome) == Chromosome(stripWhitespace(" f c C UC n D v e jx s"))); // 20% more
|
||||||
BOOST_TEST(mutation05(chromosome) == Chromosome(stripWhitespace("s f cu C U nj D v eI j sf"))); // 50% more
|
BOOST_TEST(mutation05(chromosome) == Chromosome(stripWhitespace("s f cu C U nj D v eO j sf"))); // 50% more
|
||||||
SimulationRNG::reset(2);
|
SimulationRNG::reset(2);
|
||||||
BOOST_TEST(mutation01(chromosome) == Chromosome(stripWhitespace(" f cu C U n D v e j s"))); // 10% more
|
BOOST_TEST(mutation01(chromosome) == Chromosome(stripWhitespace(" f cp C U n D v e j s"))); // 10% more
|
||||||
BOOST_TEST(mutation05(chromosome) == Chromosome(stripWhitespace("M f ce Cv U n D v e jo s"))); // 40% more
|
BOOST_TEST(mutation05(chromosome) == Chromosome(stripWhitespace("M f ce Ce U n D v e jo s"))); // 40% more
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(geneAddition_should_be_able_to_insert_before_first_position)
|
BOOST_AUTO_TEST_CASE(geneAddition_should_be_able_to_insert_before_first_position)
|
||||||
|
Loading…
Reference in New Issue
Block a user