Unfold all assignment+operation operators to optimize them better.

With test case.
This commit is contained in:
Sei Lisa 2014-07-31 18:44:50 +02:00
parent cb66f1ff4e
commit a303ef2066
2 changed files with 35 additions and 18 deletions

View file

@ -343,8 +343,8 @@ class optimizer(object):
else: # x << 0 --> x else: # x << 0 --> x
parent[index] = child[0] parent[index] = child[0]
else: else:
pass # TODO: Eliminate redundancy (x+0, x*1, x*-1, v+ZERO_VECTOR, perhaps x-1=~-x, etc.) pass # TODO: Eliminate redundancy (x*1, x*-1, x|0, x&-1, etc.)
# Include != to ^ and || to | and maybe && to & # Include != to ^ and || to | and maybe && to &
# Note some cases e.g. x*0 can't be optimized away without side-effect analysis. # Note some cases e.g. x*0 can't be optimized away without side-effect analysis.
# But some cases like %1 can be turned into *0 to save bytes. # But some cases like %1 can be turned into *0 to save bytes.
# Turn also % (power of 2) into & mask (oops, nope, negative doesn't work) # Turn also % (power of 2) into & mask (oops, nope, negative doesn't work)
@ -352,12 +352,27 @@ class optimizer(object):
return return
if nt in self.assign_ops: if nt in self.assign_ops:
# TODO: Eliminate redundant operations, e.g. a += 0; etc. # Transform the whole thing into a regular assignment, as there are
# Consider also e.g. x -= 1 or x -= a transforming it into +=. # no gains and it simplifies the optimization.
# Actually just consider transforming the whole thing into a
# regular assignment, as there are no gains and it simplifies the if nt != '=':
# optimization. # Replace the node with the expression alone
self.FoldTree(child, 1) child[1] = {'nt':'()', 't':child[1]['t'], 'ch':[child[1]]}
node['nt'] = nt[:-1]
# Linden Craziness: i += f; is valid (but not i -= f). It's
# actually performed as i = (integer)(i + (f)). This breaks
# regular equivalence of x op= y as x = x op (y) so we add
# the type cast here.
if nt == '*=' and child[0]['t'] == 'integer' and child[1]['t'] == 'float':
node['t'] = 'float' # Addition returns float.
node = self.Cast(node, 'integer')
# And wrap it in an assignment.
node = parent[index] = {'nt':'=', 't':child[0]['t'], 'ch':[child[0].copy(), node]}
# We have a regular assignment either way now. Simplify the RHS.
self.FoldTree(node['ch'], 1)
return return
if nt == 'IDENT' or nt == 'FLD': if nt == 'IDENT' or nt == 'FLD':

View file

@ -199,16 +199,17 @@ class Test02_Compiler(UnitTestCase):
string s = "1" "2"; string s = "1" "2";
list L = [(key)""]; list L = [(key)""];
default{timer(){ default{timer(){
1+([]+(integer)~1); 1+([]+(integer)~1);
list a; list a;
float f; float f;
a = 3; a += 3; a = 3; a += 3;
f += 4; f += -4.3; f += 4; f += -4.3;
integer i; integer i;
i |= i; i *= 1.3;
"a" "b" "c"; i |= i;
"a"+(key)"b"; (key)"a" + "b"; "a" "b" "c";
i>>=i; "a"+(key)"b"; (key)"a" + "b";
i>>=i;
}}''', }}''',
['explicitcast','extendedtypecast','extendedassignment', ['explicitcast','extendedtypecast','extendedassignment',
'extendedglobalexpr', 'allowmultistrings', 'allowkeyconcat', 'extendedglobalexpr', 'allowmultistrings', 'allowkeyconcat',
@ -264,6 +265,7 @@ class Test03_Optimizer(UnitTestCase):
f += 4; f += -4.3; f += 4; f += -4.3;
integer i; integer i;
i = llGetListLength(L); i = llGetListLength(L);
i *= -3.0;
print(3+2); print(3+2);
for(i=3,i;1;){} for(i=3,i;1;){}
i |= !i; i |= !i;