mirror of
https://github.com/lua/lua.git
synced 2025-01-14 05:43:00 +08:00
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.
This commit is contained in:
parent
d6af81084d
commit
8082906c05
18
lcode.c
18
lcode.c
@ -67,6 +67,15 @@ static int tonumeral (const expdesc *e, TValue *v) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Get the constant value from a constant expression
|
||||||
|
*/
|
||||||
|
static TValue *const2val (FuncState *fs, const expdesc *e) {
|
||||||
|
lua_assert(e->k == VCONST);
|
||||||
|
return &fs->ls->dyd->actvar.arr[e->u.info].k;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** If expression is a constant, fills 'v' with its value
|
** If expression is a constant, fills 'v' with its value
|
||||||
** and returns 1. Otherwise, returns 0.
|
** and returns 1. Otherwise, returns 0.
|
||||||
@ -85,6 +94,10 @@ int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v) {
|
|||||||
setsvalue(fs->ls->L, v, e->u.strval);
|
setsvalue(fs->ls->L, v, e->u.strval);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
case VCONST: {
|
||||||
|
setobj(fs->ls->L, v, const2val(fs, e));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
default: return tonumeral(e, v);
|
default: return tonumeral(e, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -730,14 +743,13 @@ void luaK_setoneret (FuncState *fs, expdesc *e) {
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Ensure that expression 'e' is not a variable.
|
** Ensure that expression 'e' is not a variable (nor a constant).
|
||||||
** (Expression still may have jump lists.)
|
** (Expression still may have jump lists.)
|
||||||
*/
|
*/
|
||||||
void luaK_dischargevars (FuncState *fs, expdesc *e) {
|
void luaK_dischargevars (FuncState *fs, expdesc *e) {
|
||||||
switch (e->k) {
|
switch (e->k) {
|
||||||
case VCONST: {
|
case VCONST: {
|
||||||
TValue *val = &fs->ls->dyd->actvar.arr[e->u.info].k;
|
const2exp(const2val(fs, e), e);
|
||||||
const2exp(val, e);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VLOCAL: { /* already in a register */
|
case VLOCAL: { /* already in a register */
|
||||||
|
@ -8,7 +8,8 @@ end
|
|||||||
print "testing code generation and optimizations"
|
print "testing code generation and optimizations"
|
||||||
|
|
||||||
-- to test constant propagation
|
-- to test constant propagation
|
||||||
local <const> k0 = 0
|
local <const> k0aux = 0
|
||||||
|
local <const> k0 = k0aux
|
||||||
local <const> k1 = 1
|
local <const> k1 = 1
|
||||||
local <const> k3 = 3
|
local <const> k3 = 3
|
||||||
local <const> k6 = k3 + (k3 << k0)
|
local <const> k6 = k3 + (k3 << k0)
|
||||||
@ -410,8 +411,9 @@ checkequal(function () return 6 and true or nil end,
|
|||||||
|
|
||||||
|
|
||||||
do -- string constants
|
do -- string constants
|
||||||
|
local <const> k0 = "00000000000000000000000000000000000000000000000000"
|
||||||
local function f1 ()
|
local function f1 ()
|
||||||
local <const> k = "00000000000000000000000000000000000000000000000000"
|
local <const> k = k0
|
||||||
return function ()
|
return function ()
|
||||||
return function () return k end
|
return function () return k end
|
||||||
end
|
end
|
||||||
@ -419,8 +421,8 @@ do -- string constants
|
|||||||
|
|
||||||
local f2 = f1()
|
local f2 = f1()
|
||||||
local f3 = f2()
|
local f3 = f2()
|
||||||
assert(f3() == string.rep("0", 50))
|
assert(f3() == k0)
|
||||||
checkK(f3, f3())
|
checkK(f3, k0)
|
||||||
-- string is not needed by other functions
|
-- string is not needed by other functions
|
||||||
assert(T.listk(f1)[1] == nil)
|
assert(T.listk(f1)[1] == nil)
|
||||||
assert(T.listk(f2)[1] == nil)
|
assert(T.listk(f2)[1] == nil)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user