Add IfElseSwap option

This enables an option that was being done unconditionally: to swap the `if` and `else` branches if the condition is shorter when negated.

Enabled by default.
This commit is contained in:
Sei Lisa 2022-10-31 20:08:26 +01:00
parent e62b5ffcb6
commit 08c429f22b
8 changed files with 44 additions and 17 deletions

View file

@ -1796,7 +1796,7 @@ class foldconst(object):
self.FoldTree(child, 2) self.FoldTree(child, 2)
self.FoldStmt(child, 2) self.FoldStmt(child, 2)
# Check if it makes sense to swap if and else branches # Check if it makes sense to swap if and else branches
if not child[2].SEF: if self.ifelseswap and not child[2].SEF:
# Check if we can gain something by negating the # Check if we can gain something by negating the
# expression. # expression.
# Swap 'if' and 'else' branch when the condition has # Swap 'if' and 'else' branch when the condition has

View file

@ -68,6 +68,7 @@ class optimizer(foldconst, renamer, deadcode, lastpass):
self.shrinknames = 'shrinknames' in options self.shrinknames = 'shrinknames' in options
self.constfold = 'constfold' in options self.constfold = 'constfold' in options
self.ifelseswap = 'ifelseswap' in options
self.optlistlength = 'listlength' in options self.optlistlength = 'listlength' in options
self.optlistadd = 'listadd' in options self.optlistadd = 'listadd' in options
self.dcr = 'dcr' in options self.dcr = 'dcr' in options

17
main.py
View file

@ -326,6 +326,9 @@ Case insensitive.
OptFloats + Optimize floats that represent an integral value. OptFloats + Optimize floats that represent an integral value.
ConstFold + Fold constant expressions to their values, and simplify ConstFold + Fold constant expressions to their values, and simplify
some expressions and statements. some expressions and statements.
IfElseSwap + In 'if' statements, when negating the condition produces
shorter code, do it and swap the if and else branches.
Requires ConstFold to be enabled.
DCR + Dead code removal. This option removes several instances DCR + Dead code removal. This option removes several instances
of code that will never execute, and performs other of code that will never execute, and performs other
optimizations like removal of unused variables, optimizations like removal of unused variables,
@ -379,9 +382,9 @@ break/continue syntax extension (which is inactive by default).
validoptions = frozenset({'extendedglobalexpr','breakcont','extendedtypecast', validoptions = frozenset({'extendedglobalexpr','breakcont','extendedtypecast',
'extendedassignment','allowkeyconcat','allowmultistrings','duplabels', 'extendedassignment','allowkeyconcat','allowmultistrings','duplabels',
'lazylists','enableswitch','errmissingdefault','funcoverride','optimize', 'lazylists','enableswitch','errmissingdefault','funcoverride','optimize',
'optsigns','optfloats','constfold','dcr','shrinknames','addstrings', 'optsigns','optfloats','constfold','ifelseswap','dcr','shrinknames',
'foldtabs','warntabs','processpre','explicitcast','listlength','listadd', 'addstrings','foldtabs','warntabs','processpre','explicitcast',
'inline', 'help', 'listlength','listadd','inline','help',
# undocumented # undocumented
'lso','expr','rsrclimit', 'lso','expr','rsrclimit',
# 'clear' is handled as a special case # 'clear' is handled as a special case
@ -396,10 +399,10 @@ def main(argv):
lslopt.lslcommon.DataPath = __file__[:-len(os.path.basename(__file__))] lslopt.lslcommon.DataPath = __file__[:-len(os.path.basename(__file__))]
# Default options # Default options
options = set(('extendedglobalexpr','extendedtypecast','extendedassignment', options = set(('extendedglobalexpr','extendedtypecast',
'allowkeyconcat','allowmultistrings','processpre','warntabs','optimize', 'extendedassignment','allowkeyconcat','allowmultistrings','processpre',
'optsigns','optfloats','constfold','dcr','errmissingdefault', 'warntabs','optimize','optsigns','optfloats','constfold','ifelseswap',
'listlength','listadd', 'dcr','errmissingdefault','listlength','listadd',
)) ))
assert not (options - validoptions), (u"Default options not present in" assert not (options - validoptions), (u"Default options not present in"

View file

@ -0,0 +1,7 @@
default{timer(){
integer a = llGetLinkNumber();
if (a == 3) llOwnerSay("1"); else llOwnerSay("2");
if (!a) llOwnerSay("3"); else llOwnerSay("4");
}}

View file

@ -0,0 +1,15 @@
default
{
timer()
{
integer a = llGetLinkNumber();
if (a == 3)
llOwnerSay("1");
else
llOwnerSay("2");
if (!a)
llOwnerSay("3");
else
llOwnerSay("4");
}
}

View file

@ -0,0 +1 @@
main.py -O -ifelseswap -

View file

@ -17,10 +17,10 @@ if ((key)((string)a)) ; else llDie();
if (<a,0,0>) ; else llDie(); if (<a,0,0>) ; else llDie();
if (<a,0,0,1>) ; else llDie(); if (<a,0,0,1>) ; else llDie();
if ((list)a) ; else llDie(); if ((list)a) ; else llDie();
if (!a) llDie(); else llOwnerSay("ok"); if (!a) llDie(); else llOwnerSay("1");
if (a == 3) llDie(); else llOwnerSay("ok"); if (a == 3) llDie(); else llOwnerSay("2");
if (a > 5) if (a == 12) ; else llDie(); else llOwnerSay("ok"); if (a > 5) if (a == 12) ; else llDie(); else llOwnerSay("3");
if (a == 12) llOwnerSay("1"); else if (a > 5) llOwnerSay("2"); if (a == 12) llOwnerSay("4"); else if (a > 5) llOwnerSay("5");
if (a > 5) if (a == 12) ; else /*@f1*/; else llDie(); if (a > 5) if (a == 12) ; else /*@f1*/; else llDie();
if (a == 12) llDie(); else if (a > 5) /*@f4*/; if (a == 12) llDie(); else if (a > 5) /*@f4*/;
// Fixed: Regression: this produces if (!(a == 3)) and no optimization kicks in // Fixed: Regression: this produces if (!(a == 3)) and no optimization kicks in

View file

@ -22,11 +22,11 @@ default
if ((list)a == []) if ((list)a == [])
llDie(); llDie();
if (a) if (a)
llOwnerSay("ok"); llOwnerSay("1");
else else
llDie(); llDie();
if (a ^ 3) if (a ^ 3)
llOwnerSay("ok"); llOwnerSay("2");
else else
llDie(); llDie();
if (5 < a) if (5 < a)
@ -35,14 +35,14 @@ default
llDie(); llDie();
} }
else else
llOwnerSay("ok"); llOwnerSay("3");
if (a ^ 12) if (a ^ 12)
{ {
if (5 < a) if (5 < a)
llOwnerSay("2"); llOwnerSay("5");
} }
else else
llOwnerSay("1"); llOwnerSay("4");
if (a < 6) if (a < 6)
llDie(); llDie();
if (a == 12) if (a == 12)