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)