From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7855) id 366A23858D39; Sun, 12 Dec 2021 21:17:23 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 366A23858D39 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Antoni Boucher To: gcc-cvs@gcc.gnu.org Subject: [gcc r12-5917] libgccjit: Add support for setting the link section of global variables [PR100688] X-Act-Checkin: gcc X-Git-Author: Antoni Boucher X-Git-Refname: refs/heads/master X-Git-Oldrev: aeedb00a1ae2ccd10b1a5f00ff466081aeadb54b X-Git-Newrev: 0b52083ea2c2dd9897031fdc3802a68fd4aa45ef Message-Id: <20211212211723.366A23858D39@sourceware.org> Date: Sun, 12 Dec 2021 21:17:23 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 12 Dec 2021 21:17:23 -0000 https://gcc.gnu.org/g:0b52083ea2c2dd9897031fdc3802a68fd4aa45ef commit r12-5917-g0b52083ea2c2dd9897031fdc3802a68fd4aa45ef Author: Antoni Boucher Date: Sun Dec 12 16:16:21 2021 -0500 libgccjit: Add support for setting the link section of global variables [PR100688] 2021-12-12 Antoni Boucher gcc/jit/ PR target/100688 * docs/topics/compatibility.rst (LIBGCCJIT_ABI_18): New ABI tag. * docs/topics/expressions.rst: Add documentation for the function gcc_jit_lvalue_set_link_section. * jit-playback.h: New function (set_link_section). * jit-recording.c: New function (set_link_section) and support for setting the link section. * jit-recording.h: New function (set_link_section) and new field m_link_section. * libgccjit.c: New function (gcc_jit_lvalue_set_link_section). * libgccjit.h: New function (gcc_jit_lvalue_set_link_section). * libgccjit.map (LIBGCCJIT_ABI_18): New ABI tag. gcc/testsuite/ PR target/100688 * jit.dg/all-non-failing-tests.h: Mention new test link-section-assembler. * jit.dg/test-link-section-assembler.c: New test. * jit.dg/jit.exp: New helper function to test that the assembly contains a pattern. Diff: --- gcc/jit/docs/topics/compatibility.rst | 9 ++++++ gcc/jit/docs/topics/expressions.rst | 21 ++++++++++++ gcc/jit/jit-playback.h | 6 ++++ gcc/jit/jit-recording.c | 21 ++++++++++-- gcc/jit/jit-recording.h | 5 ++- gcc/jit/libgccjit.c | 13 ++++++++ gcc/jit/libgccjit.h | 14 ++++++++ gcc/jit/libgccjit.map | 5 +++ gcc/testsuite/jit.dg/all-non-failing-tests.h | 3 ++ gcc/testsuite/jit.dg/jit.exp | 33 +++++++++++++++++++ gcc/testsuite/jit.dg/test-link-section-assembler.c | 37 ++++++++++++++++++++++ 11 files changed, 163 insertions(+), 4 deletions(-) diff --git a/gcc/jit/docs/topics/compatibility.rst b/gcc/jit/docs/topics/compatibility.rst index 2ad6e4232f7..c6c14f0a761 100644 --- a/gcc/jit/docs/topics/compatibility.rst +++ b/gcc/jit/docs/topics/compatibility.rst @@ -293,3 +293,12 @@ entrypoints: thread-local storage model of a variable: * :func:`gcc_jit_lvalue_set_tls_model` + +.. _LIBGCCJIT_ABI_18: + +``LIBGCCJIT_ABI_18`` +----------------------- +``LIBGCCJIT_ABI_18`` covers the addition of an API entrypoint to set the link +section of a variable: + + * :func:`gcc_jit_lvalue_set_link_section` diff --git a/gcc/jit/docs/topics/expressions.rst b/gcc/jit/docs/topics/expressions.rst index 386b80d8f8b..280e0eaea68 100644 --- a/gcc/jit/docs/topics/expressions.rst +++ b/gcc/jit/docs/topics/expressions.rst @@ -576,6 +576,27 @@ where the rvalue is computed by reading from the storage area. #ifdef LIBGCCJIT_HAVE_gcc_jit_lvalue_set_tls_model +.. function:: void + gcc_jit_lvalue_set_link_section (gcc_jit_lvalue *lvalue, + const char *section_name) + + Set the link section of a variable. + The parameter ``section_name`` must be non-NULL and must contain the + leading dot. Analogous to: + + .. code-block:: c + + int variable __attribute__((section(".section"))); + + in C. + + This entrypoint was added in :ref:`LIBGCCJIT_ABI_18`; you can test for + its presence using + + .. code-block:: c + + #ifdef LIBGCCJIT_HAVE_gcc_jit_lvalue_set_link_section + Global variables **************** diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h index c9839c21a66..21ddffb228f 100644 --- a/gcc/jit/jit-playback.h +++ b/gcc/jit/jit-playback.h @@ -681,6 +681,12 @@ public: set_decl_tls_model (as_tree (), tls_model); } + void + set_link_section (const char* name) + { + set_decl_section_name (as_tree (), name); + } + private: bool mark_addressable (location *loc); }; diff --git a/gcc/jit/jit-recording.c b/gcc/jit/jit-recording.c index 5ba35bda44c..b4240790957 100644 --- a/gcc/jit/jit-recording.c +++ b/gcc/jit/jit-recording.c @@ -3724,6 +3724,11 @@ recording::lvalue::set_tls_model (enum gcc_jit_tls_model model) m_tls_model = model; } +void recording::lvalue::set_link_section (const char *name) +{ + m_link_section = new_string (name); +} + /* The implementation of class gcc::jit::recording::param. */ /* Implementation of pure virtual hook recording::memento::replay_into @@ -4568,8 +4573,8 @@ static const enum tls_model tls_models[] = { void recording::global::replay_into (replayer *r) { - playback::lvalue *global = m_initializer - ? r->new_global_initialized (playback_location (r, m_loc), + playback::lvalue *global = m_initializer + ? r->new_global_initialized (playback_location (r, m_loc), m_kind, m_type->playback_type (), m_type->dereference ()->get_size (), @@ -4577,13 +4582,17 @@ recording::global::replay_into (replayer *r) / m_type->dereference ()->get_size (), m_initializer, playback_string (m_name)) - : r->new_global (playback_location (r, m_loc), + : r->new_global (playback_location (r, m_loc), m_kind, m_type->playback_type (), playback_string (m_name)); + if (m_tls_model != GCC_JIT_TLS_MODEL_NONE) global->set_tls_model (recording::tls_models[m_tls_model]); + if (m_link_section != NULL) + global->set_link_section (m_link_section->c_str ()); + set_playback_obj (global); } @@ -4713,6 +4722,12 @@ recording::global::write_reproducer (reproducer &r) id, tls_model_enum_strings[m_tls_model]); + if (m_link_section != NULL) + r.write (" gcc_jit_lvalue_set_link_section (%s, /* gcc_jit_lvalue *lvalue */\n" + " \"%s\"); /* */\n", + id, + m_link_section->c_str ()); + if (m_initializer) switch (m_type->dereference ()->get_size ()) { diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h index 72fa30c631e..cedb24720cf 100644 --- a/gcc/jit/jit-recording.h +++ b/gcc/jit/jit-recording.h @@ -1133,7 +1133,8 @@ public: location *loc, type *type_) : rvalue (ctxt, loc, type_), - m_tls_model (GCC_JIT_TLS_MODEL_NONE) + m_tls_model (GCC_JIT_TLS_MODEL_NONE), + m_link_section (NULL) {} playback::lvalue * @@ -1156,9 +1157,11 @@ public: 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); + void set_link_section (const char *name); protected: enum gcc_jit_tls_model m_tls_model; + string *m_link_section; }; class param : public lvalue diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c index 7ccb76a6a19..59cef614d4b 100644 --- a/gcc/jit/libgccjit.c +++ b/gcc/jit/libgccjit.c @@ -2235,6 +2235,19 @@ gcc_jit_lvalue_set_tls_model (gcc_jit_lvalue *lvalue, 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::lvalue::set_link_section method in jit-recording.c. */ + +void +gcc_jit_lvalue_set_link_section (gcc_jit_lvalue *lvalue, + const char *section_name) +{ + RETURN_IF_FAIL (section_name, NULL, NULL, "NULL section_name"); + lvalue->set_link_section (section_name); +} + /* 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 5aa2e40c7a4..024c8d79f4b 100644 --- a/gcc/jit/libgccjit.h +++ b/gcc/jit/libgccjit.h @@ -1110,6 +1110,20 @@ extern void gcc_jit_lvalue_set_tls_model (gcc_jit_lvalue *lvalue, enum gcc_jit_tls_model model); +#define LIBGCCJIT_HAVE_gcc_jit_lvalue_set_link_section + +/* Set the link section of a global variable; analogous to: + __attribute__((section(".section_name"))) + in C. + + This API entrypoint was added in LIBGCCJIT_ABI_18; you can test for its + presence using + #ifdef LIBGCCJIT_HAVE_gcc_jit_lvalue_set_link_section +*/ +extern void +gcc_jit_lvalue_set_link_section (gcc_jit_lvalue *lvalue, + const char *section_name); + 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 98d693fd00c..b17671163c7 100644 --- a/gcc/jit/libgccjit.map +++ b/gcc/jit/libgccjit.map @@ -231,3 +231,8 @@ LIBGCCJIT_ABI_17 { global: gcc_jit_lvalue_set_tls_model; } LIBGCCJIT_ABI_16; + +LIBGCCJIT_ABI_18 { + global: + gcc_jit_lvalue_set_link_section; +} LIBGCCJIT_ABI_17; diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h index 350a30b3328..3e8ccbca60e 100644 --- a/gcc/testsuite/jit.dg/all-non-failing-tests.h +++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h @@ -209,6 +209,9 @@ #undef create_code #undef verify_code +/* test-link-section-assembler.c: This can't be in the testcases array as it + doesn't have a verify_code implementation. */ + /* test-linked-list.c */ #define create_code create_code_linked_list #define verify_code verify_code_linked_list diff --git a/gcc/testsuite/jit.dg/jit.exp b/gcc/testsuite/jit.dg/jit.exp index 10b98bdc74b..3568dbb9d63 100644 --- a/gcc/testsuite/jit.dg/jit.exp +++ b/gcc/testsuite/jit.dg/jit.exp @@ -864,6 +864,39 @@ proc jit-verify-assembler { args } { jit-run-executable ${executable_from_asm} ${dg-output-text} } +# Assuming that a .s file has been written out named +# OUTPUT_FILENAME, check that the argument matches the +# output file. +# For use by the test-link-section-assembler.c testcase. +proc jit-verify-assembler-output { 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}" + 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. diff --git a/gcc/testsuite/jit.dg/test-link-section-assembler.c b/gcc/testsuite/jit.dg/test-link-section-assembler.c new file mode 100644 index 00000000000..a90b00e9a82 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-link-section-assembler.c @@ -0,0 +1,37 @@ +#include +#include + +#include "libgccjit.h" + +#define TEST_COMPILING_TO_FILE +#define OUTPUT_KIND GCC_JIT_OUTPUT_KIND_ASSEMBLER +#define OUTPUT_FILENAME "output-of-test-link-section-assembler.c.s" +#include "harness.h" + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: + int foo __attribute__((section(".section"))); + */ + gcc_jit_type *int_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_lvalue *foo = + gcc_jit_context_new_global ( + ctxt, NULL, GCC_JIT_GLOBAL_EXPORTED, int_type, "foo"); + gcc_jit_lvalue_set_link_section(foo, ".my_section"); + + gcc_jit_function *func_main = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + int_type, + "main", + 0, NULL, + 0); + gcc_jit_rvalue *zero = gcc_jit_context_zero (ctxt, int_type); + gcc_jit_block *block = gcc_jit_function_new_block (func_main, NULL); + gcc_jit_block_end_with_return (block, NULL, zero); +} + +/* { dg-final { jit-verify-output-file-was-created "" } } */ +/* { dg-final { jit-verify-assembler-output ".section .my_section" } } */