This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[jit] New API entrypoint: gcc_jit_function_add_void_return
- 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: Tue, 25 Feb 2014 15:09:25 -0500
- Subject: [jit] New API entrypoint: gcc_jit_function_add_void_return
- Authentication-results: sourceware.org; auth=none
Committed to branch dmalcolm/jit:
gcc/jit/
* libgccjit.h (gcc_jit_function_add_void_return): New.
* libgccjit.map (gcc_jit_function_add_void_return): New.
* libgccjit.c (gcc_jit_function_add_void_return): New.
* libgccjit++.h (add_return): Add overloaded variant with no
rvalue, calling gcc_jit_function_add_void_return.
* internal-api.c (gcc::jit::recording::function::add_return): Add
comment that rvalue could be NULL.
(gcc::jit::playback::function::add_return): Support rvalue being
NULL.
gcc/testsuite/
* jit.dg/test-functions.c (create_use_of_void_return): New, to add
test coverage for gcc_jit_function_add_void_return.
(verify_void_return): Likewise.
(create_code): Add call to create_use_of_void_return.
(verify_code): Add call to verify_void_return.
---
gcc/jit/ChangeLog.jit | 13 ++++++++
gcc/jit/internal-api.c | 31 +++++++++++-------
gcc/jit/libgccjit++.h | 8 +++++
gcc/jit/libgccjit.c | 17 ++++++++++
gcc/jit/libgccjit.h | 11 +++++++
gcc/jit/libgccjit.map | 1 +
gcc/testsuite/ChangeLog.jit | 8 +++++
gcc/testsuite/jit.dg/test-functions.c | 62 +++++++++++++++++++++++++++++++++++
8 files changed, 139 insertions(+), 12 deletions(-)
diff --git a/gcc/jit/ChangeLog.jit b/gcc/jit/ChangeLog.jit
index 40d445e..de352fa 100644
--- a/gcc/jit/ChangeLog.jit
+++ b/gcc/jit/ChangeLog.jit
@@ -1,5 +1,18 @@
2014-02-25 David Malcolm <dmalcolm@redhat.com>
+ * libgccjit.h (gcc_jit_function_add_void_return): New.
+ * libgccjit.map (gcc_jit_function_add_void_return): New.
+ * libgccjit.c (gcc_jit_function_add_void_return): New.
+ * libgccjit++.h (add_return): Add overloaded variant with no
+ rvalue, calling gcc_jit_function_add_void_return.
+
+ * internal-api.c (gcc::jit::recording::function::add_return): Add
+ comment that rvalue could be NULL.
+ (gcc::jit::playback::function::add_return): Support rvalue being
+ NULL.
+
+2014-02-25 David Malcolm <dmalcolm@redhat.com>
+
* internal-api.h (gcc::jit::playback::function): Add field
m_inner_block.
diff --git a/gcc/jit/internal-api.c b/gcc/jit/internal-api.c
index 43de7cd..1cb4717 100644
--- a/gcc/jit/internal-api.c
+++ b/gcc/jit/internal-api.c
@@ -1309,6 +1309,9 @@ void
recording::function::add_return (recording::location *loc,
recording::rvalue *rvalue)
{
+ /* This is used by both gcc_jit_function_add_return and
+ gcc_jit_function_add_void_return; rvalue will be non-NULL for
+ the former and NULL for the latter. */
statement *result = new return_ (this, loc, rvalue);
m_ctxt->record (result);
m_activity.safe_push (result);
@@ -3114,22 +3117,26 @@ add_return (location *loc,
{
gcc_assert (m_kind != GCC_JIT_FUNCTION_IMPORTED);
+ tree modify_retval = NULL;
tree return_type = TREE_TYPE (TREE_TYPE (m_inner_fndecl));
- tree t_lvalue = DECL_RESULT (m_inner_fndecl);
- tree t_rvalue = rvalue->as_tree ();
- if (TREE_TYPE (t_rvalue) != TREE_TYPE (t_lvalue))
- t_rvalue = build1 (CONVERT_EXPR,
- TREE_TYPE (t_lvalue),
- t_rvalue);
- tree modify_retval = build2 (MODIFY_EXPR, return_type,
- t_lvalue, t_rvalue);
+ if (rvalue)
+ {
+ tree t_lvalue = DECL_RESULT (m_inner_fndecl);
+ tree t_rvalue = rvalue->as_tree ();
+ if (TREE_TYPE (t_rvalue) != TREE_TYPE (t_lvalue))
+ t_rvalue = build1 (CONVERT_EXPR,
+ TREE_TYPE (t_lvalue),
+ t_rvalue);
+ modify_retval = build2 (MODIFY_EXPR, return_type,
+ t_lvalue, t_rvalue);
+ if (loc)
+ set_tree_location (modify_retval, loc);
+ }
tree return_stmt = build1 (RETURN_EXPR, return_type,
modify_retval);
if (loc)
- {
- set_tree_location (modify_retval, loc);
- set_tree_location (return_stmt, loc);
- }
+ set_tree_location (return_stmt, loc);
+
add_stmt (return_stmt);
}
diff --git a/gcc/jit/libgccjit++.h b/gcc/jit/libgccjit++.h
index db01053..95a8c71 100644
--- a/gcc/jit/libgccjit++.h
+++ b/gcc/jit/libgccjit++.h
@@ -329,6 +329,7 @@ namespace gccjit
void add_return (rvalue rvalue,
location loc = location ());
+ void add_return (location loc = location ());
/* A way to add a function call to the body of a function being
defined, with various numbers of args. */
@@ -1213,6 +1214,13 @@ function::add_return (rvalue rvalue,
rvalue.get_inner_rvalue ());
}
+inline void
+function::add_return (location loc)
+{
+ gcc_jit_function_add_void_return (get_inner_function (),
+ loc.get_inner_location ());
+}
+
inline rvalue
function::add_call (function other,
location loc)
diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c
index 7226d81..3493518 100644
--- a/gcc/jit/libgccjit.c
+++ b/gcc/jit/libgccjit.c
@@ -1108,6 +1108,23 @@ gcc_jit_function_add_return (gcc_jit_function *func,
return func->add_return (loc, rvalue);
}
+void
+gcc_jit_function_add_void_return (gcc_jit_function *func,
+ gcc_jit_location *loc)
+{
+ RETURN_IF_NOT_FUNC_DEFINITION (func);
+ gcc::jit::recording::context *ctxt = func->m_ctxt;
+ RETURN_IF_FAIL_PRINTF2 (
+ func->get_return_type () == ctxt->get_type (GCC_JIT_TYPE_VOID),
+ ctxt,
+ "mismatching types:"
+ " void return in function %s (return type: %s)",
+ func->get_debug_string (),
+ func->get_return_type ()->get_debug_string ());
+
+ return func->add_return (loc, NULL);
+}
+
gcc_jit_loop *
gcc_jit_function_new_loop (gcc_jit_function *func,
gcc_jit_location *loc,
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index f6fbcdf..9fe9b61 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -862,6 +862,17 @@ gcc_jit_function_add_return (gcc_jit_function *func,
gcc_jit_location *loc,
gcc_jit_rvalue *rvalue);
+/* Add a valueless return, for use within a function with
+ "void" return type.
+
+ This is equivalent to this C code:
+
+ return;
+*/
+extern void
+gcc_jit_function_add_void_return (gcc_jit_function *func,
+ gcc_jit_location *loc);
+
/* Helper function for creating a loop:
while (boolval)
{
diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map
index 3a5bb10..13d9619 100644
--- a/gcc/jit/libgccjit.map
+++ b/gcc/jit/libgccjit.map
@@ -43,6 +43,7 @@
gcc_jit_function_add_jump;
gcc_jit_function_add_label;
gcc_jit_function_add_return;
+ gcc_jit_function_add_void_return;
gcc_jit_function_as_object;
gcc_jit_function_get_param;
gcc_jit_function_new_forward_label;
diff --git a/gcc/testsuite/ChangeLog.jit b/gcc/testsuite/ChangeLog.jit
index 0299115..b8619e6 100644
--- a/gcc/testsuite/ChangeLog.jit
+++ b/gcc/testsuite/ChangeLog.jit
@@ -1,3 +1,11 @@
+2014-02-25 David Malcolm <dmalcolm@redhat.com>
+
+ * jit.dg/test-functions.c (create_use_of_void_return): New, to add
+ test coverage for gcc_jit_function_add_void_return.
+ (verify_void_return): Likewise.
+ (create_code): Add call to create_use_of_void_return.
+ (verify_code): Add call to verify_void_return.
+
2014-02-18 David Malcolm <dmalcolm@redhat.com>
* jit.dg/test-accessing-struct.c (create_code): Update for change to
diff --git a/gcc/testsuite/jit.dg/test-functions.c b/gcc/testsuite/jit.dg/test-functions.c
index 03f7590..d82995c 100644
--- a/gcc/testsuite/jit.dg/test-functions.c
+++ b/gcc/testsuite/jit.dg/test-functions.c
@@ -119,10 +119,56 @@ create_use_of_builtins (gcc_jit_context *ctxt)
create_test_of_builtin_trig (ctxt);
}
+static void
+create_use_of_void_return (gcc_jit_context *ctxt)
+{
+ /* Let's try to inject the equivalent of:
+ void
+ test_of_void_return (int *out)
+ {
+ *out = 1;
+ return;
+ *out = 2;
+ }
+ where the second assignment is unreachable.
+ */
+ gcc_jit_type *void_t =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
+ gcc_jit_type *int_t =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+ gcc_jit_type *int_ptr_t =
+ gcc_jit_type_get_pointer (int_t);
+
+ /* Build the test_fn. */
+ gcc_jit_param *param_out =
+ gcc_jit_context_new_param (ctxt, NULL, int_ptr_t, "out");
+ gcc_jit_function *test_fn =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ void_t,
+ "test_of_void_return",
+ 1, ¶m_out,
+ 0);
+ gcc_jit_function_add_assignment (
+ test_fn, NULL,
+ /* "*out = ..." */
+ gcc_jit_rvalue_dereference (gcc_jit_param_as_rvalue (param_out),
+ NULL),
+ gcc_jit_context_one (ctxt, int_t));
+ gcc_jit_function_add_void_return (test_fn, NULL);
+ gcc_jit_function_add_assignment (
+ test_fn, NULL,
+ /* "*out = ..." */
+ gcc_jit_rvalue_dereference (gcc_jit_param_as_rvalue (param_out),
+ NULL),
+ gcc_jit_context_new_rvalue_from_int (ctxt, int_t, 2));
+}
+
void
create_code (gcc_jit_context *ctxt, void *user_data)
{
create_use_of_builtins (ctxt);
+ create_use_of_void_return (ctxt);
}
static void
@@ -168,8 +214,24 @@ verify_use_of_builtins (gcc_jit_context *ctxt, gcc_jit_result *result)
verify_test_of_builtin_trig (ctxt, result);
}
+static void
+verify_void_return (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ typedef void (*fn_type) (int *);
+ CHECK_NON_NULL (result);
+
+ fn_type test_of_void_return =
+ (fn_type)gcc_jit_result_get_code (result, "test_of_void_return");
+ CHECK_NON_NULL (test_of_void_return);
+
+ int i;
+ test_of_void_return (&i);
+ CHECK_VALUE (i, 1); /* ensure correct value was written back */
+}
+
void
verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
{
verify_use_of_builtins (ctxt, result);
+ verify_void_return (ctxt, result);
}
--
1.7.11.7