Bug 70047 - Warn on inefficient function parameter passing
Summary: Warn on inefficient function parameter passing
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: unknown
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: ABI, diagnostic
Depends on:
Blocks: new-warning, new_warning
  Show dependency treegraph
 
Reported: 2016-03-02 14:14 UTC by Jaak Ristioja
Modified: 2022-02-04 08:08 UTC (History)
1 user (show)

See Also:
Host:
Target: x86_64
Build:
Known to work:
Known to fail:
Last reconfirmed: 2017-09-28 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jaak Ristioja 2016-03-02 14:14:14 UTC
According to the x86_64 ABI [1], function arguments are passed using registers and stack memory. It might be useful for x86_64 and other architectures if GCC would provide an option to warn if some parameters would (inefficiently) be passed on the stack instead of being passed via registers. This would help programmers optimize function signatures without disassembling the end result. 

Depending on the cost of different argument passing techniques in the ABI used, this warning option could benefit from multiple levels or suboptions, e.g.

  -Wparameter-passing=memory,xmm

would warn if parameters are passed on stack or via xmm registers.


Just a raw idea. :)


[1] System V Application Binary Interface. AMD64 Architecture Processor Supplement. Draft Version 0.99.6. http://www.x86-64.org/documentation/abi.pdf
Comment 1 Eric Gallager 2017-09-28 15:48:30 UTC
Could you give an example testcase that you think gcc should warn on with this option?
Comment 2 Jaak Ristioja 2017-09-28 16:42:39 UTC
Perhaps the simplest example for x86_64 would be something like:

  void f(long a1, long a2, long a3, long a4, long a5, long a6, long a7);

According to the ABI all seven arguments are classified as INTEGER-s. Arguments a1 through a6 get passed in %rdi, %rsi, %rdx, %rcx, %r8 and %r9 respectively, but a7 will be passed on the stack because no other registers are available. Therefore, in machine code passing/accessing a7 via the stack might be slightly slower than accessing the rest of the variables via registers. The situation gets more complicated with floating-point and aggregate values.
Comment 3 Eric Gallager 2017-09-28 18:42:58 UTC
I expanded the testcase:

$ cat 70047.c
void f(long a1, long a2, long a3, long a4, long a5, long a6, long a7);
void g(float b1, double b2, long double b3, long b4, long b5, long b6,
       register long b7);

struct agg {
	long f1;
	float f2;
	double f3;
	long double f4;
};

void h(struct agg c1, struct agg c2, struct agg c3, struct agg c4,
       struct agg c5, struct agg c6, struct agg c7, struct agg c8);
$ /usr/local/bin/gcc -c -Wall -Wextra -pedantic -Waggregate-return -Wvolatile-register-var -Wabi -Wpsabi -O2 70047.c
$

...which still gives no warnings when compiling, so, confirmed. Would probably make sense as part of -Wpsabi.