From: "Marc Nieper-Wißkirchen" <marc.nieper+gnu@gmail.com>
To: jit@gcc.gnu.org, gcc-patches@gcc.gnu.org
Subject: [PATCH][jit] Add thread-local globals to the libgccjit frontend
Date: Sat, 05 Jan 2019 22:10:00 -0000 [thread overview]
Message-ID: <CAEYrNrSZH-tR4JExg6bFiz+g-9GRdh=oWZzgikin-0MZK-mmfw@mail.gmail.com> (raw)
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ßkirchen <marc@nieper-wisskirchen.de>
* 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
=== jit tests ===
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 target.
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 SIGABRT
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
=== jit Summary ===
# 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 <pthread.h>
@@ -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) = 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 <typename HOST_TYPE>
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 <playback::lvalue *> (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 = 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 <typename HOST_TYPE>
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 = 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[] = {
{"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?)
next reply other threads:[~2019-01-05 22:10 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-01-05 22:10 Marc Nieper-Wißkirchen [this message]
2019-01-07 20:34 ` David Malcolm
2019-01-08 1:43 ` [committed] Fix jit test case (PR jit/88747) David Malcolm
2019-01-08 13:31 ` [PATCH][jit] Add thread-local globals to the libgccjit frontend Marc Nieper-Wißkirchen
2019-01-08 17:28 ` David Malcolm
2019-01-08 21:06 ` Marc Nieper-Wißkirchen
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='CAEYrNrSZH-tR4JExg6bFiz+g-9GRdh=oWZzgikin-0MZK-mmfw@mail.gmail.com' \
--to=marc.nieper+gnu@gmail.com \
--cc=gcc-patches@gcc.gnu.org \
--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).