Hi Duncan, Thanks for the response!> that's because clang is doing something more complicated than you are: it is > producing a function that conforms to the platform ABI for passing parameters. > The platform ABI specifies in this case that the valued should be returned via > a special in-memory mechanism (thus the "sret" extra function parameter) rather > than in a bunch of registers (which is what you are doing).Right.> The whole "why does > the front-end have to worry about the ABI" discussion has occurred several times > on the mailing list (eg: yesterday), please search the archives.Ah, indeed. I hadn’t exactly understood that in relation to this specific problem, likely due to skimming—mea culpa.>> Returning a structure packed into a single i64 value or by reference in an argument would seem to be details of the platform’s ABI. Does my compiler really need to be aware of these details, or can I just return a structure as per the documentation quoted above? > > Yes, it needs to be aware of the details. There has been some discussion of > providing a helper library for doing this, see http://llvm.org/bugs/show_bug.cgi?id=4246Apologies in advance if this has been hashed over already—and of course, one should be aware that I know _absolutely nothing_ in this regard ( (: )—but perhaps at least some platform ABI details could be handled by an IR-to-IR transformation (a la one of the function passes), taking a function that returns some arbitrary structure via a return mechanism and changing it to use the platform ABI (returning via reference on the stack) instead? Is that a total non-starter? My needs are relatively simple, as I’m not interfacing with arbitrary C functions, no var-args, or anything at all out of the ordinary. Literally the most complicated thing I need to do is return a structure.>> If the latter case, how do I build that instruction with the builder? Attempts to use LLVMConstStruct are crashing, I assume because the arguments to it in my use are not actually constants (: A quick search through IRBuilder didn’t give me any clues either, so here I am (: > > What instruction, the funky return statement? You create a return statement for > which the argument is a Value of the appropriate struct type.In this case, I actually meant building the Value of the appropriate struct type. Is there a simpler way to build a structure than to alloca a struct and store things into its fields? Or is the “{ i32 1, i32 2 }” thing only possible for 100% constant structs (I expect the answer is yes, just looking for verification (: )? Thanks again, Rob -- Rob Rix, Unknown Quantity Monochrome Industries
Hi Rob,> Apologies in advance if this has been hashed over already—and of course, one should be aware that I know _absolutely nothing_ in this regard ( (: )—but perhaps at least some platform ABI details could be handled by an IR-to-IR transformation (a la one of the function passes), taking a function that returns some arbitrary structure via a return mechanism and changing it to use the platform ABI (returning via reference on the stack) instead?yes, this has be discussed many times already on the mailing list, and in general it is not possible, sorry.> Is that a total non-starter? My needs are relatively simple, as I’m not interfacing with arbitrary C functions, no var-args, or anything at all out of the ordinary. Literally the most complicated thing I need to do is return a structure.If this routine is only going to be called from code you generate, then you can use whatever calling convention you like, for example you can just return your struct in registers. Otherwise I'm afraid you are mistaken in thinking that returning a struct is simple - in fact the ABI logic on (eg) x86-64 is really horribly complicated for this.> In this case, I actually meant building the Value of the appropriate struct type. Is there a simpler way to build a structure than to alloca a struct and store things into its fields? Or is the “{ i32 1, i32 2 }” thing only possible for 100% constant structs (I expect the answer is yes, just looking for verification (: )?Look in the docs for "first class aggregates". Check out this example: struct R { long a; long b; }; struct R f(long a, long b) { struct R A; A.a = a; A.b = b; return A; } -> %"struct R" = type { i64, i64 } define %"struct R" @f(i64 %a, i64 %b) nounwind readnone { entry: %mrv5 = insertvalue %"struct R" undef, i64 %a, 0 ; <%"struct R"> [#uses=1] %mrv6 = insertvalue %"struct R" %mrv5, i64 %b, 1 ; <%"struct R"> [#uses=1] ret %"struct R" %mrv6 }
Hi Duncan, Thank you again for your clear and thorough response.>> Apologies in advance if this has been hashed over already—and of course, one should be aware that I know _absolutely nothing_ in this regard ( (: )—but perhaps at least some platform ABI details could be handled by an IR-to-IR transformation (a la one of the function passes), taking a function that returns some arbitrary structure via a return mechanism and changing it to use the platform ABI (returning via reference on the stack) instead? > > yes, this has be discussed many times already on the mailing list, and in > general it is not possible, sorry.Okay, that’s pretty much what I expected.> If this routine is only going to be called from code you generate, then you can > use whatever calling convention you like, for example you can just return your > struct in registers. Otherwise I'm afraid you are mistaken in thinking that > returning a struct is simple - in fact the ABI logic on (eg) x86-64 is really > horribly complicated for this.Ah, I wasn’t aware of the former detail. I believe I can arrange things to suit that, or alternatively _always_ return the structure in question via the stack.>> In this case, I actually meant building the Value of the appropriate struct type. Is there a simpler way to build a structure than to alloca a struct and store things into its fields? Or is the “{ i32 1, i32 2 }” thing only possible for 100% constant structs (I expect the answer is yes, just looking for verification (: )? > > Look in the docs for "first class aggregates". Check out this example: > > <snip>Perfect, this is exactly what I was looking for. Thank you once again for taking the time to answer my foolish questions (: Gratefully, Rob -- Rob Rix, Unknown Quantity Monochrome Industries