Add getMin() and getMax(), which can detect constants

This commit is contained in:
Sei Lisa 2024-05-07 00:35:47 +02:00
parent bf505220ac
commit d2e3b9a3bd
2 changed files with 38 additions and 15 deletions

View file

@ -29,6 +29,18 @@ from strutil import xrange, unicode
class foldconst(object):
def getMin(self, node):
assert node.t in ('integer', 'float')
if node.nt == 'CONST':
return node.value
return getattr(node, 'min', None)
def getMax(self, node):
assert node.t in ('integer', 'float')
if node.nt == 'CONST':
return node.value
return getattr(node, 'max', None)
def isLocalVar(self, node):
name = node.name
scope = node.scope
@ -1322,33 +1334,35 @@ class foldconst(object):
if child[0].nt == 'CONST' and child[1].SEF:
# when CONST >= second.max: always false
# when CONST < second.min: always true
if (hasattr(child[1], 'max')
and not lslfuncs.less(child[0].value, child[1].max)
rmin = self.getMin(child[1])
rmax = self.getMax(child[1])
if (rmax is not None
and not lslfuncs.less(child[0].value, rmax)
):
parent[index] = nr(nt='CONST', t='integer',
value=0, SEF=True)
return
if (hasattr(child[1], 'min')
and lslfuncs.less(child[0].value, child[1].min)
):
if rmin is not None and lslfuncs.less(child[0].value, rmin):
parent[index] = nr(nt='CONST', t='integer',
value=1, SEF=True)
return
del rmin, rmax
if child[1].nt == 'CONST' and child[0].SEF:
# when first.max < CONST: always true
# when first.min >= CONST: always false
if (hasattr(child[0], 'max')
and lslfuncs.less(child[0].max, child[1].value)
):
lmin = self.getMin(child[0])
lmax = self.getMax(child[0])
if lmax is not None and lslfuncs.less(lmax, child[1].value):
parent[index] = nr(nt='CONST', t='integer',
value=1, SEF=True)
return
if (hasattr(child[0], 'min')
and not lslfuncs.less(child[0].min, child[1].value)
if (lmin is not None
and not lslfuncs.less(lmin, child[1].value)
):
parent[index] = nr(nt='CONST', t='integer',
value=0, SEF=True)
return
del lmin, lmax
# Convert 2147483647<i and i<-2147483648 to i&0
if (child[0].t == child[1].t == 'integer'

View file

@ -528,11 +528,20 @@ def OptimizeFunc(self, parent, index):
parent[index] = nr(nt='CONST', t='list', value=[], SEF=True)
return
if name == 'llFrand' and child[0].nt == 'CONST':
# We can set a range when the input is a constant
value = child[0].value
node.min = lslfuncs.F32(min(value, 0) * 0.9999999403953552)
node.max = lslfuncs.F32(max(value, 0) * 0.9999999403953552)
if name == 'llFrand':
# We can set a range when the input is known to be positive or negative
argmin = self.getMin(child[0])
argmax = self.getMax(child[0])
if argmin is not None and argmin >= 0:
# Positive argument
node.min = 0.
if argmax is not None:
node.max = lslfuncs.F32(argmax * 0.9999999403953552)
elif argmax is not None and argmax <= 0:
# Negative argument
node.max = 0.
if argmin is not None:
node.min = lslfuncs.F32(argmin * 0.9999999403953552)
def FuncOptSetup():
# Patch the default values list for LSO