summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-07-17 14:50:42 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-07-17 14:50:42 -0300
commit8082906c059f2b1473de4363ca57fe19b52f281f (patch)
tree1ef5607d4c2a3dc54777bf882849b0260ca8eb56
parentd6af81084df569bc8e3bd0949ad6fc0b40c8468d (diff)
downloadlua-8082906c059f2b1473de4363ca57fe19b52f281f.tar.gz
lua-8082906c059f2b1473de4363ca57fe19b52f281f.tar.bz2
lua-8082906c059f2b1473de4363ca57fe19b52f281f.zip
Fixed small issue with constant propagation
Constants directly assigned to other constants were not propagating: For instance, in local <const> k1 = 10 local <const> k2 = k1 'k2' were not treated as a compile-time constant.
-rw-r--r--lcode.c18
-rw-r--r--testes/code.lua10
2 files changed, 21 insertions, 7 deletions
diff --git a/lcode.c b/lcode.c
index 40efcff3..c2b5fc6d 100644
--- a/lcode.c
+++ b/lcode.c
@@ -68,6 +68,15 @@ static int tonumeral (const expdesc *e, TValue *v) {
68 68
69 69
70/* 70/*
71** Get the constant value from a constant expression
72*/
73static TValue *const2val (FuncState *fs, const expdesc *e) {
74 lua_assert(e->k == VCONST);
75 return &fs->ls->dyd->actvar.arr[e->u.info].k;
76}
77
78
79/*
71** If expression is a constant, fills 'v' with its value 80** If expression is a constant, fills 'v' with its value
72** and returns 1. Otherwise, returns 0. 81** and returns 1. Otherwise, returns 0.
73*/ 82*/
@@ -85,6 +94,10 @@ int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v) {
85 setsvalue(fs->ls->L, v, e->u.strval); 94 setsvalue(fs->ls->L, v, e->u.strval);
86 return 1; 95 return 1;
87 } 96 }
97 case VCONST: {
98 setobj(fs->ls->L, v, const2val(fs, e));
99 return 1;
100 }
88 default: return tonumeral(e, v); 101 default: return tonumeral(e, v);
89 } 102 }
90} 103}
@@ -730,14 +743,13 @@ void luaK_setoneret (FuncState *fs, expdesc *e) {
730 743
731 744
732/* 745/*
733** Ensure that expression 'e' is not a variable. 746** Ensure that expression 'e' is not a variable (nor a constant).
734** (Expression still may have jump lists.) 747** (Expression still may have jump lists.)
735*/ 748*/
736void luaK_dischargevars (FuncState *fs, expdesc *e) { 749void luaK_dischargevars (FuncState *fs, expdesc *e) {
737 switch (e->k) { 750 switch (e->k) {
738 case VCONST: { 751 case VCONST: {
739 TValue *val = &fs->ls->dyd->actvar.arr[e->u.info].k; 752 const2exp(const2val(fs, e), e);
740 const2exp(val, e);
741 break; 753 break;
742 } 754 }
743 case VLOCAL: { /* already in a register */ 755 case VLOCAL: { /* already in a register */
diff --git a/testes/code.lua b/testes/code.lua
index b5091458..57923b14 100644
--- a/testes/code.lua
+++ b/testes/code.lua
@@ -8,7 +8,8 @@ end
8print "testing code generation and optimizations" 8print "testing code generation and optimizations"
9 9
10-- to test constant propagation 10-- to test constant propagation
11local <const> k0 = 0 11local <const> k0aux = 0
12local <const> k0 = k0aux
12local <const> k1 = 1 13local <const> k1 = 1
13local <const> k3 = 3 14local <const> k3 = 3
14local <const> k6 = k3 + (k3 << k0) 15local <const> k6 = k3 + (k3 << k0)
@@ -410,8 +411,9 @@ checkequal(function () return 6 and true or nil end,
410 411
411 412
412do -- string constants 413do -- string constants
414 local <const> k0 = "00000000000000000000000000000000000000000000000000"
413 local function f1 () 415 local function f1 ()
414 local <const> k = "00000000000000000000000000000000000000000000000000" 416 local <const> k = k0
415 return function () 417 return function ()
416 return function () return k end 418 return function () return k end
417 end 419 end
@@ -419,8 +421,8 @@ do -- string constants
419 421
420 local f2 = f1() 422 local f2 = f1()
421 local f3 = f2() 423 local f3 = f2()
422 assert(f3() == string.rep("0", 50)) 424 assert(f3() == k0)
423 checkK(f3, f3()) 425 checkK(f3, k0)
424 -- string is not needed by other functions 426 -- string is not needed by other functions
425 assert(T.listk(f1)[1] == nil) 427 assert(T.listk(f1)[1] == nil)
426 assert(T.listk(f2)[1] == nil) 428 assert(T.listk(f2)[1] == nil)