mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #9591 from ethereum/nameSimplifier
Yul name simplifier.
This commit is contained in:
commit
0db79dbc29
@ -7,6 +7,8 @@ Compiler Features:
|
||||
* SMTChecker: Support shifts.
|
||||
* SMTChecker: Support structs.
|
||||
* Yul Optimizer: Prune unused parameters in functions.
|
||||
* Yul Optimizer: Try to simplify function names.
|
||||
|
||||
|
||||
Bugfixes:
|
||||
* Type Checker: Disallow ``virtual`` for modifiers in libraries.
|
||||
|
@ -32,7 +32,7 @@ namespace solidity::frontend
|
||||
struct OptimiserSettings
|
||||
{
|
||||
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
|
||||
"cCTUtTOntnfDIul" // Perform structural simplification
|
||||
@ -47,7 +47,7 @@ struct OptimiserSettings
|
||||
"gvif" // Run full inliner
|
||||
"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.
|
||||
static OptimiserSettings none()
|
||||
|
@ -127,6 +127,8 @@ add_library(yul
|
||||
optimiser/NameDispenser.h
|
||||
optimiser/NameDisplacer.cpp
|
||||
optimiser/NameDisplacer.h
|
||||
optimiser/NameSimplifier.cpp
|
||||
optimiser/NameSimplifier.h
|
||||
optimiser/OptimiserStep.h
|
||||
optimiser/OptimizerUtilities.cpp
|
||||
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/LoopInvariantCodeMotion.h>
|
||||
#include <libyul/optimiser/Metrics.h>
|
||||
#include <libyul/optimiser/NameSimplifier.h>
|
||||
#include <libyul/backends/evm/ConstantOptimiser.h>
|
||||
#include <libyul/AsmAnalysis.h>
|
||||
#include <libyul/AsmAnalysisInfo.h>
|
||||
@ -181,6 +182,7 @@ map<string, unique_ptr<OptimiserStep>> const& OptimiserSuite::allSteps()
|
||||
LiteralRematerialiser,
|
||||
LoadResolver,
|
||||
LoopInvariantCodeMotion,
|
||||
NameSimplifier,
|
||||
RedundantAssignEliminator,
|
||||
Rematerialiser,
|
||||
SSAReverser,
|
||||
@ -218,6 +220,7 @@ map<string, char> const& OptimiserSuite::stepNameToAbbreviationMap()
|
||||
{LiteralRematerialiser::name, 'T'},
|
||||
{LoadResolver::name, 'L'},
|
||||
{LoopInvariantCodeMotion::name, 'M'},
|
||||
{NameSimplifier::name, 'N'},
|
||||
{RedundantAssignEliminator::name, 'r'},
|
||||
{Rematerialiser::name, 'm'},
|
||||
{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)
|
||||
}
|
||||
{
|
||||
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))
|
||||
}
|
||||
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)
|
||||
}
|
||||
function abi_encode_tuple_t_uint256__to_t_uint256__fromStack(headStart, value0) -> tail
|
||||
function abi_encode_uint(headStart, value0) -> tail
|
||||
{
|
||||
tail := add(headStart, 32)
|
||||
mstore(headStart, value0)
|
||||
@ -71,7 +71,7 @@ object "Arraysum_33" {
|
||||
if gt(value, not(1)) { revert(ret, ret) }
|
||||
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() }
|
||||
mstore(slot, array)
|
||||
|
@ -1081,13 +1081,13 @@
|
||||
// let _2 := mload(0)
|
||||
// if slt(sub(_1, _2), 64) { revert(0, 0) }
|
||||
// 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(x3, x2)
|
||||
// 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) }
|
||||
// value0 := and(calldataload(headStart), sub(shl(160, 1), 1))
|
||||
@ -1106,7 +1106,7 @@
|
||||
// if iszero(lt(_3, 3)) { revert(value4, value4) }
|
||||
// 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)
|
||||
// mstore(headStart, value0)
|
||||
|
@ -473,7 +473,7 @@
|
||||
// let 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)
|
||||
// pos := add(pos, 0x60)
|
||||
// }
|
||||
@ -483,15 +483,15 @@
|
||||
// let offset := calldataload(add(_4, 64))
|
||||
// let _5 := 0xffffffffffffffff
|
||||
// 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))
|
||||
// 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(value2, value3)
|
||||
// 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
|
||||
// if iszero(slt(add(offset, _1), end)) { revert(array, array) }
|
||||
@ -509,7 +509,7 @@
|
||||
// {
|
||||
// if iszero(slt(add(src, _1), end)) { revert(0, 0) }
|
||||
// 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 src_1 := src
|
||||
// let _5 := add(src, _3)
|
||||
@ -526,7 +526,7 @@
|
||||
// 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) }
|
||||
// let length := calldataload(offset)
|
||||
@ -545,7 +545,7 @@
|
||||
// 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 i := 0
|
||||
@ -569,7 +569,7 @@
|
||||
// if gt(length, 0xffffffffffffffff) { revert(size, size) }
|
||||
// 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) }
|
||||
// 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_1, b_1 := abi_decode_t_bytes_calldata_ptr(a, b)
|
||||
// let a_2, b_2 := abi_decode_t_bytes_calldata_ptr(a_1, b_1)
|
||||
// let a_3, b_3 := abi_decode_t_bytes_calldata_ptr(a_2, b_2)
|
||||
// let a_4, b_4 := abi_decode_t_bytes_calldata_ptr(a_3, b_3)
|
||||
// let a_5, b_5 := abi_decode_t_bytes_calldata_ptr(a_4, b_4)
|
||||
// let a_6, b_6 := abi_decode_t_bytes_calldata_ptr(a_5, b_5)
|
||||
// let a, b := abi_decode_t_bytes_calldata(mload(0), mload(1))
|
||||
// let a_1, b_1 := abi_decode_t_bytes_calldata(a, b)
|
||||
// let a_2, b_2 := abi_decode_t_bytes_calldata(a_1, b_1)
|
||||
// let a_3, b_3 := abi_decode_t_bytes_calldata(a_2, b_2)
|
||||
// let a_4, b_4 := abi_decode_t_bytes_calldata(a_3, b_3)
|
||||
// let a_5, b_5 := abi_decode_t_bytes_calldata(a_4, b_4)
|
||||
// let a_6, b_6 := abi_decode_t_bytes_calldata(a_5, b_5)
|
||||
// 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) }
|
||||
// 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.optimisationSteps() == allSteps);
|
||||
BOOST_TEST(toString(chromosome) == "flcCUnDvejsxIOoighTLMrmVatpud");
|
||||
BOOST_TEST(toString(chromosome) == "flcCUnDvejsxIOoighTLMNrmVatpud");
|
||||
}
|
||||
|
||||
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);
|
||||
// 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(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);
|
||||
BOOST_TEST(mutation01(chromosome) == Chromosome(stripWhitespace(" f cu 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(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 Ce U n D v e jo s"))); // 40% more
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(geneAddition_should_be_able_to_insert_before_first_position)
|
||||
|
Loading…
Reference in New Issue
Block a user