This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[jit] Support array to pointer conversions


Committed to branch dmalcolm/jit:

gcc/jit/
	* libgccjit.c (is_valid_cast): Permit casts between pointer types.

	* internal-api.c (convert): Report more information if this ever
	occurs, and make the error occur on the playback context, so that
	it makes the gcc_jit_result be NULL.
	(gcc::jit::playback::context::build_cast): Handle pointers.  Report
	more information if an unhandlable cast reaches here.

gcc/testsuite/
	* jit.dg/test-expressions.c (called_pointer_checking_function): New.
	(make_tests_of_casts): Add test of casting from array to pointer.
	(verify_casts): Likewise.
---
 gcc/jit/ChangeLog.jit                   | 10 ++++
 gcc/jit/internal-api.c                  | 21 +++++--
 gcc/jit/libgccjit.c                     |  6 ++
 gcc/testsuite/ChangeLog.jit             |  6 ++
 gcc/testsuite/jit.dg/test-expressions.c | 98 +++++++++++++++++++++++++++++++++
 5 files changed, 137 insertions(+), 4 deletions(-)

diff --git a/gcc/jit/ChangeLog.jit b/gcc/jit/ChangeLog.jit
index 260273c..8244eba 100644
--- a/gcc/jit/ChangeLog.jit
+++ b/gcc/jit/ChangeLog.jit
@@ -1,3 +1,13 @@
+2014-03-14  David Malcolm  <dmalcolm@redhat.com>
+
+	* libgccjit.c (is_valid_cast): Permit casts between pointer types.
+
+	* internal-api.c (convert): Report more information if this ever
+	occurs, and make the error occur on the playback context, so that
+	it makes the gcc_jit_result be NULL.
+	(gcc::jit::playback::context::build_cast): Handle pointers.  Report
+	more information if an unhandlable cast reaches here.
+
 2014-03-13  David Malcolm  <dmalcolm@redhat.com>
 
 	* libgccjit.c (is_valid_cast): New.
diff --git a/gcc/jit/internal-api.c b/gcc/jit/internal-api.c
index 062095e..8e0395d 100644
--- a/gcc/jit/internal-api.c
+++ b/gcc/jit/internal-api.c
@@ -33,9 +33,14 @@
 extern tree convert (tree type, tree expr);
 
 tree
-convert (tree /*type*/, tree /*expr*/)
-{
-  error ("unhandled conversion");
+convert (tree dst_type, tree expr)
+{
+  gcc_assert (gcc::jit::active_playback_ctxt);
+  gcc::jit::active_playback_ctxt->add_error (NULL, "unhandled conversion");
+  fprintf (stderr, "input expression:\n");
+  debug_tree (expr);
+  fprintf (stderr, "requested type:\n");
+  debug_tree (dst_type);
   return error_mark_node;
 }
 
@@ -3095,8 +3100,16 @@ playback::context::build_cast (playback::location *loc,
       t_ret = convert_to_real (t_dst_type, t_expr);
       goto maybe_fold;
 
+    case POINTER_TYPE:
+      t_ret = build1 (NOP_EXPR, t_dst_type, t_expr);
+      goto maybe_fold;
+
     default:
-      add_error (loc, "can't handle cast");
+      add_error (loc, "couldn't handle cast during playback");
+      fprintf (stderr, "input expression:\n");
+      debug_tree (t_expr);
+      fprintf (stderr, "requested type:\n");
+      debug_tree (t_dst_type);
       return error_mark_node;
 
     maybe_fold:
diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c
index baab60d..5acb1bc 100644
--- a/gcc/jit/libgccjit.c
+++ b/gcc/jit/libgccjit.c
@@ -905,6 +905,12 @@ is_valid_cast (gcc::jit::recording::type *src_type,
     if (dst_is_int || dst_is_bool)
       return true;
 
+  /* Permit casts between pointer types.  */
+  gcc::jit::recording::type *deref_src_type = src_type->dereference ();
+  gcc::jit::recording::type *deref_dst_type = dst_type->dereference ();
+  if (deref_src_type && deref_dst_type)
+    return true;
+
   return false;
 }
 
diff --git a/gcc/testsuite/ChangeLog.jit b/gcc/testsuite/ChangeLog.jit
index b8f1fa8..1d8c11c 100644
--- a/gcc/testsuite/ChangeLog.jit
+++ b/gcc/testsuite/ChangeLog.jit
@@ -1,3 +1,9 @@
+2014-03-14  David Malcolm  <dmalcolm@redhat.com>
+
+	* jit.dg/test-expressions.c (called_pointer_checking_function): New.
+	(make_tests_of_casts): Add test of casting from array to pointer.
+	(verify_casts): Likewise.
+
 2014-03-13  David Malcolm  <dmalcolm@redhat.com>
 
 	* jit.dg/test-error-bad-cast.c: New test case.
diff --git a/gcc/testsuite/jit.dg/test-expressions.c b/gcc/testsuite/jit.dg/test-expressions.c
index 07fe9d6..4873098 100644
--- a/gcc/testsuite/jit.dg/test-expressions.c
+++ b/gcc/testsuite/jit.dg/test-expressions.c
@@ -492,6 +492,14 @@ make_test_of_cast (gcc_jit_context *ctxt,
     gcc_jit_rvalue_as_object (cast));
 }
 
+/* For use by test_cast_from_array_of_ints_to_int_ptr.  */
+extern int called_pointer_checking_function (int *ints)
+{
+  CHECK_VALUE (ints[0], 10);
+  CHECK_VALUE (ints[1], 4);
+  return ints[0] * ints[1];
+}
+
 static void
 make_tests_of_casts (gcc_jit_context *ctxt)
 {
@@ -501,6 +509,12 @@ make_tests_of_casts (gcc_jit_context *ctxt)
     gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT);
   gcc_jit_type *bool_type =
     gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_BOOL);
+  gcc_jit_type *array_int_type =
+    gcc_jit_context_new_array_type (ctxt, NULL,
+				    int_type,
+				    2);
+  gcc_jit_type *int_ptr_type =
+    gcc_jit_type_get_pointer (int_type);
 
   /* float/int conversions */
   CHECK_STRING_VALUE (
@@ -529,6 +543,79 @@ make_tests_of_casts (gcc_jit_context *ctxt)
 		       bool_type,
 		       "test_cast_from_int_to_bool"),
     "(bool)a");
+
+  /* array/ptr conversions */
+  {
+    gcc_jit_function *test_fn =
+      gcc_jit_context_new_function (
+	ctxt, NULL,
+	GCC_JIT_FUNCTION_EXPORTED,
+	int_type,
+	"test_cast_from_array_of_ints_to_int_ptr",
+	0, NULL,
+	0);
+    /* Equivalent to:
+          int test_cast_from_array_of_ints_to_int_ptr (void)
+	  {
+	    int array[2];
+	    array[0] = 10;
+	    array[1] = 4;
+	    return called_pointer_checking_function (array);
+	  }
+    */
+
+    gcc_jit_param *param_ints =
+      gcc_jit_context_new_param (ctxt, NULL, int_ptr_type, "ints");
+    gcc_jit_function *called_fn =
+      gcc_jit_context_new_function (
+	ctxt, NULL,
+	GCC_JIT_FUNCTION_IMPORTED,
+	int_type,
+	"called_pointer_checking_function",
+	1, &param_ints,
+	0);
+
+    gcc_jit_lvalue *array =
+      gcc_jit_function_new_local (test_fn, NULL,
+				  array_int_type,
+				  "array");
+    gcc_jit_block *block =
+      gcc_jit_function_new_block (test_fn, "block");
+    /* array[0] = 10; */
+    gcc_jit_block_add_assignment (
+      block, NULL,
+      gcc_jit_context_new_array_access (
+	ctxt, NULL,
+	gcc_jit_lvalue_as_rvalue (array),
+	gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 0)),
+      gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 10));
+    /* array[1] = 4; */
+    gcc_jit_block_add_assignment (
+      block, NULL,
+      gcc_jit_context_new_array_access (
+	ctxt, NULL,
+	gcc_jit_lvalue_as_rvalue (array),
+	gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 1)),
+      gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 4));
+    gcc_jit_rvalue *cast =
+      gcc_jit_context_new_cast (
+	ctxt,
+	NULL,
+	/* We need a get_address here.  */
+	gcc_jit_lvalue_get_address (array, NULL),
+	int_ptr_type);
+    gcc_jit_block_end_with_return (
+      block, NULL,
+      gcc_jit_context_new_call (
+	ctxt, NULL,
+	called_fn,
+	1, &cast));
+
+    CHECK_STRING_VALUE (
+      gcc_jit_object_get_debug_string (
+	gcc_jit_rvalue_as_object (cast)),
+      "(int *)&array");
+  }
 }
 
 static void
@@ -575,6 +662,17 @@ verify_casts (gcc_jit_result *result)
     CHECK_VALUE (test_cast_from_int_to_bool (0), 0);
     CHECK_VALUE (test_cast_from_int_to_bool (1), 1);
   }
+
+  /* array to ptr */
+  {
+    typedef int (*fn_type) (void);
+    fn_type test_cast_from_array_of_ints_to_int_ptr =
+      (fn_type)gcc_jit_result_get_code (
+	result,
+	"test_cast_from_array_of_ints_to_int_ptr");
+    CHECK_NON_NULL (test_cast_from_array_of_ints_to_int_ptr);
+    CHECK_VALUE (test_cast_from_array_of_ints_to_int_ptr (), 40);
+  }
 }
 
 /**********************************************************************
-- 
1.8.5.3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]