This is an archive of the discontinued LLVM Phabricator instance.

[RFC][DataLayout] Allow vector specifications by element size
Needs ReviewPublic

Authored by frasercrmck on Oct 26 2021, 6:13 AM.

Details

Summary

This patch adds the ability to configure the DataLayout specifications
on vector types by their element size, rather than their total size.

Specifying alignments by total vector size is not a good fit for some
architectures -- such as RISC-V's V extension (RVV) -- for a couple of
reasons.

The first is that for many architectures, such as those with
"Cray-style" vectors, there are a very wide set of supported vector
types, and specifying each by their total size is infeasible. RVV, for
example, could theoretically support any i8 vector type between 1 and
8192 bytes in size. Specifying optimal alignments for all such vector
types is cumbersome.

The second is that several architectures (again, like RVV) specify
vector alignment according to their element size. Thus under the current
system it is necessary either to pessimize vector alignments by rounding
them up to that of the maximum alignment across all legal vectors of
that size and/or to handle them as "misaligned" accesses.

Instead, this patch aims to both better suit and simplify the
specifications for such architectures. The ability to specify vector
alignments by element size is provided through a new specifier: ve. To
avoid any ambiguity about how this interacts with the existing v
vector specifier, the two are *mutually exclusive*; it is an error to
manually specify both in a single data layout. Since there are two v
specifiers in the set of defaults, an explicitly-set ve specifier must
be careful to erase those defaults. This decision also helps to preserve
backwards compatibility with older data layouts.

One outstanding design issue concerns how this should play with the
x86_mmx type, as that (AFAIK) doesn't have an element type.

Diff Detail

Event Timeline

frasercrmck created this revision.Oct 26 2021, 6:13 AM
frasercrmck requested review of this revision.Oct 26 2021, 6:13 AM
Herald added a project: Restricted Project. · View Herald TranscriptOct 26 2021, 6:13 AM
  • adjust comment
nikic added a comment.Dec 1 2021, 1:46 AM

Just to make sure that we don't end up with another incomplete solution: Are there any architectures where alignment could depend on both element size and total size? Are there any where it could depend on element type, i.e. where a vector of i32 and a vector of f32 may have different alignment?

llvm/lib/IR/DataLayout.cpp
401

You can use erase_if to simplify this pattern.

Just to make sure that we don't end up with another incomplete solution: Are there any architectures where alignment could depend on both element size and total size? Are there any where it could depend on element type, i.e. where a vector of i32 and a vector of f32 may have different alignment?

Great question! I'm not aware of such architectures but that's not to say they don't exist. I'm not sure how best to answer that question, given all the weird and wonderful architectures out there, unless a poll on llvm-dev suffices?

I feel like a spec that can juggle both total size and element size independently in the same DataLayout string is infeasible. Neither choice of how they'd resolve themselves when in conflict is satisfying to me. If v takes precedence over ve then ve is essentially useless (because v64 and v128 are legacy-specified by default). But if ve takes precedence over v then "v-based" architectures become way more verbose. That's why I went with the mutually-exclusive design here.

But narrowing in on your word "and", then maybe if you specified them together you can view total size as a specialization which applies on top of element size.

So the first idea that's coming to me right now would be to design a specification that would encode both total size and element size/type. Something like VX?[eif]N

  • (optional) X is the total size (or min size as that's how scalable vectors operate). Defaults to "all vectors". X if specified specializes over all non-specified vector sizes.
  • e is agnostic element size, i is int, f is floating-point. i or f specialize over e
  • N is element size

Something of a superset of this patch. It would allow something like Ve16 as this patch introduces: all 16-bit-element vectors. Vf16 could be used on top of that to apply only to all half vectors. V32f16 would apply on top of that to apply to 32-bit (2-element) half vectors.

But where does V64e16 fit into that schema? I think it would probably snuggle in between Vf16 and V32f16 but some may argue that f is more specific than e.

An alternative to total size there would be (min) number of elements, in case that was preferable. And if we decide the size/elts thing is awkward we could still keep the eif idea to allow specialization over different element types.

I think V and v would still continue to be mutually exclusive for the reasons given earlier.

I'm curious to hear your thoughts on this matter.

nikic added a comment.Dec 3 2021, 12:19 PM

Just to make sure that we don't end up with another incomplete solution: Are there any architectures where alignment could depend on both element size and total size? Are there any where it could depend on element type, i.e. where a vector of i32 and a vector of f32 may have different alignment?

Great question! I'm not aware of such architectures but that's not to say they don't exist. I'm not sure how best to answer that question, given all the weird and wonderful architectures out there, unless a poll on llvm-dev suffices?

Based on you the discussion in your comment, I think the important bit is that there is a viable future extension path: Even if we have just ve now, we can later extend that to also include a minimal total vector size etc using the scheme you suggest, if it becomes necessary. That looks like a backwards-compatible extension to me. Though probably checking with llvm-dev wouldn't hurt.

While the spec doesn't require RVV vectors to be more aligned than element size. A given microarchitecture may be more optimal if data is aligned to a VLEN chunk or perhaps a fraction of a VLEN chunk. So the preferred alignment for such a CPU would be more than element alignment. Though maybe data layout isn't the right place to handle microarchitectural differences like that.

Based on you the discussion in your comment, I think the important bit is that there is a viable future extension path: Even if we have just ve now, we can later extend that to also include a minimal total vector size etc using the scheme you suggest, if it becomes necessary. That looks like a backwards-compatible extension to me. Though probably checking with llvm-dev wouldn't hurt.

I've sent out a message to llvm-dev to gather any suggestions. I'm not sure how long to leave it though.

While the spec doesn't require RVV vectors to be more aligned than element size. A given microarchitecture may be more optimal if data is aligned to a VLEN chunk or perhaps a fraction of a VLEN chunk. So the preferred alignment for such a CPU would be more than element alignment. Though maybe data layout isn't the right place to handle microarchitectural differences like that.

That's an interesting point. I agree it's not really something for the data layout but I also can't think of where better fits that sort of thing.

rebase patch

Herald added a project: Restricted Project. · View Herald TranscriptApr 20 2022, 3:10 AM
efriedma added inline comments.Apr 25 2022, 9:50 AM
llvm/lib/IR/DataLayout.cpp
830–844

X86_MMXTyID is specifically for x86, so it's not likely to come up in practice... but should be fine to compute the alignment as if the element type is i64.