Hi all, For anyone interested, I posted two new ideas for changes to the LLVM IR. The first is basically a cleanup, the second is a major new feature: Eliminating the 'Void' Type: http://nondot.org/sabre/LLVMNotes/EliminatingVoid.txt Aggregates as First Class Values: http://nondot.org/sabre/LLVMNotes/FirstClassAggregates.txt Thanks to Dan Gohman for convincing me that aggregates as first class values is really possible, I think it is a great idea. -Chris
I would certainly make use of this in my frontend. I suggest the names "getfield" and "setfield" for the two operations, since (to me anyway) "insert" implies adding something new, as opposed to overwriting an existing value. Chris Lattner wrote:> Hi all, > > For anyone interested, I posted two new ideas for changes to the LLVM > IR. The first is basically a cleanup, the second is a major new > feature: > > Eliminating the 'Void' Type: > http://nondot.org/sabre/LLVMNotes/EliminatingVoid.txt > > Aggregates as First Class Values: > http://nondot.org/sabre/LLVMNotes/FirstClassAggregates.txt > > Thanks to Dan Gohman for convincing me that aggregates as first class > values is really possible, I think it is a great idea. > > -Chris > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > >
On Apr 27, 2008, at 10:58 AM, Talin wrote:> I would certainly make use of this in my frontend. > > I suggest the names "getfield" and "setfield" for the two operations, >I agree that 'get/insertvalue' are pretty generic, and am welcome to suggestions. Get/set *field* imply that this applies only to structs, but it also works with arrays. I would actually prefer get/insert *element* but insertelement is already taken.> since (to me anyway) "insert" implies adding something new, as opposed > to overwriting an existing value.The logic for using insert is that it replaces an element and produces the new aggregate as a whole, it doesn't update something in place (which set implies, at least to me). 'insert' is also useful because of its analogy with 'insertelement', the vector instruction. One nice thing about get/setvalue is that they are short :) -Chris
Chris Lattner wrote:> Aggregates as First Class Values: > http://nondot.org/sabre/LLVMNotes/FirstClassAggregates.txt >Thinking more about this...I kinda wish it was available right *now*, because I sure could use it. I've been working on functions returning structures today, and in the current IR I basically have two choices: Either return the struct using multiple return values (which means flattening any nested structs inside the struct to be returned, since AFAICT return values have to be first class, and then re-assembling the structure at the call site), or passing an extra argument which points to the struct to be filled in. In my opinion, that's a level of detail that the frontend really shouldn't have to know or care about. The code generator should be able to make that decision based on the platform ABI and other target-specific criteria, and the frontend has no business worrying about any of these issues. -- Talin
Hi Chris,> Eliminating the 'Void' Type: > http://nondot.org/sabre/LLVMNotes/EliminatingVoid.txtmight not some ABI's require some special stuff when returning a struct, regardless of whether the struct is empty or not? If so this might add a cost if you use {} for void. Also, there are an infinite number of different ways of returning void: return {} or {{}} or {{{}}} etc, not to mention returning zero length arrays. I guess that's life.> Aggregates as First Class Values: > http://nondot.org/sabre/LLVMNotes/FirstClassAggregates.txtDoes this mean that vector types can be removed in favour of ordinary arrays? If not, maybe at least vectors should be changed to derive from array types, and no longer be primitive types. This would make it easier to fix a bunch of problems with vector types, for example that the primitive size of <4 x i1> is 4 bits but in fact it's codegened like [4 x i1], which takes up 4 bytes. It might also reduce the amount of special vector code. Your plan means that you can have loads and stores where you don't know the size of the value being loaded/stored (unless you have target data). I don't know if it matters. You say "I suggest that aggregates be passed just like 'byval' arguments by default". Wouldn't it make more sense to pass in registers (or stack elements if you run out of registers)? Note that MVT::ValueType is no longer adequate once you have structs and arrays. Ciao, Duncan.
On May 5, 2008, at 2:02 AM, Duncan Sands wrote:> Hi Chris, > >> Eliminating the 'Void' Type: >> http://nondot.org/sabre/LLVMNotes/EliminatingVoid.txt > > might not some ABI's require some special stuff when > returning a struct, regardless of whether the struct > is empty or not? If so this might add a cost if you > use {} for void.Sure, in which case they'd need to use some special attribute, or use stret for the struct return case. This is no different than today.>> Aggregates as First Class Values: >> http://nondot.org/sabre/LLVMNotes/FirstClassAggregates.txt > > Does this mean that vector types can be removed in favour > of ordinary arrays?Not as a first step, but probably as a second step. For the first step, I don't want to allow arithmetic on aggregate values. We can generalize this after the basics are in place.> If not, maybe at least vectors should > be changed to derive from array types, and no longer be > primitive types. This would make it easier to fix a bunch > of problems with vector types, for example that the primitive > size of <4 x i1> is 4 bits but in fact it's codegened like > [4 x i1], which takes up 4 bytes. It might also reduce the > amount of special vector code.Array and Vector types share a common base class (SequentialType). I agree that simplifying layout would be a big benefit.> Your plan means that you can have loads and stores where > you don't know the size of the value being loaded/stored > (unless you have target data). I don't know if it matters.I'm not sure what you mean. Isn't this the same as loading a pointer (whose size depends on TD)?> You say "I suggest that aggregates be passed just like 'byval' > arguments by default". Wouldn't it make more sense to pass > in registers (or stack elements if you run out of registers)?an aggregate with the 'inreg' attribute could be passed that way.> Note that MVT::ValueType is no longer adequate once you have > structs and arrays.In the codegen, they are always lowered to their elements by SDISel, so they don't make it into the dag. This code is already almost all in place. -Chris
Hi Talin, On May 5, 2008, at 1:13 AM, Talin wrote:> Chris Lattner wrote: >> Aggregates as First Class Values: >> http://nondot.org/sabre/LLVMNotes/FirstClassAggregates.txt >> > Thinking more about this...I kinda wish it was available right *now*, > because I sure could use it. I've been working on functions returning > structures today, and in the current IR I basically have two choices: > Either return the struct using multiple return values (which means > flattening any nested structs inside the struct to be returned, since > AFAICT return values have to be first class, and then re-assembling > the > structure at the call site), or passing an extra argument which points > to the struct to be filled in.I'm planning to start working on this after the 2.3 release branch is created. Would you be interested in helping?> In my opinion, that's a level of detail that the frontend really > shouldn't have to know or care about. The code generator should be > able > to make that decision based on the platform ABI and other > target-specific criteria, and the frontend has no business worrying > about any of these issues.If you just need a convenient way to deal with relatively small numbers of values grouped together in an efficient manner, this new feature will be very useful. If you need to generate code to be directly linked with C code that uses arbitrary struct argument or return types, this feature will be only a small step. Front-ends will still need to know quite a lot about how structs are handled in the ABI if they want to be compatible with other C compilers. Dan
Hi,> Aggregates as First Class Values:it seems to me that having this would make the byval parameter attribute partly obsolete? Will there be semantic differences between passing a struct directly and a pointer to a struct byval? I can see that byval can be used on pointers to other things, but is that really useful? I can't see any use for compiling C code, are there other languages that have a direct use for a byval attribute? Gr. Matthijs -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 189 bytes Desc: Digital signature URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20080507/9b6ddc93/attachment.sig>
On Wed, 7 May 2008, Matthijs Kooijman wrote:>> Aggregates as First Class Values: > it seems to me that having this would make the byval parameter attribute > partly obsolete? Will there be semantic differences between passing a struct > directly and a pointer to a struct byval? > > I can see that byval can be used on pointers to other things, but is that > really useful? I can't see any use for compiling C code, are there other > languages that have a direct use for a byval attribute?Byval and passing a first class aggregate have the same semantics. However, byval is very efficient for large aggregates and first-class aggregates is efficient for small ones. -Chris -- http://nondot.org/sabre/ http://llvm.org/