# HG changeset patch # User Paul Boddie # Date 1315679370 -7200 # Node ID 835c936bfd461b66dd3be47ee17352c336686e9b # Parent b79edd6601da5ae85085db4ac05ae21071f2fc98 Fixed vacuuming to avoid removing objects referenced by more than one name in a namespace. Changed the strict constant check on attributes to permit Constant subclasses. Extended the no-operation test to check for load operations immediately after store operations. Removed the active value instruction properly when requested. Improved docstrings and instruction string representations. diff -r b79edd6601da -r 835c936bfd46 micropython/common.py --- a/micropython/common.py Thu Sep 08 00:33:33 2011 +0200 +++ b/micropython/common.py Sat Sep 10 20:29:30 2011 +0200 @@ -264,7 +264,8 @@ """ Return for the given attribute 'usage', using the 'objtable', the object types which satisfy such usage, reporting any problems for the given 'name' - and 'unit_name'. + and 'unit_name'. Each object type is given as a tuple of the form (type, + is_static). """ all_objtypes = set() diff -r b79edd6601da -r 835c936bfd46 micropython/data.py --- a/micropython/data.py Thu Sep 08 00:33:33 2011 +0200 +++ b/micropython/data.py Sat Sep 10 20:29:30 2011 +0200 @@ -977,7 +977,7 @@ """ value = self.get_value() - return not (value is None or isinstance(value, Instance)) + return not (value is None or (isinstance(value, Instance) and not isinstance(value, Constant))) def is_static_attribute(self): diff -r b79edd6601da -r 835c936bfd46 micropython/inspect.py --- a/micropython/inspect.py Thu Sep 08 00:33:33 2011 +0200 +++ b/micropython/inspect.py Sat Sep 10 20:29:30 2011 +0200 @@ -194,6 +194,24 @@ "Vacuum the given object 'obj'." + # Get all constant objects in apparent use. + + if delete_all: + obj_objects = set() + else: + obj_objects = [] + for name, attr in obj.items_for_vacuum(): + + # Get constant objects for attributes in use. + + if self.importer.uses_attribute(obj.full_name(), name) and \ + attr is not None and attr.is_constant(): + + value = attr.get_value() + obj_objects.append(value) + + # Now vacuum unused attributes and objects not in use. + for name, attr in obj.items_for_vacuum(): # Only consider deleting entire unused objects or things accessible @@ -206,12 +224,15 @@ # have been defined within the object and therefore are not # redefined by other code regions. - if attr is not None and attr.assignments == 1: + if attr is not None and attr.is_constant(): value = attr.get_value() # The value must have this object as a parent. + # However, it must not be shared by several names. - if value is not obj and value.parent is obj and value in self.all_objects: + if value is not obj and value.parent is obj and \ + value in self.all_objects and value not in obj_objects: + self.all_objects.remove(value) # Delete class contents and lambdas from functions. @@ -462,6 +483,11 @@ def _visitAttr(self, expr, attrname, node): + """ + Process the attribute provided by the given 'expr' with the given + 'attrname' and involving the given 'node'. + """ + # Attempt to identify the nature of the attribute. if isinstance(expr, Attr): diff -r b79edd6601da -r 835c936bfd46 micropython/opt.py --- a/micropython/opt.py Thu Sep 08 00:33:33 2011 +0200 +++ b/micropython/opt.py Sat Sep 10 20:29:30 2011 +0200 @@ -137,8 +137,8 @@ """ if self.active in self.active_values: - removed = self.active - self.translation.remove_op() + removed = self.translation.remove_op() + self.active_values.remove(removed) return removed else: return None @@ -239,7 +239,8 @@ # NOTE: locals/frames. return isinstance(instruction, (StoreAddress, StoreAddressContext)) and \ - instruction.attr.assignments == 1 + instruction.attr.is_constant() and \ + instruction.attr.is_strict_constant() def is_simple_input(self, instruction): @@ -263,8 +264,11 @@ last_op = last_op or self.translation.last_op() return last_op and last_op.attr == instruction.attr and ( isinstance(instruction, StoreTemp) and isinstance(last_op, LoadTemp) or - isinstance(instruction, StoreAddress) and isinstance(last_op, LoadAddress) - ) + isinstance(instruction, StoreAddress) and isinstance(last_op, LoadAddress) or + last_op.source == instruction.target and ( + isinstance(instruction, LoadTemp) and isinstance(last_op, StoreTemp) or + isinstance(instruction, LoadAddress) and isinstance(last_op, StoreAddress) + )) # Convenience tests on outputs. @@ -335,7 +339,7 @@ # Optimisation methods. See the supported_optimisations class attribute. - def optimise_constant_storage(self, expr=None): + def optimise_constant_storage(self, expr): """ Where the last operation stores a constant into a target which is also diff -r b79edd6601da -r 835c936bfd46 micropython/rsvp.py --- a/micropython/rsvp.py Thu Sep 08 00:33:33 2011 +0200 +++ b/micropython/rsvp.py Sat Sep 10 20:29:30 2011 +0200 @@ -334,7 +334,7 @@ def format_operand(self): operand = self.get_operand() - return repr(operand) + return operand is not None and repr(operand) or "" def format_working(self): return self.working != self.default_working and (", working=%r" % self.working) or ""