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 >