1.1 --- a/micropython/opt.py Sun Aug 07 23:01:35 2011 +0200
1.2 +++ b/micropython/opt.py Sun Aug 21 14:24:28 2011 +0200
1.3 @@ -3,7 +3,7 @@
1.4 """
1.5 Optimise code produced by the AST translator.
1.6
1.7 -Copyright (C) 2007, 2008, 2009, 2010 Paul Boddie <paul@boddie.org.uk>
1.8 +Copyright (C) 2007, 2008, 2009, 2010, 2011 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 @@ -30,7 +30,7 @@
1.13 supported_optimisations = [
1.14 # Code generation optimisations:
1.15 "constant_storage", "constant_accessor", "known_target", "self_access",
1.16 - "temp_storage", "load_operations", "no_operations", "unused_results",
1.17 + "temp_storage", "no_operations", "unused_results",
1.18 "unused_handlers", "accesses_by_usage",
1.19 # Inspection optimisations:
1.20 "unused_objects"
1.21 @@ -93,7 +93,7 @@
1.22
1.23 "Set the value-providing active instruction."
1.24
1.25 - if isinstance(op, current_value_instructions):
1.26 + if isinstance(op, current_value_instructions) and op.target == "working":
1.27 self.active_value = op
1.28
1.29 def clear_active_value(self):
1.30 @@ -116,12 +116,12 @@
1.31 else:
1.32 return None
1.33
1.34 - def set_source(self, expr):
1.35 + def set_target(self, target):
1.36
1.37 - "Set the source of the active instruction to 'expr'."
1.38 + "Set the target of the active instruction to 'target'."
1.39
1.40 if self.active is not None:
1.41 - self.active.source = expr
1.42 + self.active.target = target
1.43
1.44 def set_active(self, op):
1.45
1.46 @@ -131,7 +131,7 @@
1.47
1.48 def clear_active(self):
1.49
1.50 - "Clear the active instruction."
1.51 + "Clear the active instructions."
1.52
1.53 self.active = None
1.54
1.55 @@ -152,9 +152,6 @@
1.56 def should_optimise_temp_storage(self):
1.57 return "temp_storage" in self.optimisations
1.58
1.59 - def should_optimise_load_operations(self):
1.60 - return "load_operations" in self.optimisations
1.61 -
1.62 def should_optimise_away_no_operations(self):
1.63 return "no_operations" in self.optimisations
1.64
1.65 @@ -196,19 +193,9 @@
1.66 """
1.67
1.68 return isinstance(instruction, (LoadConst, LoadClass, LoadFunction,
1.69 - LoadName, LoadTemp, LoadResultIntoValue, LoadException, LoadAddress
1.70 + LoadName, LoadTemp, LoadAddress
1.71 ))
1.72
1.73 - def is_simple_input_user(self, instruction):
1.74 -
1.75 - """
1.76 - Return whether 'instruction' can use simple input from the current
1.77 - value. Such instructions would, in a low-level implementation, be able
1.78 - to have the simple input registers as operands.
1.79 - """
1.80 -
1.81 - return isinstance(instruction, simple_input_user_instructions)
1.82 -
1.83 def is_resultant_no_operation(self, instruction):
1.84
1.85 """
1.86 @@ -217,17 +204,9 @@
1.87 """
1.88
1.89 return (
1.90 - isinstance(instruction.input, LoadTemp) and isinstance(instruction, StoreTemp) and
1.91 - instruction.input.attr == instruction.attr) or (
1.92 - isinstance(instruction.input, LoadResultIntoValue) and isinstance(instruction, LoadValueIntoResult)
1.93 + isinstance(instruction, StoreTemp) and instruction.target == instruction.source
1.94 )
1.95
1.96 - def is_input(self, instruction):
1.97 -
1.98 - "Return whether 'instruction' provides an input."
1.99 -
1.100 - return isinstance(instruction, current_value_instructions)
1.101 -
1.102 # Convenience tests on outputs.
1.103
1.104 def have_constant_target(self):
1.105 @@ -236,11 +215,11 @@
1.106
1.107 return self.is_constant_target(self.active)
1.108
1.109 - def have_constant_source(self):
1.110 + def have_constant_source(self, expr):
1.111
1.112 - "Return whether the active instruction has a constant source."
1.113 + "Return whether the active assignment source instruction is constant."
1.114
1.115 - return self.is_constant_input(self.active.source)
1.116 + return self.is_constant_input(expr)
1.117
1.118 # Convenience tests on inputs.
1.119
1.120 @@ -258,12 +237,6 @@
1.121
1.122 return self.is_simple_input(self.active_value)
1.123
1.124 - def have_input(self):
1.125 -
1.126 - "Return whether the active instruction provides an input."
1.127 -
1.128 - return self.is_input(self.active_value)
1.129 -
1.130 def have_self_input(self, unit):
1.131
1.132 """
1.133 @@ -282,12 +255,7 @@
1.134 to a temporary variable retaining the result of the last instruction.
1.135 """
1.136
1.137 - # LoadResultIntoValue cannot be relied upon in general since the result register
1.138 - # could be updated since first being referenced.
1.139 -
1.140 - return isinstance(self.active_value, (LoadName, LoadTemp, LoadAddress, LoadConst, LoadClass, LoadFunction)) or \
1.141 - isinstance(self.active_value, LoadResultIntoValue) and self.active_value is self.active or \
1.142 - isinstance(self.active_value, LoadException) and self.active_value is self.active
1.143 + return isinstance(self.active_value, (LoadName, LoadTemp, LoadAddress, LoadConst, LoadClass, LoadFunction))
1.144
1.145 def have_correct_self_for_target(self, context, unit):
1.146
1.147 @@ -312,7 +280,7 @@
1.148
1.149 # Optimisation methods. See the supported_optimisations class attribute.
1.150
1.151 - def optimise_constant_storage(self):
1.152 + def optimise_constant_storage(self, expr=None):
1.153
1.154 """
1.155 Where the last operation stores a constant into a target which is also
1.156 @@ -321,7 +289,7 @@
1.157
1.158 return self.should_optimise_constant_storage() and \
1.159 self.have_constant_target() and \
1.160 - self.have_constant_source()
1.161 + self.have_constant_source(expr)
1.162
1.163 def optimise_constant_accessor(self):
1.164
1.165 @@ -336,7 +304,7 @@
1.166 # Get the details of the access.
1.167
1.168 if isinstance(value.attr, Const):
1.169 - target_name = value.attr.value_type_name()
1.170 + return value.attr, value.attr.value_type_name()
1.171 else:
1.172 target = value.attr.get_value()
1.173
1.174 @@ -405,26 +373,14 @@
1.175 # Remove the active value contributor.
1.176
1.177 removed = self.remove_active_value()
1.178 -
1.179 - # Extend the lifetime of any temporary storage location.
1.180 + if removed is not None:
1.181
1.182 - self.translation.ensure_temp(removed)
1.183 - return removed
1.184 - else:
1.185 - return self.translation.get_temp()
1.186 -
1.187 - def optimise_load_operations(self, instruction):
1.188 + # Extend the lifetime of any temporary storage location.
1.189
1.190 - """
1.191 - Incorporate previous load operations into other operations.
1.192 - """
1.193 + self.translation.ensure_temp(removed)
1.194 + return removed
1.195
1.196 - if self.should_optimise_load_operations() and \
1.197 - self.have_simple_input() and \
1.198 - self.is_simple_input_user(instruction):
1.199 -
1.200 - self.remove_active_value()
1.201 - instruction.input = self.active_value
1.202 + return self.translation.get_temp()
1.203
1.204 def optimise_away_no_operations(self, instruction):
1.205