micropython

Annotated TO_DO.txt

769:54289e78af86
2013-12-08 Paul Boddie Moved the exceptions document into the low-level concepts document. 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@710 134
Consider handling branches of values within namespaces in order to support more precise
paul@710 135
value usage.
paul@498 136
paul@498 137
Loop entry points and other places where usage becomes more specific might be used as
paul@498 138
places to impose guards. See tests/attribute_access_type_restriction_loop_list.py for an
paul@498 139
example. (Such information is already shown in the reports.)
paul@498 140
paul@498 141
Strict Interfaces/Types
paul@498 142
-----------------------
paul@498 143
paul@498 144
Make the gathering of usage parameterisable according to the optimisation level so that a
paul@498 145
choice can be made between control-flow-dependent observations and the simple collection
paul@498 146
of all attributes used with a name (producing a more static interface observation).
paul@498 147
paul@498 148
AttributeError
paul@498 149
--------------
paul@498 150
paul@504 151
Consider attribute usage observations being suspended or optional inside blocks where
paul@504 152
AttributeError may be caught (although this doesn't anticipate such exceptions being
paul@504 153
caught outside a function altogether). For example:
paul@504 154
paul@504 155
  y = a.y
paul@504 156
  try:
paul@504 157
      z = a.z # z is an optional attribute
paul@504 158
  except AttributeError:
paul@504 159
      z = None
paul@498 160
paul@394 161
Frame Optimisations
paul@394 162
===================
paul@394 163
paul@394 164
Stack frame replacement where a local frame is unused after a call, such as in a tail call
paul@394 165
situation.
paul@394 166
paul@394 167
Local assignment detection plus frame re-use. Example: slice.__init__ calls
paul@394 168
xrange.__init__ with the same arguments which are unchanged in xrange.__init__. There is
paul@419 169
therefore no need to build a new frame for this call, although in some cases the locals
paul@419 170
frame might need expanding.
paul@419 171
paul@456 172
Reference tracking where objects associated with names are assigned to attributes of other
paul@456 173
objects may assist in allocation optimisations. Recording whether an object referenced by
paul@456 174
a name is assigned to an attribute, propagated to another name and assigned to an
paul@456 175
attribute, or passed to another function or method might, if such observations were
paul@456 176
combined, allow frame-based or temporary allocation to occur.
paul@456 177
paul@620 178
Instantiation Deduction
paul@620 179
=======================
paul@620 180
paul@620 181
Consider handling Const, List and Tuple in micropython.inspect in order to produce
paul@620 182
instances of specific classes. Then, consider adding support for guard
paul@620 183
removal/verification where known instances are involved. For example:
paul@620 184
paul@620 185
  l = []
paul@620 186
  l.append(123) # type deductions are filtered using instantiation knowledge
paul@620 187
paul@620 188
Currently, this is done only for Const values in the context of attribute accesses during
paul@620 189
inspection.
paul@620 190
paul@710 191
Handling CallFunc in a similar way is more challenging. Consider the definitions in the
paul@710 192
sys module:
paul@472 193
paul@620 194
  stderr = file()
paul@620 195
paul@620 196
It must first be established that file only ever refers to the built-in file class, and
paul@620 197
only then can the assumption be made that stderr in this case refers to instances of file.
paul@620 198
If file can also refer to other objects, potential filtering operations are more severely
paul@620 199
limited.
paul@620 200
paul@710 201
Propagation of type information can also occur. For example:
paul@710 202
paul@710 203
  DeducedSource(module, program).deduce()
paul@710 204
paul@710 205
The DeducedSource invocation, if yielding an instance of the DeducedSource class, can then
paul@710 206
supply the attribute access operation with type information.
paul@710 207
paul@710 208
A more advanced example involves accesses then invocations:
paul@710 209
paul@710 210
  x = self.__class__()
paul@710 211
paul@710 212
Here, the effect should be the inference that x may refer to an instance of one of a
paul@710 213
number of eligible types of which self is also an instance.
paul@710 214
paul@620 215
Invocation-Related Deduction
paul@620 216
============================
paul@620 217
paul@620 218
Where an attribute access (either in conjunction with usage observations or independently)
paul@620 219
could refer to a number of different targets, but where the resulting attribute is then
paul@620 220
used in an invocation, filtering of the targets could be done to eliminate any targets
paul@620 221
that are not callable. Guards would need introducing to prevent inappropriate operations
paul@620 222
from occurring at run-time.
paul@472 223
paul@419 224
Inlining
paul@419 225
========
paul@419 226
paul@419 227
Where a function or method call can always be determined, the body of the target could be
paul@419 228
inlined - copied into place - within the caller. If the target is only ever called by a
paul@456 229
single caller it could be moved into place. This could enhance deductions based on
paul@456 230
attribute usage since observations from the inlined function would be merged into the
paul@456 231
caller.
paul@394 232
paul@672 233
Distinguish between frame sharing and inlining: where a called function does not rebind
paul@672 234
its names, and where the frame of the caller is compatible, the frame of the caller might
paul@672 235
be shared with the called function even if a branch and return is still involved.
paul@672 236
paul@672 237
Suitable candidates for inlining, frame sharing or enhanced analysis might be lambdas and
paul@672 238
functions containing a single statement.
paul@672 239
paul@394 240
Function Specialisation
paul@394 241
=======================
paul@394 242
paul@394 243
Specialisation of certain functions, such as isinstance(x, cls) where cls is a known
paul@394 244
constant.
paul@394 245
paul@394 246
Structure and Object Table Optimisations
paul@394 247
========================================
paul@394 248
paul@394 249
Fix object table entries for attributes not provided by any known object, or provide an
paul@394 250
error, potentially overridden by options. For example, the augmented assignment methods
paul@394 251
are not supported by the built-in objects and thus the operator module functions cause
paul@394 252
the compilation to fail. Alternatively, just supply the methods since something has to do
paul@394 253
so in the builtins.
paul@394 254
paul@394 255
Consider attribute merging where many attributes are just aliases for the same underlying
paul@394 256
definition.
paul@394 257
paul@349 258
Consider references to defaults as occurring only within the context of a particular
paul@349 259
function, thus eliminating default value classes if such functions are not themselves
paul@349 260
invoked.
paul@349 261
paul@394 262
Scope Handling
paul@394 263
==============
paul@394 264
paul@394 265
Consider merging the InspectedModule.store tests with the scope conflict handling.
paul@394 266
paul@343 267
Consider labelling _scope on assignments and dealing with the assignment of removed
paul@343 268
attributes, possibly removing the entire assignment, and distinguishing between such cases
paul@343 269
and unknown names.
paul@343 270
paul@342 271
Check name origin where multiple branches could yield multiple scope interpretations:
paul@342 272
paul@504 273
  try:
paul@504 274
      set # built-in name
paul@504 275
  except NameError:
paul@504 276
      from sets import Set as set # local definition of name
paul@342 277
paul@504 278
  set # could be confused by the local definition at run-time
paul@342 279
paul@394 280
Object Coverage
paul@394 281
===============
paul@394 282
paul@332 283
Support __init__ traversal (and other implicit names) more effectively.
paul@332 284
paul@499 285
Importing Modules
paul@499 286
=================
paul@499 287
paul@710 288
(Explicit relative imports are now supported.) Consider supporting relative imports, even
paul@710 289
though this is arguably a misfeature.
paul@499 290
paul@394 291
Other
paul@394 292
=====
paul@394 293
paul@332 294
Check context_value initialisation (avoiding or handling None effectively).
paul@332 295
paul@342 296
Consider better "macro" support where new expressions need to be generated and processed.
paul@402 297
paul@402 298
Detect TestIdentity results involving constants, potentially optimising status-affected
paul@402 299
instructions:
paul@402 300
paul@402 301
  TestIdentity(x, y) # where x is always y
paul@402 302
  JumpIfFalse(...)   # would be removed (never false)
paul@402 303
  JumpIfTrue(...)    # changed to Jump(...)
paul@402 304
paul@402 305
Status-affected blocks could be optimised away for such constant-related results.
paul@672 306
paul@672 307
Caching of structure and attribute usage information for incremental compilation.