diff options
author | Jose E. Marchesi <jose.marchesi@oracle.com> | 2023-08-10 10:53:16 +0200 |
---|---|---|
committer | Jose E. Marchesi <jose.marchesi@oracle.com> | 2023-08-11 20:34:56 +0200 |
commit | 6103df1e4fae5192c507484b1d32f00c42c70b54 (patch) | |
tree | 2bad387074928099025ef17642ff8af1216c02ce | |
parent | 38c00edd65c39b07166aa0913c79adb9bcac943c (diff) | |
download | gcc-6103df1e4fae5192c507484b1d32f00c42c70b54.zip gcc-6103df1e4fae5192c507484b1d32f00c42c70b54.tar.gz gcc-6103df1e4fae5192c507484b1d32f00c42c70b54.tar.bz2 |
bpf: allow exceeding max num of args in BPF when always_inline
BPF currently limits the number of registers used to pass arguments to
functions to five registers. There is a check for this at function
expansion time. However, if a function is guaranteed to be always
inlined (and its body never generated) by virtue of the always_inline
attribute, it can "receive" any number of arguments.
Tested in host x86_64-linux-gnu and target bpf-unknown-none.
gcc/ChangeLog
* config/bpf/bpf.cc (bpf_function_arg_advance): Do not complain
about too many arguments if function is always inlined.
gcc/testsuite/ChangeLog
* gcc.target/bpf/diag-funargs-inline-1.c: New test.
* gcc.target/bpf/diag-funargs.c: Adapt test.
-rw-r--r-- | gcc/config/bpf/bpf.cc | 9 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/bpf/diag-funargs-inline-1.c | 21 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/bpf/diag-funargs.c | 8 |
3 files changed, 36 insertions, 2 deletions
diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc index 33218b3..d27a971 100644 --- a/gcc/config/bpf/bpf.cc +++ b/gcc/config/bpf/bpf.cc @@ -732,7 +732,14 @@ bpf_function_arg_advance (cumulative_args_t ca, unsigned num_words = CEIL (num_bytes, UNITS_PER_WORD); if (*cum <= 5 && *cum + num_words > 5) - error ("too many function arguments for eBPF"); + { + /* Too many arguments for BPF. However, if the function is + gonna be inline for sure, we let it pass. Otherwise, issue + an error. */ + if (!lookup_attribute ("always_inline", + DECL_ATTRIBUTES (cfun->decl))) + error ("too many function arguments for eBPF"); + } *cum += num_words; } diff --git a/gcc/testsuite/gcc.target/bpf/diag-funargs-inline-1.c b/gcc/testsuite/gcc.target/bpf/diag-funargs-inline-1.c new file mode 100644 index 0000000..e917ef1 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/diag-funargs-inline-1.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "" } */ + +inline int __attribute__ ((always_inline)) +foo (int a1, + int a2, + int a3, + int a4, + int a5, + int a6) +{ + return a1 + a2 + a3 + a4 + a5 + a6; +} + +int +bar (int i1, int i2, int i3, int i4, int i5) +{ + return foo (i1, i2, i3, i4, i5, 10); +} + +/* { dg-final { scan-assembler-not "call\t.*" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/diag-funargs.c b/gcc/testsuite/gcc.target/bpf/diag-funargs.c index d4e9c06..42b5f05 100644 --- a/gcc/testsuite/gcc.target/bpf/diag-funargs.c +++ b/gcc/testsuite/gcc.target/bpf/diag-funargs.c @@ -11,5 +11,11 @@ foo (int a1, /* { dg-error "too many function arguments" } */ int a5, int a6) { - return a6; + return a1 + a2 + a3 + a4 + a5 + a6; +} + +int +bar (int i1, int i2, int i3, int i4, int i5) +{ + return foo (i1, i2, i3, i4, i5, 10); } |