paul@472 | 1 | Name usage types: as parameters, as base classes, as callables. This potentially restricts
|
paul@472 | 2 | attribute usage effects because names mentioned as base classes are not propagated and
|
paul@472 | 3 | made freely available for use in attribute accesses.
|
paul@472 | 4 |
|
paul@419 | 5 | Low-Level Instructions and Macro Instructions
|
paul@419 | 6 | =============================================
|
paul@419 | 7 |
|
paul@429 | 8 | Have contexts and values stored separately in memory. This involves eliminating DataValue
|
paul@429 | 9 | and storing attributes using two words.
|
paul@429 | 10 |
|
paul@419 | 11 | Migrate macro instructions such as the *Index instructions to library code implemented
|
paul@419 | 12 | using low-level instructions.
|
paul@419 | 13 |
|
paul@419 | 14 | Consider introducing classic machine level instructions (word addition, subtraction, and
|
paul@419 | 15 | so on) in order to implement all current RSVP instructions.
|
paul@419 | 16 |
|
paul@450 | 17 | Move common code sequences to a library routine, such as the context checking that occurs
|
paul@450 | 18 | in functions and methods.
|
paul@450 | 19 |
|
paul@464 | 20 | Dataflow Optimisations
|
paul@464 | 21 | ======================
|
paul@450 | 22 |
|
paul@464 | 23 | Assignments, particularly now that no result register exists, may cause StoreTemp/LoadTemp
|
paul@464 | 24 | instruction pairs to be produced and these could be eliminated.
|
paul@450 | 25 |
|
paul@417 | 26 | Class and Module Attribute Assignment
|
paul@417 | 27 | =====================================
|
paul@417 | 28 |
|
paul@417 | 29 | Verify that the context information is correctly set, particularly for the unoptimised
|
paul@417 | 30 | cases.
|
paul@417 | 31 |
|
paul@417 | 32 | Update docs/assignment.txt.
|
paul@417 | 33 |
|
paul@431 | 34 | Prevent assignments within classes, such as method aliasing, from causing the source of an
|
paul@431 | 35 | assignment from being automatically generated. Instead, only external references should be
|
paul@431 | 36 | registered.
|
paul@431 | 37 |
|
paul@431 | 38 | Prevent "from <module> import ..." statements from registering references to such local
|
paul@431 | 39 | aliases such that they cause the source of each alias to be automatically generated.
|
paul@431 | 40 |
|
paul@419 | 41 | Consider attribute assignment observations, along with the possibility of class and module
|
paul@419 | 42 | attribute assignment.
|
paul@419 | 43 |
|
paul@419 | 44 | (Note direct assignments as usual, indirect assignments via the attribute usage
|
paul@419 | 45 | mechanism. During attribute collection and inference, add assigned values to all
|
paul@419 | 46 | inferred targets.)
|
paul@419 | 47 |
|
paul@419 | 48 | (Since class attributes can be assigned, StoreAttrIndex would no longer need to reject
|
paul@419 | 49 | static attributes, although this might still be necessary where attribute usage analysis
|
paul@419 | 50 | has not been performed.)
|
paul@419 | 51 |
|
paul@419 | 52 | Potentially consider changing static attribute details to use object-relative offsets in
|
paul@419 | 53 | order to simplify the instruction implementations. This might allow us to eliminate the
|
paul@419 | 54 | static attribute flag for attributes in the object table, at least at run-time.
|
paul@419 | 55 |
|
paul@413 | 56 | Dynamic Attribute Access
|
paul@413 | 57 | ========================
|
paul@413 | 58 |
|
paul@425 | 59 | Consider explicit accessor initialisation:
|
paul@425 | 60 |
|
paul@425 | 61 | attr = accessor("attr")
|
paul@425 | 62 | getattr(C, attr)
|
paul@413 | 63 |
|
paul@394 | 64 | Attribute Usage
|
paul@394 | 65 | ===============
|
paul@394 | 66 |
|
paul@480 | 67 | Consolidate interface observations by taking all cached table accesses and determining
|
paul@480 | 68 | which usage patterns lead to the same types. For example, if full usage of {a, b} and
|
paul@480 | 69 | {a, b, c} leads to A and B in both cases, either {a, b} can be considered as partial usage
|
paul@480 | 70 | of the complete interface {a, b, c}, or the latter can be considered as an
|
paul@480 | 71 | overspecification of the former.
|
paul@480 | 72 |
|
paul@472 | 73 | Make the gathering of usage parameterisable according to the optimisation level so that a
|
paul@472 | 74 | choice can be made between control-flow-dependent observations and the simple collection
|
paul@472 | 75 | of all attributes used with a name (producing a more static interface observation).
|
paul@472 | 76 |
|
paul@472 | 77 | Usage of self to restrict attribute usage observations and coverage.
|
paul@472 | 78 |
|
paul@472 | 79 | Perform attribute usage on attributes of self as names, potentially combining observations
|
paul@472 | 80 | across methods.
|
paul@472 | 81 |
|
paul@445 | 82 | Loop entry points and other places where usage becomes more specific might be used as
|
paul@445 | 83 | places to impose guards. See tests/attribute_access_type_restriction_loop_list.py for an
|
paul@445 | 84 | example.
|
paul@445 | 85 |
|
paul@372 | 86 | Consider attribute usage observations being suspended inside blocks where AttributeError
|
paul@372 | 87 | may be caught (although this doesn't anticipate such exceptions being caught outside a
|
paul@372 | 88 | function altogether).
|
paul@372 | 89 |
|
paul@364 | 90 | Consider type deduction and its consequences where types belong to the same hierarchy
|
paul@364 | 91 | and where a guard could be generated for the most general type.
|
paul@364 | 92 |
|
paul@364 | 93 | Consider permitting multiple class alternatives where the attributes are all identical.
|
paul@364 | 94 |
|
paul@360 | 95 | Support class attribute positioning similar to instance attribute positioning, potentially
|
paul@360 | 96 | (for both) based on usage observations. For example, if __iter__ is used on two classes,
|
paul@360 | 97 | the class attribute could be exposed at a similar relative position to the class (and
|
paul@360 | 98 | potentially accessible using a LoadAttr-style instruction).
|
paul@360 | 99 |
|
paul@394 | 100 | **** Constant attribute users need not maintain usage since they are already resolved. ****
|
paul@394 | 101 |
|
paul@394 | 102 | Consider handling CallFunc in micropython.inspect in order to produce instances of specific classes.
|
paul@394 | 103 | Then, consider adding support for guard removal/verification where known instances are involved.
|
paul@394 | 104 | Consider handling branches of values within namespaces in order to support more precise value usage.
|
paul@394 | 105 |
|
paul@394 | 106 | Frame Optimisations
|
paul@394 | 107 | ===================
|
paul@394 | 108 |
|
paul@394 | 109 | Stack frame replacement where a local frame is unused after a call, such as in a tail call
|
paul@394 | 110 | situation.
|
paul@394 | 111 |
|
paul@394 | 112 | Local assignment detection plus frame re-use. Example: slice.__init__ calls
|
paul@394 | 113 | xrange.__init__ with the same arguments which are unchanged in xrange.__init__. There is
|
paul@419 | 114 | therefore no need to build a new frame for this call, although in some cases the locals
|
paul@419 | 115 | frame might need expanding.
|
paul@419 | 116 |
|
paul@456 | 117 | Reference tracking where objects associated with names are assigned to attributes of other
|
paul@456 | 118 | objects may assist in allocation optimisations. Recording whether an object referenced by
|
paul@456 | 119 | a name is assigned to an attribute, propagated to another name and assigned to an
|
paul@456 | 120 | attribute, or passed to another function or method might, if such observations were
|
paul@456 | 121 | combined, allow frame-based or temporary allocation to occur.
|
paul@456 | 122 |
|
paul@472 | 123 | Instantiation
|
paul@472 | 124 | =============
|
paul@472 | 125 |
|
paul@472 | 126 | Specific instances could be produced, providing type information and acting somewhat like
|
paul@472 | 127 | classes during inspection.
|
paul@472 | 128 |
|
paul@419 | 129 | Inlining
|
paul@419 | 130 | ========
|
paul@419 | 131 |
|
paul@419 | 132 | Where a function or method call can always be determined, the body of the target could be
|
paul@419 | 133 | inlined - copied into place - within the caller. If the target is only ever called by a
|
paul@456 | 134 | single caller it could be moved into place. This could enhance deductions based on
|
paul@456 | 135 | attribute usage since observations from the inlined function would be merged into the
|
paul@456 | 136 | caller.
|
paul@394 | 137 |
|
paul@394 | 138 | Function Specialisation
|
paul@394 | 139 | =======================
|
paul@394 | 140 |
|
paul@394 | 141 | Specialisation of certain functions, such as isinstance(x, cls) where cls is a known
|
paul@394 | 142 | constant.
|
paul@394 | 143 |
|
paul@394 | 144 | Structure and Object Table Optimisations
|
paul@394 | 145 | ========================================
|
paul@394 | 146 |
|
paul@394 | 147 | Fix object table entries for attributes not provided by any known object, or provide an
|
paul@394 | 148 | error, potentially overridden by options. For example, the augmented assignment methods
|
paul@394 | 149 | are not supported by the built-in objects and thus the operator module functions cause
|
paul@394 | 150 | the compilation to fail. Alternatively, just supply the methods since something has to do
|
paul@394 | 151 | so in the builtins.
|
paul@394 | 152 |
|
paul@394 | 153 | Consider attribute merging where many attributes are just aliases for the same underlying
|
paul@394 | 154 | definition.
|
paul@394 | 155 |
|
paul@349 | 156 | Consider references to defaults as occurring only within the context of a particular
|
paul@349 | 157 | function, thus eliminating default value classes if such functions are not themselves
|
paul@349 | 158 | invoked.
|
paul@349 | 159 |
|
paul@394 | 160 | Scope Handling
|
paul@394 | 161 | ==============
|
paul@394 | 162 |
|
paul@394 | 163 | Consider merging the InspectedModule.store tests with the scope conflict handling.
|
paul@394 | 164 |
|
paul@343 | 165 | Consider labelling _scope on assignments and dealing with the assignment of removed
|
paul@343 | 166 | attributes, possibly removing the entire assignment, and distinguishing between such cases
|
paul@343 | 167 | and unknown names.
|
paul@343 | 168 |
|
paul@342 | 169 | Check name origin where multiple branches could yield multiple scope interpretations:
|
paul@342 | 170 |
|
paul@342 | 171 | ----
|
paul@342 | 172 | try:
|
paul@342 | 173 | set # built-in name
|
paul@342 | 174 | except NameError:
|
paul@342 | 175 | from sets import Set as set # local definition of name
|
paul@342 | 176 |
|
paul@342 | 177 | set # could be confused by the local definition at run-time
|
paul@342 | 178 | ----
|
paul@342 | 179 |
|
paul@394 | 180 | Object Coverage
|
paul@394 | 181 | ===============
|
paul@394 | 182 |
|
paul@332 | 183 | Support __init__ traversal (and other implicit names) more effectively.
|
paul@332 | 184 |
|
paul@394 | 185 | Other
|
paul@394 | 186 | =====
|
paul@394 | 187 |
|
paul@482 | 188 | Consider a separate annotation phase where deductions are added to the AST for the
|
paul@482 | 189 | benefit of both the reporting and code generation phases.
|
paul@482 | 190 |
|
paul@449 | 191 | Support self attribute visualisation in the reports and/or provide a function or
|
paul@449 | 192 | annotations which can provide the eventual optimisation directly to such components.
|
paul@408 | 193 |
|
paul@332 | 194 | Check context_value initialisation (avoiding or handling None effectively).
|
paul@332 | 195 |
|
paul@342 | 196 | Consider better "macro" support where new expressions need to be generated and processed.
|
paul@402 | 197 |
|
paul@402 | 198 | Detect TestIdentity results involving constants, potentially optimising status-affected
|
paul@402 | 199 | instructions:
|
paul@402 | 200 |
|
paul@402 | 201 | TestIdentity(x, y) # where x is always y
|
paul@402 | 202 | JumpIfFalse(...) # would be removed (never false)
|
paul@402 | 203 | JumpIfTrue(...) # changed to Jump(...)
|
paul@402 | 204 |
|
paul@402 | 205 | Status-affected blocks could be optimised away for such constant-related results.
|