Skip to content

Commit 658941f

Browse files
author
Mohammad Rezaei
committed
formatting and comments
1 parent 1bbfea0 commit 658941f

File tree

7 files changed

+31
-848
lines changed

7 files changed

+31
-848
lines changed

Changelog.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Language Features:
44

55

66
Compiler Features:
7+
* Constant Optimizer: Compute masks using shifts when optimizing for size; use an ``--optimizer-runs`` value less than 200 for maximum size reduction.
78

89

910
Bugfixes:
@@ -15,8 +16,6 @@ Compiler Features:
1516
* EVM: Set default EVM Version to `prague`.
1617
* NatSpec: Capture Natspec documentation of `enum` values in the AST.
1718

18-
* Constant Optimizer: Compute masks using shifts when optimizing for size; use an ``--optimizer-runs`` value less than 200 for maximum size reduction.
19-
2019
Bugfixes:
2120
* SMTChecker: Do not consider loop conditions as constant-condition verification target as this could cause incorrect reports and internal compiler errors.
2221
* SMTChecker: Fix incorrect analysis when only a subset of contracts is selected with `--model-checker-contracts`.

libevmasm/ConstantOptimiser.cpp

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -255,13 +255,21 @@ AssemblyItems ComputeMethod::findRepresentation(u256 const& _value)
255255
return AssemblyItems{_value};
256256

257257
// check for masks first
258+
// high ones low zeros
259+
// |----------||--------------|
260+
// 0x000000000000000000000000000000000000ffffffffffff0000000000000000
258261
unsigned lowZeros = 0;
259262
unsigned highOnes = 0;
260-
for (; ((_value >> lowZeros) & 1) == 0 && lowZeros < 256; lowZeros++) {}
261-
for (; ((_value >> (lowZeros + highOnes)) & 1) == 1 && highOnes < 256; highOnes++) {}
262-
if (m_params.evmVersion.hasBitwiseShifting() && highOnes > 32 &&
263-
((_value >> (lowZeros + highOnes)) == 0) &&
264-
((lowZeros + highOnes < 256) || lowZeros > 16))
263+
while (((_value >> lowZeros) & 1) == 0 && lowZeros < 256)
264+
++lowZeros;
265+
while (((_value >> (lowZeros + highOnes)) & 1) == 1 && highOnes < 256)
266+
++highOnes;
267+
if (
268+
m_params.evmVersion.hasBitwiseShifting() &&
269+
highOnes > 32 && // push would be more efficient otherwise
270+
((_value >> (lowZeros + highOnes)) == 0) && // this is a pure mask
271+
((lowZeros + highOnes < 256) || lowZeros > 16) // otherwise negation is more effective
272+
)
265273
{
266274
// this is a big enough mask to use zero negation
267275
AssemblyItems newRoutine = AssemblyItems{u256(0), Instruction::NOT};
@@ -271,29 +279,15 @@ AssemblyItems ComputeMethod::findRepresentation(u256 const& _value)
271279
newRoutine += AssemblyItems{u256(lowZeros), Instruction::SHL};
272280
return newRoutine;
273281
}
274-
// check powers of 10
275-
u256 divBy10 = _value;
276-
unsigned pow10 = 0;
277-
while (divBy10 > 0 && divBy10 % 10 == 0)
278-
{
279-
divBy10 = divBy10 / 10;
280-
pow10++;
281-
}
282-
// 10^9 = 0x3b9aca00; requires 5 bytes with PUSH4; also 5 bytes with PUSH 5 PUSH 10 EXP
283-
if (pow10 > 9 && divBy10 == 1)
284-
{
285-
// pure power of 10
286-
return AssemblyItems{u256(pow10), u256(10), Instruction::EXP};
287-
}
288-
// 10^x * y can be encoded as: push x push 10 exp push y mul. That's about 7 bytes more than plain push
289-
if (pow10 > 12)
290-
{
291-
AssemblyItems newRoutine = findRepresentation(divBy10);
292-
newRoutine += AssemblyItems{u256(pow10), u256(10), Instruction::EXP, Instruction::MUL};
293-
return newRoutine;
294-
}
295-
if (numberEncodingSize(~_value) < numberEncodingSize(_value) &&
296-
(lowZeros+highOnes < 256 || highOnes > 16))
282+
// pure negation can sometimes produce bad results
283+
// example: 0xff00000000000000000000000000000000000000000000000000000000000000
284+
// 0xff at the most significant byte of u256
285+
// without the extra condition: not(sub(shl(0xf8, 0x01), 0x01))
286+
// the extra condition turns that into: shl(0xf8, 0xff)
287+
if (
288+
numberEncodingSize(~_value) < numberEncodingSize(_value) &&
289+
(lowZeros+highOnes < 256 || highOnes > 16)
290+
)
297291
// Negated is shorter to represent
298292
return findRepresentation(~_value) + AssemblyItems{Instruction::NOT};
299293
else

test/libevmasm/evmAssemblyTests/constant_optimizer_runs_0.asm renamed to test/libevmasm/evmAssemblyTests/constant_optimizer_masks_runs_0.asm

Lines changed: 0 additions & 270 deletions
Original file line numberDiff line numberDiff line change
@@ -223,142 +223,6 @@ PUSH 0x2
223223
PUSH 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe
224224
// masks with 256 bits
225225
PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
226-
// powers of 10
227-
PUSH 0xa
228-
PUSH 0x64
229-
PUSH 0x3e8
230-
PUSH 0x2710
231-
PUSH 0x186a0
232-
PUSH 0xf4240
233-
PUSH 0x989680
234-
PUSH 0x5f5e100
235-
PUSH 0x3b9aca00
236-
PUSH 0x2540be400
237-
PUSH 0x174876e800
238-
PUSH 0xe8d4a51000
239-
PUSH 0x9184e72a000
240-
PUSH 0x5af3107a4000
241-
PUSH 0x38d7ea4c68000
242-
PUSH 0x2386f26fc10000
243-
PUSH 0x16345785d8a0000
244-
PUSH 0xde0b6b3a7640000
245-
PUSH 0x8ac7230489e80000
246-
PUSH 0x56bc75e2d63100000
247-
PUSH 0x3635c9adc5dea00000
248-
PUSH 0x21e19e0c9bab2400000
249-
PUSH 0x152d02c7e14af6800000
250-
PUSH 0xd3c21bcecceda1000000
251-
PUSH 0x84595161401484a000000
252-
PUSH 0x52b7d2dcc80cd2e4000000
253-
PUSH 0x33b2e3c9fd0803ce8000000
254-
PUSH 0x204fce5e3e25026110000000
255-
PUSH 0x1431e0fae6d7217caa0000000
256-
PUSH 0xc9f2c9cd04674edea40000000
257-
PUSH 0x7e37be2022c0914b2680000000
258-
PUSH 0x4ee2d6d415b85acef8100000000
259-
PUSH 0x314dc6448d9338c15b0a00000000
260-
PUSH 0x1ed09bead87c0378d8e6400000000
261-
PUSH 0x13426172c74d822b878fe800000000
262-
PUSH 0xc097ce7bc90715b34b9f1000000000
263-
PUSH 0x785ee10d5da46d900f436a000000000
264-
PUSH 0x4b3b4ca85a86c47a098a224000000000
265-
PUSH 0x2f050fe938943acc45f65568000000000
266-
PUSH 0x1d6329f1c35ca4bfabb9f5610000000000
267-
PUSH 0x125dfa371a19e6f7cb54395ca0000000000
268-
PUSH 0xb7abc627050305adf14a3d9e40000000000
269-
PUSH 0x72cb5bd86321e38cb6ce6682e80000000000
270-
PUSH 0x47bf19673df52e37f2410011d100000000000
271-
PUSH 0x2cd76fe086b93ce2f768a00b22a00000000000
272-
PUSH 0x1c06a5ec5433c60ddaa16406f5a400000000000
273-
PUSH 0x118427b3b4a05bc8a8a4de845986800000000000
274-
PUSH 0xaf298d050e4395d69670b12b7f41000000000000
275-
PUSH 0x6d79f82328ea3da61e066ebb2f88a000000000000
276-
PUSH 0x446c3b15f9926687d2c40534fdb564000000000000
277-
PUSH 0x2ac3a4edbbfb8014e3ba83411e915e8000000000000
278-
PUSH 0x1aba4714957d300d0e549208b31adb10000000000000
279-
PUSH 0x10b46c6cdd6e3e0828f4db456ff0c8ea0000000000000
280-
PUSH 0xa70c3c40a64e6c51999090b65f67d9240000000000000
281-
PUSH 0x6867a5a867f103b2fffa5a71fba0e7b680000000000000
282-
PUSH 0x4140c78940f6a24fdffc78873d4490d2100000000000000
283-
PUSH 0x28c87cb5c89a2571ebfdcb54864ada834a00000000000000
284-
PUSH 0x197d4df19d605767337e9f14d3eec8920e400000000000000
285-
PUSH 0xfee50b7025c36a0802f236d04753d5b48e800000000000000
286-
PUSH 0x9f4f2726179a224501d762422c946590d91000000000000000
287-
PUSH 0x63917877cec0556b21269d695bdcbf7a87aa000000000000000
288-
PUSH 0x3e3aeb4ae1383562f4b82261d969f7ac94ca4000000000000000
289-
PUSH 0x26e4d30eccc3215dd8f3157d27e23acbdcfe68000000000000000
290-
PUSH 0x184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000
291-
PUSH 0xf316271c7fc3908a8bef464e3945ef7a25360a0000000000000000
292-
PUSH 0x97edd871cfda3a5697758bf0e3cbb5ac5741c640000000000000000
293-
PUSH 0x5ef4a74721e864761ea977768e5f518bb6891be80000000000000000
294-
PUSH 0x3b58e88c75313ec9d329eaaa18fb92f75215b17100000000000000000
295-
PUSH 0x25179157c93ec73e23fa32aa4f9d3bda934d8ee6a00000000000000000
296-
PUSH 0x172ebad6ddc73c86d67c5faa71c245689c1079502400000000000000000
297-
PUSH 0xe7d34c64a9c85d4460dbbca87196b61618a4bd216800000000000000000
298-
PUSH 0x90e40fbeea1d3a4abc8955e946fe31cdcf66f634e1000000000000000000
299-
PUSH 0x5a8e89d75252446eb5d5d5b1cc5edf20a1a059e10ca000000000000000000
300-
PUSH 0x3899162693736ac531a5a58f1fbb4b746504382ca7e4000000000000000000
301-
PUSH 0x235fadd81c2822bb3f07877973d50f28bf22a31be8ee8000000000000000000
302-
PUSH 0x161bcca7119915b50764b4abe86529797775a5f1719510000000000000000000
303-
PUSH 0xdd15fe86affad91249ef0eb713f39ebeaa987b6e6fd2a0000000000000000000
304-
// powers of 10 multiplied by ffffffffffffffff
305-
PUSH 0x9fffffffffffffff6
306-
PUSH 0x63ffffffffffffff9c
307-
PUSH 0x3e7fffffffffffffc18
308-
PUSH 0x270fffffffffffffd8f0
309-
PUSH 0x1869ffffffffffffe7960
310-
PUSH 0xf423ffffffffffff0bdc0
311-
PUSH 0x98967fffffffffff676980
312-
PUSH 0x5f5e0fffffffffffa0a1f00
313-
PUSH 0x3b9ac9ffffffffffc4653600
314-
PUSH 0x2540be3fffffffffdabf41c00
315-
PUSH 0x174876e7ffffffffe8b7891800
316-
PUSH 0xe8d4a50fffffffff172b5af000
317-
PUSH 0x9184e729ffffffff6e7b18d6000
318-
PUSH 0x5af3107a3fffffffa50cef85c000
319-
PUSH 0x38d7ea4c67ffffffc72815b398000
320-
PUSH 0x2386f26fc0ffffffdc790d903f0000
321-
PUSH 0x16345785d89fffffe9cba87a2760000
322-
PUSH 0xde0b6b3a763fffff21f494c589c0000
323-
PUSH 0x8ac7230489e7ffff7538dcfb76180000
324-
PUSH 0x56bc75e2d630ffffa9438a1d29cf00000
325-
PUSH 0x3635c9adc5de9fffc9ca36523a21600000
326-
PUSH 0x21e19e0c9bab23ffde1e61f36454dc00000
327-
PUSH 0x152d02c7e14af67fead2fd381eb509800000
328-
PUSH 0xd3c21bcecceda0ff2c3de43133125f000000
329-
PUSH 0x845951614014849f7ba6ae9ebfeb7b6000000
330-
PUSH 0x52b7d2dcc80cd2e3ad482d2337f32d1c000000
331-
PUSH 0x33b2e3c9fd0803ce4c4d1c3602f7fc318000000
332-
PUSH 0x204fce5e3e250260efb031a1c1dafd9ef0000000
333-
PUSH 0x1431e0fae6d7217c95ce1f051928de83560000000
334-
PUSH 0xc9f2c9cd04674eddda0d3632fb98b1215c0000000
335-
PUSH 0x7e37be2022c0914aa84841dfdd3f6eb4d980000000
336-
PUSH 0x4ee2d6d415b85acea92d292bea47a53107f00000000
337-
PUSH 0x314dc6448d9338c129bc39bb726cc73ea4f600000000
338-
PUSH 0x1ed09bead87c0378ba15a4152783fc872719c00000000
339-
PUSH 0x13426172c74d822b744d868d38b27dd478701800000000
340-
PUSH 0xc097ce7bc90715b28b07418436f8ea4cb460f000000000
341-
PUSH 0x785ee10d5da46d8f96e488f2a25b926ff0bc96000000000
342-
PUSH 0x4b3b4ca85a86c479be4ed597a5793b85f675ddc000000000
343-
PUSH 0x2f050fe938943acc16f1457ec76bc533ba09aa98000000000
344-
PUSH 0x1d6329f1c35ca4bf8e56cb6f3ca35b4054460a9f0000000000
345-
PUSH 0x125dfa371a19e6f7b8f63f2585e6190834abc6a360000000000
346-
PUSH 0xb7abc627050305ad399e77773afcfa520eb5c261c0000000000
347-
PUSH 0x72cb5bd86321e38c44030aaa84de1c734931997d180000000000
348-
PUSH 0x47bf19673df52e37aa81e6aa930ad1c80dbeffee2f00000000000
349-
PUSH 0x2cd76fe086b93ce2ca91302a9be6c31d08975ff4dd600000000000
350-
PUSH 0x1c06a5ec5433c60dbe9abe1aa17039f2255e9bf90a5c00000000000
351-
PUSH 0x118427b3b4a05bc89720b6d0a4e62437575b217ba679800000000000
352-
PUSH 0xaf298d050e4395d5e747242670fd6a29698f4ed480bf000000000000
353-
PUSH 0x6d79f82328ea3da5b08c7698069e6259e1f99144d0776000000000000
354-
PUSH 0x446c3b15f99266878e57ca1f0422fd782d3bfacb024a9c000000000000
355-
PUSH 0x2ac3a4edbbfb8014b8f6de536295de6b1c457cbee16ea18000000000000
356-
PUSH 0x1aba4714957d300cf39a4af41d9dab02f1ab6df74ce524f0000000000000
357-
PUSH 0x10b46c6cdd6e3e0818406ed892828ae1d70b24ba900f37160000000000000
358-
PUSH 0xa70c3c40a64e6c50f2845475b9196cd2666f6f49a09826dc0000000000000
359-
PUSH 0x6867a5a867f103b29792b4c993afe4038005a58e045f184980000000000000
360-
PUSH 0x4140c78940f6a24f9ebbb0fdfc4dee8230038778c2bb6f2df00000000000000
361-
PUSH 0x28c87cb5c89a2571c3354e9ebdb0b5115e0234ab79b5257cb600000000000000
362226
// ====
363227
// optimizationPreset: none
364228
// optimizer.constantOptimizer: true
@@ -572,138 +436,4 @@ PUSH 0x2
572436
// shr(0x01, not(0x00))
573437
// not(0x01)
574438
// not(0x00)
575-
// 0x0a
576-
// 0x64
577-
// 0x03e8
578-
// 0x2710
579-
// 0x0186a0
580-
// 0x0f4240
581-
// 0x989680
582-
// 0x05f5e100
583-
// 0x3b9aca00
584-
// exp(0x0a, 0x0a)
585-
// exp(0x0a, 0x0b)
586-
// exp(0x0a, 0x0c)
587-
// exp(0x0a, 0x0d)
588-
// exp(0x0a, 0x0e)
589-
// exp(0x0a, 0x0f)
590-
// exp(0x0a, 0x10)
591-
// exp(0x0a, 0x11)
592-
// exp(0x0a, 0x12)
593-
// exp(0x0a, 0x13)
594-
// exp(0x0a, 0x14)
595-
// exp(0x0a, 0x15)
596-
// exp(0x0a, 0x16)
597-
// exp(0x0a, 0x17)
598-
// exp(0x0a, 0x18)
599-
// exp(0x0a, 0x19)
600-
// exp(0x0a, 0x1a)
601-
// exp(0x0a, 0x1b)
602-
// exp(0x0a, 0x1c)
603-
// exp(0x0a, 0x1d)
604-
// exp(0x0a, 0x1e)
605-
// exp(0x0a, 0x1f)
606-
// exp(0x0a, 0x20)
607-
// exp(0x0a, 0x21)
608-
// exp(0x0a, 0x22)
609-
// exp(0x0a, 0x23)
610-
// exp(0x0a, 0x24)
611-
// exp(0x0a, 0x25)
612-
// exp(0x0a, 0x26)
613-
// exp(0x0a, 0x27)
614-
// exp(0x0a, 0x28)
615-
// exp(0x0a, 0x29)
616-
// exp(0x0a, 0x2a)
617-
// exp(0x0a, 0x2b)
618-
// exp(0x0a, 0x2c)
619-
// exp(0x0a, 0x2d)
620-
// exp(0x0a, 0x2e)
621-
// exp(0x0a, 0x2f)
622-
// exp(0x0a, 0x30)
623-
// exp(0x0a, 0x31)
624-
// exp(0x0a, 0x32)
625-
// exp(0x0a, 0x33)
626-
// exp(0x0a, 0x34)
627-
// exp(0x0a, 0x35)
628-
// exp(0x0a, 0x36)
629-
// exp(0x0a, 0x37)
630-
// exp(0x0a, 0x38)
631-
// exp(0x0a, 0x39)
632-
// exp(0x0a, 0x3a)
633-
// exp(0x0a, 0x3b)
634-
// exp(0x0a, 0x3c)
635-
// exp(0x0a, 0x3d)
636-
// exp(0x0a, 0x3e)
637-
// exp(0x0a, 0x3f)
638-
// exp(0x0a, 0x40)
639-
// exp(0x0a, 0x41)
640-
// exp(0x0a, 0x42)
641-
// exp(0x0a, 0x43)
642-
// exp(0x0a, 0x44)
643-
// exp(0x0a, 0x45)
644-
// exp(0x0a, 0x46)
645-
// exp(0x0a, 0x47)
646-
// exp(0x0a, 0x48)
647-
// exp(0x0a, 0x49)
648-
// exp(0x0a, 0x4a)
649-
// exp(0x0a, 0x4b)
650-
// exp(0x0a, 0x4c)
651-
// exp(0x0a, 0x4d)
652-
// sub(shl(0x41, 0x05), 0x0a)
653-
// sub(shl(0x42, 0x19), 0x64)
654-
// sub(shl(0x43, 0x7d), 0x03e8)
655-
// sub(shl(0x44, 0x0271), 0x2710)
656-
// sub(shl(0x45, 0x0c35), 0x0186a0)
657-
// sub(shl(0x46, 0x3d09), 0x0f4240)
658-
// 0x98967fffffffffff676980
659-
// 0x05f5e0fffffffffffa0a1f00
660-
// 0x3b9ac9ffffffffffc4653600
661-
// sub(shl(0x4a, 0x9502f9), exp(0x0a, 0x0a))
662-
// 0x174876e7ffffffffe8b7891800
663-
// 0xe8d4a50fffffffff172b5af000
664-
// mul(exp(0x0a, 0x0d), shr(0xc0, not(0x00)))
665-
// mul(exp(0x0a, 0x0e), shr(0xc0, not(0x00)))
666-
// mul(exp(0x0a, 0x0f), shr(0xc0, not(0x00)))
667-
// mul(exp(0x0a, 0x10), shr(0xc0, not(0x00)))
668-
// mul(exp(0x0a, 0x11), shr(0xc0, not(0x00)))
669-
// mul(exp(0x0a, 0x12), shr(0xc0, not(0x00)))
670-
// mul(exp(0x0a, 0x13), shr(0xc0, not(0x00)))
671-
// mul(exp(0x0a, 0x14), shr(0xc0, not(0x00)))
672-
// mul(exp(0x0a, 0x15), shr(0xc0, not(0x00)))
673-
// mul(exp(0x0a, 0x16), shr(0xc0, not(0x00)))
674-
// mul(exp(0x0a, 0x17), shr(0xc0, not(0x00)))
675-
// mul(exp(0x0a, 0x18), shr(0xc0, not(0x00)))
676-
// mul(exp(0x0a, 0x19), shr(0xc0, not(0x00)))
677-
// mul(exp(0x0a, 0x1a), shr(0xc0, not(0x00)))
678-
// mul(exp(0x0a, 0x1b), shr(0xc0, not(0x00)))
679-
// mul(exp(0x0a, 0x1c), shr(0xc0, not(0x00)))
680-
// mul(exp(0x0a, 0x1d), shr(0xc0, not(0x00)))
681-
// mul(exp(0x0a, 0x1e), shr(0xc0, not(0x00)))
682-
// mul(exp(0x0a, 0x1f), shr(0xc0, not(0x00)))
683-
// mul(exp(0x0a, 0x20), shr(0xc0, not(0x00)))
684-
// mul(exp(0x0a, 0x21), shr(0xc0, not(0x00)))
685-
// mul(exp(0x0a, 0x22), shr(0xc0, not(0x00)))
686-
// mul(exp(0x0a, 0x23), shr(0xc0, not(0x00)))
687-
// mul(exp(0x0a, 0x24), shr(0xc0, not(0x00)))
688-
// mul(exp(0x0a, 0x25), shr(0xc0, not(0x00)))
689-
// mul(exp(0x0a, 0x26), shr(0xc0, not(0x00)))
690-
// mul(exp(0x0a, 0x27), shr(0xc0, not(0x00)))
691-
// mul(exp(0x0a, 0x28), shr(0xc0, not(0x00)))
692-
// mul(exp(0x0a, 0x29), shr(0xc0, not(0x00)))
693-
// mul(exp(0x0a, 0x2a), shr(0xc0, not(0x00)))
694-
// mul(exp(0x0a, 0x2b), shr(0xc0, not(0x00)))
695-
// mul(exp(0x0a, 0x2c), shr(0xc0, not(0x00)))
696-
// mul(exp(0x0a, 0x2d), shr(0xc0, not(0x00)))
697-
// mul(exp(0x0a, 0x2e), shr(0xc0, not(0x00)))
698-
// mul(exp(0x0a, 0x2f), shr(0xc0, not(0x00)))
699-
// mul(exp(0x0a, 0x30), shr(0xc0, not(0x00)))
700-
// mul(exp(0x0a, 0x31), shr(0xc0, not(0x00)))
701-
// mul(exp(0x0a, 0x32), shr(0xc0, not(0x00)))
702-
// mul(exp(0x0a, 0x33), shr(0xc0, not(0x00)))
703-
// mul(exp(0x0a, 0x34), shr(0xc0, not(0x00)))
704-
// mul(exp(0x0a, 0x35), shr(0xc0, not(0x00)))
705-
// mul(exp(0x0a, 0x36), shr(0xc0, not(0x00)))
706-
// mul(exp(0x0a, 0x37), shr(0xc0, not(0x00)))
707-
// mul(exp(0x0a, 0x38), shr(0xc0, not(0x00)))
708-
// mul(exp(0x0a, 0x39), shr(0xc0, not(0x00)))
709439
// }

0 commit comments

Comments
 (0)