diff mbox

[jit] Add the ability to get int types by size/signedness.

Message ID 1392071594-24744-1-git-send-email-dmalcolm@redhat.com
State New
Headers show

Commit Message

David Malcolm Feb. 10, 2014, 10:33 p.m. UTC
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 mbox

Patch

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  <dmalcolm@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  <dmalcolm@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  <dmalcolm@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  <dmalcolm@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);