1.1 --- a/optimiser.py Thu Jul 05 23:40:53 2018 +0200
1.2 +++ b/optimiser.py Wed Jul 11 18:33:51 2018 +0200
1.3 @@ -3,7 +3,7 @@
1.4 """
1.5 Optimise object layouts and generate access instruction plans.
1.6
1.7 -Copyright (C) 2014, 2015, 2016, 2017 Paul Boddie <paul@boddie.org.uk>
1.8 +Copyright (C) 2014, 2015, 2016, 2017, 2018 Paul Boddie <paul@boddie.org.uk>
1.9
1.10 This program is free software; you can redistribute it and/or modify it under
1.11 the terms of the GNU General Public License as published by the Free Software
1.12 @@ -413,6 +413,12 @@
1.13 finally:
1.14 f.close()
1.15
1.16 + def is_allocated_attribute(self, attrname):
1.17 +
1.18 + "Return whether 'attrname' is to be allocated in an object."
1.19 +
1.20 + return not attrname.startswith("$t")
1.21 +
1.22 def populate_objects(self):
1.23
1.24 "Populate objects using attribute and usage information."
1.25 @@ -432,8 +438,8 @@
1.26
1.27 # Remove temporary names from structures.
1.28
1.29 - attrnames = filter(lambda x: not x.startswith("$t"), attrnames)
1.30 - self.all_attrs[(objkind, name)] = attrnames
1.31 + attrnames = filter(self.is_allocated_attribute, attrnames)
1.32 + self.all_attrs[Reference(objkind, name)] = attrnames
1.33
1.34 try:
1.35 self.locations = get_allocated_locations(self.all_attrs,
1.36 @@ -495,8 +501,7 @@
1.37
1.38 # Record the structures.
1.39
1.40 - for (objkind, name), attrnames in self.all_attrs.items():
1.41 - key = Reference(objkind, name)
1.42 + for key, attrnames in self.all_attrs.items():
1.43 l = self.structures[key] = [None] * len(attrnames)
1.44
1.45 for attrname in attrnames:
1.46 @@ -719,7 +724,7 @@
1.47
1.48 """
1.49 Get attribute and size information for the object attributes defined by 'd'
1.50 - providing a mapping from (object kind, type name) to attribute names.
1.51 + providing a mapping from object references to attribute names.
1.52
1.53 Return a matrix of attributes (each row entry consisting of column values
1.54 providing attribute names, with value positions corresponding to types
1.55 @@ -736,15 +741,15 @@
1.56 sizes = {}
1.57 objkinds = {}
1.58
1.59 - for objtype, attrnames in d.items():
1.60 - objkind, _name = objtype
1.61 + for ref, attrnames in d.items():
1.62 + objkind = ref.get_kind()
1.63
1.64 for attrname in attrnames:
1.65
1.66 # Record each type supporting the attribute.
1.67
1.68 init_item(attrs, attrname, set)
1.69 - attrs[attrname].add(objtype)
1.70 + attrs[attrname].add(ref)
1.71
1.72 # Maintain a record of the smallest object size supporting the given
1.73 # attribute.
1.74 @@ -761,13 +766,13 @@
1.75
1.76 # Obtain attribute details in order of size and occupancy.
1.77
1.78 - all_objtypes = d.keys()
1.79 + all_refs = d.keys()
1.80
1.81 rsizes = []
1.82 for attrname, size in sizes.items():
1.83 priority = "<instance>" in objkinds[attrname] and 0.5 or 1
1.84 occupied = len(attrs[attrname])
1.85 - key = (priority * size, size, len(all_objtypes) - occupied, attrname)
1.86 + key = (priority * size, size, len(all_refs) - occupied, attrname)
1.87 rsizes.append(key)
1.88
1.89 rsizes.sort()
1.90 @@ -775,20 +780,20 @@
1.91 # Make a matrix of attributes.
1.92
1.93 matrix = {}
1.94 - for attrname, objtypes in attrs.items():
1.95 + for attrname, refs in attrs.items():
1.96
1.97 # Traverse the object types, adding the attribute name if the object
1.98 # type supports the attribute, adding None otherwise.
1.99
1.100 row = []
1.101 - for objtype in all_objtypes:
1.102 - if objtype in objtypes:
1.103 + for ref in all_refs:
1.104 + if ref in refs:
1.105 row.append(attrname)
1.106 else:
1.107 row.append(None)
1.108 matrix[attrname] = row
1.109
1.110 - return matrix, all_objtypes, rsizes
1.111 + return matrix, all_refs, rsizes
1.112
1.113 def get_parameters_and_sizes(d):
1.114