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

Reply via email to