mirror of
https://github.com/Sei-Lisa/LSL-PyOptimizer
synced 2025-07-01 23:58:20 +00:00
Apply DeMorgan in some cases that were not caught.
Example: the optimization of if(i < 2 || i) was suboptimal, because FoldTree was done before FoldCond. In a first stage, the || was removed: if(!!(i < 2 | i)); when folded, the inner ! was optimized first and the result was if(!(1 < i & (!i))), which FoldCond wasn't smart enough to handle. The new optimization takes over from there, and converts if(!(!a & b)) with b boolean, in any order, to if(a | !b). When applied to the above expression, it gets folded to if(i < 2 | i) as expected, which is optimal. Also, new function: IsAndBool (see docstring), used on b in the above example.
This commit is contained in:
parent
fa547cd9e8
commit
e123866e6e
1 changed files with 23 additions and 0 deletions
|
@ -245,6 +245,16 @@ class foldconst(object):
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def IsAndBool(self, node):
|
||||||
|
"""For bitwise AND, in some cases we can relax the condition to this:
|
||||||
|
when bit 0 is 0, all other bits are guaranteed to be 0 as well. That's
|
||||||
|
the case of -bool which is the only case we deal with here, but an
|
||||||
|
important one because we generate it as an intermediate result in some
|
||||||
|
operations.
|
||||||
|
"""
|
||||||
|
return (node.nt == 'NEG' and self.IsBool(node.ch[0])
|
||||||
|
or self.IsBool(node))
|
||||||
|
|
||||||
def FoldCond(self, parent, index, ParentIsNegation = False):
|
def FoldCond(self, parent, index, ParentIsNegation = False):
|
||||||
"""When we know that the parent is interested only in the truth value
|
"""When we know that the parent is interested only in the truth value
|
||||||
of the node, we can perform further optimizations. This function deals
|
of the node, we can perform further optimizations. This function deals
|
||||||
|
@ -297,6 +307,19 @@ class foldconst(object):
|
||||||
self.FoldTree(parent, index)
|
self.FoldTree(parent, index)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if (child[0].nt == '&'
|
||||||
|
and any(child[0].ch[i].nt == '!'
|
||||||
|
and self.IsAndBool(child[0].ch[1-i]) for i in (0, 1))
|
||||||
|
):
|
||||||
|
# We can remove at least one !
|
||||||
|
child[0].nt = '|'
|
||||||
|
for i in (0, 1):
|
||||||
|
child[0].ch[i] = nr(nt='!', t='integer',
|
||||||
|
ch=[child[0].ch[i]], SEF=child[0].ch[i].SEF)
|
||||||
|
parent[index] = child[0]
|
||||||
|
self.FoldTree(parent, index)
|
||||||
|
self.FoldCond(parent, index)
|
||||||
|
return
|
||||||
|
|
||||||
if nt == 'NEG':
|
if nt == 'NEG':
|
||||||
# bool(-a) equals bool(a)
|
# bool(-a) equals bool(a)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue