Skip to content

Commit 948665f

Browse files
authored
Merge pull request #11749 from ethereum/simplifyConvertEvenMOre
Simplify yul conversion function even more.
2 parents 5015284 + 704820c commit 948665f

File tree

19 files changed

+141
-69
lines changed

19 files changed

+141
-69
lines changed

libsolidity/codegen/YulUtilFunctions.cpp

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ using namespace solidity;
3535
using namespace solidity::util;
3636
using namespace solidity::frontend;
3737

38+
string YulUtilFunctions::identityFunction()
39+
{
40+
string functionName = "identity";
41+
return m_functionCollector.createFunction("identity", [&](vector<string>& _args, vector<string>& _rets) {
42+
_args.push_back("value");
43+
_rets.push_back("ret");
44+
return "ret := value";
45+
});
46+
}
47+
3848
string YulUtilFunctions::combineExternalFunctionIdFunction()
3949
{
4050
string functionName = "combine_external_function_id";
@@ -3272,48 +3282,38 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to)
32723282
if (rational->isFractional())
32733283
solAssert(toCategory == Type::Category::FixedPoint, "");
32743284

3275-
if (toCategory == Type::Category::FixedBytes)
3276-
{
3277-
FixedBytesType const& toBytesType = dynamic_cast<FixedBytesType const&>(_to);
3278-
body =
3279-
Whiskers("converted := <shiftLeft>(<clean>(value))")
3280-
("shiftLeft", shiftLeftFunction(256 - toBytesType.numBytes() * 8))
3281-
("clean", cleanupFunction(_from))
3282-
.render();
3283-
}
3284-
else if (toCategory == Type::Category::Enum)
3285-
body =
3286-
Whiskers("converted := <cleanEnum>(<cleanInt>(value))")
3287-
("cleanEnum", cleanupFunction(_to))
3288-
("cleanInt", cleanupFunction(_from))
3289-
.render();
3290-
else if (toCategory == Type::Category::FixedPoint)
3291-
solUnimplemented("Not yet implemented - FixedPointType.");
3292-
else if (toCategory == Type::Category::Address || toCategory == Type::Category::Contract)
3285+
if (toCategory == Type::Category::Address || toCategory == Type::Category::Contract)
32933286
body =
32943287
Whiskers("converted := <convert>(value)")
32953288
("convert", conversionFunction(_from, IntegerType(160)))
32963289
.render();
3297-
else if (toCategory == Type::Category::Integer)
3290+
else
32983291
{
3299-
IntegerType const& to = dynamic_cast<IntegerType const&>(_to);
3300-
3301-
// Clean according to the "to" type, except if this is
3302-
// a widening conversion.
3303-
IntegerType const* cleanupType = &to;
3304-
if (fromCategory == Type::Category::Integer)
3292+
Whiskers bodyTemplate("converted := <cleanOutput>(<convert>(<cleanInput>(value)))");
3293+
bodyTemplate("cleanInput", cleanupFunction(_from));
3294+
bodyTemplate("cleanOutput", cleanupFunction(_to));
3295+
string convert;
3296+
3297+
if (auto const* toFixedBytes = dynamic_cast<FixedBytesType const*>(&_to))
3298+
convert = shiftLeftFunction(256 - toFixedBytes->numBytes() * 8);
3299+
else if (dynamic_cast<FixedPointType const*>(&_to))
3300+
solUnimplementedAssert(false, "");
3301+
else if (dynamic_cast<IntegerType const*>(&_to))
33053302
{
3306-
IntegerType const& from = dynamic_cast<IntegerType const&>(_from);
3307-
if (to.numBits() > from.numBits())
3308-
cleanupType = &from;
3303+
solUnimplementedAssert(fromCategory != Type::Category::FixedPoint, "");
3304+
convert = identityFunction();
33093305
}
3310-
body =
3311-
Whiskers("converted := <cleanInt>(value)")
3312-
("cleanInt", cleanupFunction(*cleanupType))
3313-
.render();
3306+
else if (toCategory == Type::Category::Enum)
3307+
{
3308+
solAssert(fromCategory != Type::Category::FixedPoint, "");
3309+
convert = identityFunction();
3310+
}
3311+
else
3312+
solAssert(false, "");
3313+
solAssert(!convert.empty(), "");
3314+
bodyTemplate("convert", convert);
3315+
body = bodyTemplate.render();
33143316
}
3315-
else
3316-
solAssert(false, "");
33173317
break;
33183318
}
33193319
case Type::Category::Bool:

libsolidity/codegen/YulUtilFunctions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ class YulUtilFunctions
5959
m_functionCollector(_functionCollector)
6060
{}
6161

62+
/// @returns the name of a function that returns its argument.
63+
/// Sometimes needed to satisfy templates.
64+
std::string identityFunction();
65+
6266
/// @returns a function that combines the address and selector to a single value
6367
/// for use in the ABI.
6468
std::string combineExternalFunctionIdFunction();

test/cmdlineTests/exp_base_literal/output

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -182,36 +182,64 @@ object "C_81" {
182182
cleaned := value
183183
}
184184

185+
function cleanup_t_rational_0_by_1(value) -> cleaned {
186+
cleaned := value
187+
}
188+
189+
function cleanup_t_rational_10_by_1(value) -> cleaned {
190+
cleaned := value
191+
}
192+
193+
function cleanup_t_rational_115792089237316195423570985008687907853269984665640564039457584007913129639935_by_1(value) -> cleaned {
194+
cleaned := value
195+
}
196+
197+
function cleanup_t_rational_1_by_1(value) -> cleaned {
198+
cleaned := value
199+
}
200+
201+
function cleanup_t_rational_2_by_1(value) -> cleaned {
202+
cleaned := value
203+
}
204+
205+
function cleanup_t_rational_minus_1_by_1(value) -> cleaned {
206+
cleaned := value
207+
}
208+
209+
function cleanup_t_rational_minus_2_by_1(value) -> cleaned {
210+
cleaned := value
211+
}
212+
185213
function cleanup_t_uint256(value) -> cleaned {
186214
cleaned := value
187215
}
188216

189217
function convert_t_rational_0_by_1_to_t_uint256(value) -> converted {
190-
converted := cleanup_t_uint256(value)
218+
converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value)))
191219
}
192220

193221
function convert_t_rational_10_by_1_to_t_uint256(value) -> converted {
194-
converted := cleanup_t_uint256(value)
222+
converted := cleanup_t_uint256(identity(cleanup_t_rational_10_by_1(value)))
195223
}
196224

197225
function convert_t_rational_115792089237316195423570985008687907853269984665640564039457584007913129639935_by_1_to_t_uint256(value) -> converted {
198-
converted := cleanup_t_uint256(value)
226+
converted := cleanup_t_uint256(identity(cleanup_t_rational_115792089237316195423570985008687907853269984665640564039457584007913129639935_by_1(value)))
199227
}
200228

201229
function convert_t_rational_1_by_1_to_t_uint256(value) -> converted {
202-
converted := cleanup_t_uint256(value)
230+
converted := cleanup_t_uint256(identity(cleanup_t_rational_1_by_1(value)))
203231
}
204232

205233
function convert_t_rational_2_by_1_to_t_uint256(value) -> converted {
206-
converted := cleanup_t_uint256(value)
234+
converted := cleanup_t_uint256(identity(cleanup_t_rational_2_by_1(value)))
207235
}
208236

209237
function convert_t_rational_minus_1_by_1_to_t_int256(value) -> converted {
210-
converted := cleanup_t_int256(value)
238+
converted := cleanup_t_int256(identity(cleanup_t_rational_minus_1_by_1(value)))
211239
}
212240

213241
function convert_t_rational_minus_2_by_1_to_t_int256(value) -> converted {
214-
converted := cleanup_t_int256(value)
242+
converted := cleanup_t_int256(identity(cleanup_t_rational_minus_2_by_1(value)))
215243
}
216244

217245
/// @src 0:96:368
@@ -340,6 +368,10 @@ object "C_81" {
340368
}
341369
/// @src 0:82:370
342370

371+
function identity(value) -> ret {
372+
ret := value
373+
}
374+
343375
function panic_error_0x11() {
344376
mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)
345377
mstore(4, 0x11)

test/cmdlineTests/name_simplifier/output

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ object "C_59" {
4848
for { } lt(i, _4) { i := add(i, 1) }
4949
{
5050
if slt(sub(calldatasize(), src), _2) { revert(_1, _1) }
51-
let value := allocate_memory_1228()
51+
let value := allocate_memory_1236()
5252
mstore(value, calldataload(src))
5353
mstore(dst, value)
5454
dst := add(dst, _2)
@@ -79,7 +79,7 @@ object "C_59" {
7979
}
8080
tail := add(add(headStart, and(add(length, 31), not(31))), 96)
8181
}
82-
function allocate_memory_1228() -> memPtr
82+
function allocate_memory_1236() -> memPtr
8383
{
8484
memPtr := mload(64)
8585
let newFreePtr := add(memPtr, 32)

test/cmdlineTests/yul_source_locations/output.json

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ object \"C_54\" {
5353
cleaned := value
5454
}
5555

56+
function cleanup_t_rational_42_by_1(value) -> cleaned {
57+
cleaned := value
58+
}
59+
5660
/// @src 0:175:223
5761
function constructor_C_54(var__init_12) {
5862

@@ -74,11 +78,11 @@ object \"C_54\" {
7478
/// @src 0:79:428
7579

7680
function convert_t_int256_to_t_int256(value) -> converted {
77-
converted := cleanup_t_int256(value)
81+
converted := cleanup_t_int256(identity(cleanup_t_int256(value)))
7882
}
7983

8084
function convert_t_rational_42_by_1_to_t_int256(value) -> converted {
81-
converted := cleanup_t_int256(value)
85+
converted := cleanup_t_int256(identity(cleanup_t_rational_42_by_1(value)))
8286
}
8387

8488
function copy_arguments_for_constructor_20_object_C_54() -> ret_param_0 {
@@ -98,6 +102,10 @@ object \"C_54\" {
98102
mstore(64, newFreePtr)
99103
}
100104

105+
function identity(value) -> ret {
106+
ret := value
107+
}
108+
101109
function panic_error_0x41() {
102110
mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)
103111
mstore(4, 0x41)
@@ -261,6 +269,10 @@ object \"C_54\" {
261269
cleaned := value
262270
}
263271

272+
function cleanup_t_rational_41_by_1(value) -> cleaned {
273+
cleaned := value
274+
}
275+
264276
function cleanup_t_uint160(value) -> cleaned {
265277
cleaned := and(value, 0xffffffffffffffffffffffffffffffffffffffff)
266278
}
@@ -279,19 +291,19 @@ object \"C_54\" {
279291
}
280292

281293
function convert_t_int256_to_t_int256(value) -> converted {
282-
converted := cleanup_t_int256(value)
294+
converted := cleanup_t_int256(identity(cleanup_t_int256(value)))
283295
}
284296

285297
function convert_t_rational_41_by_1_to_t_int256(value) -> converted {
286-
converted := cleanup_t_int256(value)
298+
converted := cleanup_t_int256(identity(cleanup_t_rational_41_by_1(value)))
287299
}
288300

289301
function convert_t_uint160_to_t_address(value) -> converted {
290302
converted := convert_t_uint160_to_t_uint160(value)
291303
}
292304

293305
function convert_t_uint160_to_t_uint160(value) -> converted {
294-
converted := cleanup_t_uint160(value)
306+
converted := cleanup_t_uint160(identity(cleanup_t_uint160(value)))
295307
}
296308

297309
function extract_from_storage_value_dynamict_int256(slot_value, offset) -> value {
@@ -400,6 +412,10 @@ object \"C_54\" {
400412
}
401413
/// @src 0:79:428
402414

415+
function identity(value) -> ret {
416+
ret := value
417+
}
418+
403419
function increment_t_int256(value) -> ret {
404420
value := cleanup_t_int256(value)
405421
if eq(value, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) { panic_error_0x11() }
@@ -610,6 +626,14 @@ object \"D_72\" {
610626
cleaned := value
611627
}
612628

629+
function cleanup_t_rational_3_by_1(value) -> cleaned {
630+
cleaned := value
631+
}
632+
633+
function cleanup_t_rational_42_by_1(value) -> cleaned {
634+
cleaned := value
635+
}
636+
613637
/// @src 0:175:223
614638
function constructor_C_54(var__init_12) {
615639

@@ -652,15 +676,15 @@ object \"D_72\" {
652676
/// @src 1:91:166
653677

654678
function convert_t_int256_to_t_int256(value) -> converted {
655-
converted := cleanup_t_int256(value)
679+
converted := cleanup_t_int256(identity(cleanup_t_int256(value)))
656680
}
657681

658682
function convert_t_rational_3_by_1_to_t_int256(value) -> converted {
659-
converted := cleanup_t_int256(value)
683+
converted := cleanup_t_int256(identity(cleanup_t_rational_3_by_1(value)))
660684
}
661685

662686
function convert_t_rational_42_by_1_to_t_int256(value) -> converted {
663-
converted := cleanup_t_int256(value)
687+
converted := cleanup_t_int256(identity(cleanup_t_rational_42_by_1(value)))
664688
}
665689

666690
function copy_arguments_for_constructor_71_object_D_72() -> ret_param_0 {
@@ -684,6 +708,10 @@ object \"D_72\" {
684708
mstore(64, newFreePtr)
685709
}
686710

711+
function identity(value) -> ret {
712+
ret := value
713+
}
714+
687715
function panic_error_0x11() {
688716
mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)
689717
mstore(4, 0x11)
@@ -865,6 +893,10 @@ object \"D_72\" {
865893
cleaned := value
866894
}
867895

896+
function cleanup_t_rational_41_by_1(value) -> cleaned {
897+
cleaned := value
898+
}
899+
868900
function cleanup_t_uint160(value) -> cleaned {
869901
cleaned := and(value, 0xffffffffffffffffffffffffffffffffffffffff)
870902
}
@@ -883,19 +915,19 @@ object \"D_72\" {
883915
}
884916

885917
function convert_t_int256_to_t_int256(value) -> converted {
886-
converted := cleanup_t_int256(value)
918+
converted := cleanup_t_int256(identity(cleanup_t_int256(value)))
887919
}
888920

889921
function convert_t_rational_41_by_1_to_t_int256(value) -> converted {
890-
converted := cleanup_t_int256(value)
922+
converted := cleanup_t_int256(identity(cleanup_t_rational_41_by_1(value)))
891923
}
892924

893925
function convert_t_uint160_to_t_address(value) -> converted {
894926
converted := convert_t_uint160_to_t_uint160(value)
895927
}
896928

897929
function convert_t_uint160_to_t_uint160(value) -> converted {
898-
converted := cleanup_t_uint160(value)
930+
converted := cleanup_t_uint160(identity(cleanup_t_uint160(value)))
899931
}
900932

901933
function extract_from_storage_value_dynamict_int256(slot_value, offset) -> value {
@@ -1004,6 +1036,10 @@ object \"D_72\" {
10041036
}
10051037
/// @src 1:91:166
10061038

1039+
function identity(value) -> ret {
1040+
ret := value
1041+
}
1042+
10071043
function increment_t_int256(value) -> ret {
10081044
value := cleanup_t_int256(value)
10091045
if eq(value, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) { panic_error_0x11() }

test/cmdlineTests/yul_string_format_ascii_bytes32_from_number/output.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ object \"C_11\" {
9393
}
9494

9595
function convert_t_rational_1633837924_by_1_to_t_bytes4(value) -> converted {
96-
converted := shift_left_224(cleanup_t_rational_1633837924_by_1(value))
96+
converted := cleanup_t_bytes4(shift_left_224(cleanup_t_rational_1633837924_by_1(value)))
9797
}
9898

9999
/// @src 0:91:157

test/cmdlineTests/yul_string_format_hex/output.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ object \"C_11\" {
9393
}
9494

9595
function convert_t_rational_2864434397_by_1_to_t_bytes4(value) -> converted {
96-
converted := shift_left_224(cleanup_t_rational_2864434397_by_1(value))
96+
converted := cleanup_t_bytes4(shift_left_224(cleanup_t_rational_2864434397_by_1(value)))
9797
}
9898

9999
/// @src 0:91:157

test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,5 @@ contract C {
5454
// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, "abc"
5555
// f4() -> 0x20, 0x160, 0x1, 0x80, 0xc0, 0x2, 0x3, "abc", 0x7, 0x40, 0x2, 0x2, 0x3
5656
// gas irOptimized: 113296
57-
// gas legacy: 114728
57+
// gas legacy: 114900
5858
// gas legacyOptimized: 112606

0 commit comments

Comments
 (0)