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:
Sei Lisa 2017-10-17 23:53:24 +02:00
parent b4749d8fa4
commit be767f24f0

View file

@ -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.