Skip to content

Commit 55c2530

Browse files
committed
[Tolk] Peephole optimization: SWAP+any to any/anyR
- SWAP + EQUAL -> EQUAL - same for other symmetric operators (NEQ, MUL, etc.) - SWAP + xxx PUSHINT + 32 STUR -> xxx PUSHINT + ROT + 32 STU - SWAP + STSLICER => STSLICE and vice versa - same for other storing operators (STU, STB, STREF, etc.) - SWAP + LESS/LEQ => GREATER/GEQ
1 parent b297b6e commit 55c2530

13 files changed

+362
-20
lines changed

tolk-tester/tests/a-tests.tolk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,5 +79,5 @@ fun main(): int {
7979
method_id | in | out
8080
@testcase | 0 | | 31415926535897932384626433832795028841971693993751058209749445923078164
8181

82-
@code_hash 103119459254804391561326789266022754176632268076661379738543746273668564328534
82+
@code_hash 85818713521853656486584648797214567489479452958868213061669627117427586818086
8383
*/

tolk-tester/tests/allow-post-modification.tolk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,5 +164,5 @@ fun main() {
164164
test_assign_tensor_global() PROC:<{ // x.0 x.1
165165
"""
166166

167-
@code_hash 6737917279814799680932710799951154408447028229503449454536845752635763933556
167+
@code_hash 77620375659834063567341916666636335765114427483375544778177892407598637223147
168168
*/

tolk-tester/tests/calls-tests.tolk

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,26 @@ fun test9() {
159159
return int(10) + int(5).plus1() + int.create0() + int.create0().plus1();
160160
}
161161

162+
@noinline fun cmp1(a: int, b: int) { return a == b }
163+
@noinline fun cmp2(a: int, b: int) { return b == a }
164+
@noinline fun cmp3(a: int, b: int) { return a != b }
165+
@noinline fun cmp4(a: int, b: int) { return b != a }
166+
167+
@method_id(110)
168+
fun test10(a: int, b: int) {
169+
return b - a
170+
}
171+
172+
@noinline fun leq1(a: int, b: int) { return b < a }
173+
@noinline fun leq2(a: int, b: int) { return b <= a }
174+
@noinline fun leq3(a: int, b: int) { return b > a }
175+
@noinline fun leq4(a: int, b: int) { return b >= a }
176+
177+
@method_id(111)
178+
fun test11(a: int, b: int) {
179+
return ((b < a), (b <= a), (b > a), (b >= a));
180+
}
181+
162182
fun main() {}
163183

164184
/**
@@ -171,4 +191,47 @@ fun main() {}
171191
@testcase | 107 | | 16 5
172192
@testcase | 108 | | [ 1 2 3 ] [ 5 8 1 ]
173193
@testcase | 109 | | 17
194+
@testcase | 110 | 5 8 | 3
195+
@testcase | 111 | 5 8 | 0 0 -1 -1
196+
@testcase | 111 | 7 7 | 0 -1 0 -1
197+
198+
@fif_codegen
199+
"""
200+
cmp1() PROC:<{
201+
EQUAL
202+
}>
203+
cmp2() PROC:<{
204+
EQUAL
205+
}>
206+
cmp3() PROC:<{
207+
NEQ
208+
}>
209+
cmp4() PROC:<{
210+
NEQ
211+
}>
212+
"""
213+
214+
@fif_codegen
215+
"""
216+
test10() PROC:<{
217+
SUBR
218+
}>
219+
"""
220+
221+
@fif_codegen
222+
"""
223+
leq1() PROC:<{
224+
GREATER
225+
}>
226+
leq2() PROC:<{
227+
GEQ
228+
}>
229+
leq3() PROC:<{
230+
LESS
231+
}>
232+
leq4() PROC:<{
233+
LEQ
234+
}>
235+
"""
236+
174237
*/

tolk-tester/tests/cells-slices.tolk

Lines changed: 207 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,121 @@ fun test24(uns: bool) {
318318
}
319319
}
320320

321+
fun builder.my_storeRef(mutate self, value: cell): self
322+
asm(self value) "STREFR";
323+
324+
fun builder.my_storeAddress(mutate self, value: address): self
325+
asm(value self) "STSLICE";
326+
327+
fun builder.my_storeBuilder(mutate self, value: builder): self
328+
asm(value self) "STB";
329+
330+
fun my_PUSHINT_SWAP_STU(mutate b: builder): void
331+
asm "5 PUSHINT" "SWAP" "8 STU";
332+
333+
334+
@noinline
335+
fun demo30(value: cell, dest: builder) {
336+
// SWAP + STREFR => STREF
337+
return dest.my_storeRef(value);
338+
}
339+
340+
@noinline
341+
fun demo31(dest: builder, value: cell) {
342+
// SWAP + STREF => STREFR
343+
return dest.storeRef(value);
344+
}
345+
346+
@noinline
347+
fun demo32(dest: builder, value: builder) {
348+
// SWAP + STB => STBR
349+
return dest.my_storeBuilder(value);
350+
}
351+
352+
@noinline
353+
fun demo33(value: builder, dest: builder) {
354+
// SWAP + STBR => STB
355+
return dest.storeBuilder(value);
356+
}
357+
358+
@noinline
359+
fun demo34(dest: builder, value: address) {
360+
// SWAP + STSLICE => STSLICER
361+
return dest.my_storeAddress(value);
362+
}
363+
364+
@noinline
365+
fun demo35(value: slice, dest: builder) {
366+
// SWAP + STSLICER => STSLICE
367+
return dest.storeSlice(value);
368+
}
369+
370+
@noinline
371+
fun demo36(x: int) {
372+
var b = beginCell();
373+
if (x > 0) {
374+
// inside IF: N PUSHINT + SWAP + L STU => N PUSHINT + L STUR
375+
my_PUSHINT_SWAP_STU(mutate b);
376+
}
377+
return b;
378+
}
379+
380+
@noinline
381+
fun demo37(op: int32, u: int8 | int256) {
382+
var b = beginCell();
383+
// b.storeUint(input.op, 32);
384+
if (u is int8) {
385+
// inside IF: SWAP + 0 PUSHINT + 3 STUR => 0 PUSHINT + 3 STU
386+
b.storeUint(0, 3);
387+
b.storeUint(u, 8);
388+
}
389+
return b;
390+
}
391+
392+
@method_id(130)
393+
fun test30() {
394+
return (demo37(10, 88 as int8), demo36(50));
395+
}
396+
397+
@method_id(131)
398+
fun test31() {
399+
var s = createAddressNone();
400+
var dest = beginCell().storeUint(3, 32);
401+
assert(demo35(s as slice, dest).endCell().hash() == demo34(dest, s).endCell().hash()) throw 300;
402+
var r1 = demo35(s as slice, dest).endCell().hash();
403+
var b = beginCell().storeUint(0xFF, 16);
404+
assert(demo33(b, dest).endCell().hash() == demo32(dest, b).endCell().hash()) throw 301;
405+
var r2 = demo33(b, dest).endCell().hash();
406+
var r = createEmptyCell();
407+
assert(demo30(r, dest).endCell().hash() == demo31(dest, r).endCell().hash()) throw 302;
408+
var r3 = demo30(r, dest).endCell().hash();
409+
return [r1 & 0xFFFFFFFF, r2 & 0xFFFFFFFF, r3 & 0xFFFFFFFF];
410+
}
411+
412+
@method_id(132)
413+
fun test32(p: int) {
414+
var b = beginCell();
415+
var x = p + 10;
416+
b.storeUint(x, 32); // SWAP + n STU => n STUR
417+
return b;
418+
}
419+
420+
@method_id(133)
421+
fun test33(p: int) {
422+
var b = beginCell();
423+
var x = p + 10;
424+
b.storeInt(x, 8); // SWAP + n STI => n STIR
425+
return b;
426+
}
427+
428+
@method_id(134)
429+
fun test34(p: int, n: int) {
430+
var b = beginCell();
431+
var x = p + 10;
432+
b.storeInt(x, n); // no changes, it's STIX
433+
return b;
434+
}
435+
321436
fun main(): int {
322437
return 0;
323438
}
@@ -347,6 +462,11 @@ fun main(): int {
347462
@testcase | 123 | 0 | 255
348463
@testcase | 124 | -1 | 8
349464
@testcase | 124 | 0 | 10
465+
@testcase | 130 | | BC{00030b10} BC{000205}
466+
@testcase | 131 | | [ 225345949 901620178 1560646286 ]
467+
@testcase | 132 | 0 | BC{00080000000a}
468+
@testcase | 133 | 0 | BC{00020a}
469+
@testcase | 134 | 0 8 | BC{00020a}
350470

351471
We test that consequtive storeInt/storeUint with constants are joined into a single number
352472

@@ -378,15 +498,13 @@ We test that consequtive storeInt/storeUint with constants are joined into a sin
378498
@fif_codegen
379499
"""
380500
test19() PROC:<{
381-
NEWC
382501
123 PUSHINT
383-
SWAP
502+
NEWC
384503
4 STI
385504
16 PUSHPOW2DEC
386505
16 STUR
387506
-1 PUSHINT
388-
SWAP
389-
8 STI
507+
8 STIR
390508
}>
391509
"""
392510

@@ -411,9 +529,9 @@ We test that consequtive storeInt/storeUint with constants are joined into a sin
411529
test22() PROC:<{
412530
NEWC // '2
413531
NEWC // b1 b2
414-
SWAP // b2 b1
415532
2056 PUSHINT
416-
24 STUR // b2 b1
533+
ROT
534+
24 STU // b2 b1
417535
SWAP // b1 b2
418536
10141514286835656557042350424064 PUSHINTX
419537
132 STUR // b1 b2
@@ -437,4 +555,87 @@ We test that consequtive storeInt/storeUint with constants are joined into a sin
437555
}>
438556
"""
439557

558+
@fif_codegen
559+
"""
560+
demo30() PROC:<{ // value dest
561+
STREF // dest
562+
}>
563+
demo31() PROC:<{ // dest value
564+
STREFR // dest
565+
}>
566+
demo32() PROC:<{ // dest value
567+
STBR // dest
568+
}>
569+
demo33() PROC:<{ // value dest
570+
STB // dest
571+
}>
572+
demo34() PROC:<{ // dest value
573+
STSLICER // dest
574+
}>
575+
demo35() PROC:<{ // value dest
576+
STSLICE // dest
577+
}>
578+
"""
579+
580+
@fif_codegen
581+
"""
582+
demo36() PROC:<{ // x
583+
NEWC // x b
584+
SWAP // b x
585+
0 GTINT // b '4
586+
IF:<{ // b
587+
5 PUSHINT
588+
8 STUR // b
589+
}> // b
590+
}>
591+
"""
592+
593+
@fif_codegen
594+
"""
595+
demo37() PROC:<{
596+
NEWC
597+
s3 POP
598+
42 EQINT
599+
IF:<{
600+
0 PUSHINT
601+
ROT
602+
3 STU
603+
8 STU // b
604+
}>ELSE<{
605+
DROP // b
606+
}>
607+
}>
608+
"""
609+
610+
@fif_codegen
611+
"""
612+
test32() PROC:<{ // p
613+
NEWC // p b
614+
SWAP // b p
615+
10 ADDCONST // b x
616+
32 STUR // b
617+
}>
618+
"""
619+
620+
@fif_codegen
621+
"""
622+
test33() PROC:<{ // p
623+
NEWC // p b
624+
SWAP // b p
625+
10 ADDCONST // b x
626+
8 STIR // b
627+
}>
628+
"""
629+
630+
@fif_codegen
631+
"""
632+
test34() PROC:<{
633+
NEWC
634+
s0 s2 XCHG
635+
10 ADDCONST
636+
-ROT
637+
STIX
638+
}>
639+
"""
640+
440641
*/

tolk-tester/tests/inline-tests.tolk

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -471,9 +471,9 @@ fun usedIn10ButDeclaredBelow(x: int) {
471471
NEWC
472472
32 STU // '3
473473
25 PUSHINT // '3 '9
474-
SWAP // x self
475474
107374182425 PUSHINT
476-
64 STUR // x '3
475+
ROT
476+
64 STU // x '3
477477
SWAP // '3 x
478478
}>
479479
"""

tolk-tester/tests/op-priority.tolk

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,23 +96,20 @@ fun main() {
9696
@fif_codegen
9797
"""
9898
unary_minus_1() PROC:<{ // a b c
99-
-ROT // c a b
99+
s0 s2 XCHG
100100
ADD // c '3
101101
NEGATE // c '4
102-
SWAP // '4 c
103102
MUL // '5
104103
}>
105104
unary_minus_2() PROC:<{ // a b c
106-
-ROT // c a b
105+
s0 s2 XCHG
107106
ADD // c '3
108107
NEGATE // c '4
109-
SWAP // '4 c
110108
MUL // '5
111109
}>
112110
unary_minus_3() PROC:<{ // a b c
113-
-ROT // c a b
111+
s0 s2 XCHG
114112
ADD // c '3
115-
SWAP // '3 c
116113
MUL // '4
117114
NEGATE // '5
118115
}>

tolk-tester/tests/pack-unpack-6.tolk

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,6 @@ IF:<{
212212
140 PUSHINT
213213
}>
214214
139 PUSHINT
215-
SWAP
216215
EQUAL
217216
}>
218217
"""

tolk-tester/tests/some-tests-3.tolk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,5 @@ fun f(cs: slice) {
3131
@testcase | 101 | x{000102030405060708090a0b0c0d0e0f10111213} | 6
3232
@testcase | 0 | x{000102030405060708090a0b0c0d0e0f10111213} | 0 1 2 3
3333

34-
@code_hash 110094925152266492480367791654603701827254965953641340034522027582587727126150
34+
@code_hash 110494322917670257289501183090765859207486616122530510808569169535563021169176
3535
*/

0 commit comments

Comments
 (0)