micropython

Annotated TO_DO.txt

647:8431cd5ebc65
2013-04-28 Paul Boddie Added a parent type attribute to instance attribute objects. syspython-as-target
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@631 26
Ambiguous/Multiple Class/Function Definitions
paul@631 27
=============================================
paul@631 28
paul@631 29
Classes and functions are not supposed to have multiple definitions, where one code path
paul@631 30
may define one form of a class or function with a given name and another code path may
paul@631 31
define another form with that name. Currently, such multiple definitions are treated like
paul@631 32
"unions" in the object table.
paul@631 33
paul@635 34
  Consider functions as well as classes which are supported using "shadow" names for the
paul@635 35
  second and subsequent definitions of classes in the same namespace.
paul@635 36
paul@417 37
Class and Module Attribute Assignment
paul@417 38
=====================================
paul@417 39
paul@557 40
Allow unrestricted class and module assignment (but not new external binding of
paul@557 41
attributes), eliminating run-time checks on object types in instructions like
paul@557 42
StoreAttrIndex. This may involve less specific objects being identified during inspection.
paul@557 43
paul@568 44
  Potentially re-evaluate class bases in order to see if they are non-constant.
paul@568 45
paul@417 46
Verify that the context information is correctly set, particularly for the unoptimised
paul@417 47
cases.
paul@417 48
paul@417 49
  Update docs/assignment.txt.
paul@417 50
paul@431 51
Prevent assignments within classes, such as method aliasing, from causing the source of an
paul@431 52
assignment from being automatically generated. Instead, only external references should be
paul@431 53
registered.
paul@431 54
paul@431 55
Prevent "from <module> import ..." statements from registering references to such local
paul@431 56
aliases such that they cause the source of each alias to be automatically generated.
paul@431 57
paul@419 58
Consider attribute assignment observations, along with the possibility of class and module
paul@419 59
attribute assignment.
paul@419 60
paul@419 61
  (Note direct assignments as usual, indirect assignments via the attribute usage
paul@419 62
  mechanism. During attribute collection and inference, add assigned values to all
paul@419 63
  inferred targets.)
paul@419 64
paul@419 65
  (Since class attributes can be assigned, StoreAttrIndex would no longer need to reject
paul@419 66
  static attributes, although this might still be necessary where attribute usage analysis
paul@419 67
  has not been performed.)
paul@419 68
paul@419 69
  Potentially consider changing static attribute details to use object-relative offsets in
paul@419 70
  order to simplify the instruction implementations. This might allow us to eliminate the
paul@419 71
  static attribute flag for attributes in the object table, at least at run-time.
paul@419 72
paul@413 73
Dynamic Attribute Access
paul@413 74
========================
paul@413 75
paul@425 76
Consider explicit accessor initialisation:
paul@425 77
paul@425 78
  attr = accessor("attr")
paul@425 79
  getattr(C, attr)
paul@413 80
paul@394 81
Attribute Usage
paul@394 82
===============
paul@394 83
paul@498 84
To consider: is it useful to distinguish between attribute name sets when the same names
paul@498 85
are mentioned, but where one path through the code sets different values on attributes
paul@498 86
than another? The _attrtypes collapses observations in order to make a list of object
paul@498 87
types for a name, and the final set of names leading to such type deductions might be a
paul@498 88
useful annotation to be added alongside _attrcombined.
paul@498 89
paul@613 90
  (Update the reports to group identical sets of attribute names.)
paul@613 91
paul@613 92
Attribute usage on attributes might be possible if one can show that the expression of an
paul@613 93
attribute access is constant and that the attribute target is also constant or only refers
paul@613 94
to a single type. For example, in the sys module:
paul@613 95
paul@613 96
  stderr = file()
paul@613 97
paul@613 98
If no work is done to associate the result of the invocation with the stderr name, then
paul@613 99
one could instead at least attempt to determine whether stderr is assigned only once. If
paul@613 100
so, it might be possible to record attribute usage on references to the name. For example:
paul@613 101
paul@613 102
  sys.stderr.write(...) # sys.stderr supports write -> {file, ...}
paul@575 103
paul@498 104
Interface/Type Generalisation
paul@498 105
-----------------------------
paul@498 106
paul@480 107
Consolidate interface observations by taking all cached table accesses and determining
paul@480 108
which usage patterns lead to the same types. For example, if full usage of {a, b} and
paul@480 109
{a, b, c} leads to A and B in both cases, either {a, b} can be considered as partial usage
paul@480 110
of the complete interface {a, b, c}, or the latter can be considered as an
paul@480 111
overspecification of the former.
paul@480 112
paul@364 113
Consider type deduction and its consequences where types belong to the same hierarchy
paul@364 114
and where a guard could be generated for the most general type.
paul@364 115
paul@364 116
Consider permitting multiple class alternatives where the attributes are all identical.
paul@364 117
paul@360 118
Support class attribute positioning similar to instance attribute positioning, potentially
paul@360 119
(for both) based on usage observations. For example, if __iter__ is used on two classes,
paul@360 120
the class attribute could be exposed at a similar relative position to the class (and
paul@360 121
potentially accessible using a LoadAttr-style instruction).
paul@360 122
paul@394 123
**** Constant attribute users need not maintain usage since they are already resolved. ****
paul@394 124
paul@613 125
Self-Related Usage
paul@498 126
------------------
paul@498 127
paul@498 128
Perform attribute usage on attributes of self as names, potentially combining observations
paul@498 129
across methods.
paul@498 130
paul@498 131
Additional Guards
paul@498 132
-----------------
paul@498 133
paul@498 134
Consider handling branches of values within namespaces in order to support more precise value usage.
paul@498 135
paul@498 136
Loop entry points and other places where usage becomes more specific might be used as
paul@498 137
places to impose guards. See tests/attribute_access_type_restriction_loop_list.py for an
paul@498 138
example. (Such information is already shown in the reports.)
paul@498 139
paul@498 140
Strict Interfaces/Types
paul@498 141
-----------------------
paul@498 142
paul@498 143
Make the gathering of usage parameterisable according to the optimisation level so that a
paul@498 144
choice can be made between control-flow-dependent observations and the simple collection
paul@498 145
of all attributes used with a name (producing a more static interface observation).
paul@498 146
paul@498 147
AttributeError
paul@498 148
--------------
paul@498 149
paul@504 150
Consider attribute usage observations being suspended or optional inside blocks where
paul@504 151
AttributeError may be caught (although this doesn't anticipate such exceptions being
paul@504 152
caught outside a function altogether). For example:
paul@504 153
paul@504 154
  y = a.y
paul@504 155
  try:
paul@504 156
      z = a.z # z is an optional attribute
paul@504 157
  except AttributeError:
paul@504 158
      z = None
paul@498 159
paul@394 160
Frame Optimisations
paul@394 161
===================
paul@394 162
paul@394 163
Stack frame replacement where a local frame is unused after a call, such as in a tail call
paul@394 164
situation.
paul@394 165
paul@394 166
Local assignment detection plus frame re-use. Example: slice.__init__ calls
paul@394 167
xrange.__init__ with the same arguments which are unchanged in xrange.__init__. There is
paul@419 168
therefore no need to build a new frame for this call, although in some cases the locals
paul@419 169
frame might need expanding.
paul@419 170
paul@456 171
Reference tracking where objects associated with names are assigned to attributes of other
paul@456 172
objects may assist in allocation optimisations. Recording whether an object referenced by
paul@456 173
a name is assigned to an attribute, propagated to another name and assigned to an
paul@456 174
attribute, or passed to another function or method might, if such observations were
paul@456 175
combined, allow frame-based or temporary allocation to occur.
paul@456 176
paul@620 177
Instantiation Deduction
paul@620 178
=======================
paul@620 179
paul@620 180
Consider handling Const, List and Tuple in micropython.inspect in order to produce
paul@620 181
instances of specific classes. Then, consider adding support for guard
paul@620 182
removal/verification where known instances are involved. For example:
paul@620 183
paul@620 184
  l = []
paul@620 185
  l.append(123) # type deductions are filtered using instantiation knowledge
paul@620 186
paul@620 187
Currently, this is done only for Const values in the context of attribute accesses during
paul@620 188
inspection.
paul@620 189
paul@620 190
Handling CallFunc in a similar way is more challenging. Consider the definitions in the sys module:
paul@472 191
paul@620 192
  stderr = file()
paul@620 193
paul@620 194
It must first be established that file only ever refers to the built-in file class, and
paul@620 195
only then can the assumption be made that stderr in this case refers to instances of file.
paul@620 196
If file can also refer to other objects, potential filtering operations are more severely
paul@620 197
limited.
paul@620 198
paul@620 199
Invocation-Related Deduction
paul@620 200
============================
paul@620 201
paul@620 202
Where an attribute access (either in conjunction with usage observations or independently)
paul@620 203
could refer to a number of different targets, but where the resulting attribute is then
paul@620 204
used in an invocation, filtering of the targets could be done to eliminate any targets
paul@620 205
that are not callable. Guards would need introducing to prevent inappropriate operations
paul@620 206
from occurring at run-time.
paul@472 207
paul@419 208
Inlining
paul@419 209
========
paul@419 210
paul@419 211
Where a function or method call can always be determined, the body of the target could be
paul@419 212
inlined - copied into place - within the caller. If the target is only ever called by a
paul@456 213
single caller it could be moved into place. This could enhance deductions based on
paul@456 214
attribute usage since observations from the inlined function would be merged into the
paul@456 215
caller.
paul@394 216
paul@394 217
Function Specialisation
paul@394 218
=======================
paul@394 219
paul@394 220
Specialisation of certain functions, such as isinstance(x, cls) where cls is a known
paul@394 221
constant.
paul@394 222
paul@394 223
Structure and Object Table Optimisations
paul@394 224
========================================
paul@394 225
paul@394 226
Fix object table entries for attributes not provided by any known object, or provide an
paul@394 227
error, potentially overridden by options. For example, the augmented assignment methods
paul@394 228
are not supported by the built-in objects and thus the operator module functions cause
paul@394 229
the compilation to fail. Alternatively, just supply the methods since something has to do
paul@394 230
so in the builtins.
paul@394 231
paul@394 232
Consider attribute merging where many attributes are just aliases for the same underlying
paul@394 233
definition.
paul@394 234
paul@349 235
Consider references to defaults as occurring only within the context of a particular
paul@349 236
function, thus eliminating default value classes if such functions are not themselves
paul@349 237
invoked.
paul@349 238
paul@394 239
Scope Handling
paul@394 240
==============
paul@394 241
paul@394 242
Consider merging the InspectedModule.store tests with the scope conflict handling.
paul@394 243
paul@343 244
Consider labelling _scope on assignments and dealing with the assignment of removed
paul@343 245
attributes, possibly removing the entire assignment, and distinguishing between such cases
paul@343 246
and unknown names.
paul@343 247
paul@342 248
Check name origin where multiple branches could yield multiple scope interpretations:
paul@342 249
paul@504 250
  try:
paul@504 251
      set # built-in name
paul@504 252
  except NameError:
paul@504 253
      from sets import Set as set # local definition of name
paul@342 254
paul@504 255
  set # could be confused by the local definition at run-time
paul@342 256
paul@394 257
Object Coverage
paul@394 258
===============
paul@394 259
paul@332 260
Support __init__ traversal (and other implicit names) more effectively.
paul@332 261
paul@499 262
Importing Modules
paul@499 263
=================
paul@499 264
paul@499 265
Consider supporting relative imports, even though this is arguably a misfeature.
paul@499 266
paul@394 267
Other
paul@394 268
=====
paul@394 269
paul@482 270
Consider a separate annotation phase where deductions are added to the AST for the
paul@482 271
benefit of both the reporting and code generation phases.
paul@482 272
paul@332 273
Check context_value initialisation (avoiding or handling None effectively).
paul@332 274
paul@342 275
Consider better "macro" support where new expressions need to be generated and processed.
paul@402 276
paul@402 277
Detect TestIdentity results involving constants, potentially optimising status-affected
paul@402 278
instructions:
paul@402 279
paul@402 280
  TestIdentity(x, y) # where x is always y
paul@402 281
  JumpIfFalse(...)   # would be removed (never false)
paul@402 282
  JumpIfTrue(...)    # changed to Jump(...)
paul@402 283
paul@402 284
Status-affected blocks could be optimised away for such constant-related results.