summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxuli <xuli1@eswincomputing.com>2024-03-01 09:10:12 +0000
committerPan Li <pan2.li@intel.com>2024-03-01 18:55:26 +0800
commit4547628c78618616595f4b5e1bef2b582c77793d (patch)
tree7589b2bd2633ad30d9498a993e7dccf1e6d19915
parent0a01d1232ff0a8b094270fbf45c9fd0ea46df19f (diff)
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.
-rw-r--r--gcc/config/riscv/riscv.cc55
-rw-r--r--gcc/doc/extend.texi10
-rw-r--r--gcc/testsuite/g++.target/riscv/rvv/base/attribute-riscv_vector_cc-error.C21
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/attribute-riscv_vector_cc-callee-saved.c30
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/attribute-riscv_vector_cc-error.c11
5 files changed, 119 insertions, 8 deletions
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 9f64f67cbdd..56cd8d2c23f 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 efd78014d1a..6c2c7ae5d8a 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 00000000000..63a353bebd0
--- /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 00000000000..b47ecb3b828
--- /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 00000000000..ceb5e5bf6dd
--- /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) { }