public inbox for jit@gcc.gnu.org
 help / color / mirror / Atom feed
From: David Malcolm <dmalcolm@redhat.com>
To: Guillaume Gomez <guillaume1.gomez@gmail.com>,
	jit@gcc.gnu.org, Antoni <bouanto@zoho.com>,
	gcc-patches@gcc.gnu.org
Subject: Re: [PATCH] Add support for function attributes and variable attributes
Date: Tue, 09 Jan 2024 14:59:16 -0500	[thread overview]
Message-ID: <319a998a3c63eaf0e28d7267a901ad2c016dba49.camel@redhat.com> (raw)
In-Reply-To: <CAAOQCfT5NTWWS-u1Ws=reCz3RO7ax8SkJ6vSNs5o_aD5nPD2og@mail.gmail.com>

On Wed, 2023-11-15 at 17:53 +0100, Guillaume Gomez wrote:
> Hi,
> 
> This patch adds the (incomplete) support for function and variable
> attributes. The added attributes are the ones we're using in
> rustc_codegen_gcc but all the groundwork is done to add more (and we
> will very likely add more as we didn't add all the ones we use in
> rustc_codegen_gcc yet).
> 
> The only big question with this patch is about `inline`. We currently
> handle it as an attribute because it is more convenient for us but is
> it ok or should we create a separate function to mark a function as
> inlined?
> 
> Thanks in advance for the review.

Thanks for the patch; sorry for the delay in reviewing.

At a high-level I think the API is OK as-is, but I have some nitpicks
with the implementation:

[...snip...]

> diff --git a/gcc/jit/docs/topics/types.rst b/gcc/jit/docs/topics/types.rst
> index d8c1d15d69d..6c72c99cbd9 100644
> --- a/gcc/jit/docs/topics/types.rst
> +++ b/gcc/jit/docs/topics/types.rst

[...snip...]

> +.. function::  void\
> +               gcc_jit_lvalue_add_string_attribute (gcc_jit_lvalue *variable,
> +                                                    enum gcc_jit_fn_attribute attribute,
                                                                    ^^

This got out of sync with the declaration in the header file; it should
be
    enum gcc_jit_variable_attribute attribute

[...snip...]

> diff --git a/gcc/jit/dummy-frontend.cc b/gcc/jit/dummy-frontend.cc
> index a729086bafb..898b4d6e7f8 100644
> --- a/gcc/jit/dummy-frontend.cc
> +++ b/gcc/jit/dummy-frontend.cc

It's unfortunate that jit/dummy-frontend.cc has its own copy of the
material in c-common/c-attribs.cc.  I glanced through this code, and it
seems that there are already various differences between the two copies
in the existing code, and the patch adds more such differences.

Bother - but I think this part of the patch is inevitable (and OK)
given the existing state of attribute handling here.

[...snip...]

I took a brief look through the handler functions and with the above
caveat I didn't see anything obviously wrong.  I'm going to assume this
code is OK given that presumably you've been testing it within rustcc,
right?

[..snip...]

> diff --git a/gcc/jit/libgccjit.cc b/gcc/jit/libgccjit.cc
> index 0451b4df7f9..337d4ea3b95 100644
> --- a/gcc/jit/libgccjit.cc
> +++ b/gcc/jit/libgccjit.cc
> @@ -3965,6 +3965,51 @@ gcc_jit_type_get_aligned (gcc_jit_type *type,
>    return (gcc_jit_type *)type->get_aligned (alignment_in_bytes);
>  }
>  
> +void
> +gcc_jit_function_add_attribute (gcc_jit_function *func,
> +				gcc_jit_fn_attribute attribute)
> +{
> +  RETURN_IF_FAIL (func, NULL, NULL, "NULL func");
> +
> +  func->add_attribute (attribute);

Ideally should validate parameter "attribute" here with a
RETURN_IF_FAIL.

> +}
> +
> +void
> +gcc_jit_function_add_string_attribute (gcc_jit_function *func,
> +				       gcc_jit_fn_attribute attribute,
> +				       const char* value)
> +{
> +  RETURN_IF_FAIL (func, NULL, NULL, "NULL func");

Likewise, ideally should validate parameter "attribute" here with a
RETURN_IF_FAIL.

Can "value" be NULL?  If not, then we should add a RETURN_IF_FAIL for
it here at the API boundary.

> +
> +  func->add_string_attribute (attribute, value);
> +}
> +
> +/* This function adds an attribute with multiple integer values.  For example
> +   `nonnull(1, 2)`.  The numbers in `values` are supposed to map how they
> +   should be written in C code.  So for `nonnull(1, 2)`, you should pass `1`
> +   and `2` in `values` (and set `length` to `2`). */
> +void
> +gcc_jit_function_add_integer_array_attribute (gcc_jit_function *func,
> +					      gcc_jit_fn_attribute attribute,
> +					      const int* values,
> +					      size_t length)
> +{
> +  RETURN_IF_FAIL (func, NULL, NULL, "NULL func");

As before, ideally should validate parameter "attribute" here with a
RETURN_IF_FAIL.

> +  RETURN_IF_FAIL (values, NULL, NULL, "NULL values");
> +
> +  func->add_integer_array_attribute (attribute, values, length);
> +}
> +
> +void
> +gcc_jit_lvalue_add_string_attribute (gcc_jit_lvalue *variable,
> +				     gcc_jit_variable_attribute attribute,
> +				     const char* value)
> +{
> +  RETURN_IF_FAIL (variable, NULL, NULL, "NULL variable");

As before, we should validate parameters "attribute" and "value" here
with RETURN_IF_FAILs.

We should also validate here that "variable" is indeed a variable, not
some arbitrary lvalue e.g. the address of the element of an array (or
whatever).


> +
> +  variable->add_string_attribute (attribute, value);
> +}
> +

[...snip...]

> diff --git a/gcc/testsuite/jit.dg/jit.exp b/gcc/testsuite/jit.dg/jit.exp
> index 8bf7e51c24f..657b454a003 100644
> --- a/gcc/testsuite/jit.dg/jit.exp
> +++ b/gcc/testsuite/jit.dg/jit.exp
> @@ -899,8 +899,41 @@ proc jit-verify-assembler-output { args } {
>  	pass "${asm_filename} output pattern test, ${dg-output-text}"
>  	verbose "Passed test for output pattern ${dg-output-text}" 3
>      }
> +}
> +
> +# Assuming that a .s file has been written out named
> +# OUTPUT_FILENAME, check that the argument doesn't match
> +# the output file.
> +proc jit-verify-assembler-output-not { args } {
> +    verbose "jit-verify-assembler: $args"
> +
> +    set dg-output-text [lindex $args 0]
> +    verbose "dg-output-text: ${dg-output-text}"
> +
> +    upvar 2 name name
> +    verbose "name: $name"
> +
> +    upvar 2 prog prog
> +    verbose "prog: $prog"
> +    set asm_filename [jit-get-output-filename $prog]
> +    verbose "  asm_filename: ${asm_filename}"
>  
> +    # Read the assembly file.
> +    set f [open $asm_filename r]
> +    set content [read $f]
> +    close $f
> +
> +    # Verify that the assembly matches the regex.
> +    if { [regexp ${dg-output-text} $content] } {
> +	fail "${asm_filename} output pattern test, is ${content}, should match ${dg-output-text}"

The wording of the "fail" message seems wrong; presumably this should
read "should not match", rather than "should match".

> +	verbose "Failed test for output pattern ${dg-output-text}" 3
> +    } else {
> +	pass "${asm_filename} output pattern test, ${dg-output-text}"
> +	verbose "Passed test for output pattern ${dg-output-text}" 3
> +    }
>  }
> +
> +
>  # Assuming that a .o file has been written out named
>  # OUTPUT_FILENAME, invoke the driver to try to turn it into
>  # an executable, and try to run the result.

[...snip...]

> diff --git a/gcc/testsuite/jit.dg/test-cold-attribute.c b/gcc/testsuite/jit.dg/test-cold-attribute.c
> new file mode 100644
> index 00000000000..8dc7ec5a34b
> --- /dev/null
> +++ b/gcc/testsuite/jit.dg/test-cold-attribute.c
> @@ -0,0 +1,54 @@
> +/* { dg-do compile { target x86_64-*-* } } */
> +
> +#include <stdlib.h>
> +#include <stdio.h>
> +
> +#include "libgccjit.h"
> +
> +/* We don't want set_options() in harness.h to set -O2 to see that the cold
> +   attribute affects the optimizations. */

The above comment doesn't make sense to me; harness.h effectively sets
-O3; and -O2 is wanted by this test, right?

I think the comment can be omitted given that the intent below is
clear.

> +#define TEST_ESCHEWS_SET_OPTIONS
> +static void set_options (gcc_jit_context *ctxt, const char *argv0)
> +{
> +  // Set "-O2".
> +  gcc_jit_context_set_int_option(ctxt, GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 2);
> +}

[...snip...]

> diff --git a/gcc/testsuite/jit.dg/test-const-attribute.c b/gcc/testsuite/jit.dg/test-const-attribute.c
> new file mode 100644
> index 00000000000..c06742d163f
> --- /dev/null
> +++ b/gcc/testsuite/jit.dg/test-const-attribute.c
> @@ -0,0 +1,134 @@
> +/* { dg-do compile { target x86_64-*-* } } */
> +
> +#include <stdlib.h>
> +#include <stdio.h>
> +
> +#include "libgccjit.h"
> +
> +/* We don't want set_options() in harness.h to set -O3 to see that the const
> +   attribute affects the optimizations. */

Again, this comment doesn't make sense to me, but I think it can be
removed.

> +#define TEST_ESCHEWS_SET_OPTIONS
> +static void set_options (gcc_jit_context *ctxt, const char *argv0)
> +{
> +  // Set "-O3".
> +  gcc_jit_context_set_int_option(ctxt, GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3);
> +}
> +

[...snip...]

> +
> +  /* if (x >>= 1) */
> +  /* Since gccjit doesn't (yet?) have support for `>>=` operator, we will decompose it into:
> +     `if (x = x >> 1)` */

I think it does (in theory, at least), via:

  gcc_jit_block_add_assignment_op

with

  GCC_JIT_BINARY_OP_RSHIFT

But I haven't tried it, and there's no need to update the test to make
use of it.

[...snip...]

> diff --git a/gcc/testsuite/jit.dg/test-noinline-attribute.c b/gcc/testsuite/jit.dg/test-noinline-attribute.c
> new file mode 100644
> index 00000000000..84933e60010
> --- /dev/null
> +++ b/gcc/testsuite/jit.dg/test-noinline-attribute.c
> @@ -0,0 +1,114 @@
> +/* { dg-do compile { target x86_64-*-* } } */
> +
> +#include <stdlib.h>
> +#include <stdio.h>
> +
> +#include "libgccjit.h"
> +
> +/* We don't want set_options() in harness.h to set -O2 to see that the `noinline`
> +   attribute affects the optimizations. */

Again, please lose this comment.

> +#define TEST_ESCHEWS_SET_OPTIONS
> +static void set_options (gcc_jit_context *ctxt, const char *argv0)
> +{
> +  // Set "-O2".
> +  gcc_jit_context_set_int_option(ctxt, GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 2);
> +}

[...snip...]

> diff --git a/gcc/testsuite/jit.dg/test-nonnull-attribute.c b/gcc/testsuite/jit.dg/test-nonnull-attribute.c
> new file mode 100644
> index 00000000000..3306f890657
> --- /dev/null
> +++ b/gcc/testsuite/jit.dg/test-nonnull-attribute.c
> @@ -0,0 +1,94 @@
> +/* { dg-do compile { target x86_64-*-* } } */
> +
> +#include <stdlib.h>
> +#include <stdio.h>
> +
> +#include "libgccjit.h"
> +
> +/* We don't want set_options() in harness.h to set -O2 to see that the nonnull
> +   attribute affects the optimizations. */

Likewise.

> +#define TEST_ESCHEWS_SET_OPTIONS
> +static void set_options (gcc_jit_context *ctxt, const char *argv0)
> +{
> +  // Set "-O2".
> +  gcc_jit_context_set_int_option(ctxt, GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 2);
> +}
> +

[...snip...]

> diff --git a/gcc/testsuite/jit.dg/test-pure-attribute.c b/gcc/testsuite/jit.dg/test-pure-attribute.c
> new file mode 100644
> index 00000000000..0c9ba1366e0
> --- /dev/null
> +++ b/gcc/testsuite/jit.dg/test-pure-attribute.c
> @@ -0,0 +1,134 @@
> +/* { dg-do compile { target x86_64-*-* } } */
> +
> +#include <stdlib.h>
> +#include <stdio.h>
> +
> +#include "libgccjit.h"
> +
> +/* We don't want set_options() in harness.h to set -O3 to see that the pure
> +   attribute affects the optimizations. */

Likewise.

> +#define TEST_ESCHEWS_SET_OPTIONS
> +static void set_options (gcc_jit_context *ctxt, const char *argv0)
> +{
> +  // Set "-O3".
> +  gcc_jit_context_set_int_option(ctxt, GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3);
> +}
> +

[...snip...]

Please update jit.dg/all-non-failing-tests.h for the new tests; it's
meant to list all of the (non failing) tests alphabetically.

I *think* all of the new tests aren't suitable to be run as part of a
shared context (e.g. due to touching the optimization level or
examining generated asm), so they should be listed in that header with
comments explaining why.

Thanks again for the patch.
Dave


  parent reply	other threads:[~2024-01-09 19:59 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-15 16:53 Guillaume Gomez
2023-11-15 16:56 ` Antoni Boucher
2023-11-23 21:52   ` Guillaume Gomez
2023-11-23 21:59     ` Antoni Boucher
2023-11-30  9:55       ` Guillaume Gomez
2023-12-07 17:13         ` Antoni Boucher
2023-12-09 11:12           ` Guillaume Gomez
2023-12-18 22:27             ` Guillaume Gomez
2024-01-03 13:37               ` Guillaume Gomez
2024-01-09 19:59 ` David Malcolm [this message]
2024-01-11  0:00   ` Guillaume Gomez
2024-01-11 18:46     ` David Malcolm
2024-01-11 21:40       ` Guillaume Gomez
2024-01-11 22:38         ` David Malcolm
2024-01-12 10:09           ` Guillaume Gomez
2024-01-12 13:47             ` Guillaume Gomez

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=319a998a3c63eaf0e28d7267a901ad2c016dba49.camel@redhat.com \
    --to=dmalcolm@redhat.com \
    --cc=bouanto@zoho.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=guillaume1.gomez@gmail.com \
    --cc=jit@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).