# HG changeset patch # User Paul Boddie # Date 1222624772 -7200 # Node ID 4ca9aa7a4cc3c950bf5255dd7ce4a2c1e58db126 # Parent 69e4ee444ea04fca9fcd9364400989dab8519fa5 Made the constant attribute accessor optimisation explicit. diff -r 69e4ee444ea0 -r 4ca9aa7a4cc3 docs/optimisations.txt --- a/docs/optimisations.txt Sun Sep 28 03:30:03 2008 +0200 +++ b/docs/optimisations.txt Sun Sep 28 19:59:32 2008 +0200 @@ -6,11 +6,17 @@ remove both instructions (currently a single merged instruction) +constant_accessor value instruction references a constant; +(guidance) target name provided (for use in producing an + address access instruction) + known_target value instruction references a constant; -(guidance) target and context are provided (no instructions removed) +(guidance) target and context are provided (no instructions + removed) self_access value instruction references "self" in a method; -(guidance) specified attribute name always has the same position; +(guidance) specified attribute name always has the same + position; appropriate instruction generated temp_storage value instruction is a simple input operation; diff -r 69e4ee444ea0 -r 4ca9aa7a4cc3 micropython/ast.py --- a/micropython/ast.py Sun Sep 28 03:30:03 2008 +0200 +++ b/micropython/ast.py Sun Sep 28 19:59:32 2008 +0200 @@ -395,50 +395,35 @@ # Where the last operation (defining the attribute owner) yields a # constant... - if self.optimiser.have_constant_input(): - last = self.optimiser.active_value - - # Get the details of the access. - - if isinstance(last.attr, Const): - target_name = last.attr.value_type_name() + target_name = self.optimiser.optimise_constant_accessor() + + # Only try and discover the position if the target can be resolved. + + if target_name is not None: + + # Access the object table to get the attribute position. + + try: + table_entry = self.objtable.table[target_name] + except KeyError: + raise TranslateError(self.module.full_name(), node, + "No object entry exists for target %r." % target_name) + + try: + pos = table_entry[attrname] + except KeyError: + raise TranslateError(self.module.full_name(), node, + "No attribute entry exists for name %r in target %r." % (attrname, target_name)) + + # Produce a suitable instruction. + + if AddressInstruction is not None: + self.replace_active_value(AddressInstruction(pos)) else: - target = last.attr.value - - if isinstance(target, Const): - target_name = target.value_type_name() - elif isinstance(target, Instance): - target_name = None # skip production of optimised code - else: - target_name = target.full_name() - - # Only try and discover the position if the target can be resolved. - - if target_name is not None: - - # Access the object table to get the attribute position. - - try: - table_entry = self.objtable.table[target_name] - except KeyError: - raise TranslateError(self.module.full_name(), node, - "No object entry exists for target %r." % target_name) - - try: - pos = table_entry[attrname] - except KeyError: - raise TranslateError(self.module.full_name(), node, - "No attribute entry exists for name %r in target %r." % (attrname, target_name)) - - # Produce a suitable instruction. - - if AddressInstruction is not None: - self.replace_active_value(AddressInstruction(pos)) - else: - raise TranslateError(self.module.full_name(), node, - "Storing of class or module attribute %r via an object is not permitted." % attrname) - - return + raise TranslateError(self.module.full_name(), node, + "Storing of class or module attribute %r via an object is not permitted." % attrname) + + return # Where the last operation involves the special 'self' name, check to # see if the attribute is acceptably positioned and produce a direct diff -r 69e4ee444ea0 -r 4ca9aa7a4cc3 micropython/opt.py --- a/micropython/opt.py Sun Sep 28 03:30:03 2008 +0200 +++ b/micropython/opt.py Sun Sep 28 19:59:32 2008 +0200 @@ -20,6 +20,7 @@ """ from micropython.common import * +from micropython.data import * from micropython.rsvp import * class Optimiser: @@ -27,9 +28,8 @@ "A code optimiser." supported_optimisations = [ - "constant_storage", "known_target", "self_access", - "temp_storage", "load_operations", "no_operations", - "unused_results" + "constant_storage", "constant_accessor", "known_target", "self_access", + "temp_storage", "load_operations", "no_operations", "unused_results" ] def __init__(self, translation, optimisations=None): @@ -115,6 +115,9 @@ def should_optimise_constant_storage(self): return "constant_storage" in self.optimisations + def should_optimise_constant_accessor(self): + return "constant_accessor" in self.optimisations + def should_optimise_known_target(self): return "known_target" in self.optimisations @@ -284,6 +287,33 @@ else: return 0 + def optimise_constant_accessor(self): + + """ + Where the object whose attribute is being accessed is constant, provide + information about its full name. + """ + + if self.should_optimise_constant_accessor() and self.have_constant_input(): + value = self.active_value + + # Get the details of the access. + + if isinstance(value.attr, Const): + target_name = value.attr.value_type_name() + else: + target = value.attr.value + + if isinstance(target, Const): + return target.value_type_name() + elif isinstance(target, Instance): + return None # skip production of optimised code + else: + return target.full_name() + + else: + return None + def optimise_known_target(self): """