From: Antoni Boucher Date: Sat, 4 Mar 2023 05:44:49 +0000 (-0500) Subject: libgccjit: Add gcc_jit_context_new_array_type_u64 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=r16-4527-gc11d9eaa8ac9ee;p=thirdparty%2Fgcc.git libgccjit: Add gcc_jit_context_new_array_type_u64 gcc/jit/ChangeLog: * docs/topics/compatibility.rst (LIBGCCJIT_ABI_37): New ABI tag. * docs/topics/types.rst: Document gcc_jit_context_new_array_type_u64. * jit-playback.cc (new_array_type): Change num_elements type to uint64_t. * jit-playback.h (new_array_type): Change num_elements type to uint64_t. * jit-recording.cc (recording::context::new_array_type): Change num_elements type to uint64_t. (recording::array_type::make_debug_string): Use uint64_t format. (recording::array_type::write_reproducer): Switch to gcc_jit_context_new_array_type_u64. * jit-recording.h (class array_type): Change num_elements type to uint64_t. (new_array_type): Change num_elements type to uint64_t. (num_elements): Change return type to uint64_t. * libgccjit.cc (gcc_jit_context_new_array_type_u64): New function. * libgccjit.h (gcc_jit_context_new_array_type_u64): New function. * libgccjit.exports: New function. * libgccjit.map: New function. gcc/testsuite/ChangeLog: * jit.dg/all-non-failing-tests.h: Add test-arrays-u64.c. * jit.dg/test-arrays-u64.c: New test. --- diff --git a/gcc/jit/docs/topics/compatibility.rst b/gcc/jit/docs/topics/compatibility.rst index 9379b05049e..1f8c4d9365e 100644 --- a/gcc/jit/docs/topics/compatibility.rst +++ b/gcc/jit/docs/topics/compatibility.rst @@ -474,3 +474,10 @@ information: ``LIBGCCJIT_ABI_36`` covers the addition of * :func:`gcc_jit_context_set_abort_on_unsupported_target_builtin` + +.. _LIBGCCJIT_ABI_37: + +``LIBGCCJIT_ABI_37`` +-------------------- +``LIBGCCJIT_ABI_37`` covers the addition of +:func:`gcc_jit_context_new_array_type_u64` diff --git a/gcc/jit/docs/topics/types.rst b/gcc/jit/docs/topics/types.rst index e699ee5301b..92830652913 100644 --- a/gcc/jit/docs/topics/types.rst +++ b/gcc/jit/docs/topics/types.rst @@ -162,6 +162,24 @@ Pointers, `const`, and `volatile` Given non-`void` type "T", get type "T[N]" (for a constant N). +.. function:: gcc_jit_type *\ + gcc_jit_context_new_array_type_u64 (gcc_jit_context *ctxt, \ + gcc_jit_location *loc, \ + gcc_jit_type *element_type, \ + uint64_t num_elements) + + Given non-`void` type "T", get type "T[N]" (for a constant N). + + This is the same as gcc_jit_context_new_array_type, but the type of + ``num_elements` different and thus allows creating bigger array types. + + This API entrypoint was added in :ref:`LIBGCCJIT_ABI_37`; you can test + for its presence using + + .. code-block:: c + + #ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_array_type_u64 + .. function:: gcc_jit_type *\ gcc_jit_type_get_aligned (gcc_jit_type *type, \ size_t alignment_in_bytes) diff --git a/gcc/jit/jit-playback.cc b/gcc/jit/jit-playback.cc index 63468d7367a..d5145d0e7cd 100644 --- a/gcc/jit/jit-playback.cc +++ b/gcc/jit/jit-playback.cc @@ -344,7 +344,7 @@ playback::type * playback::context:: new_array_type (playback::location *loc, playback::type *element_type, - int num_elements) + uint64_t num_elements) { gcc_assert (element_type); diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h index 11bc27900e4..f2ff4f70ff5 100644 --- a/gcc/jit/jit-playback.h +++ b/gcc/jit/jit-playback.h @@ -88,7 +88,7 @@ public: type * new_array_type (location *loc, type *element_type, - int num_elements); + uint64_t num_elements); field * new_field (location *loc, diff --git a/gcc/jit/jit-recording.cc b/gcc/jit/jit-recording.cc index 18e40356117..754ccb2b1c6 100644 --- a/gcc/jit/jit-recording.cc +++ b/gcc/jit/jit-recording.cc @@ -847,7 +847,7 @@ recording::context::get_int_type (int num_bytes, int is_signed) recording::type * recording::context::new_array_type (recording::location *loc, recording::type *element_type, - int num_elements) + uint64_t num_elements) { if (struct_ *s = element_type->dyn_cast_struct ()) if (!s->get_fields ()) @@ -3391,7 +3391,7 @@ recording::string * recording::array_type::make_debug_string () { return string::from_printf (m_ctxt, - "%s[%d]", + "%s[%ld]", m_element_type->get_debug_string (), m_num_elements); } @@ -3404,10 +3404,10 @@ recording::array_type::write_reproducer (reproducer &r) { const char *id = r.make_identifier (this, "array_type"); r.write (" gcc_jit_type *%s =\n" - " gcc_jit_context_new_array_type (%s,\n" - " %s, /* gcc_jit_location *loc */\n" - " %s, /* gcc_jit_type *element_type */\n" - " %i); /* int num_elements */\n", + " gcc_jit_context_new_array_type_u64 (%s,\n" + " %s, /* gcc_jit_location *loc */\n" + " %s, /* gcc_jit_type *element_type */\n" + " %li); /* int num_elements */\n", id, r.get_identifier (get_context ()), r.get_identifier (m_loc), diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h index eeddfbcbb65..08de684653a 100644 --- a/gcc/jit/jit-recording.h +++ b/gcc/jit/jit-recording.h @@ -106,7 +106,7 @@ public: type * new_array_type (location *loc, type *element_type, - int num_elements); + uint64_t num_elements); field * new_field (location *loc, @@ -1045,7 +1045,7 @@ class array_type : public type array_type (context *ctxt, location *loc, type *element_type, - int num_elements) + uint64_t num_elements) : type (ctxt), m_loc (loc), m_element_type (element_type), @@ -1078,7 +1078,7 @@ class array_type : public type bool is_bool () const final override { return false; } type *is_pointer () final override { return NULL; } type *is_array () final override { return m_element_type; } - int num_elements () { return m_num_elements; } + uint64_t num_elements () { return m_num_elements; } bool is_signed () const final override { return false; } void replay_into (replayer *) final override; @@ -1090,7 +1090,7 @@ class array_type : public type private: location *m_loc; type *m_element_type; - int m_num_elements; + uint64_t m_num_elements; }; class function_type : public type diff --git a/gcc/jit/libgccjit.cc b/gcc/jit/libgccjit.cc index 081b87b4066..3fc96fb989a 100644 --- a/gcc/jit/libgccjit.cc +++ b/gcc/jit/libgccjit.cc @@ -783,12 +783,22 @@ gcc_jit_context_new_array_type (gcc_jit_context *ctxt, gcc_jit_location *loc, gcc_jit_type *element_type, int num_elements) +{ + RETURN_NULL_IF_FAIL (num_elements >= 0, ctxt, NULL, "negative size"); + return gcc_jit_context_new_array_type_u64 (ctxt, loc, element_type, + (uint64_t) num_elements); +} + +gcc_jit_type * +gcc_jit_context_new_array_type_u64 (gcc_jit_context *ctxt, + gcc_jit_location *loc, + gcc_jit_type *element_type, + uint64_t num_elements) { RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context"); JIT_LOG_FUNC (ctxt->get_logger ()); /* LOC can be NULL. */ RETURN_NULL_IF_FAIL (element_type, ctxt, loc, "NULL type"); - RETURN_NULL_IF_FAIL (num_elements >= 0, ctxt, NULL, "negative size"); RETURN_NULL_IF_FAIL (!element_type->is_void (), ctxt, loc, "void type for elements"); diff --git a/gcc/jit/libgccjit.exports b/gcc/jit/libgccjit.exports index 96ce697e609..17864c7010b 100644 --- a/gcc/jit/libgccjit.exports +++ b/gcc/jit/libgccjit.exports @@ -261,3 +261,6 @@ _gcc_jit_target_info_supports_target_dependent_type # LIBGCCJIT_ABI_36 _gcc_jit_context_set_abort_on_unsupported_target_builtin + +# LIBGCCJIT_ABI_37 +_gcc_jit_context_new_array_type_u64 diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h index cf2b9513461..f71ed630589 100644 --- a/gcc/jit/libgccjit.h +++ b/gcc/jit/libgccjit.h @@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see #ifndef LIBGCCJIT_H #define LIBGCCJIT_H +#include #include #ifdef __has_include #if __has_include () @@ -676,6 +677,20 @@ gcc_jit_context_new_array_type (gcc_jit_context *ctxt, gcc_jit_type *element_type, int num_elements); +/* Given type "T", get type "T[N]" (for a constant N). + + This API entrypoint was added in LIBGCCJIT_ABI_37; you can test for its + presence using + #ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_array_type_u64 +*/ +extern gcc_jit_type * +gcc_jit_context_new_array_type_u64 (gcc_jit_context *ctxt, + gcc_jit_location *loc, + gcc_jit_type *element_type, + uint64_t num_elements); + +#define LIBGCCJIT_HAVE_gcc_jit_context_new_array_type_u64 + /* Struct-handling. */ /* Create a field, for use within a struct or union. */ diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map index 500eba9f6fb..4d767f4f75b 100644 --- a/gcc/jit/libgccjit.map +++ b/gcc/jit/libgccjit.map @@ -339,3 +339,8 @@ LIBGCCJIT_ABI_36 { global: gcc_jit_context_set_abort_on_unsupported_target_builtin; } LIBGCCJIT_ABI_35; + +LIBGCCJIT_ABI_37 { + global: + gcc_jit_context_new_array_type_u64; +} LIBGCCJIT_ABI_36; diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h index 4aa18e3b767..dc98ad24526 100644 --- a/gcc/testsuite/jit.dg/all-non-failing-tests.h +++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h @@ -73,6 +73,13 @@ #undef create_code #undef verify_code +/* test-arrays-u64.c */ +#define create_code create_code_arrays_u64 +#define verify_code verify_code_arrays_u64 +#include "test-arrays-u64.c" +#undef create_code +#undef verify_code + /* test-autovectorize.c */ #define create_code create_code_autovectorize #define verify_code verify_code_autovectorize @@ -517,6 +524,9 @@ const struct testcase testcases[] = { {"arrays", create_code_arrays, verify_code_arrays}, + {"arrays-u64", + create_code_arrays_u64, + verify_code_arrays_u64}, {"autovectorize", create_code_autovectorize, verify_code_autovectorize}, diff --git a/gcc/testsuite/jit.dg/test-arrays-u64.c b/gcc/testsuite/jit.dg/test-arrays-u64.c new file mode 100644 index 00000000000..ec8525c3a41 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-arrays-u64.c @@ -0,0 +1,165 @@ +#include +#include +#include + +#include "libgccjit.h" + +#include "harness.h" + +#define ARRAY_SIZE (4) + +/* Verify that struct layout works properly when adding an array field. */ +struct array_holder2 +{ + float m_before; + int m_ints[ARRAY_SIZE]; + float m_after; +}; + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: + + void + test_array_u64 (struct array_holder2 *ah) + { + ah->m_before = 4.0f; + for i in 0 to (ARRAY_SIZE - 1): + ah->m_ints[i] = (i * i); + ah->m_after = 2.0f; + } + */ + gcc_jit_type *void_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); + gcc_jit_type *float_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT); + gcc_jit_type *int_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + + gcc_jit_field *field_m_before = + gcc_jit_context_new_field (ctxt, NULL, float_type, "m_before"); + gcc_jit_field *field_m_ints = + gcc_jit_context_new_field ( + ctxt, NULL, + gcc_jit_context_new_array_type_u64 (ctxt, NULL, int_type, ARRAY_SIZE), + "m_ints"); + gcc_jit_field *field_m_after = + gcc_jit_context_new_field (ctxt, NULL, float_type, "m_after"); + + gcc_jit_field *fields[] = { + field_m_before, + field_m_ints, + field_m_after, + }; + + gcc_jit_struct *struct_type = + gcc_jit_context_new_struct_type ( + ctxt, + NULL, + "array_holder2", + 3, fields); + + gcc_jit_type *struct_ptr_type = + gcc_jit_type_get_pointer (gcc_jit_struct_as_type (struct_type)); + + /* Build the test_fn. */ + gcc_jit_param *param_ah = + gcc_jit_context_new_param (ctxt, NULL, struct_ptr_type, "ah"); + gcc_jit_function *func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + void_type, + "test_array_u64", + 1, ¶m_ah, + 0); + + gcc_jit_block *initial = gcc_jit_function_new_block (func, "initial"); + gcc_jit_block *loop_test = gcc_jit_function_new_block (func, "loop_test"); + gcc_jit_block *loop_body = gcc_jit_function_new_block (func, "loop_body"); + gcc_jit_block *final = gcc_jit_function_new_block (func, "final"); + + /* "ah->m_before = 4.0f;" */ + gcc_jit_block_add_assignment ( + initial, NULL, + gcc_jit_rvalue_dereference_field ( + gcc_jit_param_as_rvalue (param_ah), NULL, field_m_before), + gcc_jit_context_new_rvalue_from_int (ctxt, float_type, 4)); + + gcc_jit_block_add_comment (initial, NULL, + "for i in 0 to (ARRAY_SIZE - 1):"); + gcc_jit_lvalue *i = + gcc_jit_function_new_local (func, NULL, int_type, "i"); + gcc_jit_block_add_assignment (initial, NULL, + i, + gcc_jit_context_zero (ctxt, int_type)); + + gcc_jit_block_end_with_jump (initial, NULL, loop_test); + + gcc_jit_block_end_with_conditional (loop_test, NULL, + gcc_jit_context_new_comparison ( + ctxt, NULL, + GCC_JIT_COMPARISON_LT, + gcc_jit_lvalue_as_rvalue (i), + gcc_jit_context_new_rvalue_from_int (ctxt, int_type, ARRAY_SIZE)), + loop_body, + final); + + gcc_jit_block_add_comment (loop_body, NULL, "ah->m_ints[i] = (i * i);"); + gcc_jit_block_add_assignment ( + loop_body, NULL, + gcc_jit_context_new_array_access ( + ctxt, NULL, + gcc_jit_lvalue_as_rvalue (gcc_jit_rvalue_dereference_field ( + gcc_jit_param_as_rvalue (param_ah), + NULL, + field_m_ints)), + gcc_jit_lvalue_as_rvalue (i)), + gcc_jit_context_new_binary_op ( + ctxt, NULL, + GCC_JIT_BINARY_OP_MULT, + int_type, + gcc_jit_lvalue_as_rvalue (i), + gcc_jit_lvalue_as_rvalue (i))); + + /* "i++" */ + gcc_jit_block_add_assignment_op ( + loop_body, NULL, + i, + GCC_JIT_BINARY_OP_PLUS, + gcc_jit_context_one (ctxt, int_type)); + + gcc_jit_block_end_with_jump (loop_body, NULL, loop_test); + + /* ah->m_after = 2.0f; */ + gcc_jit_block_add_assignment ( + final, NULL, + gcc_jit_rvalue_dereference_field ( + gcc_jit_param_as_rvalue (param_ah), NULL, field_m_after), + gcc_jit_context_new_rvalue_from_int (ctxt, float_type, 2)); + gcc_jit_block_end_with_void_return (final, NULL); + +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + typedef void (*fn_type) (struct array_holder2 *ah); + + CHECK_NON_NULL (result); + fn_type test_array_u64 = + (fn_type)gcc_jit_result_get_code (result, "test_array_u64"); + CHECK_NON_NULL (test_array_u64); + + struct array_holder2 ah; + memset (&ah, 0xf0, sizeof (ah)); + + test_array_u64 (&ah); + CHECK_VALUE (ah.m_before, 4.0f); + CHECK_VALUE (ah.m_ints[0], 0); + CHECK_VALUE (ah.m_ints[1], 1); + CHECK_VALUE (ah.m_ints[2], 4); + CHECK_VALUE (ah.m_ints[3], 9); + CHECK_VALUE (ah.m_after, 2.0f); + +}