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] Add GCC_JIT_FUNCTION_ALWAYS_INLINE and fix GCC_JIT_FUNCTION_INTERNAL.


Committed to branch dmalcolm/jit:

gcc/jit/
	* libgccjit.h (enum gcc_jit_function_kind): Add
	GCC_JIT_FUNCTION_ALWAYS_INLINE.
	* internal-api.c (gcc::jit::recording::function::write_to_dump):
	Handle GCC_JIT_FUNCTION_ALWAYS_INLINE.
	(gcc::jit::playback::context::new_function): Likewise.
	(gcc::jit::playback::context::postprocess): Handle
	GCC_JIT_FUNCTION_INTERNAL and GCC_JIT_FUNCTION_ALWAYS_INLINE by
	clearing DECL_EXTERNAL and TREE_PUBLIC.  Doing so fixes the
	"undefined symbol" bug seen with GCC_JIT_FUNCTION_INTERNAL.
	* TODO.rst: Update.

gcc/testsuite/
	* jit.dg/test-functions.c (create_test_of_hidden_function): New,
	adding test coverage for GCC_JIT_FUNCTION_ALWAYS_INLINE and
	GCC_JIT_FUNCTION_INTERNAL.
	(create_tests_of_hidden_functions): Likewise.
	(verify_hidden_functions): Likewise.
	(create_code): Add call to create_tests_of_hidden_functions.
	(verify_code): Add call to verify_hidden_functions.
	* jit.dg/test-quadratic.c (make_calc_discriminant): Convert
	from GCC_JIT_FUNCTION_EXPORTED to GCC_JIT_FUNCTION_INTERNAL.
---
 gcc/jit/ChangeLog.jit                 |  13 +++++
 gcc/jit/TODO.rst                      |   5 --
 gcc/jit/internal-api.c                |  21 +++++++
 gcc/jit/libgccjit.h                   |  12 +++-
 gcc/testsuite/ChangeLog.jit           |  12 ++++
 gcc/testsuite/jit.dg/test-functions.c | 107 ++++++++++++++++++++++++++++++++++
 gcc/testsuite/jit.dg/test-quadratic.c |   4 +-
 7 files changed, 166 insertions(+), 8 deletions(-)

diff --git a/gcc/jit/ChangeLog.jit b/gcc/jit/ChangeLog.jit
index ef820ea..223fd6a 100644
--- a/gcc/jit/ChangeLog.jit
+++ b/gcc/jit/ChangeLog.jit
@@ -1,5 +1,18 @@
 2014-03-07  David Malcolm  <dmalcolm@redhat.com>
 
+	* libgccjit.h (enum gcc_jit_function_kind): Add
+	GCC_JIT_FUNCTION_ALWAYS_INLINE.
+	* internal-api.c (gcc::jit::recording::function::write_to_dump):
+	Handle GCC_JIT_FUNCTION_ALWAYS_INLINE.
+	(gcc::jit::playback::context::new_function): Likewise.
+	(gcc::jit::playback::context::postprocess): Handle
+	GCC_JIT_FUNCTION_INTERNAL and GCC_JIT_FUNCTION_ALWAYS_INLINE by
+	clearing DECL_EXTERNAL and TREE_PUBLIC.  Doing so fixes the
+	"undefined symbol" bug seen with GCC_JIT_FUNCTION_INTERNAL.
+	* TODO.rst: Update.
+
+2014-03-07  David Malcolm  <dmalcolm@redhat.com>
+
 	* libgccjit++.h (gccjit::context::new_global): New.
 
 2014-03-07  David Malcolm  <dmalcolm@redhat.com>
diff --git a/gcc/jit/TODO.rst b/gcc/jit/TODO.rst
index ea09e45..b2d8c04 100644
--- a/gcc/jit/TODO.rst
+++ b/gcc/jit/TODO.rst
@@ -114,11 +114,6 @@ Initial Release
 
 Bugs
 ====
-* INTERNAL functions don't seem to work (see e.g. test-quadratic, on trying
-  to make calc_disc be internal leads to:
-        /tmp/libgccjit-4FZm6B/fake.so: undefined symbol: calc_discriminant
-  works at -O3 (because it inlines away the call); fails at -O0
-
 * fixing all the state issues: make it work repeatedly with optimization
   turned up to full.
 
diff --git a/gcc/jit/internal-api.c b/gcc/jit/internal-api.c
index 1cb15ce..17c8e9e 100644
--- a/gcc/jit/internal-api.c
+++ b/gcc/jit/internal-api.c
@@ -1317,6 +1317,9 @@ recording::function::write_to_dump (dump &d)
     case GCC_JIT_FUNCTION_INTERNAL:
       d.write ("static ");
       break;
+    case GCC_JIT_FUNCTION_ALWAYS_INLINE:
+      d.write ("static inline ");
+      break;
      }
   d.write ("%s\n", m_return_type->get_debug_string ());
 
@@ -2534,6 +2537,17 @@ new_function (location *loc,
       DECL_ARGUMENTS(fndecl) = param_decl_list;
     }
 
+  if (kind == GCC_JIT_FUNCTION_ALWAYS_INLINE)
+    {
+      DECL_DECLARED_INLINE_P (fndecl) = 1;
+
+      /* Add attribute "always_inline": */
+      DECL_ATTRIBUTES (fndecl) =
+	tree_cons (get_identifier ("always_inline"),
+		   NULL,
+		   DECL_ATTRIBUTES (fndecl));
+    }
+
   function *func = new function (this, fndecl, kind);
   m_functions.safe_push (func);
   return func;
@@ -3195,6 +3209,13 @@ postprocess ()
       DECL_PRESERVE_P (m_inner_fndecl) = 1;
     }
 
+  if (m_kind == GCC_JIT_FUNCTION_INTERNAL
+      ||m_kind == GCC_JIT_FUNCTION_ALWAYS_INLINE)
+    {
+      DECL_EXTERNAL (m_inner_fndecl) = 0;
+      TREE_PUBLIC (m_inner_fndecl) = 0;
+    }
+
   if (m_kind != GCC_JIT_FUNCTION_IMPORTED)
     {
       /* Seem to need this in gimple-low.c: */
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index e8f35b9..3019449 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -468,8 +468,18 @@ enum gcc_jit_function_kind
   /* Function is not defined by the client code; we're merely
      referring to it.  Analogous to using an "extern" function from a
      header file.  */
-  GCC_JIT_FUNCTION_IMPORTED
+  GCC_JIT_FUNCTION_IMPORTED,
 
+  /* Function is only ever inlined into other functions, and is
+     invisible outside of the JIT.
+
+     Analogous to prefixing with "inline" and adding
+     __attribute__((always_inline)).
+
+     Inlining will only occur when the optimization level is
+     above 0; when optimization is off, this is essentially the
+     same as GCC_JIT_FUNCTION_INTERNAL.  */
+  GCC_JIT_FUNCTION_ALWAYS_INLINE
 };
 
 
diff --git a/gcc/testsuite/ChangeLog.jit b/gcc/testsuite/ChangeLog.jit
index 08fe76c..ec8af3d 100644
--- a/gcc/testsuite/ChangeLog.jit
+++ b/gcc/testsuite/ChangeLog.jit
@@ -1,5 +1,17 @@
 2014-03-07  David Malcolm  <dmalcolm@redhat.com>
 
+	* jit.dg/test-functions.c (create_test_of_hidden_function): New,
+	adding test coverage for GCC_JIT_FUNCTION_ALWAYS_INLINE and
+	GCC_JIT_FUNCTION_INTERNAL.
+	(create_tests_of_hidden_functions): Likewise.
+	(verify_hidden_functions): Likewise.
+	(create_code): Add call to create_tests_of_hidden_functions.
+	(verify_code): Add call to verify_hidden_functions.
+	* jit.dg/test-quadratic.c (make_calc_discriminant): Convert
+	from GCC_JIT_FUNCTION_EXPORTED to GCC_JIT_FUNCTION_INTERNAL.
+
+2014-03-07  David Malcolm  <dmalcolm@redhat.com>
+
 	* jit.dg/test-functions.c: Reorder function definitions, grouping
 	them by subject-matter rather than by create-vs-verify phase.
 
diff --git a/gcc/testsuite/jit.dg/test-functions.c b/gcc/testsuite/jit.dg/test-functions.c
index b3e3251..3d03ada 100644
--- a/gcc/testsuite/jit.dg/test-functions.c
+++ b/gcc/testsuite/jit.dg/test-functions.c
@@ -7,6 +7,111 @@
 #include "harness.h"
 
 /**********************************************************************
+ GCC_JIT_FUNCTION_ALWAYS_INLINE and GCC_JIT_FUNCTION_INTERNAL
+ **********************************************************************/
+static void
+create_test_of_hidden_function (gcc_jit_context *ctxt,
+				enum gcc_jit_function_kind hidden_kind,
+				const char *hidden_func_name,
+				const char *visible_func_name)
+{
+  /* Let's try to inject the equivalent of:
+     static double hidden_mult (double a, double b)
+     {
+       return x * x;
+     }
+     double my_square (double x)
+     {
+       return my_mult (x, x);
+     }
+
+     where hidden_mult can potentially be
+       inline  __attribute__((always_inline)).  */
+  gcc_jit_type *double_type =
+    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_DOUBLE);
+
+  /* Create "my_mult" */
+  gcc_jit_param *param_a =
+    gcc_jit_context_new_param (ctxt, NULL, double_type, "a");
+  gcc_jit_param *param_b =
+    gcc_jit_context_new_param (ctxt, NULL, double_type, "b");
+  gcc_jit_param *params[2] = {param_a, param_b};
+  gcc_jit_function *my_mult =
+    gcc_jit_context_new_function (ctxt, NULL,
+				  hidden_kind,
+                                  double_type,
+                                  hidden_func_name,
+                                  2, params,
+                                  0);
+  gcc_jit_block *body_of_my_mult =
+    gcc_jit_function_new_block (my_mult, NULL);
+  gcc_jit_block_end_with_return (
+    body_of_my_mult, NULL,
+    gcc_jit_context_new_binary_op (
+      ctxt, NULL,
+      GCC_JIT_BINARY_OP_MULT,
+      double_type,
+      gcc_jit_param_as_rvalue (param_a),
+      gcc_jit_param_as_rvalue (param_b)));
+
+  /* Create "my_square" */
+  gcc_jit_param *param_x =
+    gcc_jit_context_new_param (ctxt, NULL, double_type, "x");
+  gcc_jit_function *my_square =
+    gcc_jit_context_new_function (ctxt, NULL,
+                                  GCC_JIT_FUNCTION_EXPORTED,
+                                  double_type,
+                                  visible_func_name,
+                                  1, &param_x,
+                                  0);
+  gcc_jit_block *body_of_my_square =
+    gcc_jit_function_new_block (my_square, NULL);
+  gcc_jit_rvalue *args[2] = {gcc_jit_param_as_rvalue (param_x),
+			     gcc_jit_param_as_rvalue (param_x)};
+  gcc_jit_block_end_with_return (
+    body_of_my_square, NULL,
+    gcc_jit_context_new_call (
+      ctxt, NULL,
+      my_mult,
+      2, args));
+}
+
+static void
+create_tests_of_hidden_functions (gcc_jit_context *ctxt)
+{
+  create_test_of_hidden_function (ctxt,
+				  GCC_JIT_FUNCTION_INTERNAL,
+				  "my_internal_mult",
+				  "my_square_with_internal");
+  create_test_of_hidden_function (ctxt,
+				  GCC_JIT_FUNCTION_ALWAYS_INLINE,
+				  "my_always_inline_mult",
+				  "my_square_with_always_inline");
+}
+
+static void
+verify_hidden_functions (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+  CHECK_NON_NULL (result);
+
+  /* GCC_JIT_FUNCTION_INTERNAL and GCC_JIT_FUNCTION_ALWAYS_INLINE
+     functions should not be accessible in the result.  */
+  CHECK_VALUE (NULL, gcc_jit_result_get_code (result, "my_internal_mult"));
+  CHECK_VALUE (NULL, gcc_jit_result_get_code (result, "my_always_inline_mult"));
+
+  typedef double (*fn_type) (double);
+  fn_type my_square_with_internal =
+    (fn_type)gcc_jit_result_get_code (result, "my_square_with_internal");
+  CHECK_NON_NULL (my_square_with_internal);
+  CHECK_VALUE (my_square_with_internal (5.0), 25.0);
+
+  fn_type my_square_with_always_inline =
+    (fn_type)gcc_jit_result_get_code (result, "my_square_with_always_inline");
+  CHECK_NON_NULL (my_square_with_always_inline);
+  CHECK_VALUE (my_square_with_always_inline (5.0), 25.0);
+}
+
+/**********************************************************************
  Builtin functions
  **********************************************************************/
 
@@ -236,6 +341,7 @@ verify_void_return (gcc_jit_context *ctxt, gcc_jit_result *result)
 void
 create_code (gcc_jit_context *ctxt, void *user_data)
 {
+  create_tests_of_hidden_functions (ctxt);
   create_use_of_builtins (ctxt);
   create_use_of_void_return (ctxt);
 }
@@ -244,6 +350,7 @@ create_code (gcc_jit_context *ctxt, void *user_data)
 void
 verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
 {
+  verify_hidden_functions (ctxt, result);
   verify_use_of_builtins (ctxt, result);
   verify_void_return (ctxt, result);
 }
diff --git a/gcc/testsuite/jit.dg/test-quadratic.c b/gcc/testsuite/jit.dg/test-quadratic.c
index b984445..715174c 100644
--- a/gcc/testsuite/jit.dg/test-quadratic.c
+++ b/gcc/testsuite/jit.dg/test-quadratic.c
@@ -17,7 +17,7 @@ struct quadratic
 
      extern double sqrt (double);
 
-     void
+     static void
      calc_discriminant (struct quadratic *q)
      {
        // (b^2 - 4ac)
@@ -149,7 +149,7 @@ make_calc_discriminant (struct quadratic_test *testcase)
 			       testcase->quadratic_ptr, "q");
   testcase->calc_discriminant =
     gcc_jit_context_new_function (testcase->ctxt, NULL,
-				  GCC_JIT_FUNCTION_EXPORTED,
+				  GCC_JIT_FUNCTION_INTERNAL,
 				  testcase->void_type,
 				  "calc_discriminant",
 				  1, &param_q,
-- 
1.7.11.7


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