this change has two key benefits:
1. we no longer need to allocate large contigious buffers for Regions with lots
of Blocks, or Blocks with lots of Ops.
2. this simplifies re-arranging, inserting, and moving parts of the IR structure.
vector move callbacks allow mie_name instances to be stored in movable memory,
as the internal bst pointers can now be fixed during vector resize operations.
the builtin.module op behaves exactly like any other op, and is designed
to be a container for other ops of any type. it can be used as the
top-level container for other ops (other top-level containers can be used
instead).
this also changes the file format. now, an ir file can only contain a
single top-level op. any other ops in the ir must be contained
directly or indirectly by this top-level op.
under this new system, dialects can define their own custom attributes,
complete with their own print() and parse() callbacks, which can then be
used as values in an op's attribute dictionary.
alongside custom dialect attributes, the former int, float, and string
constant values have been converted to attributes provided by the
arith and builtin dialects respectively. the caches for these attributes
have also been moved from mie_ctx to their respective dialect data
structures.
this system will allow new types of attributes to be implemented,
including dictionaries, arrays, and references to types themselves
(rather than just particular values of a given type).