mirror of
https://github.com/Sei-Lisa/LSL-PyOptimizer
synced 2025-07-01 23:58:20 +00:00
Move things around to better places; undo 8d33746
.
We oversought that the optimization that 8d33746
applied was already present, so no need to duplicate it.
A better place for handling '|' was under the code that already did so. No functionality change involved.
This commit is contained in:
parent
b4749d8fa4
commit
be767f24f0
1 changed files with 86 additions and 83 deletions
|
@ -271,17 +271,52 @@ class foldconst(object):
|
|||
self.FoldCond(parent, index, ParentIsNegation)
|
||||
return
|
||||
|
||||
|
||||
if nt in self.binary_ops and child[0]['t'] == child[1]['t'] == 'integer':
|
||||
if nt == '!=':
|
||||
if child[0]['nt'] == 'CONST' and child[0]['value'] == 1 \
|
||||
or child[1]['nt'] == 'CONST' and child[1]['value'] == 1:
|
||||
# a != 1 -> a - 1 (which FoldTree will transform to ~-a)
|
||||
node['nt'] = '-'
|
||||
else:
|
||||
# This converts != to ^; FoldTree will simplify ^-1 to ~
|
||||
# and optimize out ^0.
|
||||
node['nt'] = '^'
|
||||
self.FoldTree(parent, index)
|
||||
return
|
||||
|
||||
if nt == '==':
|
||||
if child[0]['nt'] == 'CONST' and -1 <= child[0]['value'] <= 1 \
|
||||
or child[1]['nt'] == 'CONST' and -1 <= child[1]['value'] <= 1:
|
||||
# Transform a==b into !(a-b) if either a or b are in [-1, 1]
|
||||
parent[index] = {'nt':'!', 't':'integer', 'ch':[node]}
|
||||
node['nt'] = '-'
|
||||
self.FoldTree(parent, index)
|
||||
return
|
||||
|
||||
if nt == '|':
|
||||
# In FoldCond(a | b), both a and b are conds themselves.
|
||||
# In a boolean context, the operands count as booleans.
|
||||
self.FoldCond(child, 0)
|
||||
self.FoldCond(child, 1)
|
||||
|
||||
# Deal with operands in any order
|
||||
a, b = 0, 1
|
||||
# Put constant in child[b] if present
|
||||
if child[b]['nt'] != 'CONST':
|
||||
a, b = 1, 0
|
||||
if (child[b]['nt'] == 'CONST' and child[b]['value']
|
||||
and 'SEF' in child[a]
|
||||
):
|
||||
node = parent[index] = child[b]
|
||||
node['value'] = -1
|
||||
return
|
||||
del a, b
|
||||
|
||||
# Specific optimization to catch a bitwise test appearing frequently.
|
||||
# If b and c are nonzero constant powers of two:
|
||||
# !(a & b) | !(a & c) -> ~(a|~(b|c))
|
||||
# e.g. if (a & 4 && a & 8) -> if (!~(a|-13))
|
||||
if (nt == '|'
|
||||
and child[0]['nt'] == '!' and child[0]['ch'][0]['nt'] == '&'
|
||||
if (child[0]['nt'] == '!' and child[0]['ch'][0]['nt'] == '&'
|
||||
and child[1]['nt'] == '!' and child[1]['ch'][0]['nt'] == '&'
|
||||
):
|
||||
and1 = child[0]['ch'][0]['ch']
|
||||
|
@ -296,15 +331,16 @@ class foldconst(object):
|
|||
val2 = and2[d]['value']
|
||||
if (val1 and val2
|
||||
# power of 2
|
||||
and ((val1 & (val1 - 1)) == 0 or val1 == -2147483648)
|
||||
and ((val2 & (val2 - 1)) == 0 or val2 == -2147483648)
|
||||
and (val1 & (val1 - 1) & 0xFFFFFFFF) == 0
|
||||
and (val2 & (val2 - 1) & 0xFFFFFFFF) == 0
|
||||
and self.CompareTrees(and1[a], and2[c])
|
||||
):
|
||||
# Check passed
|
||||
child[0] = and1[a]
|
||||
child[1] = and1[b]
|
||||
child[1]['value'] = ~(val1 | val2)
|
||||
parent[index] = {'nt':'~', 't':'integer', 'ch':[node]}
|
||||
parent[index] = {'nt':'~', 't':'integer',
|
||||
'ch':[node]}
|
||||
if 'SEF' in node:
|
||||
parent[index]['SEF'] = True
|
||||
self.FoldCond(parent, index, ParentIsNegation)
|
||||
|
@ -351,43 +387,10 @@ class foldconst(object):
|
|||
parent[index] = child[a]
|
||||
ch1[d]['value'] &= ~ch2[f]['value']
|
||||
return
|
||||
del ch1, ch2
|
||||
|
||||
if nt in self.binary_ops and child[0]['t'] == child[1]['t'] == 'integer':
|
||||
if nt == '!=':
|
||||
if child[0]['nt'] == 'CONST' and child[0]['value'] == 1 \
|
||||
or child[1]['nt'] == 'CONST' and child[1]['value'] == 1:
|
||||
# a != 1 -> a - 1 (which FoldTree will transform to ~-a)
|
||||
node['nt'] = '-'
|
||||
else:
|
||||
# This converts != to ^; FoldTree will simplify ^-1 to ~
|
||||
# and optimize out ^0.
|
||||
node['nt'] = '^'
|
||||
self.FoldTree(parent, index)
|
||||
return
|
||||
del a, b, c, d, e, f
|
||||
|
||||
if nt == '==':
|
||||
if child[0]['nt'] == 'CONST' and -1 <= child[0]['value'] <= 1 \
|
||||
or child[1]['nt'] == 'CONST' and -1 <= child[1]['value'] <= 1:
|
||||
# Transform a==b into !(a-b) if either a or b are in [-1, 1]
|
||||
parent[index] = {'nt':'!', 't':'integer', 'ch':[node]}
|
||||
node['nt'] = '-'
|
||||
self.FoldTree(parent, index)
|
||||
return
|
||||
|
||||
if nt == '|':
|
||||
# In a boolean context, the operands count as booleans.
|
||||
self.FoldCond(child, 0)
|
||||
self.FoldCond(child, 1)
|
||||
|
||||
# Deal with operands in any order
|
||||
a, b = 0, 1
|
||||
# Put constant in child[b] if present
|
||||
if child[b]['nt'] != 'CONST':
|
||||
a, b = 1, 0
|
||||
if child[b]['nt'] == 'CONST' and child[b]['value'] and 'SEF' in child[a]:
|
||||
parent[index] = child[b]
|
||||
child[b]['value'] = -1
|
||||
return
|
||||
|
||||
# Check if the operands are a negation ('!') or can be inverted
|
||||
# without adding more than 1 byte and are boolean.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue