From 1b3c8a4d89085b0bddd65661b5079315d85f7ab0 Mon Sep 17 00:00:00 2001 From: Sei Lisa Date: Sun, 6 Jan 2019 23:49:33 +0100 Subject: [PATCH] Check min and max to determine truth value of condition Also added some min/max values for a few functions. This allows optimizing things like: ! llGetNumberOfPrims() -> 0 --- fndata.txt | 9 +++++++ lslopt/lslfoldconst.py | 33 ++++++++++++++++++++---- unit_tests/regression.suite/boolexpr.lsl | 5 +++- unit_tests/regression.suite/boolexpr.out | 1 + 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/fndata.txt b/fndata.txt index fd14620..5c37e82 100644 --- a/fndata.txt +++ b/fndata.txt @@ -578,6 +578,7 @@ string llGetLinkName(integer linknumber) integer llGetLinkNumber() - SEF +- min 0 integer llGetLinkNumberOfSides(integer link) - SEF @@ -637,9 +638,12 @@ key llGetNumberOfNotecardLines(string name) integer llGetNumberOfPrims() - SEF +- min 1 integer llGetNumberOfSides() - SEF +- min 1 +- max 9 list llGetObjectAnimationNames() - SEF @@ -663,6 +667,9 @@ integer llGetObjectPermMask(integer mask) integer llGetObjectPrimCount(key object_id) - SEF +- min 0 +- max 256 +- return 0 if nulluuid(object_id) vector llGetOmega() # physics caveat @@ -684,12 +691,14 @@ integer llGetParcelFlags(vector pos) integer llGetParcelMaxPrims(vector pos, integer sim_wide) - SEF +- min 0 string llGetParcelMusicURL() - SEF integer llGetParcelPrimCount(vector pos, integer category, integer sim_wide) - SEF +- min 0 list llGetParcelPrimOwners(vector pos) - delay 2.0 diff --git a/lslopt/lslfoldconst.py b/lslopt/lslfoldconst.py index 277b125..b77405a 100644 --- a/lslopt/lslfoldconst.py +++ b/lslopt/lslfoldconst.py @@ -260,6 +260,27 @@ class foldconst(object): return (node.nt == 'NEG' and self.IsBool(node.ch[0]) or self.IsBool(node)) + def GetTruth(self, node): + """Decode truth value of node when possible. + Returns True if it's always true, False if it's always false, and None + if it can't be determined. + """ + if node.nt == 'CONST': + return lslfuncs.cond(node.value) + min = getattr(node, 'min', None) + max = getattr(node, 'max', None) + if min is None or max is None: + if node.nt == 'FNCALL': + min = self.symtab[0][node.name].get('min', min) + max = self.symtab[0][node.name].get('max', max) + if min is not None and min > 0: + return True + if max is not None and max < 0: + return True + if min == max == 0: + return False + return None + def FoldCond(self, parent, index, ParentIsNegation = False): """When we know that the parent is interested only in the truth value of the node, we can perform further optimizations. This function deals @@ -267,11 +288,13 @@ class foldconst(object): """ node = parent[index] nt = node.nt - if nt in ('CONST', 'IDENT', 'FLD'): - if node.nt == 'CONST': - node.t = 'integer' - node.value = 1 if lslfuncs.cond(node.value) else 0 - return # Nothing to do if it's already simplified. + truth = self.GetTruth(node) + if truth is not None and node.SEF: + parent[index] = nr(nt='CONST',t='integer',value=1 if truth else 0, + SEF=True) + return + if nt in ('IDENT', 'FLD'): + return # Nothing to do if it's already simplified. child = node.ch if nt == 'FNCALL' and 'strlen' in self.symtab[0][node.name]: diff --git a/unit_tests/regression.suite/boolexpr.lsl b/unit_tests/regression.suite/boolexpr.lsl index 185fc60..346aee7 100644 --- a/unit_tests/regression.suite/boolexpr.lsl +++ b/unit_tests/regression.suite/boolexpr.lsl @@ -4,7 +4,10 @@ if (llSameGroup(llGetOwner()) && llDetectedGroup(0)) llDie(); // TODO // llGetEnergy() has min=0 and max=1, therefore (integer)llGetEnergy() is bool, -// however we don't yet handle it. +// however we don't handle it yet (needs min and max applied to expressions). if ((integer)llGetEnergy() && llSameGroup(llGetOwner())) llDie(); +// Check that min and max work as they should. This is always true. +if (llGetNumberOfPrims()) llDie(); + }} diff --git a/unit_tests/regression.suite/boolexpr.out b/unit_tests/regression.suite/boolexpr.out index 88a59fe..e15561d 100644 --- a/unit_tests/regression.suite/boolexpr.out +++ b/unit_tests/regression.suite/boolexpr.out @@ -6,5 +6,6 @@ default llDie(); if ((integer)llGetEnergy() & -llSameGroup(llGetOwner())) llDie(); + llDie(); } }