1.1 --- a/micropython/ast.py Sun Apr 27 21:05:55 2008 +0200
1.2 +++ b/micropython/ast.py Mon Apr 28 00:53:10 2008 +0200
1.3 @@ -48,7 +48,7 @@
1.4
1.5 "A translated module."
1.6
1.7 - supported_optimisations = ["constant_storage", "known_target", "self_access"]
1.8 + supported_optimisations = ["constant_storage", "known_target", "self_access", "temp_storage"]
1.9
1.10 def __init__(self, module, importer, optimisations=None):
1.11
1.12 @@ -255,6 +255,7 @@
1.13 return
1.14
1.15 # Get the details of the access.
1.16 + # NOTE: Support constants here.
1.17
1.18 target = last.attr.value
1.19 target_name = target.full_name()
1.20 @@ -271,6 +272,8 @@
1.21 raise TranslateError(self.module.full_name(), node,
1.22 "No attribute entry exists for name %r in target %r." % (attrname, target_name))
1.23
1.24 + # NOTE: Support constants here.
1.25 +
1.26 if isinstance(target, micropython.inspect.Instance):
1.27 self.replace_op(AttrInstruction(pos))
1.28 else:
1.29 @@ -547,6 +550,9 @@
1.30 def _should_optimise_self_access(self):
1.31 return "self_access" in self.optimisations
1.32
1.33 + def _should_optimise_temp_storage(self):
1.34 + return "temp_storage" in self.optimisations
1.35 +
1.36 def _have_constant_input(self, n):
1.37 last = self.last_ops(n+1)
1.38 return len(last) > n and (isinstance(last[n], LoadAddress) and last[n].attr.assignments == 1 or
1.39 @@ -561,8 +567,32 @@
1.40 self.unit.is_method() and isinstance(last, LoadName) and \
1.41 last.attr.name == "self"
1.42
1.43 + def _have_temp_compatible_access(self):
1.44 + last = self.last_op()
1.45 + # NOTE: Should expand to cover LoadAttr and LoadAttrIndex, but this
1.46 + # NOTE: would require inspection of the stack operands.
1.47 + return isinstance(last, (LoadName, LoadTemp, LoadAddress))
1.48 +
1.49 # Optimisation methods. See the supported_optimisations class attribute.
1.50
1.51 + def _optimise_temp_storage(self):
1.52 +
1.53 + """
1.54 + Where the next operation would involve storing a value into temporary
1.55 + storage, record and remove any simple instruction which produced the
1.56 + value such that instead of subsequently accessing the temporary storage,
1.57 + that instruction is substituted.
1.58 + """
1.59 +
1.60 + if self._should_optimise_temp_storage() and \
1.61 + self._have_temp_compatible_access():
1.62 +
1.63 + last = self.last_op()
1.64 + self.remove_ops(1)
1.65 + return last
1.66 + else:
1.67 + return None
1.68 +
1.69 def _optimise_constant_storage(self, instruction, n):
1.70
1.71 """
1.72 @@ -647,22 +677,31 @@
1.73 right_label = self.new_label()
1.74 end_label = self.new_label()
1.75
1.76 - # NOTE: Decide on temporary storage access.
1.77 + # NOTE: Potentially remove the reservation if optimised storage is used.
1.78
1.79 temp_position = self.reserve_temp(2)
1.80
1.81 self.dispatch(node.left)
1.82 - self.new_op(StoreTemp(temp_position))
1.83 +
1.84 + temp1 = self._optimise_temp_storage()
1.85 + if not temp1:
1.86 + self.new_op(StoreTemp(temp_position))
1.87 + temp1 = LoadTemp(temp_position)
1.88 +
1.89 self.dispatch(node.right)
1.90 - self.new_op(StoreTemp(temp_position + 1))
1.91 +
1.92 + temp2 = self._optimise_temp_storage()
1.93 + if not temp2:
1.94 + self.new_op(StoreTemp(temp_position + 1))
1.95 + temp2 = LoadTemp(temp_position + 1)
1.96
1.97 # Left method.
1.98
1.99 self._startCallFunc()
1.100 - self.new_op(LoadTemp(temp_position))
1.101 + self.new_op(temp1)
1.102 self._generateAttr(node, left_method, (LoadAddress, LoadAttr, LoadAttrIndex))
1.103 - self.new_op(LoadTemp(temp_position)) # Explicit context as first argument.
1.104 - self.new_op(LoadTemp(temp_position + 1))
1.105 + self.new_op(temp1) # Explicit context as first argument.
1.106 + self.new_op(temp2)
1.107 self._endCallFunc()
1.108
1.109 self.dispatch(compiler.ast.Name("AttributeError"))
1.110 @@ -673,10 +712,10 @@
1.111
1.112 self.set_label(right_label)
1.113 self._startCallFunc()
1.114 - self.new_op(LoadTemp(temp_position + 1))
1.115 + self.new_op(temp2)
1.116 self._generateAttr(node, right_method, (LoadAddress, LoadAttr, LoadAttrIndex))
1.117 - self.new_op(LoadTemp(temp_position + 1)) # Explicit context as first argument.
1.118 - self.new_op(LoadTemp(temp_position))
1.119 + self.new_op(temp2) # Explicit context as first argument.
1.120 + self.new_op(temp1)
1.121 self._endCallFunc()
1.122
1.123 self.set_label(end_label)