From 00156914f0805788190706935962fe65ab5fd7cb Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sat, 4 Mar 2023 00:44:49 -0500 Subject: [PATCH] libgccjit: Add gcc_jit_context_new_array_type_unsigned_long gcc/jit/ChangeLog: * docs/topics/compatibility.rst (LIBGCCJIT_ABI_28): New ABI tag. * docs/topics/types.rst: Document gcc_jit_context_new_array_type_unsigned_long. * jit-playback.cc (new_array_type): Change num_elements type to unsigned long. * jit-playback.h (new_array_type): Change num_elements type to unsigned long. * jit-recording.cc (recording::context::new_array_type): Change num_elements type to unsigned long. (recording::array_type::make_debug_string): Use unsigned long format. (recording::array_type::write_reproducer): Switch to gcc_jit_context_new_array_type_unsigned_long. * jit-recording.h (class array_type): Change num_elements type to unsigned long. (new_array_type): Change num_elements type to unsigned long. (num_elements): Change return type to unsigned long. * libgccjit.cc (gcc_jit_context_new_array_type_unsigned_long): New function. * libgccjit.h (gcc_jit_context_new_array_type_unsigned_long): New function. * libgccjit.map: New function. gcc/testsuite/ChangeLog: * jit.dg/all-non-failing-tests.h: Add test-arrays-unsigned-long.c. * jit.dg/test-arrays-unsigned-long.c: New test. --- gcc/jit/docs/topics/compatibility.rst | 7 + gcc/jit/docs/topics/types.rst | 18 ++ gcc/jit/jit-playback.cc | 2 +- gcc/jit/jit-playback.h | 2 +- gcc/jit/jit-recording.cc | 12 +- gcc/jit/jit-recording.h | 8 +- gcc/jit/libgccjit.cc | 12 +- gcc/jit/libgccjit.h | 14 ++ gcc/jit/libgccjit.map | 5 + gcc/testsuite/jit.dg/all-non-failing-tests.h | 10 ++ .../jit.dg/test-arrays-unsigned-long.c | 165 ++++++++++++++++++ 11 files changed, 242 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/jit.dg/test-arrays-unsigned-long.c diff --git a/gcc/jit/docs/topics/compatibility.rst b/gcc/jit/docs/topics/compatibility.rst index 9cfb054f653..a8c8cf45630 100644 --- a/gcc/jit/docs/topics/compatibility.rst +++ b/gcc/jit/docs/topics/compatibility.rst @@ -397,3 +397,10 @@ on functions and variables: -------------------- ``LIBGCCJIT_ABI_27`` covers the addition of :func:`gcc_jit_context_new_sizeof` + +.. _LIBGCCJIT_ABI_28: + +``LIBGCCJIT_ABI_28`` +-------------------- +``LIBGCCJIT_ABI_28`` covers the addition of +:func:`gcc_jit_context_new_array_type_unsigned_long` diff --git a/gcc/jit/docs/topics/types.rst b/gcc/jit/docs/topics/types.rst index bb51f037b7e..d83ecd3cf13 100644 --- a/gcc/jit/docs/topics/types.rst +++ b/gcc/jit/docs/topics/types.rst @@ -160,6 +160,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_unsigned_long (gcc_jit_context *ctxt, \ + gcc_jit_location *loc, \ + gcc_jit_type *element_type, \ + unsigned long 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_28`; you can test + for its presence using + + .. code-block:: c + + #ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_array_type_unsigned_long + .. 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 6baa838af10..b3775a18a83 100644 --- a/gcc/jit/jit-playback.cc +++ b/gcc/jit/jit-playback.cc @@ -327,7 +327,7 @@ playback::type * playback::context:: new_array_type (playback::location *loc, playback::type *element_type, - int num_elements) + unsigned long num_elements) { gcc_assert (element_type); diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h index aa6a086613c..7cbb2d1f8d8 100644 --- a/gcc/jit/jit-playback.h +++ b/gcc/jit/jit-playback.h @@ -80,7 +80,7 @@ public: type * new_array_type (location *loc, type *element_type, - int num_elements); + unsigned long num_elements); field * new_field (location *loc, diff --git a/gcc/jit/jit-recording.cc b/gcc/jit/jit-recording.cc index 68a2e860c1f..3a05e91c140 100644 --- a/gcc/jit/jit-recording.cc +++ b/gcc/jit/jit-recording.cc @@ -841,7 +841,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) + unsigned long num_elements) { if (struct_ *s = element_type->dyn_cast_struct ()) if (!s->get_fields ()) @@ -3129,7 +3129,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); } @@ -3142,10 +3142,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_unsigned_long (%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 d8d16f4fe29..c359c2526cc 100644 --- a/gcc/jit/jit-recording.h +++ b/gcc/jit/jit-recording.h @@ -95,7 +95,7 @@ public: type * new_array_type (location *loc, type *element_type, - int num_elements); + unsigned long num_elements); field * new_field (location *loc, @@ -878,7 +878,7 @@ class array_type : public type array_type (context *ctxt, location *loc, type *element_type, - int num_elements) + unsigned long num_elements) : type (ctxt), m_loc (loc), m_element_type (element_type), @@ -892,7 +892,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; } + unsigned long num_elements () { return m_num_elements; } bool is_signed () const final override { return false; } void replay_into (replayer *) final override; @@ -904,7 +904,7 @@ class array_type : public type private: location *m_loc; type *m_element_type; - int m_num_elements; + unsigned long m_num_elements; }; class function_type : public type diff --git a/gcc/jit/libgccjit.cc b/gcc/jit/libgccjit.cc index f40a9781405..32b6df6d80f 100644 --- a/gcc/jit/libgccjit.cc +++ b/gcc/jit/libgccjit.cc @@ -767,12 +767,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_unsigned_long (ctxt, loc, element_type, + (unsigned long) num_elements); +} + +gcc_jit_type * +gcc_jit_context_new_array_type_unsigned_long (gcc_jit_context *ctxt, + gcc_jit_location *loc, + gcc_jit_type *element_type, + unsigned long 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.h b/gcc/jit/libgccjit.h index 74e847b2dec..92663e1ff7b 100644 --- a/gcc/jit/libgccjit.h +++ b/gcc/jit/libgccjit.h @@ -663,6 +663,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_28; you can test for its + presence using + #ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_array_type_unsigned_long +*/ +extern gcc_jit_type * +gcc_jit_context_new_array_type_unsigned_long (gcc_jit_context *ctxt, + gcc_jit_location *loc, + gcc_jit_type *element_type, + unsigned long num_elements); + +#define LIBGCCJIT_HAVE_gcc_jit_context_new_array_type_unsigned_long + /* 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 99aa5970be1..d6efc0ddf56 100644 --- a/gcc/jit/libgccjit.map +++ b/gcc/jit/libgccjit.map @@ -289,3 +289,8 @@ LIBGCCJIT_ABI_27 { global: gcc_jit_context_new_sizeof; } LIBGCCJIT_ABI_26; + +LIBGCCJIT_ABI_28 { + global: + gcc_jit_context_new_array_type_unsigned_long; +} LIBGCCJIT_ABI_27; diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h index 14a0a321550..223d98bcbc4 100644 --- a/gcc/testsuite/jit.dg/all-non-failing-tests.h +++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h @@ -66,6 +66,13 @@ #undef create_code #undef verify_code +/* test-arrays-unsigned-long.c */ +#define create_code create_code_arrays_unsigned_long +#define verify_code verify_code_arrays_unsigned_long +#include "test-arrays-unsigned-long.c" +#undef create_code +#undef verify_code + /* test-autovectorize.c */ #define create_code create_code_autovectorize #define verify_code verify_code_autovectorize @@ -461,6 +468,9 @@ const struct testcase testcases[] = { {"arrays", create_code_arrays, verify_code_arrays}, + {"arrays-unsigned-long", + create_code_arrays_unsigned_long, + verify_code_arrays_unsigned_long}, {"autovectorize", create_code_autovectorize, verify_code_autovectorize}, diff --git a/gcc/testsuite/jit.dg/test-arrays-unsigned-long.c b/gcc/testsuite/jit.dg/test-arrays-unsigned-long.c new file mode 100644 index 00000000000..0a82c7046ea --- /dev/null +++ b/gcc/testsuite/jit.dg/test-arrays-unsigned-long.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_unsigned_long (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_unsigned_long (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_unsigned_long", + 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_unsigned_long = + (fn_type)gcc_jit_result_get_code (result, "test_array_unsigned_long"); + CHECK_NON_NULL (test_array_unsigned_long); + + struct array_holder2 ah; + memset (&ah, 0xf0, sizeof (ah)); + + test_array_unsigned_long (&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); + +} -- 2.43.0