aboutsummaryrefslogtreecommitdiff
path: root/testes
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-07-12 11:38:42 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-07-12 11:38:42 -0300
commitf6aab3ec1f111cd8d968bdcb7ca800e93b819d24 (patch)
tree4c36c418ecc9062e6d95de73457198b38b0afce9 /testes
parentbe8445d7e4b6122620c428877b51a27d464253d5 (diff)
downloadlua-f6aab3ec1f111cd8d968bdcb7ca800e93b819d24.tar.gz
lua-f6aab3ec1f111cd8d968bdcb7ca800e93b819d24.tar.bz2
lua-f6aab3ec1f111cd8d968bdcb7ca800e93b819d24.zip
First implementation of constant propagation
Local constant variables initialized with compile-time constants are optimized away from the code.
Diffstat (limited to 'testes')
-rw-r--r--testes/code.lua89
-rw-r--r--testes/constructs.lua24
-rw-r--r--testes/locals.lua2
-rw-r--r--testes/math.lua16
4 files changed, 89 insertions, 42 deletions
diff --git a/testes/code.lua b/testes/code.lua
index 128ca2cb..49d682f8 100644
--- a/testes/code.lua
+++ b/testes/code.lua
@@ -7,6 +7,22 @@ if T==nil then
7end 7end
8print "testing code generation and optimizations" 8print "testing code generation and optimizations"
9 9
10-- to test constant propagation
11local <const> k0 = 0
12local <const> k1 = 1
13local <const> k3 = 3
14local <const> k6 = k3 + (k3 << k0)
15local <const> kFF0 = 0xFF0
16local <const> k3_78 = 3.78
17local <const> x, <const> k3_78_4 = 10, k3_78 / 4
18assert(x == 10)
19
20local <const> kx = "x"
21
22local <const> kTrue = true
23local <const> kFalse = false
24
25local <const> kNil = nil
10 26
11-- this code gave an error for the code checker 27-- this code gave an error for the code checker
12do 28do
@@ -27,12 +43,12 @@ end
27 43
28local function foo () 44local function foo ()
29 local a 45 local a
30 a = 3; 46 a = k3;
31 a = 0; a = 0.0; a = -7 + 7 47 a = 0; a = 0.0; a = -7 + 7
32 a = 3.78/4; a = 3.78/4 48 a = k3_78/4; a = k3_78_4
33 a = -3.78/4; a = 3.78/4; a = -3.78/4 49 a = -k3_78/4; a = k3_78/4; a = -3.78/4
34 a = -3.79/4; a = 0.0; a = -0; 50 a = -3.79/4; a = 0.0; a = -0;
35 a = 3; a = 3.0; a = 3; a = 3.0 51 a = k3; a = 3.0; a = 3; a = 3.0
36end 52end
37 53
38checkKlist(foo, {3.78/4, -3.78/4, -3.79/4}) 54checkKlist(foo, {3.78/4, -3.78/4, -3.79/4})
@@ -86,10 +102,11 @@ end, 'CLOSURE', 'NEWTABLE', 'GETTABUP', 'CALL', 'SETLIST', 'CALL', 'RETURN')
86 102
87-- sequence of LOADNILs 103-- sequence of LOADNILs
88check(function () 104check(function ()
105 local <const> kNil = nil
89 local a,b,c 106 local a,b,c
90 local d; local e; 107 local d; local e;
91 local f,g,h; 108 local f,g,h;
92 d = nil; d=nil; b=nil; a=nil; c=nil; 109 d = nil; d=nil; b=nil; a=kNil; c=nil;
93end, 'LOADNIL', 'RETURN0') 110end, 'LOADNIL', 'RETURN0')
94 111
95check(function () 112check(function ()
@@ -109,7 +126,7 @@ check (function (a,b,c) return a end, 'RETURN1')
109 126
110 127
111-- infinite loops 128-- infinite loops
112check(function () while true do local a = -1 end end, 129check(function () while kTrue do local a = -1 end end,
113'LOADI', 'JMP', 'RETURN0') 130'LOADI', 'JMP', 'RETURN0')
114 131
115check(function () while 1 do local a = -1 end end, 132check(function () while 1 do local a = -1 end end,
@@ -125,9 +142,9 @@ check(function (a,b,c,d) return a..b..c..d end,
125 142
126-- not 143-- not
127check(function () return not not nil end, 'LOADBOOL', 'RETURN1') 144check(function () return not not nil end, 'LOADBOOL', 'RETURN1')
128check(function () return not not false end, 'LOADBOOL', 'RETURN1') 145check(function () return not not kFalse end, 'LOADBOOL', 'RETURN1')
129check(function () return not not true end, 'LOADBOOL', 'RETURN1') 146check(function () return not not true end, 'LOADBOOL', 'RETURN1')
130check(function () return not not 1 end, 'LOADBOOL', 'RETURN1') 147check(function () return not not k3 end, 'LOADBOOL', 'RETURN1')
131 148
132-- direct access to locals 149-- direct access to locals
133check(function () 150check(function ()
@@ -144,7 +161,8 @@ end,
144-- direct access to constants 161-- direct access to constants
145check(function () 162check(function ()
146 local a,b 163 local a,b
147 a.x = 3.2 164 local c = kNil
165 a[kx] = 3.2
148 a.x = b 166 a.x = b
149 a[b] = 'x' 167 a[b] = 'x'
150end, 168end,
@@ -152,8 +170,9 @@ end,
152 170
153-- "get/set table" with numeric indices 171-- "get/set table" with numeric indices
154check(function (a) 172check(function (a)
173 local <const> k255 = 255
155 a[1] = a[100] 174 a[1] = a[100]
156 a[255] = a[256] 175 a[k255] = a[256]
157 a[256] = 5 176 a[256] = 5
158end, 177end,
159 'GETI', 'SETI', 178 'GETI', 'SETI',
@@ -170,7 +189,7 @@ end,
170 189
171check(function () 190check(function ()
172 local a,b 191 local a,b
173 a[true] = false 192 a[kTrue] = false
174end, 193end,
175 'LOADNIL', 'LOADBOOL', 'SETTABLE', 'RETURN0') 194 'LOADNIL', 'LOADBOOL', 'SETTABLE', 'RETURN0')
176 195
@@ -238,37 +257,39 @@ local function checkF (func, val)
238end 257end
239 258
240checkF(function () return 0.0 end, 0.0) 259checkF(function () return 0.0 end, 0.0)
241checkI(function () return 0 end, 0) 260checkI(function () return k0 end, 0)
242checkI(function () return -0//1 end, 0) 261checkI(function () return -k0//1 end, 0)
243checkK(function () return 3^-1 end, 1/3) 262checkK(function () return 3^-1 end, 1/3)
244checkK(function () return (1 + 1)^(50 + 50) end, 2^100) 263checkK(function () return (1 + 1)^(50 + 50) end, 2^100)
245checkK(function () return (-2)^(31 - 2) end, -0x20000000 + 0.0) 264checkK(function () return (-2)^(31 - 2) end, -0x20000000 + 0.0)
246checkF(function () return (-3^0 + 5) // 3.0 end, 1.0) 265checkF(function () return (-k3^0 + 5) // 3.0 end, 1.0)
247checkI(function () return -3 % 5 end, 2) 266checkI(function () return -k3 % 5 end, 2)
248checkF(function () return -((2.0^8 + -(-1)) % 8)/2 * 4 - 3 end, -5.0) 267checkF(function () return -((2.0^8 + -(-1)) % 8)/2 * 4 - 3 end, -5.0)
249checkF(function () return -((2^8 + -(-1)) % 8)//2 * 4 - 3 end, -7.0) 268checkF(function () return -((2^8 + -(-1)) % 8)//2 * 4 - 3 end, -7.0)
250checkI(function () return 0xF0.0 | 0xCC.0 ~ 0xAA & 0xFD end, 0xF4) 269checkI(function () return 0xF0.0 | 0xCC.0 ~ 0xAA & 0xFD end, 0xF4)
251checkI(function () return ~(~0xFF0 | 0xFF0) end, 0) 270checkI(function () return ~(~kFF0 | kFF0) end, 0)
252checkI(function () return ~~-1024.0 end, -1024) 271checkI(function () return ~~-1024.0 end, -1024)
253checkI(function () return ((100 << 6) << -4) >> 2 end, 100) 272checkI(function () return ((100 << k6) << -4) >> 2 end, 100)
254 273
255-- borders around MAXARG_sBx ((((1 << 17) - 1) >> 1) == 65535) 274-- borders around MAXARG_sBx ((((1 << 17) - 1) >> 1) == 65535)
256local a = 17; local sbx = ((1 << a) - 1) >> 1 -- avoid folding 275local a = 17; local sbx = ((1 << a) - 1) >> 1 -- avoid folding
257checkI(function () return 65535 end, sbx) 276local <const> border = 65535
258checkI(function () return -65535 end, -sbx) 277checkI(function () return border end, sbx)
259checkI(function () return 65536 end, sbx + 1) 278checkI(function () return -border end, -sbx)
260checkK(function () return 65537 end, sbx + 2) 279checkI(function () return border + 1 end, sbx + 1)
261checkK(function () return -65536 end, -(sbx + 1)) 280checkK(function () return border + 2 end, sbx + 2)
281checkK(function () return -(border + 1) end, -(sbx + 1))
262 282
263checkF(function () return 65535.0 end, sbx + 0.0) 283local <const> border = 65535.0
264checkF(function () return -65535.0 end, -sbx + 0.0) 284checkF(function () return border end, sbx + 0.0)
265checkF(function () return 65536.0 end, (sbx + 1.0)) 285checkF(function () return -border end, -sbx + 0.0)
266checkK(function () return 65537.0 end, (sbx + 2.0)) 286checkF(function () return border + 1 end, (sbx + 1.0))
267checkK(function () return -65536.0 end, -(sbx + 1.0)) 287checkK(function () return border + 2 end, (sbx + 2.0))
288checkK(function () return -(border + 1) end, -(sbx + 1.0))
268 289
269 290
270-- immediate operands 291-- immediate operands
271checkR(function (x) return x + 1 end, 10, 11, 'ADDI', 'RETURN1') 292checkR(function (x) return x + k1 end, 10, 11, 'ADDI', 'RETURN1')
272checkR(function (x) return 128 + x end, 0.0, 128.0, 'ADDI', 'RETURN1') 293checkR(function (x) return 128 + x end, 0.0, 128.0, 'ADDI', 'RETURN1')
273checkR(function (x) return x * -127 end, -1.0, 127.0, 'MULI', 'RETURN1') 294checkR(function (x) return x * -127 end, -1.0, 127.0, 'MULI', 'RETURN1')
274checkR(function (x) return 20 * x end, 2, 40, 'MULI', 'RETURN1') 295checkR(function (x) return 20 * x end, 2, 40, 'MULI', 'RETURN1')
@@ -276,7 +297,7 @@ checkR(function (x) return x ^ -2 end, 2, 0.25, 'POWI', 'RETURN1')
276checkR(function (x) return x / 40 end, 40, 1.0, 'DIVI', 'RETURN1') 297checkR(function (x) return x / 40 end, 40, 1.0, 'DIVI', 'RETURN1')
277checkR(function (x) return x // 1 end, 10.0, 10.0, 'IDIVI', 'RETURN1') 298checkR(function (x) return x // 1 end, 10.0, 10.0, 'IDIVI', 'RETURN1')
278checkR(function (x) return x % (100 - 10) end, 91, 1, 'MODI', 'RETURN1') 299checkR(function (x) return x % (100 - 10) end, 91, 1, 'MODI', 'RETURN1')
279checkR(function (x) return 1 << x end, 3, 8, 'SHLI', 'RETURN1') 300checkR(function (x) return k1 << x end, 3, 8, 'SHLI', 'RETURN1')
280checkR(function (x) return x << 2 end, 10, 40, 'SHRI', 'RETURN1') 301checkR(function (x) return x << 2 end, 10, 40, 'SHRI', 'RETURN1')
281checkR(function (x) return x >> 2 end, 8, 2, 'SHRI', 'RETURN1') 302checkR(function (x) return x >> 2 end, 8, 2, 'SHRI', 'RETURN1')
282checkR(function (x) return x & 1 end, 9, 1, 'BANDK', 'RETURN1') 303checkR(function (x) return x & 1 end, 9, 1, 'BANDK', 'RETURN1')
@@ -295,7 +316,7 @@ checkR(function (x) return x % (100.0 - 10) end, 91, 1.0, 'MODK', 'RETURN1')
295 316
296-- no foldings (and immediate operands) 317-- no foldings (and immediate operands)
297check(function () return -0.0 end, 'LOADF', 'UNM', 'RETURN1') 318check(function () return -0.0 end, 'LOADF', 'UNM', 'RETURN1')
298check(function () return 3/0 end, 'LOADI', 'DIVI', 'RETURN1') 319check(function () return k3/0 end, 'LOADI', 'DIVI', 'RETURN1')
299check(function () return 0%0 end, 'LOADI', 'MODI', 'RETURN1') 320check(function () return 0%0 end, 'LOADI', 'MODI', 'RETURN1')
300check(function () return -4//0 end, 'LOADI', 'IDIVI', 'RETURN1') 321check(function () return -4//0 end, 'LOADI', 'IDIVI', 'RETURN1')
301check(function (x) return x >> 2.0 end, 'LOADF', 'SHR', 'RETURN1') 322check(function (x) return x >> 2.0 end, 'LOADF', 'SHR', 'RETURN1')
@@ -335,7 +356,7 @@ end,
335 356
336do -- tests for table access in upvalues 357do -- tests for table access in upvalues
337 local t 358 local t
338 check(function () t.x = t.y end, 'GETTABUP', 'SETTABUP') 359 check(function () t[kx] = t.y end, 'GETTABUP', 'SETTABUP')
339 check(function (a) t[a()] = t[a()] end, 360 check(function (a) t[a()] = t[a()] end,
340 'MOVE', 'CALL', 'GETUPVAL', 'MOVE', 'CALL', 361 'MOVE', 'CALL', 'GETUPVAL', 'MOVE', 'CALL',
341 'GETUPVAL', 'GETTABLE', 'SETTABLE') 362 'GETUPVAL', 'GETTABLE', 'SETTABLE')
@@ -379,6 +400,12 @@ function (a)
379end 400end
380) 401)
381 402
403checkequal(function () return 6 or true or nil end,
404 function () return k6 or kTrue or kNil end)
405
406checkequal(function () return 6 and true or nil end,
407 function () return k6 and kTrue or kNil end)
408
382 409
383print 'OK' 410print 'OK'
384 411
diff --git a/testes/constructs.lua b/testes/constructs.lua
index fe4db2cb..8a549e10 100644
--- a/testes/constructs.lua
+++ b/testes/constructs.lua
@@ -287,7 +287,7 @@ a,b = F(nil)==nil; assert(a == true and b == nil)
287------------------------------------------------------------------ 287------------------------------------------------------------------
288 288
289-- sometimes will be 0, sometimes will not... 289-- sometimes will be 0, sometimes will not...
290_ENV.GLOB1 = math.floor(os.time()) % 2 290_ENV.GLOB1 = math.random(0, 1)
291 291
292-- basic expressions with their respective values 292-- basic expressions with their respective values
293local basiccases = { 293local basiccases = {
@@ -298,6 +298,26 @@ local basiccases = {
298 {"(0==_ENV.GLOB1)", 0 == _ENV.GLOB1}, 298 {"(0==_ENV.GLOB1)", 0 == _ENV.GLOB1},
299} 299}
300 300
301local prog
302
303if _ENV.GLOB1 == 0 then
304 basiccases[2][1] = "F" -- constant false
305
306 prog = [[
307 local <const> F = false
308 if %s then IX = true end
309 return %s
310]]
311else
312 basiccases[4][1] = "k10" -- constant 10
313
314 prog = [[
315 local <const> k10 = 10
316 if %s then IX = true end
317 return %s
318 ]]
319end
320
301print('testing short-circuit optimizations (' .. _ENV.GLOB1 .. ')') 321print('testing short-circuit optimizations (' .. _ENV.GLOB1 .. ')')
302 322
303 323
@@ -337,8 +357,6 @@ cases[1] = basiccases
337for i = 2, level do cases[i] = createcases(i) end 357for i = 2, level do cases[i] = createcases(i) end
338print("+") 358print("+")
339 359
340local prog = [[if %s then IX = true end; return %s]]
341
342local i = 0 360local i = 0
343for n = 1, level do 361for n = 1, level do
344 for _, v in pairs(cases[n]) do 362 for _, v in pairs(cases[n]) do
diff --git a/testes/locals.lua b/testes/locals.lua
index 0de00a98..1b82dd7f 100644
--- a/testes/locals.lua
+++ b/testes/locals.lua
@@ -324,7 +324,7 @@ do
324 324
325 -- errors due to non-closable values 325 -- errors due to non-closable values
326 local function foo () 326 local function foo ()
327 local <toclose> x = 34 327 local <toclose> x = {}
328 end 328 end
329 local stat, msg = pcall(foo) 329 local stat, msg = pcall(foo)
330 assert(not stat and string.find(msg, "variable 'x'")) 330 assert(not stat and string.find(msg, "variable 'x'"))
diff --git a/testes/math.lua b/testes/math.lua
index c45a91ad..befce12e 100644
--- a/testes/math.lua
+++ b/testes/math.lua
@@ -270,7 +270,7 @@ else
270end 270end
271 271
272do 272do
273 local NaN = 0/0 273 local <const> NaN = 0/0
274 assert(not (NaN < 0)) 274 assert(not (NaN < 0))
275 assert(not (NaN > minint)) 275 assert(not (NaN > minint))
276 assert(not (NaN <= -9)) 276 assert(not (NaN <= -9))
@@ -767,7 +767,8 @@ assert(a == '10' and b == '20')
767 767
768do 768do
769 print("testing -0 and NaN") 769 print("testing -0 and NaN")
770 local mz, z = -0.0, 0.0 770 local <const> mz = -0.0
771 local <const> z = 0.0
771 assert(mz == z) 772 assert(mz == z)
772 assert(1/mz < 0 and 0 < 1/z) 773 assert(1/mz < 0 and 0 < 1/z)
773 local a = {[mz] = 1} 774 local a = {[mz] = 1}
@@ -775,17 +776,18 @@ do
775 a[z] = 2 776 a[z] = 2
776 assert(a[z] == 2 and a[mz] == 2) 777 assert(a[z] == 2 and a[mz] == 2)
777 local inf = math.huge * 2 + 1 778 local inf = math.huge * 2 + 1
778 mz, z = -1/inf, 1/inf 779 local <const> mz = -1/inf
780 local <const> z = 1/inf
779 assert(mz == z) 781 assert(mz == z)
780 assert(1/mz < 0 and 0 < 1/z) 782 assert(1/mz < 0 and 0 < 1/z)
781 local NaN = inf - inf 783 local <const> NaN = inf - inf
782 assert(NaN ~= NaN) 784 assert(NaN ~= NaN)
783 assert(not (NaN < NaN)) 785 assert(not (NaN < NaN))
784 assert(not (NaN <= NaN)) 786 assert(not (NaN <= NaN))
785 assert(not (NaN > NaN)) 787 assert(not (NaN > NaN))
786 assert(not (NaN >= NaN)) 788 assert(not (NaN >= NaN))
787 assert(not (0 < NaN) and not (NaN < 0)) 789 assert(not (0 < NaN) and not (NaN < 0))
788 local NaN1 = 0/0 790 local <const> NaN1 = 0/0
789 assert(NaN ~= NaN1 and not (NaN <= NaN1) and not (NaN1 <= NaN)) 791 assert(NaN ~= NaN1 and not (NaN <= NaN1) and not (NaN1 <= NaN))
790 local a = {} 792 local a = {}
791 assert(not pcall(rawset, a, NaN, 1)) 793 assert(not pcall(rawset, a, NaN, 1))
@@ -814,8 +816,8 @@ end
814-- the first call after seed 1007 should return 0x7a7040a5a323c9d6 816-- the first call after seed 1007 should return 0x7a7040a5a323c9d6
815do 817do
816 -- all computations assume at most 32-bit integers 818 -- all computations assume at most 32-bit integers
817 local h = 0x7a7040a5 -- higher half 819 local <const> h = 0x7a7040a5 -- higher half
818 local l = 0xa323c9d6 -- lower half 820 local <const> l = 0xa323c9d6 -- lower half
819 821
820 math.randomseed(1007) 822 math.randomseed(1007)
821 -- get the low 'intbits' of the 64-bit expected result 823 -- get the low 'intbits' of the 64-bit expected result