From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 120238 invoked by alias); 5 Jan 2019 22:10:50 -0000 Mailing-List: contact jit-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Subscribe: Sender: jit-owner@gcc.gnu.org Received: (qmail 120216 invoked by uid 89); 5 Jan 2019 22:10:49 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Checked: by ClamAV 0.100.2 on sourceware.org X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 spammy=Within, sk:decl_de, sk:verify_, sk:set_dec X-Spam-Status: No, score=-26.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on sourceware.org X-Spam-Level: X-Spam-User: qpsmtpd, 2 recipients X-HELO: mail-pf1-f180.google.com Received: from mail-pf1-f180.google.com (HELO mail-pf1-f180.google.com) (209.85.210.180) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 05 Jan 2019 22:10:45 +0000 Received: by mail-pf1-f180.google.com with SMTP id r136so19953747pfc.6; Sat, 05 Jan 2019 14:10:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to :content-transfer-encoding; bh=mb+sjgxxELAMo1hILymWYFeNLJzFXKqH+0lfm2TiN1g=; b=i6ZOqJNlXMvbu0oAUZl9XufCARozPf/vj+ZLAompKVr5IuJTzLCRmWzT6kB3AprDWl nAgONJCmZHAP6UIv3zy1KIGWtXlFvYrepvl6fJ0DboyD8j96IIL3jhF6raJbMqVGB6O+ /Hol8OEZRScVCCnXqskI0VF6fIqUp4Jypq1B8e1EncBWGqFDeY59iy7zrgqFafmJsaiW EM5HilhrXCuVpNFICUdhUZIUXTaC7eSxrOhc0XOwLh8NsAfctr+JBDcRPUztJN0+mlzt OFzEMia6TZemk51D7tybEZfC5O6qwaJK/PQX5/Npmj3tjNSIxm9Bf04xkZBcUy0IxB0Y 9w2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to :content-transfer-encoding; bh=mb+sjgxxELAMo1hILymWYFeNLJzFXKqH+0lfm2TiN1g=; b=O6qVHXwRjkKjFnAkJaL3EbZcpTViv0UZBtnVSBBp1wBWlmnaPuJ8MsLVSGYH33fxyh A1+QafEUcZRbD9/mQ+PNbqWPTUTVEPqO5FZnUytmwyyzf6WQLYHdRpoqUvzfO7at8iRv wNe1BzH/DgpVBdYqeZOgbKxDcmCvsKvF0tW1fZmdD0lGHlzH6ROnedGkLheannY87QJY xIbTce7WEJMWOwl/wM4Z7oaj3h6CCQlSjApqx8NkHRAO1KjTwrzAcTgOKYR93PxU5wA4 yYoTzVjrgjlglFo7tjS/YpihQYBJ+KD3Wu3qJOdmYjdcZNslZqKIYxMyIBSsoKb+cqqL fCzA== X-Gm-Message-State: AJcUukf0oDQOLlI/UZJo0gKd7Htd21Lfx9PzKri8fAI4IwXdgPD70NVb T071OgLFNkULaqCgW2dvCCgid2vFPUbU+9wAiNcudlsPDmQ= X-Google-Smtp-Source: ALg8bN5ztw/O966cj6qAlHXe0IsNiYKhQLHeoXEkfTS7SyOLtK0Phvvu+c9JrI74A6sayjr20YAPhqC5e7rdhiMsATo= X-Received: by 2002:a63:88c7:: with SMTP id l190mr52054868pgd.110.1546726243192; Sat, 05 Jan 2019 14:10:43 -0800 (PST) MIME-Version: 1.0 From: =?UTF-8?Q?Marc_Nieper=2DWi=C3=9Fkirchen?= Date: Tue, 01 Jan 2019 00:00:00 -0000 Message-ID: Subject: [PATCH][jit] Add thread-local globals to the libgccjit frontend To: jit@gcc.gnu.org, gcc-patches@gcc.gnu.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-SW-Source: 2019-q1/txt/msg00004.txt.bz2 This patch adds thread-local globals to the libgccjit frontend. The library user can mark a global as being thread-local by calling `gcc_jit_lvalue_set_bool_thread_local'. It is implemented by calling `set_decl_tls_model (inner, decl_default_tls_model (inner))', where `inner' is the GENERIC tree corresponding to the global. ChangeLog 2019-01-05 Marc Nieper-Wi=C3=9Fkirchen * docs/topics/compatibility.rst: Add LIBGCCJIT_ABI_11. * docs/topics/expressions.rst (Global variables): Add documentation of gcc_jit_lvalue_set_bool_thread_local. * docs/_build/texinfo/libgccjit.texi: Regenerate. * jit-playback.c: Include "varasm.h". Within namespace gcc::jit::playback... (context::new_global) Add "thread_local_p" param and use it to set DECL_TLS_MODEL. * jit-playback.h: Within namespace gcc::jit::playback... (context::new_global: Add "thread_local_p" param. * jit-recording.c: Within namespace gcc::jit::recording... (global::replay_into): Provide m_thread_local to call to new_global. (global::write_reproducer): Call write_reproducer_thread_local. (global::write_reproducer_thread_local): New method. * jit-recording.h: Within namespace gcc::jit::recording... (lvalue::dyn_cast_global): New virtual function. (global::m_thread_local): New field. * libgccjit.c (gcc_jit_lvalue_set_bool_thread_local): New function. * libgccjit.h (LIBGCCJIT_HAVE_gcc_jit_lvalue_set_bool_thread_local): New macro. (gcc_jit_lvalue_set_bool_thread_local): New function. * libgccjit.map (LIBGCCJIT_ABI_11): New. (gcc_jit_lvalue_set_bool_thread_local): Add. Testing The result of `make check-jit' is (the failing test in `test-sum-squares.c` is also failing without this patch on my machine): Native configuration is x86_64-pc-linux-gnu =3D=3D=3D jit tests =3D=3D=3D Schedule of variations: unix Running target unix Using /usr/share/dejagnu/baseboards/unix.exp as board description file for target. Using /usr/share/dejagnu/config/unix.exp as generic interface file for targ= et. Using /home/mnieper/gcc/src/gcc/testsuite/config/default.exp as tool-and-target-specific interface file. Running /home/mnieper/gcc/src/gcc/testsuite/jit.dg/jit.exp ... FAIL: test-combination.c.exe iteration 1 of 5: verify_code_sum_of_squares: dump_vrp1: actual: " FAIL: test-combination.c.exe killed: 20233 exp6 0 0 CHILDKILLED SIGABRT SIG= ABRT FAIL: test-sum-of-squares.c.exe iteration 1 of 5: verify_code: dump_vrp1: actual: " FAIL: test-sum-of-squares.c.exe killed: 22698 exp6 0 0 CHILDKILLED SIGABRT SIGABRT FAIL: test-threads.c.exe: verify_code_sum_of_squares: dump_vrp1: actual: " FAIL: test-threads.c.exe killed: 22840 exp6 0 0 CHILDKILLED SIGABRT SIGABRT =3D=3D=3D jit Summary =3D=3D=3D # of expected passes 6506 # of unexpected failures 6 Patch diff --git a/gcc/jit/docs/topics/compatibility.rst b/gcc/jit/docs/topics/compatibility.rst index 38d338b1f..10926537d 100644 --- a/gcc/jit/docs/topics/compatibility.rst +++ b/gcc/jit/docs/topics/compatibility.rst @@ -171,3 +171,9 @@ entrypoints: ``LIBGCCJIT_ABI_10`` covers the addition of :func:`gcc_jit_context_new_rvalue_from_vector` + +``LIBGCCJIT_ABI_11`` +-------------------- + +``LIBGCCJIT_ABI_11`` covers the addition of +:func:`gcc_jit_lvalue_set_bool_thread_local` diff --git a/gcc/jit/docs/topics/expressions.rst b/gcc/jit/docs/topics/expressions.rst index 9dee2d87a..984d02cc8 100644 --- a/gcc/jit/docs/topics/expressions.rst +++ b/gcc/jit/docs/topics/expressions.rst @@ -576,6 +576,21 @@ Global variables referring to it. Analogous to using an "extern" global from a header file. +.. function:: void\ + gcc_jit_lvalue_set_bool_thread_local (gcc_jit_lvalue *global= ,\ + int thread_local_p) + + Given a :c:type:`gcc_jit_lvalue *` for a global created through + :c:func:`gcc_jit_context_new_global`, mark/clear the global as being + thread-local. Analogous to a global with thread storage duration in C11. + + This entrypoint was added in :ref:`LIBGCCJIT_ABI_11`; you can test for + its presence using + + .. code-block:: c + + #ifdef LIBGCCJIT_HAVE_gcc_jit_lvalue_set_bool_thread_local + Working with pointers, structs and unions ----------------------------------------- diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c index 86f588db9..6c00a98c0 100644 --- a/gcc/jit/jit-playback.c +++ b/gcc/jit/jit-playback.c @@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see #include "opt-suggestions.h" #include "gcc.h" #include "diagnostic.h" +#include "varasm.h" #include @@ -461,7 +462,8 @@ playback::context:: new_global (location *loc, enum gcc_jit_global_kind kind, type *type, - const char *name) + const char *name, + bool thread_local_p) { gcc_assert (type); gcc_assert (name); @@ -487,6 +489,8 @@ new_global (location *loc, DECL_EXTERNAL (inner) =3D 1; break; } + if (thread_local_p) + set_decl_tls_model (inner, decl_default_tls_model (inner)); if (loc) set_tree_location (inner, loc); diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h index bc4de9c03..fc0843f58 100644 --- a/gcc/jit/jit-playback.h +++ b/gcc/jit/jit-playback.h @@ -103,7 +103,8 @@ public: new_global (location *loc, enum gcc_jit_global_kind kind, type *type, - const char *name); + const char *name, + bool thread_local_p); template rvalue * diff --git a/gcc/jit/jit-recording.c b/gcc/jit/jit-recording.c index 04cc6a690..75557af19 100644 --- a/gcc/jit/jit-recording.c +++ b/gcc/jit/jit-recording.c @@ -4280,7 +4280,8 @@ recording::global::replay_into (replayer *r) set_playback_obj (r->new_global (playback_location (r, m_loc), m_kind, m_type->playback_type (), - playback_string (m_name))); + playback_string (m_name), + m_thread_local)); } /* Override the default implementation of @@ -4356,6 +4357,22 @@ recording::global::write_reproducer (reproducer &r) global_kind_reproducer_strings[m_kind], r.get_identifier_as_type (get_type ()), m_name->get_debug_string ()); + write_reproducer_thread_local (r, id); +} + +/* Subroutine for use by global's write_reproducer methods. */ + +void +recording::global::write_reproducer_thread_local (reproducer &r, + const char *id) +{ + if (m_thread_local) + { + r.write (" gcc_jit_lvalue_set_bool_thread_local (%s, /* gcc_jit_lvalue *global*/\n" + " %i); /* int thread_local_p*/\n", + id, + 1); + } } /* The implementation of the various const-handling classes: diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h index b9c6544d0..6a3d32dd6 100644 --- a/gcc/jit/jit-recording.h +++ b/gcc/jit/jit-recording.h @@ -1054,6 +1054,8 @@ public: return static_cast (m_playback_obj); } + virtual global *dyn_cast_global () { return NULL; } + lvalue * access_field (location *loc, field *field); @@ -1285,7 +1287,8 @@ public: string *name) : lvalue (ctxt, loc, type), m_kind (kind), - m_name (name) + m_name (name), + m_thread_local (false) {} void replay_into (replayer *) FINAL OVERRIDE; @@ -1294,7 +1297,17 @@ public: void write_to_dump (dump &d) FINAL OVERRIDE; -private: + global *dyn_cast_global () FINAL OVERRIDE { return this; } + + void set_thread_local (bool thread_local_p) + { + m_thread_local =3D thread_local_p; + } + + protected: + void write_reproducer_thread_local (reproducer &r, const char *id); + + private: string * make_debug_string () FINAL OVERRIDE { return m_name; } void write_reproducer (reproducer &r) FINAL OVERRIDE; enum precedence get_precedence () const FINAL OVERRIDE @@ -1305,6 +1318,7 @@ private: private: enum gcc_jit_global_kind m_kind; string *m_name; + bool m_thread_local; }; template diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c index de7fb2579..2b643c63f 100644 --- a/gcc/jit/libgccjit.c +++ b/gcc/jit/libgccjit.c @@ -3102,3 +3102,23 @@ gcc_jit_context_new_rvalue_from_vector (gcc_jit_context *ctxt, as_vec_type, (gcc::jit::recording::rvalue **)elements); } + +/* Public entrypoint. See description in libgccjit.h. + + After error-checking, the real work is effectively done by the + gcc::jit::global::set_thread_local setter in jit-recording.h. */ + +void +gcc_jit_lvalue_set_bool_thread_local (gcc_jit_lvalue *lvalue, + int thread_local_p) +{ + RETURN_IF_FAIL (lvalue, NULL, NULL, "NULL global"); + JIT_LOG_FUNC (lvalue->get_context ()->get_logger ()); + + /* Verify that it's a global. */ + gcc::jit::recording::global *global =3D lvalue->dyn_cast_global (); + RETURN_IF_FAIL_PRINTF1 (global, NULL, NULL, "not a global: %s", + lvalue->get_debug_string ()); + + global->set_thread_local (thread_local_p); +} diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h index e872ae789..d64d05a8d 100644 --- a/gcc/jit/libgccjit.h +++ b/gcc/jit/libgccjit.h @@ -1450,6 +1450,18 @@ gcc_jit_context_new_rvalue_from_vector (gcc_jit_context *ctxt, size_t num_elements, gcc_jit_rvalue **elements); +#define LIBGCCJIT_HAVE_gcc_jit_lvalue_set_bool_thread_local + +/* Mark/clear a global as thread-local. + + This API entrypoint was added in LIBGCCJIT_ABI_11; you can test for its + presence using + #ifdef LIBGCCJIT_HAVE_gcc_jit_lvalue_set_bool_thread_local +*/ +extern void +gcc_jit_lvalue_set_bool_thread_local (gcc_jit_lvalue *global, + int thread_local_p); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map index 2826f1ca6..741320bbe 100644 --- a/gcc/jit/libgccjit.map +++ b/gcc/jit/libgccjit.map @@ -170,3 +170,8 @@ LIBGCCJIT_ABI_10 { global: gcc_jit_context_new_rvalue_from_vector; } LIBGCCJIT_ABI_9; + +LIBGCCJIT_ABI_11 { + global: + gcc_jit_lvalue_set_bool_thread_local; +} LIBGCCJIT_ABI_10; diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h index bf02e1258..c2654ff09 100644 --- a/gcc/testsuite/jit.dg/all-non-failing-tests.h +++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h @@ -224,6 +224,13 @@ #undef create_code #undef verify_code +/* test-factorial-must-tail-call.c */ +#define create_code create_code_thread_local +#define verify_code verify_code_thread_local +#include "test-thread-local.c" +#undef create_code +#undef verify_code + /* test-types.c */ #define create_code create_code_types #define verify_code verify_code_types @@ -353,6 +360,9 @@ const struct testcase testcases[] =3D { {"switch", create_code_switch, verify_code_switch}, + {"thread_local", + create_code_thread_local, + verify_code_thread_local}, {"types", create_code_types, verify_code_types}, diff --git a/gcc/testsuite/jit.dg/jit.exp b/gcc/testsuite/jit.dg/jit.exp index 869d9f693..3be4f2c18 100644 --- a/gcc/testsuite/jit.dg/jit.exp +++ b/gcc/testsuite/jit.dg/jit.exp @@ -379,6 +379,16 @@ proc jit-dg-test { prog do_what extra_tool_flags } { append extra_tool_flags " -lpthread" } + # test-thread-local.c needs to be linked against pthreads + if {[string match "*test-thread-local.c" $prog]} { + append extra_tool_flags " -lpthread" + } + + # test-combination.c needs to be linked against pthreads + if {[string match "*test-combination.c" $prog]} { + append extra_tool_flags " -lpthread" + } + # Any test case that uses jit-verify-output-file-was-created # needs to call jit-setup-compile-to-file here. # (is there a better way to handle setup/finish pairs in dg?)