Hi Rafael, > + Assert(!Attrs->paramHasAttr(0, ParamAttr::ByVal), > + "Attribute ByVal should not apply to functions!");
why not? > + "Attribute ByVal should only apply to pointer to structs!", > &F); Why? Why are arrays not allowed? Here's my take on this whole area. Perhaps I'm just confused :) On some targets the ABI specifies that C functions that take a by-copy struct argument that is sufficiently small should pass it in registers, or maybe on the stack. Likewise, on some targets the ABI specifies that a function that returns a struct should return it in certain registers or on the stack (StructReturn attribute). On other targets, by-copy struct arguments are passed by passing pointer to a copy, or by passing a pointer to the original struct with a copy being made in the callee, I don't know which. Likewise, on targets with nothing specified for StructReturn in the ABI, the value is returned by writing through a pointer into a struct supplied by the caller. [ByVal and StructReturn are closely related, so maybe we should change the names: ByVal -> CopyIn, StructReturn -> CopyOut]. Note that the representation in the IR is "by reference": a pointer to the struct is passed: declare void @h(%struct.foo* byval %num) I think ByVal should mean: if the struct is compatible with the ABI's way of passing structs by-copy, then pass using this method, otherwise pass by reference. At the level of the target independent IR, it would be *undefined* as to whether a ByVal parameter is in fact passed by reference or by copy. My understanding is that this is exactly how StructReturn works: if, before calling the function, you write to the struct that is passed in as the StructReturn parameter, and then you try reading from the struct inside the function you may (returned by reference) or may not (returned by copy) see the values you previously wrote. Thus on some targets ByVal parameters would always be passed by reference. On others, small structs would be passed by copy, large ones by reference. On others, all structs would be passed by copy. Disadvantages of this scheme: (1) in order to implement C semantics of passing a struct by copy [which requires that a copy always be made, regardless of the size of the struct], it would be necessary to, for example, pass the parameter ByVal, immediately make a copy of the struct inside the function, and use the copy everywhere inside the function. This would always give the correct semantics while being compatible with ABI requirements (thanks to the ByVal). The downside is that in cases when the ByVal parameter is in fact passed by copy, an unnecessary copy is being made. Hopefully the codegen optimizers can be taught to remove the pointless copy in this case. Thus the disadvantage is: additional work may be needed on the codegen optimizers to get this to work optimally. Advantages of this scheme: (1) it doesn't *require* any changes to the target independent optimizers, eg to alias analysis, the inliner and who knows what else: they can just ignore the ByVal attribute, which amounts to considering the struct to have been passed by reference (which is how it is represented in the IR). Now, you might want to enhance the optimizers so they can exploit the undefinedness of whether the struct is passed by reference or by copy, but this is optional can be implemented incrementally. It seems to me that this is much much better than having to say in various places: ok, this thing looks like a pointer but it's not really a pointer! That way lies madness. If I dare say so, that way lies... gcc! (2) targets that don't have a special way of passing structs by-copy don't have to do anything. (3) if a function is known not to write to a struct parameter, then that parameter could be marked ByVal, meaning that it will (hopefully) get passed by the most efficient method for the target (in registers). I say hopefully, because I suppose some ABIs may specify that by-copy structs of any size must be passed on the stack, which would mean that promoting a parameter to ByVal could result in a slowdown rather than a speedup. (4) it conceptually unifies the treatment of ByVal and StructReturn parameters. Ciao, Duncan. _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits