diff options
author | xuli <xuli1@eswincomputing.com> | 2024-03-01 09:10:12 +0000 |
---|---|---|
committer | Pan Li <pan2.li@intel.com> | 2024-03-01 18:55:26 +0800 |
commit | 4547628c78618616595f4b5e1bef2b582c77793d (patch) | |
tree | 7589b2bd2633ad30d9498a993e7dccf1e6d19915 /gcc | |
parent | 0a01d1232ff0a8b094270fbf45c9fd0ea46df19f (diff) | |
download | gcc-4547628c78618616595f4b5e1bef2b582c77793d.zip gcc-4547628c78618616595f4b5e1bef2b582c77793d.tar.gz gcc-4547628c78618616595f4b5e1bef2b582c77793d.tar.bz2 |
RISC-V: Add riscv_vector_cc function attribute
Standard vector calling convention variant will only enabled when function
has vector argument or returning value by default, however user may also
want to invoke function without that during a vectorized loop at some situation,
but it will cause a huge performance penalty due to vector register store/restore.
So user can declare function with this riscv_vector_cc attribute like below, that could enforce
function will use standard vector calling convention variant.
void foo() __attribute__((riscv_vector_cc));
[[riscv::vector_cc]] void foo(); // For C++11 and C23
For more details please reference the below link.
https://github.com/riscv-non-isa/riscv-c-api-doc/pull/67
gcc/ChangeLog:
* config/riscv/riscv.cc (TARGET_GNU_ATTRIBUTES): Add riscv_vector_cc
attribute to riscv_attribute_table.
(riscv_vector_cc_function_p): Return true if FUNC is a riscv_vector_cc function.
(riscv_fntype_abi): Add riscv_vector_cc attribute check.
* doc/extend.texi: Add riscv_vector_cc attribute description.
gcc/testsuite/ChangeLog:
* g++.target/riscv/rvv/base/attribute-riscv_vector_cc-error.C: New test.
* gcc.target/riscv/rvv/base/attribute-riscv_vector_cc-callee-saved.c: New test.
* gcc.target/riscv/rvv/base/attribute-riscv_vector_cc-error.c: New test.
Diffstat (limited to 'gcc')
5 files changed, 119 insertions, 8 deletions
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 9f64f67..56cd8d2 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -537,24 +537,52 @@ static tree riscv_handle_fndecl_attribute (tree *, tree, tree, int, bool *); static tree riscv_handle_type_attribute (tree *, tree, tree, int, bool *); /* Defining target-specific uses of __attribute__. */ -TARGET_GNU_ATTRIBUTES (riscv_attribute_table, +static const attribute_spec riscv_gnu_attributes[] = { /* Syntax: { name, min_len, max_len, decl_required, type_required, function_type_required, affects_type_identity, handler, exclude } */ /* The attribute telling no prologue/epilogue. */ - { "naked", 0, 0, true, false, false, false, - riscv_handle_fndecl_attribute, NULL }, + {"naked", 0, 0, true, false, false, false, riscv_handle_fndecl_attribute, + NULL}, /* This attribute generates prologue/epilogue for interrupt handlers. */ - { "interrupt", 0, 1, false, true, true, false, - riscv_handle_type_attribute, NULL }, + {"interrupt", 0, 1, false, true, true, false, riscv_handle_type_attribute, + NULL}, /* The following two are used for the built-in properties of the Vector type and are not used externally */ {"RVV sizeless type", 4, 4, false, true, false, true, NULL, NULL}, - {"RVV type", 0, 0, false, true, false, true, NULL, NULL} -}); + {"RVV type", 0, 0, false, true, false, true, NULL, NULL}, + /* This attribute is used to declare a function, forcing it to use the + standard vector calling convention variant. Syntax: + __attribute__((riscv_vector_cc)). */ + {"riscv_vector_cc", 0, 0, false, true, true, true, NULL, NULL} +}; + +static const scoped_attribute_specs riscv_gnu_attribute_table = +{ + "gnu", {riscv_gnu_attributes} +}; + +static const attribute_spec riscv_attributes[] = +{ + /* This attribute is used to declare a function, forcing it to use the + standard vector calling convention variant. Syntax: + [[riscv::vector_cc]]. */ + {"vector_cc", 0, 0, false, true, true, true, NULL, NULL} +}; + +static const scoped_attribute_specs riscv_nongnu_attribute_table = +{ + "riscv", {riscv_attributes} +}; + +static const scoped_attribute_specs *const riscv_attribute_table[] = +{ + &riscv_gnu_attribute_table, + &riscv_nongnu_attribute_table +}; /* Order for the CLOBBERs/USEs of gpr_save. */ static const unsigned gpr_save_reg_order[] = { @@ -5425,6 +5453,16 @@ riscv_arguments_is_vector_type_p (const_tree fntype) return false; } +/* Return true if FUNC is a riscv_vector_cc function. + For more details please reference the below link. + https://github.com/riscv-non-isa/riscv-c-api-doc/pull/67 */ +static bool +riscv_vector_cc_function_p (const_tree fntype) +{ + return lookup_attribute ("vector_cc", TYPE_ATTRIBUTES (fntype)) != NULL_TREE + || lookup_attribute ("riscv_vector_cc", TYPE_ATTRIBUTES (fntype)) != NULL_TREE; +} + /* Implement TARGET_FNTYPE_ABI. */ static const predefined_function_abi & @@ -5434,7 +5472,8 @@ riscv_fntype_abi (const_tree fntype) reference the below link. https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/389 */ if (riscv_return_value_is_vector_type_p (fntype) - || riscv_arguments_is_vector_type_p (fntype)) + || riscv_arguments_is_vector_type_p (fntype) + || riscv_vector_cc_function_p (fntype)) return riscv_v_abi (); return default_function_abi; diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index efd78014..6c2c7ae 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -6314,6 +6314,16 @@ Permissible values for this parameter are @code{user}, @code{supervisor}, and @code{machine}. If there is no parameter, then it defaults to @code{machine}. +@cindex @code{riscv_vector_cc} function attribute, RISC-V +@item riscv_vector_cc +Use this attribute to force the function to use the vector calling +convention variant. + +@smallexample +void foo() __attribute__((riscv_vector_cc)); +[[riscv::vector_cc]] void foo(); // For C++11 and C23 +@end smallexample + @end table The following target-specific function attributes are available for the diff --git a/gcc/testsuite/g++.target/riscv/rvv/base/attribute-riscv_vector_cc-error.C b/gcc/testsuite/g++.target/riscv/rvv/base/attribute-riscv_vector_cc-error.C new file mode 100644 index 0000000..63a353b --- /dev/null +++ b/gcc/testsuite/g++.target/riscv/rvv/base/attribute-riscv_vector_cc-error.C @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -O1" } */ + +[[riscv::vector_cc]] void foo();// For C++11 and C23 + +[[riscv::vector_cc]] int var; /* { dg-warning "'vector_cc' attribute only applies to function types" } */ + +void __attribute__((riscv_vector_cc)) func(); +void __attribute__((riscv_vector_cc(1))) func_invalid(); /* { dg-error "wrong number of arguments specified for 'riscv_vector_cc' attribute" } */ + +void test_no_attribute(int); +void __attribute__((riscv_vector_cc)) test_no_attribute(int x) { } + +class test_cc { + __attribute__((riscv_vector_cc)) void member_func(); +}; + +void test_lambda() { + __attribute__((riscv_vector_cc)) auto lambda = []() { /* { dg-warning "'riscv_vector_cc' attribute only applies to function types" } */ + }; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/attribute-riscv_vector_cc-callee-saved.c b/gcc/testsuite/gcc.target/riscv/rvv/base/attribute-riscv_vector_cc-callee-saved.c new file mode 100644 index 0000000..b47ecb3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/attribute-riscv_vector_cc-callee-saved.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d" } */ + +void __attribute__((riscv_vector_cc)) bar1 (int a); +void bar2 (); + +void __attribute__((riscv_vector_cc)) +foo1 (int a) +{ + bar1 (a); +} + +void __attribute__((riscv_vector_cc)) +foo2 (int a) +{ + char data[1024]; + bar2 (); +} + +void +foo3 (int *a) +{ + bar1 (*a); +} + +/* { dg-final { scan-assembler-not {\.variant_cc\tbar2} } } */ +/* { dg-final { scan-assembler-not {\.variant_cc\tfoo3} } } */ +/* { dg-final { scan-assembler-times {\.variant_cc\tbar1} 1 } } */ +/* { dg-final { scan-assembler-times {\.variant_cc\tfoo1} 1 } } */ +/* { dg-final { scan-assembler-times {\.variant_cc\tfoo2} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/attribute-riscv_vector_cc-error.c b/gcc/testsuite/gcc.target/riscv/rvv/base/attribute-riscv_vector_cc-error.c new file mode 100644 index 0000000..ceb5e5b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/attribute-riscv_vector_cc-error.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -O1" } */ + +__attribute__((riscv_vector_cc)) int var; /* { dg-warning "'riscv_vector_cc' attribute only applies to function types" } */ +[[riscv::vector_cc]] int var1; /* { dg-warning "'vector_cc' attribute only applies to function types" } */ + +void __attribute__((riscv_vector_cc)) func(); +void __attribute__((riscv_vector_cc(1))) func_invalid(); /* { dg-error "wrong number of arguments specified for 'riscv_vector_cc' attribute" } */ + +void test_no_attribute(int); +void __attribute__((riscv_vector_cc)) test_no_attribute(int x) { } |