| # Lowering IREEPyDM to IREE | |
| At the top-level, a program expressed in IREEPyDM ("PyDM") can be lowered to | |
| IREE via the overall conversion pass `-convert-iree-pydm-to-iree`; however, | |
| additional steps are needed to link a runtime library, etc. | |
| This document provides application notes for how the conversion is | |
| implemented. | |
| ## Type Conversion | |
| Generally, types in PyDM map 1:1 with IREE types in a way which facilitates | |
| a direct conversion. | |
| ## `object` and `object<type>` records | |
| Objects map to IREE variant lists (`!iree.list<?>`) of N elements, where the | |
| elements are laid out as: | |
| * [0]: Type Code - i32 representing the type code of the object. | |
| * [1] (optional): Data corresponding to the type. | |
| * [2] (optional): i64 TypeID - if the `id()` function has been evaluated for | |
| this object, then this element will contain the unique id. | |
| ### Type Codes | |
| The special type code `0` means "not assigned", which is distinct from `None`. | |
| Other built-in types correspond to the `BuiltinTypeCode` enum in the dialect. | |
| The following specifies the contents of the `data` field (1) of the object | |
| record, per type code: | |
| * `None`: No contents | |
| * `Tuple`: An `!iree.list` of objects | |
| * `List`: An `!iree.list` of objects | |
| * `Str`: TODO: needs to be a union of i8/i16/i32 codepoint array | |
| * `Bytes`: TODO: should be a memory buffer of some kind | |
| * `ExceptionResult`: TODO: should hold a boxed exception of some kind | |
| * `Type`: An object representing the type | |
| * `Bool`: Implementation defined `iree_vm_value_type_t` field (typically | |
| `iree_vm_value_type_t.i8`). | |
| * `Integer`: Implementation defined `iree_vm_value_type_t` field (typically | |
| `iree_vm_value_type_t.i32`). | |
| * `Real`: Implementation defined `iree_vm_value_type_t` field (typically | |
| `iree_vm_value_type_t.f32`). | |
| * `Complex`: TODO | |
| * `Integer1` / `UInteger1`: `iree_vm_value_type_t.i8` | |
| * `Integer2` / `UInteger2`: `iree_vm_value_type_t.i16` | |
| * `Integer4` / `UInteger4`: `iree_vm_value_type_t.i32 | |
| * `Integer8` / `UInteger8`: `iree_vm_value_type_t.i64 | |
| * `Float2` : `iree_vm_value_type_t.i16` with bit value of an IEEE FP16 | |
| * `Float4` : `iree_vm_value_type_t.f32` | |
| * `Float8` : `iree_vm_value_type_t.f64` | |
| * `BFloat2` : `iree_vm_value_type_t.i16` with bit value of a BFloat16 (thanks | |
| Google). | |
| * `Complex4` : TODO | |
| * `Complex8` : TODO | |
| * `Object` (and custom): An object record, as described here | |
| ### Mutability | |
| The VM enforces no immutability constraints on the object records here (i.e. | |
| they are just lists). If the compiler believes that it can recycle an object, | |
| it is free to resize it appropriately and re-assign its contents. In this | |
| way, things like closure cells and free variable cells can just be | |
| allocated object records that that compiler completely reassigns the contents | |
| of on assignment. | |
| ## Unboxed values | |
| All values can exist in the program unboxed and will have a VM IR type which | |
| corresponds to their runtime variant form (i.e. `!iree.list`, `i32`, etc). | |
| ## `!iree_pydm.exception_result` | |
| The `exception_result` type is returned from every PyDM function indicating | |
| whether the call completed successfully or in an error state. We encode it as | |
| a signed `i32` value at runtime, where: | |
| * `0` : indicates normal termination. | |
| * `<0` : signals one of a predefined list of primitive exception types | |
| which do not contain any detail (i.e. `ValueException` analog). | |
| * `>0` : is an index into a global exception lookup table with slots | |
| corresponding to logical threads of execution. | |
| ### Pre-defined exception codes: | |
| * `-1` : `StopIteration` - Standard exception which indicates exhaustion of | |
| an iterator. | |
| * `-2` : `StopAsyncIteration` - Standard exception which indicates exhaustion | |
| of an async iterator. | |
| * `-3` : `RuntimeError` - general catch-all failure exception class. | |
| * `-4` : `ValueError` | |
| * `-5` : `NotImplementedError` | |
| * `-6` : `KeyError` | |
| * `-7` : `IndexError` | |
| * `-8` : `AttributeError` | |
| * `-9` : `TypeError` | |
| * `-10` : `UnboundLocalError` | |
| These pre-defined exception codes are allocated when the compiler has a need | |
| to raise or interoperate with an exception category. |