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] New API entrypoint: gcc_jit_function_add_void_return


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, &param_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


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