diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-07-17 14:50:42 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-07-17 14:50:42 -0300 |
| commit | 8082906c059f2b1473de4363ca57fe19b52f281f (patch) | |
| tree | 1ef5607d4c2a3dc54777bf882849b0260ca8eb56 | |
| parent | d6af81084df569bc8e3bd0949ad6fc0b40c8468d (diff) | |
| download | lua-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.c | 18 | ||||
| -rw-r--r-- | testes/code.lua | 10 |
2 files changed, 21 insertions, 7 deletions
| @@ -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 | */ | ||
| 73 | static 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 | */ |
| 736 | void luaK_dischargevars (FuncState *fs, expdesc *e) { | 749 | void 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 | |||
| 8 | print "testing code generation and optimizations" | 8 | print "testing code generation and optimizations" |
| 9 | 9 | ||
| 10 | -- to test constant propagation | 10 | -- to test constant propagation |
| 11 | local <const> k0 = 0 | 11 | local <const> k0aux = 0 |
| 12 | local <const> k0 = k0aux | ||
| 12 | local <const> k1 = 1 | 13 | local <const> k1 = 1 |
| 13 | local <const> k3 = 3 | 14 | local <const> k3 = 3 |
| 14 | local <const> k6 = k3 + (k3 << k0) | 15 | local <const> k6 = k3 + (k3 << k0) |
| @@ -410,8 +411,9 @@ checkequal(function () return 6 and true or nil end, | |||
| 410 | 411 | ||
| 411 | 412 | ||
| 412 | do -- string constants | 413 | do -- 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) |
