On Tue, Jan 12, 2010 at 5:46 PM, Dan Gohman <gohman at apple.com> wrote:> > On Jan 12, 2010, at 5:01 PM, Talin wrote: > > > Here is the LangRef part of the patch. > > > +<p>The union type is used to represent a set of possible data types > which can > > + exist at a given location in memory (also known as an "untagged" > > + union). > [...] > > This wording is somewhat misleading; memory in LLVM has no types. > How about: > > "A union type describes an object with size and alignment suitable for > an object of any one of a given set of types." >OK> > Also, is it really useful to support > insertvalue/extractvalue/getelementptr on unions? The benefit of unions > that I'm aware of is it allows target-independent IR to work with > appropriately sized and aligned memory. This doesn't require any special > support for accessing union members; for example: > > %p = alloca union { i32, double } > %q = bitcast union { i32, double }* %p to double* > store i32 2.0, double* %q > > Would this be a reasonable approach? >It depends on whether or not unions can be passed around as SSA values or not. I can think of situations where you would want to. In particular, GEP is useful because you can avoid the bitcast above - GEP to element 0 if you want an int (in the example above), or to element 1 if you want a double. Also, I'm thinking that insertvalue might be the best way to construct a constant union. Right now there's a bit of a problem in that the data type of a constant must match exactly the declared type; However in the case of a union what we want is for the data type of the initializer to exactly match the type of one of the union members. I thought this would be relatively easy to do, but it's a little trickier than I realized. -- -- Talin -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20100113/2be8f496/attachment.html>
On Jan 13, 2010, at 12:11 PM, Talin wrote:> > It depends on whether or not unions can be passed around as SSA > values or not. I can think of situations where you would want to. > > In particular, GEP is useful because you can avoid the bitcast above > - GEP to element 0 if you want an int (in the example above), or to > element 1 if you want a double. > > Also, I'm thinking that insertvalue might be the best way to > construct a constant union. Right now there's a bit of a problem in > that the data type of a constant must match exactly the declared > type; However in the case of a union what we want is for the data > type of the initializer to exactly match the type of one of the > union members. I thought this would be relatively easy to do, but > it's a little trickier than I realized.I think it is useful to support insert/extract on unions just for orthogonality alone. Stuff that works on structs should generally work on unions too. -Chris -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20100115/b79cc1e6/attachment.html>
On Jan 13, 2010, at 12:11 PM, Talin wrote:> > It depends on whether or not unions can be passed around as SSA values or not. I can think of situations where you would want to.I'm skeptical that you *really* want to (i.e. that you wouldn't be better off just writing helper functions in your front-end which do the addressing and load/store and then moving on). But, I'm not really interested in getting in the way here. Dan
On Fri, Jan 15, 2010 at 11:02 AM, Dan Gohman <gohman at apple.com> wrote:> > On Jan 13, 2010, at 12:11 PM, Talin wrote: > > > > It depends on whether or not unions can be passed around as SSA values or > not. I can think of situations where you would want to. > > I'm skeptical that you *really* want to (i.e. that you wouldn't > be better off just writing helper functions in your front-end > which do the addressing and load/store and then moving on). > But, I'm not really interested in getting in the way here. > > Let me give you a use case then:Say I have a function which returns either a floating-point number or an error code (like divide by zero or something). The way that I would represent this return result is: { i1, union { float, i32 } } In other words, what we have is a small struct that contains a one-bit discriminator field, followed by a union of float and i32. The discriminator field tells us what type is stored in the union - 0 = float, 1 = i32, so this is a typical 'tagged' union. (We can also have untagged or "C-style" unions, as long as the programmer has some other means of knowing what type is stored in the union.) Using a union here (as opposed to using bitcast) solves a number of problems: 1) The size of the struct is automatically calculated by taking the largest field of the union. Without unions, your frontend would have to calculate the size of each possible field, as well as their alignment, and use that to figure the maximum structure size. If your front-end is target-agnostic, you may not even know how to calculate the correct struct size. 2) The struct is small enough to be returned as a first-class SSA value, and with a union you can use it directly. Since bitcast only works on pointers, in order to use it you would have to alloca some temporary memory to hold the function result, store the result into it, then use a combination of GEP and bitcast to get a correctly-typed pointer to the second field, and finally load the value. With a union, you can simply extract the second field without ever having to muck about with pointers and allocas. 3) The union provides an additional layer of type safety, since you can only extract types which are declared in the union, and not any arbitrary type that you could get with a bitcast. (Although I consider this a relatively minor point since type safety isn't a major concern in IR.) 4) It's possible that some future version of the optimizer could use the additional type information provided by the union which the bitcast does not. Perhaps an optimizer which knows that all of the union members are numbers and not pointers could make some additional assumptions... -- -- Talin -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20100115/d12df0d7/attachment.html>