LLVM now supports a "scalable" vector type:
<vscale x N x ELT> (e.g. <vscale x 4 x i32>)
that represents a vector of X*N ELTs for some runtime value X
[https://reviews.llvm.org/D32530]. The number of elements is therefore
not known at compile time and can depend on choices made by the execution
environment. This RFC is about how we can provide C and C++ types that
map to this LLVM type.
The main complication is that, because the number of elements isn't
known at compile time, "sizeof" can't work in the same way as it does
for normal vector types. Our suggested fix for this is to separate the
concept of "complete type" into two:
* does the type have enough information to construct objects of that type?
For want of a better term, types that have this property are
"definite" while types that don't are "indefinite".
* will it be possible to measure the size of the type using "sizeof",
once the type is definite?
If so, the type is "sized", otherwise it is "sizeless".
"Complete" is then equivalent to "sized and definite". The new scalable
vectors are definite but sizeless, and so are never complete.
We can then redefine certain rules to use the distinction between
definite and indefinite types rather than complete and incomplete types.
(This is a simple change to make in Clang.) Things like "sizeof" and
pointer arithmetic continue to require complete types, and so are invalid
for the new types. See below for a more detailed description.
We're also proposing to treat the new C and C++ types as opaque built-in
types rather than first-class vector types, for two reasons:
(1) It means that we don't need to define what the "vscale" is for
all targets, or emulate general vscale operations for all targets.
We can just provide the types that the target supports natively,
and for which the target already has a defined ABI.
(2) It allows for more abstraction. For example, SVE has scalable types
that are logically tuples of 2, 3 or 4 vectors. Defining them as opaque
built-in types means that we don't need to treat them as single vectors
in C and C++, even if that happens to be how LLVM represents them.
Building tuple types into the compiler also means that we don't need
to support scalable vectors in structures or arrays.
In case this looks familiar...