Hi Alon,
> The docs say "[byval] indicates that the pointer parameter should
> really be passed by value to the function. The attribute implies
> that a hidden copy of the pointee is made between the caller and
> the callee, so the callee is unable to modify the value in the
> callee."
>
> I am not sure what this means though - when I generate code
> from the LLVM assembly, do I need to do anything with byval?
yes, the pointee needs to be passed by-copy, which usually means on the
stack but could mean in a bunch of registers.
> Either in the calling location or in the called function?
The caller does the copy IIRC. If you look at the .s file you should see
it happening.
I've> been trying to figure this out from generated LLVM assembly
> and it puzzles me.
You can't really figure it out from LLVM IR. Look at final target assembler
(.s).
Ciao, Duncan.
>
> For example, this code
>
> struct point
> {
> int x, y;
> };
>
> void dump(struct point p) {
> p.x++; // should not modify
> p.y++; // anything in the caller!
> printf("dump: %d,%d\n", p.x, p.y);
> }
>
> int main( int argc, const char *argv[] ) {
> point p = { 54, 2 };
> printf("pre: %d,%d\n", p.x, p.y);
> dump(p);
> return 0;
> }
>
> when compiled with some LLVM optimization passes (not all),
> looks like this in main():
>
> %p = alloca %struct.point, align 4 ; [#uses=5
type=%struct.point*]
> %agg.tmp = alloca %struct.point, align 4 ; [#uses=1
type=%struct.point*]
> [..]
> %3 = bitcast %struct.point* %agg.tmp to i8*, !dbg !39 ; [#uses=1
type=i8*] [debug line = 18:13]
> %4 = bitcast %struct.point* %p to i8*, !dbg !39 ; [#uses=1 type=i8*]
[debug line = 18:13]
> call void @llvm.memcpy.p0i8.p0i8.i32(i8* %3, i8* %4, i32 8, i32 4, i1
false), !dbg !39 ; [debug line = 18:13]
> call void @_Z4dump5point(%struct.point* byval align 4 %p), !dbg !39 ;
[debug line = 18:13]
>
> It looks like a copy is made in the caller, but the copy
> isn't used - instead the original is passed to the function.
> So this will not work properly unless the called function
> creates a copy. There is no explicit code created for this,
> but since it is tagged 'byval' an implementation can create
> a copy in the called function. Is that what I should do?
>
> Or, is it the responsibility of the caller to create a
> copy, and this will appear explicitly in the LLVM assembly?
> A copy does appear to be made in the code above, it just
> isn't used - is that a bug?
>
> I don't see this happen without optimizations - then
> the temporary copy is actually used. Is the problem then
> that I am running some, but not all LLVM optimization
> passes? In other words, is it possible for the opt tool
> to output code that doesn't work (without other passes
> being run later)? Or is there some meaning to byval that
> makes it valid - I guess it would have to mean that
> implementations need to create a copy in the called
> function?
>
> Best,
> Alon Zakai
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev