Skip to content

Commit 4547628

Browse files
xuliIncarnation-p-lee
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 0a01d12 commit 4547628

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[] = {
@@ -5425,6 +5453,16 @@ riscv_arguments_is_vector_type_p (const_tree fntype)
54255453
return false;
54265454
}
54275455

5456+
/* Return true if FUNC is a riscv_vector_cc function.
5457+
For more details please reference the below link.
5458+
https://github.com/riscv-non-isa/riscv-c-api-doc/pull/67 */
5459+
static bool
5460+
riscv_vector_cc_function_p (const_tree fntype)
5461+
{
5462+
return lookup_attribute ("vector_cc", TYPE_ATTRIBUTES (fntype)) != NULL_TREE
5463+
|| lookup_attribute ("riscv_vector_cc", TYPE_ATTRIBUTES (fntype)) != NULL_TREE;
5464+
}
5465+
54285466
/* Implement TARGET_FNTYPE_ABI. */
54295467

54305468
static const predefined_function_abi &
@@ -5434,7 +5472,8 @@ riscv_fntype_abi (const_tree fntype)
54345472
reference the below link.
54355473
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/389 */
54365474
if (riscv_return_value_is_vector_type_p (fntype)
5437-
|| riscv_arguments_is_vector_type_p (fntype))
5475+
|| riscv_arguments_is_vector_type_p (fntype)
5476+
|| riscv_vector_cc_function_p (fntype))
54385477
return riscv_v_abi ();
54395478

54405479
return default_function_abi;

gcc/doc/extend.texi

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

6317+
@cindex @code{riscv_vector_cc} function attribute, RISC-V
6318+
@item riscv_vector_cc
6319+
Use this attribute to force the function to use the vector calling
6320+
convention variant.
6321+
6322+
@smallexample
6323+
void foo() __attribute__((riscv_vector_cc));
6324+
[[riscv::vector_cc]] void foo(); // For C++11 and C23
6325+
@end smallexample
6326+
63176327
@end table
63186328

63196329
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)