Skip to content

Commit 06e0544

Browse files
committed
[Tolk] Gas optimization: replace ternary with CONDSEL when it's safe
1 parent 6f5fb74 commit 06e0544

File tree

3 files changed

+415
-0
lines changed

3 files changed

+415
-0
lines changed
Lines changed: 367 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,367 @@
1+
const TWO = 2;
2+
global gTup: tuple;
3+
4+
fun get1() { gTup.push(1); return 1; }
5+
fun get2() { gTup.push(2); return 2; }
6+
7+
struct Point {
8+
x: int;
9+
y: int;
10+
}
11+
12+
@noinline
13+
fun Point.create0NoInline(): Point {
14+
return { x: 0, y: 0 }
15+
}
16+
17+
fun Point.create0(): Point {
18+
return { x: 0, y: 0 }
19+
}
20+
21+
@method_id(101)
22+
fun test101(x: int) {
23+
return (x ? 2 : 1, x == 5 ? TWO : 1);
24+
}
25+
26+
@method_id(102)
27+
fun test102(x: int?) {
28+
return x == null ? (0!) : ((x));
29+
}
30+
31+
@method_id(103)
32+
fun test103(x: bool) {
33+
if (x ? -1 : +1) {
34+
return x ? -2 : +2;
35+
}
36+
throw 123;
37+
}
38+
39+
@method_id(104)
40+
fun test104(x: (int, int)) {
41+
return x.0 ? true : null;
42+
}
43+
44+
@method_id(105)
45+
fun test105(getX: bool) {
46+
var p: Point = { x: 10, y: 20 };
47+
return getX ? p.x : p!.y;
48+
}
49+
50+
@noinline
51+
fun helper106(glob: bool, t: tuple) {
52+
return glob ? gTup : t;
53+
}
54+
55+
@method_id(106)
56+
fun test106() {
57+
gTup = createEmptyTuple();
58+
gTup.push(1);
59+
return helper106(true, createEmptyTuple());
60+
}
61+
62+
@noinline
63+
fun helper107(t: (int, Point)) {
64+
return t.0 ? t.0 : t.1.y;
65+
}
66+
67+
@method_id(107)
68+
fun test107() {
69+
return (helper107((1, {x: 10, y:20})), helper107((0, {x: 10, y: 20})));
70+
}
71+
72+
@method_id(108)
73+
fun test108(calcMin: bool) {
74+
var cb = calcMin ? min : max;
75+
return cb(10, 20);
76+
}
77+
78+
@method_id(109)
79+
fun test109(bigCost: bool) {
80+
return bigCost ? ton("0.05") : (ton("0.001"));
81+
}
82+
83+
@method_id(110)
84+
fun test110(k: int) {
85+
val c: [int, int, int] = [k, 6, 7];
86+
return c.0 > 0 ? c.1 : c.2;
87+
}
88+
89+
@method_id(111)
90+
fun test111(g: bool) {
91+
return g ? (1, 2) : (3, 4);
92+
}
93+
94+
95+
@method_id(200)
96+
fun test200(x: int) {
97+
return 10 > 3 ? 200 : 100;
98+
}
99+
100+
@method_id(201)
101+
fun test201(x: int) {
102+
return (x is slice) ? 200 : x;
103+
}
104+
105+
@method_id(202)
106+
fun test202(x: int) {
107+
x > 10 ? x : 0;
108+
x < 10 ? x! : -10;
109+
return x;
110+
}
111+
112+
@method_id(203)
113+
fun test203() {
114+
var xx = false;
115+
if (!xx) {
116+
return xx ? 100 : 200;
117+
}
118+
return 300;
119+
}
120+
121+
122+
@method_id(220)
123+
fun test220(p: Point?, getNull: bool) {
124+
if (p == null) {
125+
return getNull ? p : 20;
126+
}
127+
return p.y;
128+
}
129+
130+
@method_id(221)
131+
fun test221(c: (int, (int,int)?)) {
132+
if (c.1 != null) {
133+
return c.0 > 5 ? c.1.0 : c.1.1;
134+
}
135+
return c.0 > 5 ? 0 : c.1;
136+
}
137+
138+
139+
@method_id(300)
140+
fun test300(x: int): tuple | int {
141+
// no condsel, because more that 1 slot
142+
return x > 0 ? x : gTup;
143+
}
144+
145+
@method_id(301)
146+
fun test301(first: bool) {
147+
var opt1 = (10, 20);
148+
var opt2 = (30, 40);
149+
// no condsel, because not 1 slot arguments
150+
return first ? opt1 : opt2;
151+
}
152+
153+
@method_id(302)
154+
fun test302(x: int?) {
155+
// no condsel, because not trivial (unary operator)
156+
return x == null ? 0 : -x;
157+
}
158+
159+
@method_id(303)
160+
fun test303(first: bool) {
161+
gTup = createEmptyTuple();
162+
// no condsel, because not trivial
163+
return (first ? get1() : get2(), gTup);
164+
}
165+
166+
@method_id(304)
167+
fun test304(y: bool) {
168+
return y ? Point.create0NoInline().y : 5;
169+
}
170+
171+
@method_id(305)
172+
fun test305(y: bool) {
173+
return y ? Point.create0().y : 5;
174+
}
175+
176+
177+
fun main() {}
178+
179+
/**
180+
@testcase | 101 | 0 | 1 1
181+
@testcase | 101 | 5 | 2 2
182+
@testcase | 101 | 9 | 2 1
183+
@testcase | 102 | 8 | 8
184+
@testcase | 102 | null | 0
185+
@testcase | 103 | -1 | -2
186+
@testcase | 104 | 1 2 | -1
187+
@testcase | 104 | 0 2 | (null)
188+
@testcase | 105 | -1 | 10
189+
@testcase | 106 | | [ 1 ]
190+
@testcase | 107 | | 1 20
191+
@testcase | 108 | 0 | 20
192+
@testcase | 109 | -1 | 50000000
193+
@testcase | 110 | 5 | 6
194+
@testcase | 110 | -5 | 7
195+
@testcase | 111 | -1 | 1 2
196+
@testcase | 111 | 0 | 3 4
197+
198+
@testcase | 200 | 20 | 200
199+
@testcase | 201 | 5 | 5
200+
@testcase | 202 | 5 | 5
201+
@testcase | 203 | | 200
202+
203+
@testcase | 220 | null null 0 -1 | (null)
204+
@testcase | 220 | null null 0 0 | 20
205+
@testcase | 220 | 9 8 123 5 | 8
206+
@testcase | 221 | 10 null null 0 | 0
207+
@testcase | 221 | 3 null null 0 | (null)
208+
@testcase | 221 | 10 3 4 100 | 3
209+
@testcase | 221 | 3 3 4 100 | 4
210+
211+
@testcase | 300 | 5 | 5 1
212+
@testcase | 301 | -1 | 10 20
213+
@testcase | 302 | null | 0
214+
@testcase | 303 | -1 | 1 [ 1 ]
215+
@testcase | 304 | -1 | 0
216+
@testcase | 304 | 0 | 5
217+
@testcase | 305 | 0 | 5
218+
@testcase | 305 | 0 | 5
219+
220+
@fif_codegen
221+
"""
222+
test101() PROC:<{
223+
DUP
224+
2 PUSHINT
225+
1 PUSHINT
226+
CONDSEL
227+
SWAP
228+
5 EQINT
229+
2 PUSHINT
230+
1 PUSHINT
231+
CONDSEL
232+
}>
233+
"""
234+
235+
@fif_codegen
236+
"""
237+
test102() PROC:<{ // x
238+
DUP // x x
239+
ISNULL // x '1
240+
0 PUSHINT
241+
ROT // '1 '3=0 x
242+
CONDSEL // '2
243+
}>
244+
"""
245+
246+
@fif_codegen
247+
"""
248+
test103() PROC:<{
249+
-2 PUSHINT
250+
2 PUSHINT
251+
CONDSEL
252+
}>
253+
"""
254+
255+
@fif_codegen
256+
"""
257+
test105() PROC:<{ // getX
258+
10 PUSHINT // getX '3=10
259+
20 PUSHINT // getX p.x=10 p.y=20
260+
CONDSEL // '5
261+
}>
262+
"""
263+
264+
@fif_codegen
265+
"""
266+
helper106() PROC:<{
267+
$gTup GETGLOB
268+
SWAP
269+
CONDSEL
270+
}>
271+
"""
272+
273+
@fif_codegen
274+
"""
275+
helper107() PROC:<{
276+
NIP
277+
s1 s(-1) PUXC
278+
CONDSEL
279+
}>
280+
"""
281+
282+
@fif_codegen
283+
"""
284+
test108() PROC:<{
285+
CONT:<{
286+
MIN
287+
}>
288+
CONT:<{
289+
MAX
290+
}>
291+
CONDSEL
292+
10 PUSHINT
293+
20 PUSHINT
294+
ROT
295+
2 1 CALLXARGS
296+
}>
297+
"""
298+
299+
@fif_codegen
300+
"""
301+
test109() PROC:<{
302+
50000000 PUSHINT
303+
1000000 PUSHINT
304+
CONDSEL
305+
}>
306+
"""
307+
308+
@fif_codegen
309+
"""
310+
test200() PROC:<{
311+
DROP
312+
200 PUSHINT
313+
}>
314+
"""
315+
316+
@fif_codegen
317+
"""
318+
test201() PROC:<{
319+
// '2
320+
}>
321+
"""
322+
323+
@fif_codegen
324+
"""
325+
test202() PROC:<{
326+
}>
327+
"""
328+
329+
@fif_codegen
330+
"""
331+
test203() PROC:<{
332+
200 PUSHINT
333+
}>
334+
"""
335+
336+
@fif_codegen
337+
"""
338+
test220() PROC:<{
339+
s3 POP
340+
0 EQINT
341+
IFJMP:<{
342+
20 PUSHINT
343+
CONDSEL
344+
}>
345+
NIP
346+
}>
347+
"""
348+
349+
@fif_codegen
350+
"""
351+
test304() PROC:<{
352+
IF:<{
353+
Point.create0NoInline() CALLDICT
354+
"""
355+
356+
@fif_codegen
357+
"""
358+
test305() PROC:<{
359+
IF:<{
360+
0 PUSHINT
361+
}>ELSE<{
362+
5 PUSHINT
363+
}>
364+
}>
365+
"""
366+
367+
*/

0 commit comments

Comments
 (0)