This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[jit] Support array to pointer conversions
- From: David Malcolm <dmalcolm at redhat dot com>
- To: jit at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Cc: David Malcolm <dmalcolm at redhat dot com>
- Date: Fri, 14 Mar 2014 13:42:46 -0400
- Subject: [jit] Support array to pointer conversions
- Authentication-results: sourceware.org; auth=none
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, ¶m_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