# HG changeset patch # User Paul Boddie # Date 1209336790 -7200 # Node ID 7afa1b5f52cee1ca43991b8c9aba5e1619a5047e # Parent d4884c5a16e970e3ce145758d8547fc419ddb084 Attempted to add optimisations around temporary storage access. diff -r d4884c5a16e9 -r 7afa1b5f52ce micropython/ast.py --- a/micropython/ast.py Sun Apr 27 21:05:55 2008 +0200 +++ b/micropython/ast.py Mon Apr 28 00:53:10 2008 +0200 @@ -48,7 +48,7 @@ "A translated module." - supported_optimisations = ["constant_storage", "known_target", "self_access"] + supported_optimisations = ["constant_storage", "known_target", "self_access", "temp_storage"] def __init__(self, module, importer, optimisations=None): @@ -255,6 +255,7 @@ return # Get the details of the access. + # NOTE: Support constants here. target = last.attr.value target_name = target.full_name() @@ -271,6 +272,8 @@ raise TranslateError(self.module.full_name(), node, "No attribute entry exists for name %r in target %r." % (attrname, target_name)) + # NOTE: Support constants here. + if isinstance(target, micropython.inspect.Instance): self.replace_op(AttrInstruction(pos)) else: @@ -547,6 +550,9 @@ def _should_optimise_self_access(self): return "self_access" in self.optimisations + def _should_optimise_temp_storage(self): + return "temp_storage" in self.optimisations + def _have_constant_input(self, n): last = self.last_ops(n+1) return len(last) > n and (isinstance(last[n], LoadAddress) and last[n].attr.assignments == 1 or @@ -561,8 +567,32 @@ self.unit.is_method() and isinstance(last, LoadName) and \ last.attr.name == "self" + def _have_temp_compatible_access(self): + last = self.last_op() + # NOTE: Should expand to cover LoadAttr and LoadAttrIndex, but this + # NOTE: would require inspection of the stack operands. + return isinstance(last, (LoadName, LoadTemp, LoadAddress)) + # Optimisation methods. See the supported_optimisations class attribute. + def _optimise_temp_storage(self): + + """ + Where the next operation would involve storing a value into temporary + storage, record and remove any simple instruction which produced the + value such that instead of subsequently accessing the temporary storage, + that instruction is substituted. + """ + + if self._should_optimise_temp_storage() and \ + self._have_temp_compatible_access(): + + last = self.last_op() + self.remove_ops(1) + return last + else: + return None + def _optimise_constant_storage(self, instruction, n): """ @@ -647,22 +677,31 @@ right_label = self.new_label() end_label = self.new_label() - # NOTE: Decide on temporary storage access. + # NOTE: Potentially remove the reservation if optimised storage is used. temp_position = self.reserve_temp(2) self.dispatch(node.left) - self.new_op(StoreTemp(temp_position)) + + temp1 = self._optimise_temp_storage() + if not temp1: + self.new_op(StoreTemp(temp_position)) + temp1 = LoadTemp(temp_position) + self.dispatch(node.right) - self.new_op(StoreTemp(temp_position + 1)) + + temp2 = self._optimise_temp_storage() + if not temp2: + self.new_op(StoreTemp(temp_position + 1)) + temp2 = LoadTemp(temp_position + 1) # Left method. self._startCallFunc() - self.new_op(LoadTemp(temp_position)) + self.new_op(temp1) self._generateAttr(node, left_method, (LoadAddress, LoadAttr, LoadAttrIndex)) - self.new_op(LoadTemp(temp_position)) # Explicit context as first argument. - self.new_op(LoadTemp(temp_position + 1)) + self.new_op(temp1) # Explicit context as first argument. + self.new_op(temp2) self._endCallFunc() self.dispatch(compiler.ast.Name("AttributeError")) @@ -673,10 +712,10 @@ self.set_label(right_label) self._startCallFunc() - self.new_op(LoadTemp(temp_position + 1)) + self.new_op(temp2) self._generateAttr(node, right_method, (LoadAddress, LoadAttr, LoadAttrIndex)) - self.new_op(LoadTemp(temp_position + 1)) # Explicit context as first argument. - self.new_op(LoadTemp(temp_position)) + self.new_op(temp2) # Explicit context as first argument. + self.new_op(temp1) self._endCallFunc() self.set_label(end_label)