Skip to content

Commit f0cd70d

Browse files
xuliChen Yixuan
authored andcommitted
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. riscv-non-isa/riscv-c-api-doc#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.
1 parent 3ad1b08 commit f0cd70d

File tree

5 files changed

+119
-8
lines changed

5 files changed

+119
-8
lines changed

gcc/config/riscv/riscv.cc

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -537,24 +537,52 @@ static tree riscv_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
537537
static tree riscv_handle_type_attribute (tree *, tree, tree, int, bool *);
538538

539539
/* Defining target-specific uses of __attribute__. */
540-
TARGET_GNU_ATTRIBUTES (riscv_attribute_table,
540+
static const attribute_spec riscv_gnu_attributes[] =
541541
{
542542
/* Syntax: { name, min_len, max_len, decl_required, type_required,
543543
function_type_required, affects_type_identity, handler,
544544
exclude } */
545545

546546
/* The attribute telling no prologue/epilogue. */
547-
{ "naked", 0, 0, true, false, false, false,
548-
riscv_handle_fndecl_attribute, NULL },
547+
{"naked", 0, 0, true, false, false, false, riscv_handle_fndecl_attribute,
548+
NULL},
549549
/* This attribute generates prologue/epilogue for interrupt handlers. */
550-
{ "interrupt", 0, 1, false, true, true, false,
551-
riscv_handle_type_attribute, NULL },
550+
{"interrupt", 0, 1, false, true, true, false, riscv_handle_type_attribute,
551+
NULL},
552552

553553
/* The following two are used for the built-in properties of the Vector type
554554
and are not used externally */
555555
{"RVV sizeless type", 4, 4, false, true, false, true, NULL, NULL},
556-
{"RVV type", 0, 0, false, true, false, true, NULL, NULL}
557-
});
556+
{"RVV type", 0, 0, false, true, false, true, NULL, NULL},
557+
/* This attribute is used to declare a function, forcing it to use the
558+
standard vector calling convention variant. Syntax:
559+
__attribute__((riscv_vector_cc)). */
560+
{"riscv_vector_cc", 0, 0, false, true, true, true, NULL, NULL}
561+
};
562+
563+
static const scoped_attribute_specs riscv_gnu_attribute_table =
564+
{
565+
"gnu", {riscv_gnu_attributes}
566+
};
567+
568+
static const attribute_spec riscv_attributes[] =
569+
{
570+
/* This attribute is used to declare a function, forcing it to use the
571+
standard vector calling convention variant. Syntax:
572+
[[riscv::vector_cc]]. */
573+
{"vector_cc", 0, 0, false, true, true, true, NULL, NULL}
574+
};
575+
576+
static const scoped_attribute_specs riscv_nongnu_attribute_table =
577+
{
578+
"riscv", {riscv_attributes}
579+
};
580+
581+
static const scoped_attribute_specs *const riscv_attribute_table[] =
582+
{
583+
&riscv_gnu_attribute_table,
584+
&riscv_nongnu_attribute_table
585+
};
558586

559587
/* Order for the CLOBBERs/USEs of gpr_save. */
560588
static const unsigned gpr_save_reg_order[] = {
@@ -5417,6 +5445,16 @@ riscv_arguments_is_vector_type_p (const_tree fntype)
54175445
return false;
54185446
}
54195447

5448+
/* Return true if FUNC is a riscv_vector_cc function.
5449+
For more details please reference the below link.
5450+
https://github.com/riscv-non-isa/riscv-c-api-doc/pull/67 */
5451+
static bool
5452+
riscv_vector_cc_function_p (const_tree fntype)
5453+
{
5454+
return lookup_attribute ("vector_cc", TYPE_ATTRIBUTES (fntype)) != NULL_TREE
5455+
|| lookup_attribute ("riscv_vector_cc", TYPE_ATTRIBUTES (fntype)) != NULL_TREE;
5456+
}
5457+
54205458
/* Implement TARGET_FNTYPE_ABI. */
54215459

54225460
static const predefined_function_abi &
@@ -5426,7 +5464,8 @@ riscv_fntype_abi (const_tree fntype)
54265464
reference the below link.
54275465
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/389 */
54285466
if (riscv_return_value_is_vector_type_p (fntype)
5429-
|| riscv_arguments_is_vector_type_p (fntype))
5467+
|| riscv_arguments_is_vector_type_p (fntype)
5468+
|| riscv_vector_cc_function_p (fntype))
54305469
return riscv_v_abi ();
54315470

54325471
return default_function_abi;

gcc/doc/extend.texi

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6116,6 +6116,16 @@ Permissible values for this parameter are @code{user}, @code{supervisor},
61166116
and @code{machine}. If there is no parameter, then it defaults to
61176117
@code{machine}.
61186118

6119+
@cindex @code{riscv_vector_cc} function attribute, RISC-V
6120+
@item riscv_vector_cc
6121+
Use this attribute to force the function to use the vector calling
6122+
convention variant.
6123+
6124+
@smallexample
6125+
void foo() __attribute__((riscv_vector_cc));
6126+
[[riscv::vector_cc]] void foo(); // For C++11 and C23
6127+
@end smallexample
6128+
61196129
@end table
61206130

61216131
The following target-specific function attributes are available for the
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/* { dg-do compile } */
2+
/* { dg-options "-march=rv64gcv -mabi=lp64d -O1" } */
3+
4+
[[riscv::vector_cc]] void foo();// For C++11 and C23
5+
6+
[[riscv::vector_cc]] int var; /* { dg-warning "'vector_cc' attribute only applies to function types" } */
7+
8+
void __attribute__((riscv_vector_cc)) func();
9+
void __attribute__((riscv_vector_cc(1))) func_invalid(); /* { dg-error "wrong number of arguments specified for 'riscv_vector_cc' attribute" } */
10+
11+
void test_no_attribute(int);
12+
void __attribute__((riscv_vector_cc)) test_no_attribute(int x) { }
13+
14+
class test_cc {
15+
__attribute__((riscv_vector_cc)) void member_func();
16+
};
17+
18+
void test_lambda() {
19+
__attribute__((riscv_vector_cc)) auto lambda = []() { /* { dg-warning "'riscv_vector_cc' attribute only applies to function types" } */
20+
};
21+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/* { dg-do compile } */
2+
/* { dg-options "-march=rv64gcv -mabi=lp64d" } */
3+
4+
void __attribute__((riscv_vector_cc)) bar1 (int a);
5+
void bar2 ();
6+
7+
void __attribute__((riscv_vector_cc))
8+
foo1 (int a)
9+
{
10+
bar1 (a);
11+
}
12+
13+
void __attribute__((riscv_vector_cc))
14+
foo2 (int a)
15+
{
16+
char data[1024];
17+
bar2 ();
18+
}
19+
20+
void
21+
foo3 (int *a)
22+
{
23+
bar1 (*a);
24+
}
25+
26+
/* { dg-final { scan-assembler-not {\.variant_cc\tbar2} } } */
27+
/* { dg-final { scan-assembler-not {\.variant_cc\tfoo3} } } */
28+
/* { dg-final { scan-assembler-times {\.variant_cc\tbar1} 1 } } */
29+
/* { dg-final { scan-assembler-times {\.variant_cc\tfoo1} 1 } } */
30+
/* { dg-final { scan-assembler-times {\.variant_cc\tfoo2} 1 } } */
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/* { dg-do compile } */
2+
/* { dg-options "-march=rv64gcv -mabi=lp64d -O1" } */
3+
4+
__attribute__((riscv_vector_cc)) int var; /* { dg-warning "'riscv_vector_cc' attribute only applies to function types" } */
5+
[[riscv::vector_cc]] int var1; /* { dg-warning "'vector_cc' attribute only applies to function types" } */
6+
7+
void __attribute__((riscv_vector_cc)) func();
8+
void __attribute__((riscv_vector_cc(1))) func_invalid(); /* { dg-error "wrong number of arguments specified for 'riscv_vector_cc' attribute" } */
9+
10+
void test_no_attribute(int);
11+
void __attribute__((riscv_vector_cc)) test_no_attribute(int x) { }

0 commit comments

Comments
 (0)