From 1cdf9f7ff00b4a91d004b16f108097b1a290423f Mon Sep 17 00:00:00 2001 From: Sei Lisa Date: Thu, 2 Nov 2017 23:19:33 +0100 Subject: [PATCH] Collect used library functions as reusable names for the renamer. Implements another TODO. There was a TODO about a new counter per scope, but that makes no sense. The renamer only acts on global variables, global function and parameter names, state names, and event parameters. We're already restarting the counters at every function, which is the closest to what that TODO was about. --- lslopt/lsllastpass.py | 14 ++++++++++++-- lslopt/lsloptimizer.py | 4 ++-- lslopt/lslrenamer.py | 16 ++++++++-------- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/lslopt/lsllastpass.py b/lslopt/lsllastpass.py index 8a9e5d9..af4ffed 100644 --- a/lslopt/lsllastpass.py +++ b/lslopt/lsllastpass.py @@ -106,6 +106,13 @@ class lastpass(object): self.BadStCh = True return + if nt == 'FNCALL': + # lslrenamer can benefit from a list of used library functions, + # so provide it. + if 'Loc' not in self.symtab[0][node['name']]: + # system library function + self.usedlibfuncs.add(node['name']) + def LastPassPostOrder(self, parent, index): node = parent[index] nt = node['nt'] @@ -154,11 +161,14 @@ class lastpass(object): self.subinfo = subinfo def LastPass(self): + """Last optimizations pass""" + self.globalmode = False tree = self.tree - # Last optimizations pass + self.usedlibfuncs = set() + # self.subinfo is subtree-local info. self.subinfo = {} for idx in xrange(len(tree)): @@ -168,4 +178,4 @@ class lastpass(object): self.globalmode = False else: self.RecursiveLastPass(tree, idx) - pass + return {'libfuncs':self.usedlibfuncs} diff --git a/lslopt/lsloptimizer.py b/lslopt/lsloptimizer.py index e8191ae..2952a02 100644 --- a/lslopt/lsloptimizer.py +++ b/lslopt/lsloptimizer.py @@ -90,10 +90,10 @@ class optimizer(foldconst, renamer, deadcode, lastpass): if self.constfold: self.FoldScript(warningpass=True) - self.LastPass() + names = self.LastPass() if self.shrinknames: - self.ShrinkNames() + self.ShrinkNames(UsableAsParams = names['libfuncs']) treesymtab = (self.tree, self.symtab) del self.tree diff --git a/lslopt/lslrenamer.py b/lslopt/lslrenamer.py index 7d0d876..60e3956 100644 --- a/lslopt/lslrenamer.py +++ b/lslopt/lslrenamer.py @@ -23,13 +23,9 @@ # # A side effect of this change is that the script becomes unreadable gibberish. -# TODO: Make a new counter per scope. -# TODO: Reuse used library function names for UDF and event parameters. - class renamer(object): CharSet1 = '_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' CharSet2 = '0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' - # TODO: Derive these from builtins.txt somehow. Kws = frozenset({'do', 'if', 'PI', 'for', 'key', 'EOF', 'jump', 'else', 'list', 'TRUE', 'LOOP', 'case' @@ -54,7 +50,7 @@ class renamer(object): if ret not in self.Kws and ret not in self.UsedNames: return ret - def ShrinkNames(self): + def ShrinkNames(self, UsableAsGlobals = None, UsableAsParams = None): """Implements the shrinknames option.""" self.WordFirstChar = 0 self.WordRestOfChars = [] @@ -66,11 +62,13 @@ class renamer(object): 'System', 'UThread', 'UThreadStackFrame', 'Pop', 'IsRestoring', 'IsSaveDue', 'ResumeVoid', ]) + if UsableAsGlobals is not None: + ReusableNames |= UsableAsGlobals # Names from ReusableNames that have already been used self.UsedNames = set() - # Make a first pass to separate the symbols into three categories. + # Make a preliminary pass to separate the symbols into three categories globalvars = [] states = [] functions = [] @@ -89,8 +87,8 @@ class renamer(object): assert False, 'Invalid kind at this scope: ' \ + kind # pragma: no cover - # We make four passes, one for states, then functions, then globals, - # then parameter names and locals, in that order. + # We make four passes, one for states, then function names, then + # global names, then parameter names and locals, in that order. # State names are usable as short identifiers for parameters. stateNames = [] @@ -159,6 +157,8 @@ class renamer(object): # Do the same for function and event parameter names. Pure locals get # long distinct names. + if UsableAsParams is not None: + ReusableNames |= UsableAsParams First = True restart = self.WordFirstChar restartReusable = ReusableNames