Suppose this structure is passed by value to a function foo(struct S1),
struct S1 {
int i0;
float f0;
double d0;
long long l0;
};
and the ABI dictates the elements of the structure are copied to both
integer and floating pointer argument registers in the following way:
(i0, f0) => 1st 64-bit integer argument register
d0 => 2nd double float argument register (doubles are passed in FP registers)
l0 => 3rd 64-bit integer argument register
What is the best way to find out whether integer registers or floating
pointer registers should be used for argument passing inside
TargetLowering::LowerCall? I can get basic information of the
structure being passed (for example, by calling
ArgFlagsTy::getByValSize() or ArgFlagsTy::getByValAlign() to get size
and alignment), but there doesn't seem to be an easy way to find more
detailed information. Do I have to get the instance of StructType for
structure S1 and analyze it?
On Thu, Oct 20, 2011 at 2:21 PM, Akira Hatanaka <ahatanak at gmail.com> wrote:> Suppose this structure is passed by value to a function foo(struct S1), > > struct S1 { > int i0; > float f0; > double d0; > long long l0; > }; > > and the ABI dictates the elements of the structure are copied to both > integer and floating pointer argument registers in the following way: > > (i0, f0) => 1st 64-bit integer argument register > d0 => 2nd double float argument register (doubles are passed in FP registers) > l0 => 3rd 64-bit integer argument register > > What is the best way to find out whether integer registers or floating > pointer registers should be used for argument passing inside > TargetLowering::LowerCall? I can get basic information of the > structure being passed (for example, by calling > ArgFlagsTy::getByValSize() or ArgFlagsTy::getByValAlign() to get size > and alignment), but there doesn't seem to be an easy way to find more > detailed information. Do I have to get the instance of StructType for > structure S1 and analyze it?The way we do stuff like this for x86-64 is adding handling to clang; for example, to handle your case, make clang lower "void f(struct S1 x)" to the following: define void @x(i64 %x.1, double %x.2, i64 %x.3) Basically, an LLVM struct type doesn't really encode enough information to accurately compute the C calling convention, so we handle the tricky cases in the frontend. The relevant code is in clang/lib/CodeGen/TargetInfo.cpp . -Eli
Thanks, I will try that. On Fri, Oct 21, 2011 at 9:24 AM, Eli Friedman <eli.friedman at gmail.com> wrote:> On Thu, Oct 20, 2011 at 2:21 PM, Akira Hatanaka <ahatanak at gmail.com> wrote: >> Suppose this structure is passed by value to a function foo(struct S1), >> >> struct S1 { >> int i0; >> float f0; >> double d0; >> long long l0; >> }; >> >> and the ABI dictates the elements of the structure are copied to both >> integer and floating pointer argument registers in the following way: >> >> (i0, f0) => 1st 64-bit integer argument register >> d0 => 2nd double float argument register (doubles are passed in FP registers) >> l0 => 3rd 64-bit integer argument register >> >> What is the best way to find out whether integer registers or floating >> pointer registers should be used for argument passing inside >> TargetLowering::LowerCall? I can get basic information of the >> structure being passed (for example, by calling >> ArgFlagsTy::getByValSize() or ArgFlagsTy::getByValAlign() to get size >> and alignment), but there doesn't seem to be an easy way to find more >> detailed information. Do I have to get the instance of StructType for >> structure S1 and analyze it? > > The way we do stuff like this for x86-64 is adding handling to clang; > for example, to handle your case, make clang lower "void f(struct S1 > x)" to the following: > > define void @x(i64 %x.1, double %x.2, i64 %x.3) > > Basically, an LLVM struct type doesn't really encode enough > information to accurately compute the C calling convention, so we > handle the tricky cases in the frontend. The relevant code is in > clang/lib/CodeGen/TargetInfo.cpp . > > -Eli >
Reasonably Related Threads
- [LLVMdev] questions about byval argument passing
- Options for custom CCState, CCAssignFn, and GlobalISel
- Options for custom CCState, CCAssignFn, and GlobalISel
- Options for custom CCState, CCAssignFn, and GlobalISel
- [LLVMdev] A question of Sparc assembly generated by llc