diff options
author | Antoni Boucher <bouanto@zoho.com> | 2021-12-11 19:01:15 -0500 |
---|---|---|
committer | Antoni Boucher <bouanto@zoho.com> | 2021-12-11 19:01:15 -0500 |
commit | c6b7f68bfd61fcd02842e672476f9924d5ba1d3c (patch) | |
tree | ee9a6a1ee8b03fc90e4ea5493336cdd407988975 /gcc/jit | |
parent | 611fdb0fc5b95ee15215e2e3679834f311919096 (diff) | |
download | gcc-c6b7f68bfd61fcd02842e672476f9924d5ba1d3c.zip gcc-c6b7f68bfd61fcd02842e672476f9924d5ba1d3c.tar.gz gcc-c6b7f68bfd61fcd02842e672476f9924d5ba1d3c.tar.bz2 |
libgccjit: Add support for TLS variable [PR95415]
2021-12-11 Antoni Boucher <bouanto@zoho.com>
gcc/jit/
PR target/95415
* docs/topics/compatibility.rst (LIBGCCJIT_ABI_17): New ABI
tag.
* docs/topics/expressions.rst: Add document for the function
gcc_jit_lvalue_set_tls_model.
* jit-playback.h: New function (set_tls_model).
* jit-recording.c: New function (set_tls_model), new
variables (tls_models and tls_model_enum_strings) and support
for setting the tls model.
* jit-recording.h: New function (set_tls_model) and new
field m_tls_model.
* libgccjit.c: New function (gcc_jit_lvalue_set_tls_model).
* libgccjit.h: New function (gcc_jit_lvalue_set_tls_model)
and new enum (gcc_jit_tls_model).
* libgccjit.map (LIBGCCJIT_ABI_17): New ABI tag.
gcc/testsuite/
PR target/95415
* jit.dg/all-non-failing-tests.h: Add test-tls.c.
* jit.dg/test-tls.c: New test.
Diffstat (limited to 'gcc/jit')
-rw-r--r-- | gcc/jit/docs/topics/compatibility.rst | 9 | ||||
-rw-r--r-- | gcc/jit/docs/topics/expressions.rst | 37 | ||||
-rw-r--r-- | gcc/jit/jit-playback.h | 6 | ||||
-rw-r--r-- | gcc/jit/jit-recording.c | 39 | ||||
-rw-r--r-- | gcc/jit/jit-recording.h | 7 | ||||
-rw-r--r-- | gcc/jit/libgccjit.c | 18 | ||||
-rw-r--r-- | gcc/jit/libgccjit.h | 21 | ||||
-rw-r--r-- | gcc/jit/libgccjit.map | 5 |
8 files changed, 138 insertions, 4 deletions
diff --git a/gcc/jit/docs/topics/compatibility.rst b/gcc/jit/docs/topics/compatibility.rst index 52ee3f8..2ad6e42 100644 --- a/gcc/jit/docs/topics/compatibility.rst +++ b/gcc/jit/docs/topics/compatibility.rst @@ -284,3 +284,12 @@ entrypoints: * :func:`gcc_jit_struct_get_field` * :func:`gcc_jit_struct_get_field_count` + +.. _LIBGCCJIT_ABI_17: + +``LIBGCCJIT_ABI_17`` +----------------------- +``LIBGCCJIT_ABI_17`` covers the addition of an API entrypoint to set the +thread-local storage model of a variable: + + * :func:`gcc_jit_lvalue_set_tls_model` diff --git a/gcc/jit/docs/topics/expressions.rst b/gcc/jit/docs/topics/expressions.rst index 396259e..386b80d 100644 --- a/gcc/jit/docs/topics/expressions.rst +++ b/gcc/jit/docs/topics/expressions.rst @@ -539,6 +539,43 @@ where the rvalue is computed by reading from the storage area. in C. +.. function:: void\ + gcc_jit_lvalue_set_tls_model (gcc_jit_lvalue *lvalue,\ + enum gcc_jit_tls_model model) + + Make a variable a thread-local variable. + + The "model" parameter determines the thread-local storage model of the "lvalue": + + .. type:: enum gcc_jit_tls_model + + .. c:macro:: GCC_JIT_TLS_MODEL_NONE + + Don't set the TLS model. + + .. c:macro:: GCC_JIT_TLS_MODEL_GLOBAL_DYNAMIC + + .. c:macro:: GCC_JIT_TLS_MODEL_LOCAL_DYNAMIC + + .. c:macro:: GCC_JIT_TLS_MODEL_INITIAL_EXEC + + .. c:macro:: GCC_JIT_TLS_MODEL_LOCAL_EXEC + + This is analogous to: + + .. code-block:: c + + _Thread_local int foo __attribute__ ((tls_model("MODEL"))); + + in C. + + This entrypoint was added in :ref:`LIBGCCJIT_ABI_17`; you can test for + its presence using + + .. code-block:: c + + #ifdef LIBGCCJIT_HAVE_gcc_jit_lvalue_set_tls_model + Global variables **************** diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h index f670c9e..c9839c2 100644 --- a/gcc/jit/jit-playback.h +++ b/gcc/jit/jit-playback.h @@ -675,6 +675,12 @@ public: rvalue * get_address (location *loc); + void + set_tls_model (enum tls_model tls_model) + { + set_decl_tls_model (as_tree (), tls_model); + } + private: bool mark_addressable (location *loc); }; diff --git a/gcc/jit/jit-recording.c b/gcc/jit/jit-recording.c index 2eecf44..5ba35bd 100644 --- a/gcc/jit/jit-recording.c +++ b/gcc/jit/jit-recording.c @@ -3718,6 +3718,12 @@ recording::lvalue::get_address (recording::location *loc) return result; } +void +recording::lvalue::set_tls_model (enum gcc_jit_tls_model model) +{ + m_tls_model = model; +} + /* The implementation of class gcc::jit::recording::param. */ /* Implementation of pure virtual hook recording::memento::replay_into @@ -4544,6 +4550,16 @@ recording::block::dump_edges_to_dot (pretty_printer *pp) # pragma GCC diagnostic pop #endif +namespace recording { +static const enum tls_model tls_models[] = { + TLS_MODEL_NONE, /* GCC_JIT_TLS_MODEL_NONE */ + TLS_MODEL_GLOBAL_DYNAMIC, /* GCC_JIT_TLS_MODEL_GLOBAL_DYNAMIC */ + TLS_MODEL_LOCAL_DYNAMIC, /* GCC_JIT_TLS_MODEL_LOCAL_DYNAMIC */ + TLS_MODEL_INITIAL_EXEC, /* GCC_JIT_TLS_MODEL_INITIAL_EXEC */ + TLS_MODEL_LOCAL_EXEC, /* GCC_JIT_TLS_MODEL_LOCAL_EXEC */ +}; +} /* namespace recording */ + /* The implementation of class gcc::jit::recording::global. */ /* Implementation of pure virtual hook recording::memento::replay_into @@ -4552,8 +4568,7 @@ recording::block::dump_edges_to_dot (pretty_printer *pp) void recording::global::replay_into (replayer *r) { - set_playback_obj ( - m_initializer + playback::lvalue *global = m_initializer ? r->new_global_initialized (playback_location (r, m_loc), m_kind, m_type->playback_type (), @@ -4565,7 +4580,11 @@ recording::global::replay_into (replayer *r) : r->new_global (playback_location (r, m_loc), m_kind, m_type->playback_type (), - playback_string (m_name))); + playback_string (m_name)); + if (m_tls_model != GCC_JIT_TLS_MODEL_NONE) + global->set_tls_model (recording::tls_models[m_tls_model]); + + set_playback_obj (global); } /* Override the default implementation of @@ -4663,6 +4682,14 @@ recording::global::write_initializer_reproducer (const char *id, reproducer &r) /* Implementation of recording::memento::write_reproducer for globals. */ +static const char * const tls_model_enum_strings[] = { + "GCC_JIT_TLS_MODEL_NONE", + "GCC_JIT_TLS_MODEL_GLOBAL_DYNAMIC", + "GCC_JIT_TLS_MODEL_LOCAL_DYNAMIC", + "GCC_JIT_TLS_MODEL_INITIAL_EXEC", + "GCC_JIT_TLS_MODEL_LOCAL_EXEC", +}; + void recording::global::write_reproducer (reproducer &r) { @@ -4680,6 +4707,12 @@ recording::global::write_reproducer (reproducer &r) r.get_identifier_as_type (get_type ()), m_name->get_debug_string ()); + if (m_tls_model != GCC_JIT_TLS_MODEL_NONE) + r.write (" gcc_jit_lvalue_set_tls_model (%s, /* gcc_jit_lvalue *lvalue */\n" + " %s); /* enum gcc_jit_tls_model model */\n", + id, + tls_model_enum_strings[m_tls_model]); + if (m_initializer) switch (m_type->dereference ()->get_size ()) { diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h index 3163ff6..72fa30c 100644 --- a/gcc/jit/jit-recording.h +++ b/gcc/jit/jit-recording.h @@ -1132,7 +1132,8 @@ public: lvalue (context *ctxt, location *loc, type *type_) - : rvalue (ctxt, loc, type_) + : rvalue (ctxt, loc, type_), + m_tls_model (GCC_JIT_TLS_MODEL_NONE) {} playback::lvalue * @@ -1154,6 +1155,10 @@ public: const char *access_as_rvalue (reproducer &r) OVERRIDE; virtual const char *access_as_lvalue (reproducer &r); virtual bool is_global () const { return false; } + void set_tls_model (enum gcc_jit_tls_model model); + +protected: + enum gcc_jit_tls_model m_tls_model; }; class param : public lvalue diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c index 5d051e4..7ccb76a 100644 --- a/gcc/jit/libgccjit.c +++ b/gcc/jit/libgccjit.c @@ -2220,6 +2220,24 @@ gcc_jit_lvalue_get_address (gcc_jit_lvalue *lvalue, /* Public entrypoint. See description in libgccjit.h. After error-checking, the real work is done by the + gcc::jit::recording::lvalue::set_tls_model method in jit-recording.c. */ + +void +gcc_jit_lvalue_set_tls_model (gcc_jit_lvalue *lvalue, + enum gcc_jit_tls_model model) +{ + RETURN_IF_FAIL (lvalue, NULL, NULL, "NULL lvalue"); + JIT_LOG_FUNC (lvalue->get_context ()->get_logger ()); + RETURN_IF_FAIL_PRINTF1 (lvalue->is_global (), lvalue->get_context (), NULL, + "lvalue \"%s\" not a global", + lvalue->get_debug_string ()); + + lvalue->set_tls_model (model); +} + +/* Public entrypoint. See description in libgccjit.h. + + After error-checking, the real work is done by the gcc::jit::recording::function::new_local method in jit-recording.c. */ gcc_jit_lvalue * diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h index a1c9436..5aa2e40 100644 --- a/gcc/jit/libgccjit.h +++ b/gcc/jit/libgccjit.h @@ -739,6 +739,16 @@ enum gcc_jit_function_kind GCC_JIT_FUNCTION_ALWAYS_INLINE }; +/* Thread local storage model. */ +enum gcc_jit_tls_model +{ + GCC_JIT_TLS_MODEL_NONE, + GCC_JIT_TLS_MODEL_GLOBAL_DYNAMIC, + GCC_JIT_TLS_MODEL_LOCAL_DYNAMIC, + GCC_JIT_TLS_MODEL_INITIAL_EXEC, + GCC_JIT_TLS_MODEL_LOCAL_EXEC, +}; + /* Create a function. */ extern gcc_jit_function * gcc_jit_context_new_function (gcc_jit_context *ctxt, @@ -1089,6 +1099,17 @@ extern gcc_jit_rvalue * gcc_jit_lvalue_get_address (gcc_jit_lvalue *lvalue, gcc_jit_location *loc); +#define LIBGCCJIT_HAVE_gcc_jit_lvalue_set_tls_model + +/* Set the thread-local storage model of a global variable + + This API entrypoint was added in LIBGCCJIT_ABI_17; you can test for its + presence using + #ifdef LIBGCCJIT_HAVE_gcc_jit_lvalue_set_tls_model */ +extern void +gcc_jit_lvalue_set_tls_model (gcc_jit_lvalue *lvalue, + enum gcc_jit_tls_model model); + extern gcc_jit_lvalue * gcc_jit_function_new_local (gcc_jit_function *func, gcc_jit_location *loc, diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map index 64e7909..98d693f 100644 --- a/gcc/jit/libgccjit.map +++ b/gcc/jit/libgccjit.map @@ -226,3 +226,8 @@ LIBGCCJIT_ABI_16 { gcc_jit_type_is_struct; gcc_jit_struct_get_field_count; } LIBGCCJIT_ABI_15; + +LIBGCCJIT_ABI_17 { + global: + gcc_jit_lvalue_set_tls_model; +} LIBGCCJIT_ABI_16; |