mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #11749 from ethereum/simplifyConvertEvenMOre
Simplify yul conversion function even more.
This commit is contained in:
commit
948665ff89
@ -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:
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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() }
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -49,5 +49,5 @@ contract C {
|
||||
// ----
|
||||
// f() -> 0xff
|
||||
// gas irOptimized: 121438
|
||||
// gas legacy: 126745
|
||||
// gas legacy: 128035
|
||||
// gas legacyOptimized: 123476
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -29,5 +29,5 @@ contract C {
|
||||
// ----
|
||||
// t() -> 9
|
||||
// gas irOptimized: 99004
|
||||
// gas legacy: 158997
|
||||
// gas legacy: 159083
|
||||
// gas legacyOptimized: 108916
|
||||
|
@ -27,4 +27,4 @@ contract D {
|
||||
// gas legacy: 115012
|
||||
// g() -> 5
|
||||
// gas irOptimized: 78811
|
||||
// gas legacy: 115472
|
||||
// gas legacy: 115558
|
||||
|
@ -23,5 +23,5 @@ contract A {
|
||||
// ----
|
||||
// f(), 10 ether -> 3007, 3008, 3009
|
||||
// gas irOptimized: 270255
|
||||
// gas legacy: 422627
|
||||
// gas legacy: 422885
|
||||
// gas legacyOptimized: 287856
|
||||
|
@ -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
|
||||
|
@ -27,5 +27,5 @@ contract C {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// test() -> 9, 7
|
||||
// gas legacy: 125064
|
||||
// gas legacy: 130016
|
||||
// t2() -> 9
|
||||
|
Loading…
Reference in New Issue
Block a user