diff mbox series

RISC-V: Add norelax function attribute

Message ID 20241107161904.27295-1-shiyulong@iscas.ac.cn
State New
Headers show
Series RISC-V: Add norelax function attribute | expand

Commit Message

yulong Nov. 7, 2024, 4:19 p.m. UTC
From: yulong <shiyulong@iscas.ac.cn>

This patch adds norelax function attribute that be discussed in riscv-c-api-doc PR#94.
URL:https://github.com/riscv-non-isa/riscv-c-api-doc/pull/94

gcc/ChangeLog:

        * config/riscv/riscv.cc (riscv_declare_function_name): Add new attribute.

---
 gcc/config/riscv/riscv.cc                     | 18 +++++++++++++---
 .../gcc.target/riscv/target-attr-norelax.c    | 21 +++++++++++++++++++
 2 files changed, 36 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/target-attr-norelax.c

Comments

Kito Cheng Nov. 7, 2024, 4:32 p.m. UTC | #1
LGTM, thanks!, and I will defer this for a little bit to make the
c-api side stable :)

On Fri, Nov 8, 2024 at 12:19 AM <shiyulong@iscas.ac.cn> wrote:
>
> From: yulong <shiyulong@iscas.ac.cn>
>
> This patch adds norelax function attribute that be discussed in riscv-c-api-doc PR#94.
> URL:https://github.com/riscv-non-isa/riscv-c-api-doc/pull/94
>
> gcc/ChangeLog:
>
>         * config/riscv/riscv.cc (riscv_declare_function_name): Add new attribute.
>
> ---
>  gcc/config/riscv/riscv.cc                     | 18 +++++++++++++---
>  .../gcc.target/riscv/target-attr-norelax.c    | 21 +++++++++++++++++++
>  2 files changed, 36 insertions(+), 3 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/target-attr-norelax.c
>
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index 2e9ac280c8f2..42525ff6faa3 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -654,6 +654,10 @@ static const attribute_spec riscv_gnu_attributes[] =
>       types.  */
>    {"riscv_rvv_vector_bits", 1, 1, false, true, false, true,
>     riscv_handle_rvv_vector_bits_attribute, NULL},
> +  /* This attribute is used to declare a function, forcing it to use the
> +    standard vector calling convention variant. Syntax:
> +    __attribute__((norelax)). */
> +  {"norelax", 0, 0, true, false, false, false, NULL, NULL},
>  };
>
>  static const scoped_attribute_specs riscv_gnu_attribute_table  =
> @@ -10051,10 +10055,17 @@ riscv_declare_function_name (FILE *stream, const char *name, tree fndecl)
>    riscv_asm_output_variant_cc (stream, fndecl, name);
>    ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "function");
>    ASM_OUTPUT_FUNCTION_LABEL (stream, name, fndecl);
> -  if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl))
> +  if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
> +      || lookup_attribute ("norelax", DECL_ATTRIBUTES (fndecl)))
>      {
>        fprintf (stream, "\t.option push\n");
> -
> +      if (lookup_attribute ("norelax", DECL_ATTRIBUTES (fndecl)))
> +       {
> +         fprintf (stream, "\t.option norelax\n");
> +       }
> +    }
> +  if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl))
> +    {
>        struct cl_target_option *local_cl_target =
>         TREE_TARGET_OPTION (DECL_FUNCTION_SPECIFIC_TARGET (fndecl));
>        struct cl_target_option *global_cl_target =
> @@ -10078,7 +10089,8 @@ riscv_declare_function_size (FILE *stream, const char *name, tree fndecl)
>    if (!flag_inhibit_size_directive)
>      ASM_OUTPUT_MEASURED_SIZE (stream, name);
>
> -  if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl))
> +  if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
> +      || lookup_attribute ("norelax", DECL_ATTRIBUTES (fndecl)))
>      {
>        fprintf (stream, "\t.option pop\n");
>      }
> diff --git a/gcc/testsuite/gcc.target/riscv/target-attr-norelax.c b/gcc/testsuite/gcc.target/riscv/target-attr-norelax.c
> new file mode 100644
> index 000000000000..77de6195ad1e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/target-attr-norelax.c
> @@ -0,0 +1,21 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv32gc" { target { rv32 } } } */
> +/* { dg-options "-march=rv64gc" { target { rv64 } } } */
> +
> +__attribute__((norelax))
> +void foo1()
> +{}
> +
> +void foo2(void)
> +{}
> +
> +int main()
> +{
> +  foo1();
> +  foo2();
> +  return 0;
> +}
> +
> +/* { dg-final { scan-assembler-times ".option push\t" 1 } } */
> +/* { dg-final { scan-assembler-times ".option norelax\t" 1 } } */
> +/* { dg-final { scan-assembler-times ".option pop\t" 1 } } */
> --
> 2.34.1
>
Yangyu Chen Nov. 7, 2024, 4:35 p.m. UTC | #2
Thanks for doing this!

> On Nov 8, 2024, at 00:19, shiyulong@iscas.ac.cn wrote:
> 
> From: yulong <shiyulong@iscas.ac.cn>
> 
> This patch adds norelax function attribute that be discussed in riscv-c-api-doc PR#94.
> URL:https://github.com/riscv-non-isa/riscv-c-api-doc/pull/94
> 
> gcc/ChangeLog:
> 
>        * config/riscv/riscv.cc (riscv_declare_function_name): Add new attribute.
> 
> ---
> gcc/config/riscv/riscv.cc                     | 18 +++++++++++++---
> .../gcc.target/riscv/target-attr-norelax.c    | 21 +++++++++++++++++++
> 2 files changed, 36 insertions(+), 3 deletions(-)
> create mode 100644 gcc/testsuite/gcc.target/riscv/target-attr-norelax.c
> 
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index 2e9ac280c8f2..42525ff6faa3 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -654,6 +654,10 @@ static const attribute_spec riscv_gnu_attributes[] =
>      types.  */
>   {"riscv_rvv_vector_bits", 1, 1, false, true, false, true,
>    riscv_handle_rvv_vector_bits_attribute, NULL},
> +  /* This attribute is used to declare a function, forcing it to use the
> +    standard vector calling convention variant. Syntax:
> +    __attribute__((norelax)). */
> +  {"norelax", 0, 0, true, false, false, false, NULL, NULL},
> };
> 
> static const scoped_attribute_specs riscv_gnu_attribute_table  =
> @@ -10051,10 +10055,17 @@ riscv_declare_function_name (FILE *stream, const char *name, tree fndecl)
>   riscv_asm_output_variant_cc (stream, fndecl, name);
>   ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "function");
>   ASM_OUTPUT_FUNCTION_LABEL (stream, name, fndecl);
> -  if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl))
> +  if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
> +      || lookup_attribute ("norelax", DECL_ATTRIBUTES (fndecl)))
>     {
>       fprintf (stream, "\t.option push\n");
> -
> +      if (lookup_attribute ("norelax", DECL_ATTRIBUTES (fndecl)))
> + {
> +  fprintf (stream, "\t.option norelax\n");
> + }
> +    }
> +  if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl))
> +    {

It's better to include the above 2 lines in the first block.

So the whole block `if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl))`
will be in the true block of `if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
|| lookup_attribute ("norelax", DECL_ATTRIBUTES (fndecl)))`.

Don't forget to adjust the indentation.

Otherwise, LGTM.

>       struct cl_target_option *local_cl_target =
> TREE_TARGET_OPTION (DECL_FUNCTION_SPECIFIC_TARGET (fndecl));
>       struct cl_target_option *global_cl_target =
> @@ -10078,7 +10089,8 @@ riscv_declare_function_size (FILE *stream, const char *name, tree fndecl)
>   if (!flag_inhibit_size_directive)
>     ASM_OUTPUT_MEASURED_SIZE (stream, name);
> 
> -  if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl))
> +  if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
> +      || lookup_attribute ("norelax", DECL_ATTRIBUTES (fndecl)))
>     {
>       fprintf (stream, "\t.option pop\n");
>     }
> diff --git a/gcc/testsuite/gcc.target/riscv/target-attr-norelax.c b/gcc/testsuite/gcc.target/riscv/target-attr-norelax.c
> new file mode 100644
> index 000000000000..77de6195ad1e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/target-attr-norelax.c
> @@ -0,0 +1,21 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv32gc" { target { rv32 } } } */
> +/* { dg-options "-march=rv64gc" { target { rv64 } } } */
> +
> +__attribute__((norelax))
> +void foo1()
> +{}
> +
> +void foo2(void)
> +{}
> +
> +int main()
> +{
> +  foo1();
> +  foo2();
> +  return 0;
> +}
> +
> +/* { dg-final { scan-assembler-times ".option push\t" 1 } } */
> +/* { dg-final { scan-assembler-times ".option norelax\t" 1 } } */
> +/* { dg-final { scan-assembler-times ".option pop\t" 1 } } */
> -- 
> 2.34.1
yulong Nov. 8, 2024, 7:03 a.m. UTC | #3
Thanks, Kito and yangyu!

在 2024/11/8 0:35, Yangyu Chen 写道:
> Thanks for doing this!
>
>> On Nov 8, 2024, at 00:19, shiyulong@iscas.ac.cn wrote:
>>
>> From: yulong <shiyulong@iscas.ac.cn>
>>
>> This patch adds norelax function attribute that be discussed in riscv-c-api-doc PR#94.
>> URL:https://github.com/riscv-non-isa/riscv-c-api-doc/pull/94
>>
>> gcc/ChangeLog:
>>
>>         * config/riscv/riscv.cc (riscv_declare_function_name): Add new attribute.
>>
>> ---
>> gcc/config/riscv/riscv.cc                     | 18 +++++++++++++---
>> .../gcc.target/riscv/target-attr-norelax.c    | 21 +++++++++++++++++++
>> 2 files changed, 36 insertions(+), 3 deletions(-)
>> create mode 100644 gcc/testsuite/gcc.target/riscv/target-attr-norelax.c
>>
>> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
>> index 2e9ac280c8f2..42525ff6faa3 100644
>> --- a/gcc/config/riscv/riscv.cc
>> +++ b/gcc/config/riscv/riscv.cc
>> @@ -654,6 +654,10 @@ static const attribute_spec riscv_gnu_attributes[] =
>>       types.  */
>>    {"riscv_rvv_vector_bits", 1, 1, false, true, false, true,
>>     riscv_handle_rvv_vector_bits_attribute, NULL},
>> +  /* This attribute is used to declare a function, forcing it to use the
>> +    standard vector calling convention variant. Syntax:
>> +    __attribute__((norelax)). */
>> +  {"norelax", 0, 0, true, false, false, false, NULL, NULL},
>> };
>>
>> static const scoped_attribute_specs riscv_gnu_attribute_table  =
>> @@ -10051,10 +10055,17 @@ riscv_declare_function_name (FILE *stream, const char *name, tree fndecl)
>>    riscv_asm_output_variant_cc (stream, fndecl, name);
>>    ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "function");
>>    ASM_OUTPUT_FUNCTION_LABEL (stream, name, fndecl);
>> -  if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl))
>> +  if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
>> +      || lookup_attribute ("norelax", DECL_ATTRIBUTES (fndecl)))
>>      {
>>        fprintf (stream, "\t.option push\n");
>> -
>> +      if (lookup_attribute ("norelax", DECL_ATTRIBUTES (fndecl)))
>> + {
>> +  fprintf (stream, "\t.option norelax\n");
>> + }
>> +    }
>> +  if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl))
>> +    {
> It's better to include the above 2 lines in the first block.
>
> So the whole block `if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl))`
> will be in the true block of `if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
> || lookup_attribute ("norelax", DECL_ATTRIBUTES (fndecl)))`.
>
> Don't forget to adjust the indentation.
>
> Otherwise, LGTM.
>
>>        struct cl_target_option *local_cl_target =
>> TREE_TARGET_OPTION (DECL_FUNCTION_SPECIFIC_TARGET (fndecl));
>>        struct cl_target_option *global_cl_target =
>> @@ -10078,7 +10089,8 @@ riscv_declare_function_size (FILE *stream, const char *name, tree fndecl)
>>    if (!flag_inhibit_size_directive)
>>      ASM_OUTPUT_MEASURED_SIZE (stream, name);
>>
>> -  if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl))
>> +  if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
>> +      || lookup_attribute ("norelax", DECL_ATTRIBUTES (fndecl)))
>>      {
>>        fprintf (stream, "\t.option pop\n");
>>      }
>> diff --git a/gcc/testsuite/gcc.target/riscv/target-attr-norelax.c b/gcc/testsuite/gcc.target/riscv/target-attr-norelax.c
>> new file mode 100644
>> index 000000000000..77de6195ad1e
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/riscv/target-attr-norelax.c
>> @@ -0,0 +1,21 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-march=rv32gc" { target { rv32 } } } */
>> +/* { dg-options "-march=rv64gc" { target { rv64 } } } */
>> +
>> +__attribute__((norelax))
>> +void foo1()
>> +{}
>> +
>> +void foo2(void)
>> +{}
>> +
>> +int main()
>> +{
>> +  foo1();
>> +  foo2();
>> +  return 0;
>> +}
>> +
>> +/* { dg-final { scan-assembler-times ".option push\t" 1 } } */
>> +/* { dg-final { scan-assembler-times ".option norelax\t" 1 } } */
>> +/* { dg-final { scan-assembler-times ".option pop\t" 1 } } */
>> -- 
>> 2.34.1
diff mbox series

Patch

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 2e9ac280c8f2..42525ff6faa3 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -654,6 +654,10 @@  static const attribute_spec riscv_gnu_attributes[] =
      types.  */
   {"riscv_rvv_vector_bits", 1, 1, false, true, false, true,
    riscv_handle_rvv_vector_bits_attribute, NULL},
+  /* This attribute is used to declare a function, forcing it to use the
+    standard vector calling convention variant. Syntax:
+    __attribute__((norelax)). */
+  {"norelax", 0, 0, true, false, false, false, NULL, NULL},
 };
 
 static const scoped_attribute_specs riscv_gnu_attribute_table  =
@@ -10051,10 +10055,17 @@  riscv_declare_function_name (FILE *stream, const char *name, tree fndecl)
   riscv_asm_output_variant_cc (stream, fndecl, name);
   ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "function");
   ASM_OUTPUT_FUNCTION_LABEL (stream, name, fndecl);
-  if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl))
+  if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
+      || lookup_attribute ("norelax", DECL_ATTRIBUTES (fndecl)))
     {
       fprintf (stream, "\t.option push\n");
-
+      if (lookup_attribute ("norelax", DECL_ATTRIBUTES (fndecl)))
+	{
+	  fprintf (stream, "\t.option norelax\n");
+	}
+    }
+  if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl))
+    {
       struct cl_target_option *local_cl_target =
 	TREE_TARGET_OPTION (DECL_FUNCTION_SPECIFIC_TARGET (fndecl));
       struct cl_target_option *global_cl_target =
@@ -10078,7 +10089,8 @@  riscv_declare_function_size (FILE *stream, const char *name, tree fndecl)
   if (!flag_inhibit_size_directive)
     ASM_OUTPUT_MEASURED_SIZE (stream, name);
 
-  if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl))
+  if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
+      || lookup_attribute ("norelax", DECL_ATTRIBUTES (fndecl)))
     {
       fprintf (stream, "\t.option pop\n");
     }
diff --git a/gcc/testsuite/gcc.target/riscv/target-attr-norelax.c b/gcc/testsuite/gcc.target/riscv/target-attr-norelax.c
new file mode 100644
index 000000000000..77de6195ad1e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/target-attr-norelax.c
@@ -0,0 +1,21 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc" { target { rv64 } } } */
+
+__attribute__((norelax))
+void foo1()
+{}
+
+void foo2(void)
+{}
+
+int main()
+{
+  foo1();
+  foo2();
+  return 0;
+}
+
+/* { dg-final { scan-assembler-times ".option push\t" 1 } } */
+/* { dg-final { scan-assembler-times ".option norelax\t" 1 } } */
+/* { dg-final { scan-assembler-times ".option pop\t" 1 } } */