This is an archive of the discontinued LLVM Phabricator instance.

Don't Promote Args for Variadic Functions
ClosedPublic

Authored by tjablin on Aug 25 2014, 1:28 PM.

Details

Reviewers
joerg
rnk
Summary

Improve description of the problem based on helpful feedback from rnk.

Diff Detail

Event Timeline

tjablin updated this revision to Diff 12917.Aug 25 2014, 1:28 PM
tjablin retitled this revision from to Don't Promote Args for Variadic Functions.
tjablin updated this object.
tjablin edited the test plan for this revision. (Show Details)
tjablin added a reviewer: joerg.
tjablin added a subscriber: Unknown Object (MLST).
rnk accepted this revision.Aug 25 2014, 2:50 PM
rnk added a reviewer: rnk.
rnk added a subscriber: rnk.

lgtm

Do you think we can one day support promoting byval struct parameters that aren't in the variadic argument pack, or will that change the classification of downstream structs on the edge of the regparm area?

This revision is now accepted and ready to land.Aug 25 2014, 2:50 PM

I think the answer is 'no' as long as LLVM handles variadic args the way it
currently does. Currently, the fits_in_gp predicate is computed based on
assumptions about the size of arguments on the stack. Anything that could
change that will break variadic functions.

rnk added a comment.Aug 25 2014, 3:17 PM
In D5055#9, @tjablin wrote:

I think the answer is 'no' as long as LLVM handles variadic args the way it
currently does. Currently, the fits_in_gp predicate is computed based on
assumptions about the size of arguments on the stack. Anything that could
change that will break variadic functions.

I don't think this is entirely accurate. Each va_arg expansion from Clang should be completely independent, and so far as I can tell doesn't encode any information about how many non-variadic parameters there were. It *does* encode information about the AST-level type, which is what is breaking this test case of 5 pointers plus one 2 x i64 struct.

rnk added a comment.Aug 25 2014, 3:46 PM

Hm, now I understand the problem. I wouldn't say that the stack size is hardcoded into the IR in any way, though. The issue is that adding / removing / promoting non-pack parameters changes the classification of pack parameters. The classification of arguments at the call site is decided at compile time by clang, and the classification in the callee is determined dynamically by clang's expansion of va_arg.

DAE already knows this:

Liveness Result;
if (F.getFunctionType()->isVarArg()) {
  // Variadic functions will already have a va_arg function expanded inside
  // them, making them potentially very sensitive to ABI changes resulting
  // from removing arguments entirely, so don't. For example AArch64 handles
  // register and stack HFAs very differently, and this is reflected in the
  // IR which has already been generated.
  Result = Live;

For some reason argument promotion doesn't know this, even though it also removes dead arguments. I'm a bit surprised at the duplicated functionality, honestly.

tjablin updated this revision to Diff 12923.Aug 25 2014, 4:24 PM
tjablin updated this object.
tjablin edited edge metadata.
rnk closed this revision.Aug 25 2014, 5:08 PM

Thanks! Landed in r216421.