1.1 --- a/micropython/opt.py Sun Aug 21 21:38:56 2011 +0200
1.2 +++ b/micropython/opt.py Sun Aug 21 23:59:52 2011 +0200
1.3 @@ -53,9 +53,9 @@
1.4
1.5 self.active = None
1.6
1.7 - # The instruction providing the active value.
1.8 + # Instructions providing the active value.
1.9
1.10 - self.active_value = None
1.11 + self.active_values = set()
1.12
1.13 def get_attribute_store_instructions(self):
1.14
1.15 @@ -75,12 +75,30 @@
1.16 None
1.17 )
1.18
1.19 - def reset(self):
1.20 + def reset(self, block=None, blocks=None):
1.21 +
1.22 + """
1.23 + Reset the optimiser for the given 'block' (or the current block),
1.24 + clearing the active value instructions if no 'blocks' are given, or
1.25 + collecting the active instructions from each of the blocks otherwise.
1.26 + """
1.27 +
1.28 + self.clear_active()
1.29 +
1.30 + # Make a new collection of instructions for a new block.
1.31
1.32 - "Reset the optimiser, clearing the active instructions."
1.33 + if block:
1.34 + self.active_values = set()
1.35 + block.set_active_values(self.active_values)
1.36 +
1.37 + # Otherwise, clear the collection for an existing block.
1.38
1.39 - self.clear_active_value()
1.40 - self.clear_active()
1.41 + else:
1.42 + self.active_values.clear()
1.43 +
1.44 + if blocks:
1.45 + for b in blocks:
1.46 + self.active_values.update(b.get_active_values())
1.47
1.48 def set_new(self, op):
1.49
1.50 @@ -94,13 +112,17 @@
1.51 "Set the value-providing active instruction."
1.52
1.53 if isinstance(op, current_value_instructions) and op.target == "working":
1.54 - self.active_value = op
1.55 + self.active_values.clear()
1.56 + self.active_values.add(op)
1.57
1.58 - def clear_active_value(self):
1.59 + def get_active_value(self):
1.60
1.61 - "Clear the value-providing active instruction."
1.62 + "Get any single active value or None if none or more than one exist."
1.63
1.64 - self.active_value = None
1.65 + if len(self.active_values) == 1:
1.66 + return list(self.active_values)[0]
1.67 + else:
1.68 + return None
1.69
1.70 def remove_active_value(self):
1.71
1.72 @@ -109,7 +131,7 @@
1.73 if appropriate, but keep a record of the active instruction itself.
1.74 """
1.75
1.76 - if self.active_value is self.active:
1.77 + if self.active in self.active_values:
1.78 removed = self.active
1.79 self.translation.remove_op()
1.80 return removed
1.81 @@ -120,8 +142,8 @@
1.82
1.83 "Set the target of the active instruction to 'target'."
1.84
1.85 - if self.active is not None:
1.86 - self.active.target = target
1.87 + for expr in self.active_values:
1.88 + expr.target = target
1.89
1.90 def set_active(self, op):
1.91
1.92 @@ -227,15 +249,13 @@
1.93
1.94 "Return whether the active instruction provides a constant input."
1.95
1.96 - return self.is_constant_input(self.active_value)
1.97 -
1.98 - have_known_target = have_constant_input
1.99 + return self.get_active_value() and self.is_constant_input(self.get_active_value())
1.100
1.101 def have_simple_input(self):
1.102
1.103 "Return whether the active instruction provides a simple input."
1.104
1.105 - return self.is_simple_input(self.active_value)
1.106 + return self.get_active_value() and self.is_simple_input(self.get_active_value())
1.107
1.108 def have_self_input(self, unit):
1.109
1.110 @@ -244,18 +264,16 @@
1.111 given 'unit'.
1.112 """
1.113
1.114 - return isinstance(unit, Function) and \
1.115 - unit.is_method() and isinstance(self.active_value, LoadName) and \
1.116 - self.active_value.attr.name == "self"
1.117 -
1.118 - def have_temp_compatible_access(self):
1.119 + if not (isinstance(unit, Function) and unit.is_method()):
1.120 + return 0
1.121
1.122 - """
1.123 - Indicate whether the active instruction can be used in place of access
1.124 - to a temporary variable retaining the result of the last instruction.
1.125 - """
1.126 + expr = self.get_active_value()
1.127 + return expr and isinstance(expr, LoadName) and expr.attr.name == "self"
1.128
1.129 - return isinstance(self.active_value, (LoadName, LoadTemp, LoadAddress, LoadConst, LoadClass, LoadFunction))
1.130 + # Indicate whether the active instruction can be used in place of access
1.131 + # to a temporary variable retaining the result of the last instruction.
1.132 +
1.133 + have_temp_compatible_access = have_simple_input
1.134
1.135 def have_correct_self_for_target(self, context, unit):
1.136
1.137 @@ -299,7 +317,7 @@
1.138 """
1.139
1.140 if self.should_optimise_constant_accessor() and self.have_constant_input():
1.141 - value = self.active_value
1.142 + value = self.get_active_value()
1.143
1.144 # Get the details of the access.
1.145
1.146 @@ -328,8 +346,8 @@
1.147 appropriate, get information about the specific initialiser.
1.148 """
1.149
1.150 - if self.should_optimise_known_target() and self.have_known_target():
1.151 - value = self.active_value
1.152 + if self.should_optimise_known_target() and self.have_constant_input():
1.153 + value = self.get_active_value()
1.154 target = value.attr.get_value()
1.155 context = value.attr.get_context()
1.156