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.
This commit is contained in:
Sei Lisa 2017-11-02 23:19:33 +01:00
parent 93828b9286
commit 1cdf9f7ff0
3 changed files with 22 additions and 12 deletions

View file

@ -106,6 +106,13 @@ class lastpass(object):
self.BadStCh = True self.BadStCh = True
return 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): def LastPassPostOrder(self, parent, index):
node = parent[index] node = parent[index]
nt = node['nt'] nt = node['nt']
@ -154,11 +161,14 @@ class lastpass(object):
self.subinfo = subinfo self.subinfo = subinfo
def LastPass(self): def LastPass(self):
"""Last optimizations pass"""
self.globalmode = False self.globalmode = False
tree = self.tree tree = self.tree
# Last optimizations pass self.usedlibfuncs = set()
# self.subinfo is subtree-local info. # self.subinfo is subtree-local info.
self.subinfo = {} self.subinfo = {}
for idx in xrange(len(tree)): for idx in xrange(len(tree)):
@ -168,4 +178,4 @@ class lastpass(object):
self.globalmode = False self.globalmode = False
else: else:
self.RecursiveLastPass(tree, idx) self.RecursiveLastPass(tree, idx)
pass return {'libfuncs':self.usedlibfuncs}

View file

@ -90,10 +90,10 @@ class optimizer(foldconst, renamer, deadcode, lastpass):
if self.constfold: if self.constfold:
self.FoldScript(warningpass=True) self.FoldScript(warningpass=True)
self.LastPass() names = self.LastPass()
if self.shrinknames: if self.shrinknames:
self.ShrinkNames() self.ShrinkNames(UsableAsParams = names['libfuncs'])
treesymtab = (self.tree, self.symtab) treesymtab = (self.tree, self.symtab)
del self.tree del self.tree

View file

@ -23,13 +23,9 @@
# #
# A side effect of this change is that the script becomes unreadable gibberish. # 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): class renamer(object):
CharSet1 = '_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' CharSet1 = '_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
CharSet2 = '0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' CharSet2 = '0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
# TODO: Derive these from builtins.txt somehow.
Kws = frozenset({'do', 'if', 'PI', Kws = frozenset({'do', 'if', 'PI',
'for', 'key', 'EOF', 'for', 'key', 'EOF',
'jump', 'else', 'list', 'TRUE', 'LOOP', 'case' '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: if ret not in self.Kws and ret not in self.UsedNames:
return ret return ret
def ShrinkNames(self): def ShrinkNames(self, UsableAsGlobals = None, UsableAsParams = None):
"""Implements the shrinknames option.""" """Implements the shrinknames option."""
self.WordFirstChar = 0 self.WordFirstChar = 0
self.WordRestOfChars = [] self.WordRestOfChars = []
@ -66,11 +62,13 @@ class renamer(object):
'System', 'UThread', 'UThreadStackFrame', 'Pop', 'System', 'UThread', 'UThreadStackFrame', 'Pop',
'IsRestoring', 'IsSaveDue', 'ResumeVoid', 'IsRestoring', 'IsSaveDue', 'ResumeVoid',
]) ])
if UsableAsGlobals is not None:
ReusableNames |= UsableAsGlobals
# Names from ReusableNames that have already been used # Names from ReusableNames that have already been used
self.UsedNames = set() 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 = [] globalvars = []
states = [] states = []
functions = [] functions = []
@ -89,8 +87,8 @@ class renamer(object):
assert False, 'Invalid kind at this scope: ' \ assert False, 'Invalid kind at this scope: ' \
+ kind # pragma: no cover + kind # pragma: no cover
# We make four passes, one for states, then functions, then globals, # We make four passes, one for states, then function names, then
# then parameter names and locals, in that order. # global names, then parameter names and locals, in that order.
# State names are usable as short identifiers for parameters. # State names are usable as short identifiers for parameters.
stateNames = [] stateNames = []
@ -159,6 +157,8 @@ class renamer(object):
# Do the same for function and event parameter names. Pure locals get # Do the same for function and event parameter names. Pure locals get
# long distinct names. # long distinct names.
if UsableAsParams is not None:
ReusableNames |= UsableAsParams
First = True First = True
restart = self.WordFirstChar restart = self.WordFirstChar
restartReusable = ReusableNames restartReusable = ReusableNames