Structs passed by value

Hello,

I’m trying to change the default behavior for how structures are passed to functions to use pass-by-value. Currently LLVM’s default behavior is to pass structures by reference. I’m not disputing the benefits of this but I really want to change the default behavior for experimentation purposes.

To this end I’ve changed the code in DefaultABIInfo::classifyArgumentType() to use the different types. What I’ve found is that none of the options yield the expected results for the input code (see below). Except for the indirect case, the function signature is changed to take each structure element. How can I modify LLVM to pass structures by value?

Thanks,

Javier

[Original Code]

struct myType {

long val;

};

int convert(struct myType in)

{

return (int)in.val;

}

[Expected Result]

define i32 @convert(%myType %in) nounwind readonly alwaysinline{

entry:

%in.addr = alloca %myType, align 8

store %myType %in, %myType* %in.addr, align 8

%0 = getelementptr inbounds %myType* %in.addr, i32 0, i32 0

%1 = load i64* %0, align 8

%conv = trunc i64 %1 to i32

ret i32 %conv

}

[ABIArgInfo::getIndirect(0) – Default]

%struct.myType = type { i64 }

define i32 @convert(%struct.myType* nocapture byval %in) nounwind readonly {

entry:

%val = getelementptr inbounds %struct.myType* %in, i64 0, i32 0

%0 = load i64* %val, align 8, !tbaa !0

%conv = trunc i64 %0 to i32

ret i32 %conv

}

[ABIArgInfo::getExtend(), ABIArgInfo::getDirect(), ABIArgInfo::getExpand()]

define i32 @convert(i64 %in.coerce0) nounwind readnone {

entry:

%conv = trunc i64 %in.coerce0 to i32

ret i32 %conv

}

Hi,

Hello,

I’m trying to change the default behavior for how structures are passed to functions to use pass-by-value. Currently LLVM’s default behavior is to pass structures by reference. I’m not disputing the benefits of this but I really want to change the default behavior for experimentation purposes.

Are you sure that the current behavior is passing structures by reference? In your example, the function “convert” is given a pointer %in, but that pointer is marked “byval”. According to http://llvm.org/docs/LangRef.html that means that it is pass-by-value:

“This 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 caller.”

etc…

Is the problem that in the backend, you do not see a copy being made?

Jan,

Thanks for the reply. The behavior of the default case is pass by value but the mechanism is pass by reference as seen in the code. My understanding is that the byVal is there to indicate that the data pointed to by the parameter shouldn’t be updated when the function ends with the internal copy value. I still think that a true pass by value mechanism doesn’t exist in LLVM.

Javier