diff --git a/lslopt/lslfoldconst.py b/lslopt/lslfoldconst.py index 8462a84..fa4259a 100644 --- a/lslopt/lslfoldconst.py +++ b/lslopt/lslfoldconst.py @@ -1796,7 +1796,7 @@ class foldconst(object): self.FoldTree(child, 2) self.FoldStmt(child, 2) # 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 # expression. # Swap 'if' and 'else' branch when the condition has diff --git a/lslopt/lsloptimizer.py b/lslopt/lsloptimizer.py index de915fb..a4af521 100644 --- a/lslopt/lsloptimizer.py +++ b/lslopt/lsloptimizer.py @@ -68,6 +68,7 @@ class optimizer(foldconst, renamer, deadcode, lastpass): self.shrinknames = 'shrinknames' in options self.constfold = 'constfold' in options + self.ifelseswap = 'ifelseswap' in options self.optlistlength = 'listlength' in options self.optlistadd = 'listadd' in options self.dcr = 'dcr' in options diff --git a/main.py b/main.py index 1428a38..6bbd6b9 100755 --- a/main.py +++ b/main.py @@ -326,6 +326,9 @@ Case insensitive. OptFloats + Optimize floats that represent an integral value. ConstFold + Fold constant expressions to their values, and simplify 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 of code that will never execute, and performs other optimizations like removal of unused variables, @@ -379,9 +382,9 @@ break/continue syntax extension (which is inactive by default). validoptions = frozenset({'extendedglobalexpr','breakcont','extendedtypecast', 'extendedassignment','allowkeyconcat','allowmultistrings','duplabels', 'lazylists','enableswitch','errmissingdefault','funcoverride','optimize', - 'optsigns','optfloats','constfold','dcr','shrinknames','addstrings', - 'foldtabs','warntabs','processpre','explicitcast','listlength','listadd', - 'inline', 'help', + 'optsigns','optfloats','constfold','ifelseswap','dcr','shrinknames', + 'addstrings','foldtabs','warntabs','processpre','explicitcast', + 'listlength','listadd','inline','help', # undocumented 'lso','expr','rsrclimit', # 'clear' is handled as a special case @@ -396,10 +399,10 @@ def main(argv): lslopt.lslcommon.DataPath = __file__[:-len(os.path.basename(__file__))] # Default options - options = set(('extendedglobalexpr','extendedtypecast','extendedassignment', - 'allowkeyconcat','allowmultistrings','processpre','warntabs','optimize', - 'optsigns','optfloats','constfold','dcr','errmissingdefault', - 'listlength','listadd', + options = set(('extendedglobalexpr','extendedtypecast', + 'extendedassignment','allowkeyconcat','allowmultistrings','processpre', + 'warntabs','optimize','optsigns','optfloats','constfold','ifelseswap', + 'dcr','errmissingdefault','listlength','listadd', )) assert not (options - validoptions), (u"Default options not present in" diff --git a/unit_tests/regression.suite/if-else-noswap.lsl b/unit_tests/regression.suite/if-else-noswap.lsl new file mode 100644 index 0000000..17f920c --- /dev/null +++ b/unit_tests/regression.suite/if-else-noswap.lsl @@ -0,0 +1,7 @@ +default{timer(){ + +integer a = llGetLinkNumber(); +if (a == 3) llOwnerSay("1"); else llOwnerSay("2"); +if (!a) llOwnerSay("3"); else llOwnerSay("4"); + +}} diff --git a/unit_tests/regression.suite/if-else-noswap.out b/unit_tests/regression.suite/if-else-noswap.out new file mode 100644 index 0000000..25f5beb --- /dev/null +++ b/unit_tests/regression.suite/if-else-noswap.out @@ -0,0 +1,15 @@ +default +{ + timer() + { + integer a = llGetLinkNumber(); + if (a == 3) + llOwnerSay("1"); + else + llOwnerSay("2"); + if (!a) + llOwnerSay("3"); + else + llOwnerSay("4"); + } +} diff --git a/unit_tests/regression.suite/if-else-noswap.run b/unit_tests/regression.suite/if-else-noswap.run new file mode 100644 index 0000000..49df1de --- /dev/null +++ b/unit_tests/regression.suite/if-else-noswap.run @@ -0,0 +1 @@ +main.py -O -ifelseswap - diff --git a/unit_tests/regression.suite/if-stmt.lsl b/unit_tests/regression.suite/if-stmt.lsl index 42b255f..62c430d 100644 --- a/unit_tests/regression.suite/if-stmt.lsl +++ b/unit_tests/regression.suite/if-stmt.lsl @@ -17,10 +17,10 @@ if ((key)((string)a)) ; else llDie(); if () ; else llDie(); if () ; else llDie(); if ((list)a) ; else llDie(); -if (!a) llDie(); else llOwnerSay("ok"); -if (a == 3) llDie(); else llOwnerSay("ok"); -if (a > 5) if (a == 12) ; else llDie(); else llOwnerSay("ok"); -if (a == 12) llOwnerSay("1"); else if (a > 5) llOwnerSay("2"); +if (!a) llDie(); else llOwnerSay("1"); +if (a == 3) llDie(); else llOwnerSay("2"); +if (a > 5) if (a == 12) ; else llDie(); else llOwnerSay("3"); +if (a == 12) llOwnerSay("4"); else if (a > 5) llOwnerSay("5"); if (a > 5) if (a == 12) ; else /*@f1*/; else llDie(); if (a == 12) llDie(); else if (a > 5) /*@f4*/; // Fixed: Regression: this produces if (!(a == 3)) and no optimization kicks in diff --git a/unit_tests/regression.suite/if-stmt.out b/unit_tests/regression.suite/if-stmt.out index 423e421..6ac0ffb 100644 --- a/unit_tests/regression.suite/if-stmt.out +++ b/unit_tests/regression.suite/if-stmt.out @@ -22,11 +22,11 @@ default if ((list)a == []) llDie(); if (a) - llOwnerSay("ok"); + llOwnerSay("1"); else llDie(); if (a ^ 3) - llOwnerSay("ok"); + llOwnerSay("2"); else llDie(); if (5 < a) @@ -35,14 +35,14 @@ default llDie(); } else - llOwnerSay("ok"); + llOwnerSay("3"); if (a ^ 12) { if (5 < a) - llOwnerSay("2"); + llOwnerSay("5"); } else - llOwnerSay("1"); + llOwnerSay("4"); if (a < 6) llDie(); if (a == 12)