Committed to branch dmalcolm/jit: Provide a way to get a N-byte int with a given signedness. Also, use template tricks in the C++ wrapper API so that one can map types by writing e.g.
gccjit::type index_t_gcc = ctxt.get_int_type <octave_idx_type> (); and having the compiler figure out the details of the type and call into libgccjit accordingly. gcc/jit/ * libgccjit.h (gcc_jit_context_get_int_type): New. * libgccjit.map (gcc_jit_context_get_int_type): New. * libgccjit.c (gcc_jit_context_get_int_type): New. * internal-api.h (gcc::jit::recording::context::get_int_type): New. (gcc::jit::recording::context::get_int_type<T>): New template. * internal-api.c (gcc::jit::recording::context::get_int_type): New. * libgccjit++.h: Include <limits> so we can use std::numeric_limits. (gccjit::context::get_int_type): New. (gccjit::context::get_int_type<T>): New. gcc/testsuite/ * jit.dg/test-types.c (struct zoo): Add field m_sized_int_type, to be populated by... (create_code): Use gcc_jit_context_get_int_type. (verify_code): Verify that type from gcc_jit_context_get_int_type works properly. * jit.dg/test-operator-overloading.cc (make_types): Use the template form of get_int_type. * jit.dg/test-quadratic.cc (make_types): Likewise. --- gcc/jit/ChangeLog.jit | 14 +++++++++ gcc/jit/internal-api.c | 37 +++++++++++++++++++++++ gcc/jit/internal-api.h | 3 ++ gcc/jit/libgccjit++.h | 23 ++++++++++++++ gcc/jit/libgccjit.c | 10 ++++++ gcc/jit/libgccjit.h | 4 +++ gcc/jit/libgccjit.map | 1 + gcc/testsuite/ChangeLog.jit | 11 +++++++ gcc/testsuite/jit.dg/test-operator-overloading.cc | 2 +- gcc/testsuite/jit.dg/test-quadratic.cc | 2 +- gcc/testsuite/jit.dg/test-types.c | 18 +++++++++++ 11 files changed, 123 insertions(+), 2 deletions(-) diff --git a/gcc/jit/ChangeLog.jit b/gcc/jit/ChangeLog.jit index 001cefb..68c38db 100644 --- a/gcc/jit/ChangeLog.jit +++ b/gcc/jit/ChangeLog.jit @@ -1,5 +1,19 @@ 2014-02-10 David Malcolm <dmalc...@redhat.com> + * libgccjit.h (gcc_jit_context_get_int_type): New. + * libgccjit.map (gcc_jit_context_get_int_type): New. + * libgccjit.c (gcc_jit_context_get_int_type): New. + + * internal-api.h (gcc::jit::recording::context::get_int_type): New. + (gcc::jit::recording::context::get_int_type<T>): New template. + * internal-api.c (gcc::jit::recording::context::get_int_type): New. + + * libgccjit++.h: Include <limits> so we can use std::numeric_limits. + (gccjit::context::get_int_type): New. + (gccjit::context::get_int_type<T>): New. + +2014-02-10 David Malcolm <dmalc...@redhat.com> + * libgccjit.h (gcc_jit_function_get_param): New. * libgccjit.map (gcc_jit_function_get_param): New. * libgccjit.c (gcc_jit_function_get_param): New. diff --git a/gcc/jit/internal-api.c b/gcc/jit/internal-api.c index 85d8fd1..9ff0eb8 100644 --- a/gcc/jit/internal-api.c +++ b/gcc/jit/internal-api.c @@ -215,6 +215,43 @@ recording::context::get_type (enum gcc_jit_types kind) } recording::type * +recording::context::get_int_type (int num_bytes, int is_signed) +{ + /* We can't use a switch here since some of the values are macros affected + by options; e.g. i386.h has + #define LONG_TYPE_SIZE (TARGET_X32 ? 32 : BITS_PER_WORD) + Compare with tree.c's make_or_reuse_type. Note that the _SIZE macros + are in bits, rather than bytes. + */ + const int num_bits = num_bytes * 8; + if (num_bits == INT_TYPE_SIZE) + return get_type (is_signed + ? GCC_JIT_TYPE_INT + : GCC_JIT_TYPE_UNSIGNED_INT); + if (num_bits == CHAR_TYPE_SIZE) + return get_type (is_signed + ? GCC_JIT_TYPE_SIGNED_CHAR + : GCC_JIT_TYPE_UNSIGNED_CHAR); + if (num_bits == SHORT_TYPE_SIZE) + return get_type (is_signed + ? GCC_JIT_TYPE_SHORT + : GCC_JIT_TYPE_UNSIGNED_SHORT); + if (num_bits == LONG_TYPE_SIZE) + return get_type (is_signed + ? GCC_JIT_TYPE_LONG + : GCC_JIT_TYPE_UNSIGNED_LONG); + if (num_bits == LONG_LONG_TYPE_SIZE) + return get_type (is_signed + ? GCC_JIT_TYPE_LONG_LONG + : GCC_JIT_TYPE_UNSIGNED_LONG_LONG); + + /* Some other size, not corresponding to the C int types. */ + /* To be written: support arbitrary other sizes, sharing by + memoizing at the recording::context level? */ + gcc_unreachable (); +} + +recording::type * recording::context::new_array_type (recording::location *loc, recording::type *element_type, int num_elements) diff --git a/gcc/jit/internal-api.h b/gcc/jit/internal-api.h index aa98728..55772a6 100644 --- a/gcc/jit/internal-api.h +++ b/gcc/jit/internal-api.h @@ -143,6 +143,9 @@ public: get_type (enum gcc_jit_types type); type * + get_int_type (int num_bytes, int is_signed); + + type * new_array_type (location *loc, type *element_type, int num_elements); diff --git a/gcc/jit/libgccjit++.h b/gcc/jit/libgccjit++.h index 74c02ea..de3939c 100644 --- a/gcc/jit/libgccjit++.h +++ b/gcc/jit/libgccjit++.h @@ -5,6 +5,7 @@ #include "libgccjit.h" +#include <limits> #include <ostream> #include <vector> @@ -82,6 +83,13 @@ namespace gccjit int column); type get_type (enum gcc_jit_types kind); + type get_int_type (size_t num_bytes, int is_signed); + + /* A way to map a specific int type, using the compiler to + get the details automatically e.g.: + gccjit::type type = get_int_type <my_int_type_t> (); */ + template <typename T> + type get_int_type (); type new_array_type (type element_type, int num_elements, location loc = location ()); @@ -465,6 +473,21 @@ context::get_type (enum gcc_jit_types kind) } inline type +context::get_int_type (size_t num_bytes, int is_signed) +{ + return type (gcc_jit_context_get_int_type (m_inner_ctxt, + num_bytes, + is_signed)); +} + +template <typename T> +inline type +context::get_int_type () +{ + return get_int_type (sizeof (T), std::numeric_limits<T>::is_signed); +} + +inline type context::new_array_type (type element_type, int num_elements, location loc) { return type (gcc_jit_context_new_array_type ( diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c index da1afdc..94b3271 100644 --- a/gcc/jit/libgccjit.c +++ b/gcc/jit/libgccjit.c @@ -246,6 +246,16 @@ gcc_jit_context_get_type (gcc_jit_context *ctxt, } gcc_jit_type * +gcc_jit_context_get_int_type (gcc_jit_context *ctxt, + int num_bytes, int is_signed) +{ + RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context"); + RETURN_NULL_IF_FAIL (num_bytes >= 0, ctxt, "negative size"); + + return (gcc_jit_type *)ctxt->get_int_type (num_bytes, is_signed); +} + +gcc_jit_type * gcc_jit_type_get_pointer (gcc_jit_type *type) { RETURN_NULL_IF_FAIL (type, NULL, "NULL type"); diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h index 03e9ff8..976bcb2 100644 --- a/gcc/jit/libgccjit.h +++ b/gcc/jit/libgccjit.h @@ -349,6 +349,10 @@ extern gcc_jit_type * gcc_jit_context_get_type (gcc_jit_context *ctxt, enum gcc_jit_types type_); +extern gcc_jit_type * +gcc_jit_context_get_int_type (gcc_jit_context *ctxt, + int num_bytes, int is_signed); + /* Constructing new types. */ /* Given type "T", get type "T*". */ diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map index 45b2a2f..d63f9a3 100644 --- a/gcc/jit/libgccjit.map +++ b/gcc/jit/libgccjit.map @@ -6,6 +6,7 @@ gcc_jit_context_compile; gcc_jit_context_get_first_error; gcc_jit_context_get_type; + gcc_jit_context_get_int_type; gcc_jit_context_new_array_access; gcc_jit_context_new_array_type; gcc_jit_context_new_binary_op; diff --git a/gcc/testsuite/ChangeLog.jit b/gcc/testsuite/ChangeLog.jit index 11987e0..e108fb7e 100644 --- a/gcc/testsuite/ChangeLog.jit +++ b/gcc/testsuite/ChangeLog.jit @@ -1,5 +1,16 @@ 2014-02-10 David Malcolm <dmalc...@redhat.com> + * jit.dg/test-types.c (struct zoo): Add field m_sized_int_type, + to be populated by... + (create_code): Use gcc_jit_context_get_int_type. + (verify_code): Verify that type from gcc_jit_context_get_int_type + works properly. + * jit.dg/test-operator-overloading.cc (make_types): Use the + template form of get_int_type. + * jit.dg/test-quadratic.cc (make_types): Likewise. + +2014-02-10 David Malcolm <dmalc...@redhat.com> + * jit.dg/test-operator-overloading.cc: New testcase, a rewrite of test-quadratic.cc to use operator overloading. diff --git a/gcc/testsuite/jit.dg/test-operator-overloading.cc b/gcc/testsuite/jit.dg/test-operator-overloading.cc index 313b3e6..1124d9c 100644 --- a/gcc/testsuite/jit.dg/test-operator-overloading.cc +++ b/gcc/testsuite/jit.dg/test-operator-overloading.cc @@ -94,7 +94,7 @@ make_types (quadratic_test &testcase) testcase.numeric_type_ptr = testcase.numeric_type.get_pointer (); testcase.zero = testcase.ctxt.zero (testcase.numeric_type); - testcase.int_type = testcase.ctxt.get_type (GCC_JIT_TYPE_INT); + testcase.int_type = testcase.ctxt.get_int_type <int> (); testcase.a = testcase.ctxt.new_field (testcase.numeric_type, "a"); testcase.b = testcase.ctxt.new_field (testcase.numeric_type, "b"); diff --git a/gcc/testsuite/jit.dg/test-quadratic.cc b/gcc/testsuite/jit.dg/test-quadratic.cc index daeaee7..ba58c18 100644 --- a/gcc/testsuite/jit.dg/test-quadratic.cc +++ b/gcc/testsuite/jit.dg/test-quadratic.cc @@ -93,7 +93,7 @@ make_types (quadratic_test &testcase) testcase.numeric_type_ptr = testcase.numeric_type.get_pointer (); testcase.zero = testcase.ctxt.zero (testcase.numeric_type); - testcase.int_type = testcase.ctxt.get_type (GCC_JIT_TYPE_INT); + testcase.int_type = testcase.ctxt.get_int_type <int> (); testcase.a = testcase.ctxt.new_field (testcase.numeric_type, "a"); testcase.b = testcase.ctxt.new_field (testcase.numeric_type, "b"); diff --git a/gcc/testsuite/jit.dg/test-types.c b/gcc/testsuite/jit.dg/test-types.c index 90b5f6e..4782680 100644 --- a/gcc/testsuite/jit.dg/test-types.c +++ b/gcc/testsuite/jit.dg/test-types.c @@ -26,6 +26,8 @@ struct zoo long long m_long_long; unsigned long long m_unsigned_long_long; + int m_sized_int_type; + float m_float; double m_double; long double m_long_double; @@ -93,6 +95,13 @@ create_code (gcc_jit_context *ctxt, void *user_data) gcc_jit_field *field_m_unsigned_long_long = CREATE_FIELD (GCC_JIT_TYPE_UNSIGNED_LONG_LONG, "m_unsigned_long_long"); + /* Signed int type with sizeof (int): */ + gcc_jit_type *sized_int_type = + gcc_jit_context_get_int_type (ctxt, sizeof (int), 1); + gcc_jit_field *field_m_sized_int_type = + gcc_jit_context_new_field ( + ctxt, NULL, sized_int_type, "m_sized_int_type"); + gcc_jit_field *field_m_float = CREATE_FIELD (GCC_JIT_TYPE_FLOAT, "m_float"); gcc_jit_field *field_m_double = @@ -130,6 +139,8 @@ create_code (gcc_jit_context *ctxt, void *user_data) field_m_long_long, field_m_unsigned_long_long, + field_m_sized_int_type, + field_m_float, field_m_double, field_m_long_double, @@ -240,6 +251,11 @@ create_code (gcc_jit_context *ctxt, void *user_data) gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UNSIGNED_LONG_LONG), 123456789)) + ASSIGN(field_m_sized_int_type, + gcc_jit_context_new_rvalue_from_int ( + ctxt, + sized_int_type, 500)) + ASSIGN(field_m_float, gcc_jit_context_new_rvalue_from_double ( ctxt, @@ -312,6 +328,8 @@ verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) CHECK_VALUE (z.m_long_long, -42); CHECK_VALUE (z.m_unsigned_long_long, 123456789); + CHECK_VALUE (z.m_sized_int_type, 500); + CHECK_VALUE (z.m_float, 3.141f); CHECK_VALUE (z.m_double, 3.141); CHECK_VALUE (z.m_long_double, 3.141); -- 1.7.11.7