[LLVMdev] Plans considering first class structs and multiple return values
Matthijs Kooijman
matthijs at stdin.nl
Mon Jun 9 01:31:07 PDT 2008
Hi Chris,
On Sat, Jun 07, 2008 at 02:59:03PM -0700, Chris Lattner wrote:
> On Jun 2, 2008, at 1:03 PM, Matthijs Kooijman wrote:
> >> Can you give some background about what kinds of things you're
> >> thinking
> >> about for this?
> > For example, when I have a function returning {i32, i32} and I want
> > to add
> > another i32 to that. If this was a function that simply returns two
> > i32
> > values, any caller will only use extractvalue on the result to get the
> > seperate values (since the struct as a whole has no meaning). In
> > this case, I
> > can make the function return {i32, i32, i32}, add an extra
> > extractvalue in
> > each caller and be done.
>
> This can't really work in either case. Once created, there is no way
> to change the type of a Value*. Changing the result of a call from
> {i32, i32} to {i32, i32, i32} is just as impossible as changing it
> from {i32,i32} to i32. You have to create a new callinst in either
> case.
By "Changing the return type", I meant "Create a new function with a changed
return type and updating all calls". The argument still holds, that this is
easier to do in some cases than others.
> > { {i32, i32}, i32}, which means we get something like:
> >
> > %tmp = @foo () ; { {i32, i32}, i32}
> > %complex = extractvalue { {i32, i32}, i32} %tmp, 0
> > @bar ( {i32, i32 } %complex)
>
> Why would you ever want to pass multiple values as an aggregate to a
> call? The only thing I can think of is for ABI reasons. If you can
> do an ABI changing transformation (such as you propose) the first
> thing I'd do is expand the aggregate to pass as a series of scalars.
> Having argpromotion do this would be very natural.
I was just using @bar to show that the complex struct is used as-is somewhere,
so it can't be broken up completely. In this particular case, it could be that
@foo() is internal (and thus can be changed) but @bar is external and has to
be kept unchanged.
Anyway, it was just an example.
In practice, just taking whatever the function is returning now, and put that
into a struct together with whatever you want to add and then letting other
passes make something pretty out of the resulting extractvalue/insertvalue
forest will work just fine.
> After MRVs are working really well, I'd like to consider removing the
> void type:
> http://nondot.org/sabre/LLVMNotes/EliminatingVoid.txt
>
> This would make it so that calls always return a value, and 'ret'
> always takes a value. This would be a nice simplification to the IR I
> think.
Doing this will make functions returning a single value stand out even more,
since a function returning 0 or more than 1 values will always return a
struct, while a function returning 1 value will just return that value. Don't
think this is really a problem, though.
> If you're using IRBuilder, why not just add a new CreateBuildMRV
> method that inserts the sequence of insertvalue's for you?
Hmm, that would actually make sense I guess. I'm not currently using
IRBuilder, but I might move some code into there.
> stretpromotion was really just for testing. I expect that when MRVs
> work predictably 100% of the time (even if not something the ABI
> supports, for example) that the functionality will be pulled into the
> argpromotion pass.
Will sretpromotion still be needed? If the frontends would generate functions
returning a struct directly instead of using an sret argument, sret could
perhaps be removed alltogether? Though I guess there is an ABI difference
between using sret and returning a structure directly?
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/20080609/845b4de8/attachment.sig>
More information about the llvm-dev
mailing list