This is an archive of the discontinued LLVM Phabricator instance.

AMDGPU: Use direct struct returns
ClosedPublic

Authored by arsenm on Aug 1 2017, 1:22 PM.

Details

Summary

This is an improvement over always using byval for
structs.

This will use registers until ~16 are used, and then
switch back to byval. This needs more work, since I'm
not sure it ever really makes sense to use byval. If
the register limit is exceeded, the arguments still
end up passed on the stack, but with a different ABI.
It also may make sense to base this on number of
registers used for non-struct arguments, rather than
just arguments that appear first in the argument list.

Diff Detail

Event Timeline

arsenm created this revision.Aug 1 2017, 1:22 PM
b-sumner added inline comments.Aug 7 2017, 12:59 PM
lib/CodeGen/TargetInfo.cpp
7563

Won't NumRegsLeft wrap if size==64 and NumRegsLeft == 1 potentially causing an assert later?

yaxunl added inline comments.Aug 8 2017, 12:24 PM
lib/CodeGen/TargetInfo.cpp
7391

Please add descriptions for the above newly added functions.

7406

why do we need this function if it always return true

arsenm added inline comments.Aug 8 2017, 12:34 PM
lib/CodeGen/TargetInfo.cpp
7391

I prefer not to put descriptions on overrides since they will just be out of date with the declaration

7406

The default is return false

yaxunl added inline comments.Aug 8 2017, 12:42 PM
lib/CodeGen/TargetInfo.cpp
7391

Please add descriptions for the non-override functions and data members above.

arsenm updated this revision to Diff 110272.Aug 8 2017, 1:28 PM

Fix assert when estimating array registers

b-sumner added inline comments.Aug 8 2017, 1:46 PM
lib/CodeGen/TargetInfo.cpp
7571

What we do here depends on NumRegsLeft when the block is entered and NumRegs. If NumRegsLeft >= NumRegs then we just need 2 adjacent registers. If NumRegsLeft == 1 and NumRegs == 2, then do we pass the low half in a register and the upper half in memory, or all of it in memory? Anyway, I think NumRegsLeft shouldn't be updated until we know it's OK, and then we don't need the min().

arsenm added inline comments.Aug 8 2017, 2:23 PM
lib/CodeGen/TargetInfo.cpp
7391

I've added them to the body

7571

It's all one or the other. Whether it's passed in memory or not is really determined in codegen based on the actual register limit (which is also higher than the 16 used here, at least for now). Here selects whether to use byval or not. The ABI is slightly different whether it's passed as byval or as too many registers. I'm not sure it ever really makes sense to use byval yet, so I wasn't trying to be very precise here.

b-sumner added inline comments.Aug 8 2017, 2:46 PM
lib/CodeGen/TargetInfo.cpp
7571

Thanks. Just one more question. If we use memory for an argument, are all following arguments required to use memory? In that case, the min() is correct. But if a following argument could use a register, then the amount to subtract is NumRegs <= NumRegsLeft ? NumRegs : 0.

arsenm added inline comments.Aug 8 2017, 4:59 PM
lib/CodeGen/TargetInfo.cpp
7571

For what this does now, any large aggregates after NumRegsLeft == 0 will use byval. Simple types like int or small structs will still be directly passed arguments.

yaxunl accepted this revision.Aug 9 2017, 5:52 AM

LGTM. Thanks!

This revision is now accepted and ready to land.Aug 9 2017, 5:52 AM
arsenm closed this revision.Aug 9 2017, 2:59 PM

r310527