Here is the LangRef part of the patch. On Tue, Jan 12, 2010 at 2:11 PM, Chris Lattner <clattner at apple.com> wrote:> > On Jan 11, 2010, at 4:30 PM, Talin wrote: > > I'm working on a new version of the patch. >> >> Another thing I wanted to ask about - do you prefer to have one giant >> patch that has everything, or a series of incremental patches? I can see >> advantages either way. >> > > A series of incremental patches is strongly preferred, starting with > LangRef.html. > > > Normally I would want to do this as a series of incremental patches, >> however this is a rather large project and it may take me quite a while >> before it's completely done. I don't doubt that I will need some assistance >> when it comes to the trickier parts (like the optimization aspects you >> mentioned.) So there's a risk involved in submitting the first one or two >> patches, because the final patch might not be ready in time for the next >> release. >> >> On the other hand, it will be a lot easier for others to assist if we go >> ahead and submit the initial work. >> > > No problem, just submit it as you go. When the langref piece goes in, just > say in it that this is an experimental feature in development. Thanks > Talin, > > -Chris > >-- -- Talin -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20100112/de2f07ac/attachment.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: unionref.patch Type: application/octet-stream Size: 8332 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20100112/de2f07ac/attachment.obj>
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." 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? Dan
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>
I'm still working on the next patch, it's going somewhat slowly. I wanted to create a unit test that actually created a union, and in order to do that I had to implement constant unions. And rather than creating a special syntax for constructing a union, I decided that it was simplest to implement the insertvalue instruction for a constant union expression: @foo = constant union { i32, float } insertvalue union { i32, float } undef, i32 4, 0 What this says is to start with an undef, and then insert the value '4' into the integer field (the zeroth field) of the union. The reason for doing it this way is that to construct a union, you really need 4 pieces of information: The type of the union, the type and value of the member to be initialized, and the index of which member is being initialized. Originally I thought about having the last be detected automatically by what type of initializer was used: @foo = constant union { i32, float } i32 4 However, from a syntactical standpoint what you get is two types in a row - "union { i32, float }" followed by "i32". That is completely unlike any other IR syntax and doesn't fit well into the parser. Using insertvalue as an initializer has the advantage that it's parameters supply all of information we need. The disadvantage is that you have to type the union type signature twice, but I doubt that will be a major issue since IR isn't meant to be typed by hand anyway. On Tue, Jan 12, 2010 at 5:01 PM, Talin <viridia at gmail.com> wrote:> Here is the LangRef part of the patch. > > > On Tue, Jan 12, 2010 at 2:11 PM, Chris Lattner <clattner at apple.com> wrote: > >> >> On Jan 11, 2010, at 4:30 PM, Talin wrote: >> >> I'm working on a new version of the patch. >>> >>> Another thing I wanted to ask about - do you prefer to have one giant >>> patch that has everything, or a series of incremental patches? I can see >>> advantages either way. >>> >> >> A series of incremental patches is strongly preferred, starting with >> LangRef.html. >> >> >> Normally I would want to do this as a series of incremental patches, >>> however this is a rather large project and it may take me quite a while >>> before it's completely done. I don't doubt that I will need some assistance >>> when it comes to the trickier parts (like the optimization aspects you >>> mentioned.) So there's a risk involved in submitting the first one or two >>> patches, because the final patch might not be ready in time for the next >>> release. >>> >>> On the other hand, it will be a lot easier for others to assist if we go >>> ahead and submit the initial work. >>> >> >> No problem, just submit it as you go. When the langref piece goes in, >> just say in it that this is an experimental feature in development. Thanks >> Talin, >> >> -Chris >> >> > > > -- > -- Talin >-- -- Talin -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20100114/1fd36eca/attachment.html>
On Tue, Jan 12, 2010 at 8: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." > > 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?I can think of another benefit of the insertvalue/extractvalue/etc approach, which is that then LLVM checks your types for you. In other words, it makes sure you don't put an i64 into a union of i32 and double, whereas you can always bitcast an i64 to that union. Reid
2010/1/14 Talin <viridia at gmail.com>:> The reason for doing it this way is that to construct a union, you really > need 4 pieces of information: The type of the union, the type and value of > the member to be initialized, and the index of which member is being > initialized.Does requiring the index mean that uniquing the union type will have to re-write many of the corresponding insertvalue calls? For instance, how would this round-trip? @foo = constant union { float, i32 } insertvalue union { i32, float } undef, i32 4, 0 @bar = constant union { i32, float } insertvalue union { float, i32 } undef, i32 4, 1 I'm very glad to see a non-bitcast method of using unions, BTW.
2010/1/14 Talin <viridia at gmail.com>:> Originally I thought about having the last be detected > automatically by what type of initializer was used: > @foo = constant union { i32, float } i32 4 > However, from a syntactical standpoint what you get is two types in a row - > "union { i32, float }" followed by "i32". That is completely unlike any > other IR syntax and doesn't fit well into the parser. >It seems to me like that's similar to the ptrtoint and such instructions that change the type and not necessarily the value, so perhaps the main union operations should be: %foo = elementtounion i32 4 to union { i32, float } %bar = uniontoelement union { i32, float } %foo to i32 Conceptually I dislike the insertvalue, since the point of an insert is to keep some other part of the value intact, something not needed with unions.
On Jan 14, 2010, at 8:27 PM, Talin wrote:> I'm still working on the next patch, it's going somewhat slowly. I > wanted to create a unit test that actually created a union, and in > order to do that I had to implement constant unions. And rather than > creating a special syntax for constructing a union, I decided that > it was simplest to implement the insertvalue instruction for a > constant union expression: > > @foo = constant union { i32, float } insertvalue union { i32, > float } undef, i32 4, 0 > > What this says is to start with an undef, and then insert the value > '4' into the integer field (the zeroth field) of the union.Insertvalue constant exprs should work on these, but that should fall out from insertvalue just working on unions. However:> > The reason for doing it this way is that to construct a union, you > really need 4 pieces of information: The type of the union, the type > and value of the member to be initialized, and the index of which > member is being initialized. Originally I thought about having the > last be detected automatically by what type of initializer was used: > > @foo = constant union { i32, float } i32 4I think we really do need a "ConstantUnion" class. How about syntax like this: @foo = constant union { i32, float, double, i32*, i32 } { i32 4 } That seems simple and unambiguous, and analogous to structs. -Chris