From patchwork Wed Aug 16 16:32:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guillaume Gomez X-Patchwork-Id: 1821964 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=cd9mBuZJ; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RQtwH1DSRz1yNr for ; Thu, 17 Aug 2023 02:32:45 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 8ABE43858D33 for ; Wed, 16 Aug 2023 16:32:43 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8ABE43858D33 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1692203563; bh=gEmbrOSwYaRda+FZ5BmEdIUy8hHHUjoBcEqXsy3nWfM=; h=Date:Subject:To:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=cd9mBuZJbzxcom0OFXt4YlYO+LTovItDTGOyQcs5K/VAFvzTdBsPfjN1sLe4ddaH0 7wNKgbNdbduSUYFnimajUdqqz7itdGWOpODguHlps9FJos/xpZWjfCH9SGp9CJVhLN PDrKES917rvQ+UomaKadjO1uXKMXQhfnodnoTMAA= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wm1-x32e.google.com (mail-wm1-x32e.google.com [IPv6:2a00:1450:4864:20::32e]) by sourceware.org (Postfix) with ESMTPS id C9AD53858D33; Wed, 16 Aug 2023 16:32:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C9AD53858D33 Received: by mail-wm1-x32e.google.com with SMTP id 5b1f17b1804b1-3fe24dd8898so63603675e9.2; Wed, 16 Aug 2023 09:32:19 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692203539; x=1692808339; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=gEmbrOSwYaRda+FZ5BmEdIUy8hHHUjoBcEqXsy3nWfM=; b=DWDWgvoDRFXr29UXnXQzaTAKkblSfP5Vu5C+Sq3Hzzos9TfF8mR2j+WxygG5plRNJM A7zts6n2RtvwGK1271zClAyPelSH5hgCbKyiVTBUL9yROm2F+k/Rr6uwgHwC7cRiwRqR CGDoLw6Mo8rg8OzWlKOlDYmaJgZVxjwoJiZrxFEoluX673Vp14jqaloedu5x5loRYTQA UZsgTi79qhYAfkPPNcT7rJY9+Vp1ANKGLLREt05ZV25kFDiG9IOm7WZWiYwTn3VISXXt yb4toHQdCGOUyIL+gm0yUC6EE2qMHkWBYJX5Xozc/dKSMhKzMiMKJhyQVvfL2E+bFvY2 vWug== X-Gm-Message-State: AOJu0YwHtAeHobFPeed8cjmHd4kJx+whjl9DkNZXminrAHLiXaC+BHLz Dsl6Tae0hwA7qA6HHF9dwuQ83I7G9Nk/IECj8oRs79Z99ko= X-Google-Smtp-Source: AGHT+IHE/1V8RYQIzhrvhswrgbwhjnL02RewcmRduqF1aEG+ygLO4v8AADTCxob0SH3mENTZyKQwRrnLrU/zLXOUs8I= X-Received: by 2002:a7b:cbd0:0:b0:3fb:fea1:affa with SMTP id n16-20020a7bcbd0000000b003fbfea1affamr1806161wmi.37.1692203538541; Wed, 16 Aug 2023 09:32:18 -0700 (PDT) MIME-Version: 1.0 Date: Wed, 16 Aug 2023 18:32:07 +0200 Message-ID: Subject: [PATCH] libgccjit: Add support for `restrict` attribute on function parameters To: gcc-patches@gcc.gnu.org, jit@gcc.gnu.org X-Spam-Status: No, score=-8.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Guillaume Gomez via Gcc-patches From: Guillaume Gomez Reply-To: Guillaume Gomez Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" Hi, This patch adds the possibility to specify the __restrict__ attribute for function parameters. It is used by the Rust GCC backend. Thanks in advance for the review. From 8cafadb8409094c7fc66a1073397942a60cb27b3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 11 Aug 2023 22:48:11 +0200 Subject: [PATCH] Add support for `restrict` attribute on function parameters gcc/jit/Changelog: * jit-playback.cc: Remove trailing whitespace characters. * jit-playback.h: Add get_restrict method. * jit-recording.cc: Add get_restrict methods. * jit-recording.h: Add get_restrict methods. * libgccjit++.h: Add get_restrict methods. * libgccjit.cc: Add gcc_jit_type_get_restrict. * libgccjit.h: Declare gcc_jit_type_get_restrict. * libgccjit.map: Declare gcc_jit_type_get_restrict. gcc/testsuite/ChangeLog: * jit.dg/test-restrict.c: Add test for __restrict__ attribute. Signed-off-by: Guillaume Gomez --- gcc/jit/jit-playback.cc | 2 +- gcc/jit/jit-playback.h | 5 ++ gcc/jit/jit-recording.cc | 47 +++++++++++++++++ gcc/jit/jit-recording.h | 37 ++++++++++++- gcc/jit/libgccjit++.h | 6 +++ gcc/jit/libgccjit.cc | 14 +++++ gcc/jit/libgccjit.h | 4 ++ gcc/jit/libgccjit.map | 1 + gcc/testsuite/jit.dg/test-restrict.c | 77 ++++++++++++++++++++++++++++ 9 files changed, 191 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/jit.dg/test-restrict.c diff --git a/gcc/jit/jit-playback.cc b/gcc/jit/jit-playback.cc index 88e1b212030..0eb4e94fdc4 100644 --- a/gcc/jit/jit-playback.cc +++ b/gcc/jit/jit-playback.cc @@ -3793,7 +3793,7 @@ if (t) \ NAME_TYPE (complex_float_type_node, "complex float"); NAME_TYPE (complex_double_type_node, "complex double"); NAME_TYPE (complex_long_double_type_node, "complex long double"); - + m_const_char_ptr = build_pointer_type( build_qualified_type (char_type_node, TYPE_QUAL_CONST)); diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h index d153f4945d8..fb4f7b8b65b 100644 --- a/gcc/jit/jit-playback.h +++ b/gcc/jit/jit-playback.h @@ -490,6 +490,11 @@ public: return new type (build_qualified_type (m_inner, TYPE_QUAL_VOLATILE)); } + type *get_restrict () const + { + return new type (build_qualified_type (m_inner, TYPE_QUAL_RESTRICT)); + } + type *get_aligned (size_t alignment_in_bytes) const; type *get_vector (size_t num_units) const; diff --git a/gcc/jit/jit-recording.cc b/gcc/jit/jit-recording.cc index f962c9748c4..c5f50349311 100644 --- a/gcc/jit/jit-recording.cc +++ b/gcc/jit/jit-recording.cc @@ -2380,6 +2380,19 @@ recording::type::get_const () return result; } +/* Given a type T, get the type restrict T. + + Implements the post-error-checking part of + gcc_jit_type_get_restrict. */ + +recording::type * +recording::type::get_restrict () +{ + recording::type *result = new memento_of_get_restrict (this); + m_ctxt->record (result); + return result; +} + /* Given a type T, get the type volatile T. Implements the post-error-checking part of @@ -3090,6 +3103,40 @@ recording::memento_of_get_volatile::write_reproducer (reproducer &r) r.get_identifier_as_type (m_other_type)); } +/* The implementation of class gcc::jit::recording::memento_of_get_restrict. */ + +/* Implementation of pure virtual hook recording::memento::replay_into + for recording::memento_of_get_restrict. */ + +void +recording::memento_of_get_restrict::replay_into (replayer *) +{ + set_playback_obj (m_other_type->playback_type ()->get_restrict ()); +} + +/* Implementation of recording::memento::make_debug_string for + results of get_restrict, prepending "restrict ". */ + +recording::string * +recording::memento_of_get_restrict::make_debug_string () +{ + return string::from_printf (m_ctxt, + "restrict %s", m_other_type->get_debug_string ()); +} + +/* Implementation of recording::memento::write_reproducer for restrict + types. */ + +void +recording::memento_of_get_restrict::write_reproducer (reproducer &r) +{ + const char *id = r.make_identifier (this, "type"); + r.write (" gcc_jit_type *%s =\n" + " gcc_jit_type_get_restrict (%s);\n", + id, + r.get_identifier_as_type (m_other_type)); +} + /* The implementation of class gcc::jit::recording::memento_of_get_aligned. */ /* Implementation of pure virtual hook recording::memento::replay_into diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h index 929bbe37c3f..1aff22ff689 100644 --- a/gcc/jit/jit-recording.h +++ b/gcc/jit/jit-recording.h @@ -555,6 +555,7 @@ public: type *get_pointer (); type *get_const (); type *get_volatile (); + type *get_restrict (); type *get_aligned (size_t alignment_in_bytes); type *get_vector (size_t num_units); @@ -603,6 +604,7 @@ public: virtual bool is_bool () const = 0; virtual type *is_pointer () = 0; virtual type *is_volatile () { return NULL; } + virtual type *is_restrict () { return NULL; } virtual type *is_const () { return NULL; } virtual type *is_array () = 0; virtual struct_ *is_struct () { return NULL; } @@ -737,7 +739,7 @@ private: }; /* A decorated version of a type, for get_const, get_volatile, - get_aligned, and get_vector. */ + get_aligned, get_restrict, and get_vector. */ class decorated_type : public type { @@ -829,6 +831,39 @@ private: void write_reproducer (reproducer &r) final override; }; +/* Result of "gcc_jit_type_get_restrict". */ +class memento_of_get_restrict : public decorated_type +{ +public: + memento_of_get_restrict (type *other_type) + : decorated_type (other_type) {} + + bool is_same_type_as (type *other) final override + { + if (!other->is_restrict ()) + return false; + return m_other_type->is_same_type_as (other->is_restrict ()); + } + + type* copy(context* ctxt) final override + { + type* result = new memento_of_get_restrict (m_other_type->copy (ctxt)); + ctxt->record (result); + return result; + } + + /* Strip off the "restrict", giving the underlying type. */ + type *unqualified () final override { return m_other_type; } + + type *is_restrict () final override { return m_other_type; } + + void replay_into (replayer *) final override; + +private: + string * make_debug_string () final override; + void write_reproducer (reproducer &r) final override; +}; + /* Result of "gcc_jit_type_get_aligned". */ class memento_of_get_aligned : public decorated_type { diff --git a/gcc/jit/libgccjit++.h b/gcc/jit/libgccjit++.h index 4b88e877bc9..b430f7eb049 100644 --- a/gcc/jit/libgccjit++.h +++ b/gcc/jit/libgccjit++.h @@ -1410,6 +1410,12 @@ type::get_const () return type (gcc_jit_type_get_const (get_inner_type ())); } +inline type +type::get_restrict () +{ + return type (gcc_jit_type_get_restrict (get_inner_type ())); +} + inline type type::get_volatile () { diff --git a/gcc/jit/libgccjit.cc b/gcc/jit/libgccjit.cc index 050e68b738c..9b87e0569d6 100644 --- a/gcc/jit/libgccjit.cc +++ b/gcc/jit/libgccjit.cc @@ -539,6 +539,20 @@ gcc_jit_type_get_volatile (gcc_jit_type *type) return (gcc_jit_type *)type->get_volatile (); } +/* Public entrypoint. See description in libgccjit.h. + + After error-checking, the real work is done by the + gcc::jit::recording::type::get_restrict method, in + jit-recording.cc. */ + +gcc_jit_type * +gcc_jit_type_get_restrict (gcc_jit_type *type) +{ + RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type"); + + return (gcc_jit_type *)type->get_restrict (); +} + /* Public entrypoint. See description in libgccjit.h. After error-checking, the real work is done by the diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h index 60eaf39bff6..2e0d08a06d8 100644 --- a/gcc/jit/libgccjit.h +++ b/gcc/jit/libgccjit.h @@ -635,6 +635,10 @@ gcc_jit_type_get_const (gcc_jit_type *type); extern gcc_jit_type * gcc_jit_type_get_volatile (gcc_jit_type *type); +/* Given type "T", get type "restrict T". */ +extern gcc_jit_type * +gcc_jit_type_get_restrict (gcc_jit_type *type); + #define LIBGCCJIT_HAVE_SIZED_INTEGERS /* Given types LTYPE and RTYPE, return non-zero if they are compatible. diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map index e52de0057a5..b7289b13845 100644 --- a/gcc/jit/libgccjit.map +++ b/gcc/jit/libgccjit.map @@ -104,6 +104,7 @@ LIBGCCJIT_ABI_0 gcc_jit_type_as_object; gcc_jit_type_get_const; gcc_jit_type_get_pointer; + gcc_jit_type_get_restrict; gcc_jit_type_get_volatile; local: *; diff --git a/gcc/testsuite/jit.dg/test-restrict.c b/gcc/testsuite/jit.dg/test-restrict.c new file mode 100644 index 00000000000..4c8c4407f91 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-restrict.c @@ -0,0 +1,77 @@ +/* { dg-do compile { target x86_64-*-* } } */ + +#include +#include + +#include "libgccjit.h" + +/* We don't want set_options() in harness.h to set -O3 to see that the cold + attribute affects the optimizations. */ +#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); +} + +#define TEST_COMPILING_TO_FILE +#define OUTPUT_KIND GCC_JIT_OUTPUT_KIND_ASSEMBLER +#define OUTPUT_FILENAME "output-of-test-restrict.c.s" +#include "harness.h" + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: +void t(int *__restrict__ a, int *__restrict__ b, char *__restrict__ c) { + *a += *c; + *b += *c; +} + */ + gcc_jit_type *int_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_type *pint_type = gcc_jit_type_get_pointer(int_type); + gcc_jit_type *pint_restrict_type = gcc_jit_type_get_restrict(pint_type); + + gcc_jit_type *void_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); + + gcc_jit_param *a = + gcc_jit_context_new_param (ctxt, NULL, pint_restrict_type, "a"); + gcc_jit_param *b = + gcc_jit_context_new_param (ctxt, NULL, pint_restrict_type, "b"); + gcc_jit_param *c = + gcc_jit_context_new_param (ctxt, NULL, pint_restrict_type, "c"); + gcc_jit_param *params[3] = {a, b, c}; + + gcc_jit_function *func_t = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + void_type, + "t", + 3, params, + 0); + + gcc_jit_block *block = gcc_jit_function_new_block (func_t, NULL); + + /* *a += *c; */ + gcc_jit_block_add_assignment_op ( + block, NULL, + gcc_jit_rvalue_dereference (gcc_jit_param_as_rvalue (a), NULL), + GCC_JIT_BINARY_OP_PLUS, + gcc_jit_lvalue_as_rvalue ( + gcc_jit_rvalue_dereference (gcc_jit_param_as_rvalue (c), NULL))); + /* *b += *c; */ + gcc_jit_block_add_assignment_op ( + block, NULL, + gcc_jit_rvalue_dereference (gcc_jit_param_as_rvalue (b), NULL), + GCC_JIT_BINARY_OP_PLUS, + gcc_jit_lvalue_as_rvalue ( + gcc_jit_rvalue_dereference (gcc_jit_param_as_rvalue (c), NULL))); + + gcc_jit_block_end_with_void_return (block, NULL); +} + +/* { dg-final { jit-verify-output-file-was-created "" } } */ +/* { dg-final { jit-verify-assembler-output "addl %eax, (%rdi) + addl %eax, (%rsi)" } } */ -- 2.34.1