Merge pull request #11749 from ethereum/simplifyConvertEvenMOre

Simplify yul conversion function even more.
This commit is contained in:
chriseth 2021-08-17 14:39:59 +02:00 committed by GitHub
commit 948665ff89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 144 additions and 72 deletions

View File

@ -35,6 +35,16 @@ using namespace solidity;
using namespace solidity::util;
using namespace solidity::frontend;
string YulUtilFunctions::identityFunction()
{
string functionName = "identity";
return m_functionCollector.createFunction("identity", [&](vector<string>& _args, vector<string>& _rets) {
_args.push_back("value");
_rets.push_back("ret");
return "ret := value";
});
}
string YulUtilFunctions::combineExternalFunctionIdFunction()
{
string functionName = "combine_external_function_id";
@ -3272,48 +3282,38 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to)
if (rational->isFractional())
solAssert(toCategory == Type::Category::FixedPoint, "");
if (toCategory == Type::Category::FixedBytes)
{
FixedBytesType const& toBytesType = dynamic_cast<FixedBytesType const&>(_to);
body =
Whiskers("converted := <shiftLeft>(<clean>(value))")
("shiftLeft", shiftLeftFunction(256 - toBytesType.numBytes() * 8))
("clean", cleanupFunction(_from))
.render();
}
else if (toCategory == Type::Category::Enum)
body =
Whiskers("converted := <cleanEnum>(<cleanInt>(value))")
("cleanEnum", cleanupFunction(_to))
("cleanInt", cleanupFunction(_from))
.render();
else if (toCategory == Type::Category::FixedPoint)
solUnimplemented("Not yet implemented - FixedPointType.");
else if (toCategory == Type::Category::Address || toCategory == Type::Category::Contract)
if (toCategory == Type::Category::Address || toCategory == Type::Category::Contract)
body =
Whiskers("converted := <convert>(value)")
("convert", conversionFunction(_from, IntegerType(160)))
.render();
else if (toCategory == Type::Category::Integer)
{
IntegerType const& to = dynamic_cast<IntegerType const&>(_to);
// Clean according to the "to" type, except if this is
// a widening conversion.
IntegerType const* cleanupType = &to;
if (fromCategory == Type::Category::Integer)
{
IntegerType const& from = dynamic_cast<IntegerType const&>(_from);
if (to.numBits() > from.numBits())
cleanupType = &from;
}
body =
Whiskers("converted := <cleanInt>(value)")
("cleanInt", cleanupFunction(*cleanupType))
.render();
}
else
solAssert(false, "");
{
Whiskers bodyTemplate("converted := <cleanOutput>(<convert>(<cleanInput>(value)))");
bodyTemplate("cleanInput", cleanupFunction(_from));
bodyTemplate("cleanOutput", cleanupFunction(_to));
string convert;
if (auto const* toFixedBytes = dynamic_cast<FixedBytesType const*>(&_to))
convert = shiftLeftFunction(256 - toFixedBytes->numBytes() * 8);
else if (dynamic_cast<FixedPointType const*>(&_to))
solUnimplementedAssert(false, "");
else if (dynamic_cast<IntegerType const*>(&_to))
{
solUnimplementedAssert(fromCategory != Type::Category::FixedPoint, "");
convert = identityFunction();
}
else if (toCategory == Type::Category::Enum)
{
solAssert(fromCategory != Type::Category::FixedPoint, "");
convert = identityFunction();
}
else
solAssert(false, "");
solAssert(!convert.empty(), "");
bodyTemplate("convert", convert);
body = bodyTemplate.render();
}
break;
}
case Type::Category::Bool:

View File

@ -59,6 +59,10 @@ public:
m_functionCollector(_functionCollector)
{}
/// @returns the name of a function that returns its argument.
/// Sometimes needed to satisfy templates.
std::string identityFunction();
/// @returns a function that combines the address and selector to a single value
/// for use in the ABI.
std::string combineExternalFunctionIdFunction();

View File

@ -182,36 +182,64 @@ object "C_81" {
cleaned := value
}
function cleanup_t_rational_0_by_1(value) -> cleaned {
cleaned := value
}
function cleanup_t_rational_10_by_1(value) -> cleaned {
cleaned := value
}
function cleanup_t_rational_115792089237316195423570985008687907853269984665640564039457584007913129639935_by_1(value) -> cleaned {
cleaned := value
}
function cleanup_t_rational_1_by_1(value) -> cleaned {
cleaned := value
}
function cleanup_t_rational_2_by_1(value) -> cleaned {
cleaned := value
}
function cleanup_t_rational_minus_1_by_1(value) -> cleaned {
cleaned := value
}
function cleanup_t_rational_minus_2_by_1(value) -> cleaned {
cleaned := value
}
function cleanup_t_uint256(value) -> cleaned {
cleaned := value
}
function convert_t_rational_0_by_1_to_t_uint256(value) -> converted {
converted := cleanup_t_uint256(value)
converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value)))
}
function convert_t_rational_10_by_1_to_t_uint256(value) -> converted {
converted := cleanup_t_uint256(value)
converted := cleanup_t_uint256(identity(cleanup_t_rational_10_by_1(value)))
}
function convert_t_rational_115792089237316195423570985008687907853269984665640564039457584007913129639935_by_1_to_t_uint256(value) -> converted {
converted := cleanup_t_uint256(value)
converted := cleanup_t_uint256(identity(cleanup_t_rational_115792089237316195423570985008687907853269984665640564039457584007913129639935_by_1(value)))
}
function convert_t_rational_1_by_1_to_t_uint256(value) -> converted {
converted := cleanup_t_uint256(value)
converted := cleanup_t_uint256(identity(cleanup_t_rational_1_by_1(value)))
}
function convert_t_rational_2_by_1_to_t_uint256(value) -> converted {
converted := cleanup_t_uint256(value)
converted := cleanup_t_uint256(identity(cleanup_t_rational_2_by_1(value)))
}
function convert_t_rational_minus_1_by_1_to_t_int256(value) -> converted {
converted := cleanup_t_int256(value)
converted := cleanup_t_int256(identity(cleanup_t_rational_minus_1_by_1(value)))
}
function convert_t_rational_minus_2_by_1_to_t_int256(value) -> converted {
converted := cleanup_t_int256(value)
converted := cleanup_t_int256(identity(cleanup_t_rational_minus_2_by_1(value)))
}
/// @src 0:96:368
@ -340,6 +368,10 @@ object "C_81" {
}
/// @src 0:82:370
function identity(value) -> ret {
ret := value
}
function panic_error_0x11() {
mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)
mstore(4, 0x11)

View File

@ -48,7 +48,7 @@ object "C_59" {
for { } lt(i, _4) { i := add(i, 1) }
{
if slt(sub(calldatasize(), src), _2) { revert(_1, _1) }
let value := allocate_memory_1228()
let value := allocate_memory_1236()
mstore(value, calldataload(src))
mstore(dst, value)
dst := add(dst, _2)
@ -79,7 +79,7 @@ object "C_59" {
}
tail := add(add(headStart, and(add(length, 31), not(31))), 96)
}
function allocate_memory_1228() -> memPtr
function allocate_memory_1236() -> memPtr
{
memPtr := mload(64)
let newFreePtr := add(memPtr, 32)

View File

@ -53,6 +53,10 @@ object \"C_54\" {
cleaned := value
}
function cleanup_t_rational_42_by_1(value) -> cleaned {
cleaned := value
}
/// @src 0:175:223
function constructor_C_54(var__init_12) {
@ -74,11 +78,11 @@ object \"C_54\" {
/// @src 0:79:428
function convert_t_int256_to_t_int256(value) -> converted {
converted := cleanup_t_int256(value)
converted := cleanup_t_int256(identity(cleanup_t_int256(value)))
}
function convert_t_rational_42_by_1_to_t_int256(value) -> converted {
converted := cleanup_t_int256(value)
converted := cleanup_t_int256(identity(cleanup_t_rational_42_by_1(value)))
}
function copy_arguments_for_constructor_20_object_C_54() -> ret_param_0 {
@ -98,6 +102,10 @@ object \"C_54\" {
mstore(64, newFreePtr)
}
function identity(value) -> ret {
ret := value
}
function panic_error_0x41() {
mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)
mstore(4, 0x41)
@ -261,6 +269,10 @@ object \"C_54\" {
cleaned := value
}
function cleanup_t_rational_41_by_1(value) -> cleaned {
cleaned := value
}
function cleanup_t_uint160(value) -> cleaned {
cleaned := and(value, 0xffffffffffffffffffffffffffffffffffffffff)
}
@ -279,11 +291,11 @@ object \"C_54\" {
}
function convert_t_int256_to_t_int256(value) -> converted {
converted := cleanup_t_int256(value)
converted := cleanup_t_int256(identity(cleanup_t_int256(value)))
}
function convert_t_rational_41_by_1_to_t_int256(value) -> converted {
converted := cleanup_t_int256(value)
converted := cleanup_t_int256(identity(cleanup_t_rational_41_by_1(value)))
}
function convert_t_uint160_to_t_address(value) -> converted {
@ -291,7 +303,7 @@ object \"C_54\" {
}
function convert_t_uint160_to_t_uint160(value) -> converted {
converted := cleanup_t_uint160(value)
converted := cleanup_t_uint160(identity(cleanup_t_uint160(value)))
}
function extract_from_storage_value_dynamict_int256(slot_value, offset) -> value {
@ -400,6 +412,10 @@ object \"C_54\" {
}
/// @src 0:79:428
function identity(value) -> ret {
ret := value
}
function increment_t_int256(value) -> ret {
value := cleanup_t_int256(value)
if eq(value, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) { panic_error_0x11() }
@ -610,6 +626,14 @@ object \"D_72\" {
cleaned := value
}
function cleanup_t_rational_3_by_1(value) -> cleaned {
cleaned := value
}
function cleanup_t_rational_42_by_1(value) -> cleaned {
cleaned := value
}
/// @src 0:175:223
function constructor_C_54(var__init_12) {
@ -652,15 +676,15 @@ object \"D_72\" {
/// @src 1:91:166
function convert_t_int256_to_t_int256(value) -> converted {
converted := cleanup_t_int256(value)
converted := cleanup_t_int256(identity(cleanup_t_int256(value)))
}
function convert_t_rational_3_by_1_to_t_int256(value) -> converted {
converted := cleanup_t_int256(value)
converted := cleanup_t_int256(identity(cleanup_t_rational_3_by_1(value)))
}
function convert_t_rational_42_by_1_to_t_int256(value) -> converted {
converted := cleanup_t_int256(value)
converted := cleanup_t_int256(identity(cleanup_t_rational_42_by_1(value)))
}
function copy_arguments_for_constructor_71_object_D_72() -> ret_param_0 {
@ -684,6 +708,10 @@ object \"D_72\" {
mstore(64, newFreePtr)
}
function identity(value) -> ret {
ret := value
}
function panic_error_0x11() {
mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)
mstore(4, 0x11)
@ -865,6 +893,10 @@ object \"D_72\" {
cleaned := value
}
function cleanup_t_rational_41_by_1(value) -> cleaned {
cleaned := value
}
function cleanup_t_uint160(value) -> cleaned {
cleaned := and(value, 0xffffffffffffffffffffffffffffffffffffffff)
}
@ -883,11 +915,11 @@ object \"D_72\" {
}
function convert_t_int256_to_t_int256(value) -> converted {
converted := cleanup_t_int256(value)
converted := cleanup_t_int256(identity(cleanup_t_int256(value)))
}
function convert_t_rational_41_by_1_to_t_int256(value) -> converted {
converted := cleanup_t_int256(value)
converted := cleanup_t_int256(identity(cleanup_t_rational_41_by_1(value)))
}
function convert_t_uint160_to_t_address(value) -> converted {
@ -895,7 +927,7 @@ object \"D_72\" {
}
function convert_t_uint160_to_t_uint160(value) -> converted {
converted := cleanup_t_uint160(value)
converted := cleanup_t_uint160(identity(cleanup_t_uint160(value)))
}
function extract_from_storage_value_dynamict_int256(slot_value, offset) -> value {
@ -1004,6 +1036,10 @@ object \"D_72\" {
}
/// @src 1:91:166
function identity(value) -> ret {
ret := value
}
function increment_t_int256(value) -> ret {
value := cleanup_t_int256(value)
if eq(value, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) { panic_error_0x11() }

View File

@ -93,7 +93,7 @@ object \"C_11\" {
}
function convert_t_rational_1633837924_by_1_to_t_bytes4(value) -> converted {
converted := shift_left_224(cleanup_t_rational_1633837924_by_1(value))
converted := cleanup_t_bytes4(shift_left_224(cleanup_t_rational_1633837924_by_1(value)))
}
/// @src 0:91:157

View File

@ -93,7 +93,7 @@ object \"C_11\" {
}
function convert_t_rational_2864434397_by_1_to_t_bytes4(value) -> converted {
converted := shift_left_224(cleanup_t_rational_2864434397_by_1(value))
converted := cleanup_t_bytes4(shift_left_224(cleanup_t_rational_2864434397_by_1(value)))
}
/// @src 0:91:157

View File

@ -54,5 +54,5 @@ contract C {
// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, "abc"
// f4() -> 0x20, 0x160, 0x1, 0x80, 0xc0, 0x2, 0x3, "abc", 0x7, 0x40, 0x2, 0x2, 0x3
// gas irOptimized: 113296
// gas legacy: 114728
// gas legacy: 114900
// gas legacyOptimized: 112606

View File

@ -49,5 +49,5 @@ contract C {
// ----
// f() -> 0xff
// gas irOptimized: 121438
// gas legacy: 126745
// gas legacy: 128035
// gas legacyOptimized: 123476

View File

@ -22,5 +22,5 @@ contract B {
// ----
// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004
// gas irOptimized: 121038
// gas legacy: 235167
// gas legacy: 235339
// gas legacyOptimized: 133299

View File

@ -22,6 +22,6 @@ contract c {
// compileViaYul: also
// ----
// test() -> 2, 3, 4, 5
// gas irOptimized: 137059
// gas irOptimized: 137074
// gas legacy: 147484
// gas legacyOptimized: 146456

View File

@ -19,5 +19,5 @@ contract c {
// ----
// test((uint16,uint16,uint16[3],uint16[])): 0x20, 2, 3, 0, 0, 4, 0xC0, 4, 0, 0, 5, 0, 0 -> 2, 3, 4, 5
// gas irOptimized: 139100
// gas legacy: 144322
// gas legacy: 145150
// gas legacyOptimized: 139171

View File

@ -14,5 +14,5 @@ contract C {
// deposit() ->
// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, "def"
// gas irOptimized: 23685
// gas legacy: 24170
// gas legacy: 24342
// gas legacyOptimized: 23753

View File

@ -35,10 +35,10 @@ contract test {
// compileViaYul: also
// ----
// constructor()
// gas irOptimized: 500656
// gas irOptimized: 526745
// gas legacy: 733634
// gas legacyOptimized: 478742
// prb_pi() -> 3141592656369545286
// gas irOptimized: 63037
// gas irOptimized: 62867
// gas legacy: 98903
// gas legacyOptimized: 75735

View File

@ -29,5 +29,5 @@ contract C {
// ----
// t() -> 9
// gas irOptimized: 99004
// gas legacy: 158997
// gas legacy: 159083
// gas legacyOptimized: 108916

View File

@ -27,4 +27,4 @@ contract D {
// gas legacy: 115012
// g() -> 5
// gas irOptimized: 78811
// gas legacy: 115472
// gas legacy: 115558

View File

@ -23,5 +23,5 @@ contract A {
// ----
// f(), 10 ether -> 3007, 3008, 3009
// gas irOptimized: 270255
// gas legacy: 422627
// gas legacy: 422885
// gas legacyOptimized: 287856

View File

@ -19,5 +19,5 @@ contract C {
// ----
// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 77, 1, 2, 88
// gas irOptimized: 203716
// gas legacy: 208666
// gas legacy: 209194
// gas legacyOptimized: 203583

View File

@ -27,5 +27,5 @@ contract C {
// compileViaYul: also
// ----
// test() -> 9, 7
// gas legacy: 125064
// gas legacy: 130016
// t2() -> 9