libgccjit: introduce gcc_jit_context_add_driver_option
authorAndrea Corallo <andrea.corallo@arm.com>
Tue, 5 Feb 2019 22:11:04 +0000 (22:11 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Tue, 5 Feb 2019 22:11:04 +0000 (22:11 +0000)
gcc/jit/ChangeLog:
2019-02-05  Andrea Corallo <andrea.corallo@arm.com>

* docs/topics/compatibility.rst (LIBGCCJIT_ABI_11): New ABI tag.
* docs/topics/contexts.rst (Additional driver options): New
section.
* jit-playback.c (invoke_driver): Add call to append_driver_options.
* jit-recording.c: Within namespace gcc::jit...
(recording::context::~context): Free the optnames within
m_driver_options.
(recording::context::add_driver_option): New method.
(recording::context::append_driver_options): New method.
(recording::context::dump_reproducer_to_file): Add driver
options.
* jit-recording.h: Within namespace gcc::jit...
(recording::context::add_driver_option): New method.
(recording::context::append_driver_options): New method.
(recording::context::m_driver_options): New field.
* libgccjit++.h (gccjit::context::add_driver_option): New
method.
* libgccjit.c (gcc_jit_context_add_driver_option): New API
entrypoint.
* libgccjit.h (gcc_jit_context_add_driver_option): New API
entrypoint.
(LIBGCCJIT_HAVE_gcc_jit_context_add_driver_option): New
macro.
* libgccjit.map (LIBGCCJIT_ABI_11): New ABI tag.

gcc/testsuite/ChangeLog:
2019-02-05  Andrea Corallo <andrea.corallo@arm.com>

* jit.dg/add-driver-options-testlib.c: Add support file for
test-add-driver-options.c testcase.
* jit.dg/all-non-failing-tests.h: Add note about
test-add-driver-options.c
* jit.dg/jit.exp (jit-dg-test): Update to support
add-driver-options-testlib.c compilation.
* jit.dg/test-add-driver-options.c: New testcase.

From-SVN: r268563

15 files changed:
gcc/jit/ChangeLog
gcc/jit/docs/topics/compatibility.rst
gcc/jit/docs/topics/contexts.rst
gcc/jit/jit-playback.c
gcc/jit/jit-recording.c
gcc/jit/jit-recording.h
gcc/jit/libgccjit++.h
gcc/jit/libgccjit.c
gcc/jit/libgccjit.h
gcc/jit/libgccjit.map
gcc/testsuite/ChangeLog
gcc/testsuite/jit.dg/add-driver-options-testlib.c [new file with mode: 0644]
gcc/testsuite/jit.dg/all-non-failing-tests.h
gcc/testsuite/jit.dg/jit.exp
gcc/testsuite/jit.dg/test-add-driver-options.c [new file with mode: 0644]

index 12a6c61a669001a1a802f35df93dfd8b87c71b54..c57c99a1a4f4a5925e97a8e484039d737a690cd5 100644 (file)
@@ -1,3 +1,30 @@
+2019-02-05  Andrea Corallo <andrea.corallo@arm.com>
+
+       * docs/topics/compatibility.rst (LIBGCCJIT_ABI_11): New ABI tag.
+       * docs/topics/contexts.rst (Additional driver options): New
+       section.
+       * jit-playback.c (invoke_driver): Add call to append_driver_options.
+       * jit-recording.c: Within namespace gcc::jit...
+       (recording::context::~context): Free the optnames within
+       m_driver_options.
+       (recording::context::add_driver_option): New method.
+       (recording::context::append_driver_options): New method.
+       (recording::context::dump_reproducer_to_file): Add driver
+       options.
+       * jit-recording.h: Within namespace gcc::jit...
+       (recording::context::add_driver_option): New method.
+       (recording::context::append_driver_options): New method.
+       (recording::context::m_driver_options): New field.
+       * libgccjit++.h (gccjit::context::add_driver_option): New
+       method.
+       * libgccjit.c (gcc_jit_context_add_driver_option): New API
+       entrypoint.
+       * libgccjit.h (gcc_jit_context_add_driver_option): New API
+       entrypoint.
+       (LIBGCCJIT_HAVE_gcc_jit_context_add_driver_option): New
+       macro.
+       * libgccjit.map (LIBGCCJIT_ABI_11): New ABI tag.
+
 2019-01-01  Jakub Jelinek  <jakub@redhat.com>
 
        Update copyright years.
index 38d338b1f606baf59fbb05c60faacb8f0578d0c8..abefa56f37d032b814d814c75ee228ca576a364c 100644 (file)
@@ -168,6 +168,12 @@ entrypoints:
 
 ``LIBGCCJIT_ABI_10``
 --------------------
-
 ``LIBGCCJIT_ABI_10`` covers the addition of
 :func:`gcc_jit_context_new_rvalue_from_vector`
+
+.. _LIBGCCJIT_ABI_11:
+
+``LIBGCCJIT_ABI_11``
+--------------------
+``LIBGCCJIT_ABI_11`` covers the addition of
+:func:`gcc_jit_context_add_driver_option`
index 95964cac683950d0ea42f2a84d24250855838308..2f8aeb7acdc733e976805cc067d88b663c0883e0 100644 (file)
@@ -546,3 +546,36 @@ Additional command-line options
    .. code-block:: c
 
       #ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option
+
+.. function:: void gcc_jit_context_add_driver_option (gcc_jit_context *ctxt,\
+                                                     const char *optname)
+
+   Add an arbitrary gcc driver option to the context, for use by
+   :func:`gcc_jit_context_compile` and
+   :func:`gcc_jit_context_compile_to_file`.
+
+   The parameter ``optname`` must be non-NULL.  The underlying buffer is
+   copied, so that it does not need to outlive the call.
+
+   Extra options added by `gcc_jit_context_add_driver_option` are
+   applied *after* all other options potentially overriding them.
+   Options from parent contexts are inherited by child contexts; options
+   from the parent are applied *before* those from the child.
+
+   For example:
+
+   .. code-block:: c
+
+      gcc_jit_context_add_driver_option (ctxt, "-lm");
+      gcc_jit_context_add_driver_option (ctxt, "-fuse-linker-plugin");
+
+   Note that only some options are likely to be meaningful; there is no
+   "frontend" within libgccjit, so typically only those affecting
+   assembler and linker are likely to be useful.
+
+   This entrypoint was added in :ref:`LIBGCCJIT_ABI_11`; you can test for
+   its presence using
+
+   .. code-block:: c
+
+      #ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_driver_option
index 86f588db9ae233963a6bd21f86b1eb9deb392ad8..b74495c58b2cca694a54b3d13bd4df3c40156cd0 100644 (file)
@@ -2459,6 +2459,10 @@ invoke_driver (const char *ctxt_progname,
   if (0)
     ADD_ARG ("-v");
 
+  /* Add any user-provided driver extra options.  */
+
+  m_recording_ctxt->append_driver_options (&argvec);
+
 #undef ADD_ARG
 
   /* pex_one's error-handling requires pname to be non-NULL.  */
index 04cc6a6903383b73b80c8c7ceba84ef560f27b9c..8ffd0d452b2d89ebb1236370de900415eb805fe3 100644 (file)
@@ -616,6 +616,8 @@ recording::context::~context ()
   char *optname;
   FOR_EACH_VEC_ELT (m_command_line_options, i, optname)
     free (optname);
+  FOR_EACH_VEC_ELT (m_driver_options, i, optname)
+    free (optname);
 
   if (m_builtins_manager)
     delete m_builtins_manager;
@@ -1307,6 +1309,31 @@ recording::context::append_command_line_options (vec <char *> *argvec)
     argvec->safe_push (xstrdup (optname));
 }
 
+/* Add the given optname to this context's list of extra driver options.  */
+
+void
+recording::context::add_driver_option (const char *optname)
+{
+  m_driver_options.safe_push (xstrdup (optname));
+}
+
+/* Add any user-provided driver options, starting with any from
+   parent contexts.
+   Called by playback::context::invoke_driver.  */
+
+void
+recording::context::append_driver_options (auto_string_vec *argvec)
+{
+  if (m_parent_ctxt)
+    m_parent_ctxt->append_driver_options (argvec);
+
+  int i;
+  char *optname;
+
+  FOR_EACH_VEC_ELT (m_driver_options, i, optname)
+    argvec->safe_push (xstrdup (optname));
+}
+
 /* Add the given dumpname/out_ptr pair to this context's list of requested
    dumps.
 
@@ -1799,6 +1826,17 @@ recording::context::dump_reproducer_to_file (const char *path)
                     optname);
        }
 
+      if (!m_driver_options.is_empty ())
+       {
+         int i;
+         char *optname;
+         r.write ("  /* User-provided driver options.  */\n");
+         FOR_EACH_VEC_ELT (m_driver_options, i, optname)
+           r.write ("  gcc_jit_context_add_driver_option (%s, \"%s\");\n",
+                    r.get_identifier (contexts[ctxt_idx]),
+                    optname);
+       }
+
       if (m_requested_dumps.length ())
        {
          r.write ("  /* Requested dumps.  */\n");
index b9c6544d0186851a4eff4adf7260f4ff5e4d9c79..b9f2250802fb3eea5d2532594ec69ad1f9ba7e14 100644 (file)
@@ -217,6 +217,12 @@ public:
   void
   append_command_line_options (vec <char *> *argvec);
 
+  void
+  add_driver_option (const char *optname);
+
+  void
+  append_driver_options (auto_string_vec *argvec);
+
   void
   enable_dump (const char *dumpname,
               char **out_ptr);
@@ -317,6 +323,7 @@ private:
   bool m_bool_options[GCC_JIT_NUM_BOOL_OPTIONS];
   bool m_inner_bool_options[NUM_INNER_BOOL_OPTIONS];
   auto_vec <char *> m_command_line_options;
+  auto_vec <char *> m_driver_options;
 
   /* Dumpfiles that were requested via gcc_jit_context_enable_dump.  */
   auto_vec<requested_dump> m_requested_dumps;
index 5c2bd2dfd4c4bf0c54b1c54240cbacfe367a2af1..55aebcac4f54017f4d20ec789014714a67f665bb 100644 (file)
@@ -127,6 +127,7 @@ namespace gccjit
     void set_bool_use_external_driver (int bool_value);
 
     void add_command_line_option (const char *optname);
+    void add_driver_option (const char *optname);
 
     void set_timer (gccjit::timer t);
     gccjit::timer get_timer () const;
@@ -686,6 +687,12 @@ context::add_command_line_option (const char *optname)
   gcc_jit_context_add_command_line_option (m_inner_ctxt, optname);
 }
 
+inline void
+context::add_driver_option (const char *optname)
+{
+  gcc_jit_context_add_driver_option (m_inner_ctxt, optname);
+}
+
 inline void
 context::set_timer (gccjit::timer t)
 {
index de7fb257918242cbc929272ae92e5bd832ba096d..e4f17f8b35082bcb203c49d4ac0686924c2b4aa5 100644 (file)
@@ -2642,6 +2642,25 @@ gcc_jit_context_add_command_line_option (gcc_jit_context *ctxt,
   ctxt->add_command_line_option (optname);
 }
 
+/* Public entrypoint.  See description in libgccjit.h.
+
+   The real work is done by the
+   gcc::jit::recording::context::add_driver_option method in
+   jit-recording.c.  */
+
+void
+gcc_jit_context_add_driver_option (gcc_jit_context *ctxt,
+                                  const char *optname)
+{
+  RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
+  JIT_LOG_FUNC (ctxt->get_logger ());
+  RETURN_IF_FAIL (optname, ctxt, NULL, "NULL optname");
+  if (ctxt->get_logger ())
+    ctxt->get_logger ()->log ("optname: %s", optname);
+
+  ctxt->add_driver_option (optname);
+}
+
 /* Public entrypoint.  See description in libgccjit.h.
 
    After error-checking, the real work is done by the
index e872ae78906f2e811254c4a23017f46761f5dc4f..beeb747ca8fc210d2347bc28f0338d37b59103d7 100644 (file)
@@ -325,6 +325,28 @@ gcc_jit_context_add_command_line_option (gcc_jit_context *ctxt,
 
 #define LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option
 
+/* Add an arbitrary gcc driver option to the context.
+   The context takes a copy of the string, so the
+   (const char *) optname is not needed anymore after the call
+   returns.
+
+   Note that only some options are likely to be meaningful; there is no
+   "frontend" within libgccjit, so typically only those affecting
+   assembler and linker are likely to be useful.
+
+   This entrypoint was added in LIBGCCJIT_ABI_11; you can test for
+   its presence using
+   #ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_driver_option
+*/
+extern void
+gcc_jit_context_add_driver_option (gcc_jit_context *ctxt,
+                                  const char *optname);
+
+/* Pre-canned feature-test macro for detecting the presence of
+   gcc_jit_context_add_driver_option within libgccjit.h.  */
+
+#define LIBGCCJIT_HAVE_gcc_jit_context_add_driver_option
+
 /* Compile the context to in-memory machine code.
 
    This can be called more that once on a given context,
index 2826f1ca680751a1ea268b331e5755fbcb9875bb..16f5253ab23f4a35c7b2ae3742714ffd2aa7586b 100644 (file)
@@ -170,3 +170,8 @@ LIBGCCJIT_ABI_10 {
   global:
     gcc_jit_context_new_rvalue_from_vector;
 } LIBGCCJIT_ABI_9;
+
+LIBGCCJIT_ABI_11 {
+  global:
+    gcc_jit_context_add_driver_option;
+} LIBGCCJIT_ABI_10;
\ No newline at end of file
index 4ae0914eb717c500b913b0abc22fb088473ce396..616741669fa4ad38a47b0af113fb31d5b3a0845f 100644 (file)
@@ -1,3 +1,13 @@
+2019-02-05  Andrea Corallo <andrea.corallo@arm.com>
+
+       * jit.dg/add-driver-options-testlib.c: Add support file for
+       test-add-driver-options.c testcase.
+       * jit.dg/all-non-failing-tests.h: Add note about
+       test-add-driver-options.c
+       * jit.dg/jit.exp (jit-dg-test): Update to support
+       add-driver-options-testlib.c compilation.
+       * jit.dg/test-add-driver-options.c: New testcase.
+
 2019-02-05  Jakub Jelinek  <jakub@redhat.com>
 
        PR rtl-optimization/11304
diff --git a/gcc/testsuite/jit.dg/add-driver-options-testlib.c b/gcc/testsuite/jit.dg/add-driver-options-testlib.c
new file mode 100644 (file)
index 0000000..1757bb1
--- /dev/null
@@ -0,0 +1,6 @@
+/* Used by test-add-driver-options.c */
+
+extern int callee_function (void)
+{
+  return 1978;
+}
index bf02e1258bb04a008a59e9b6fe9fe582685a029b..9a10418b308cf7aa9944b697d74ea50c52dfc56e 100644 (file)
@@ -22,6 +22,9 @@
 #undef create_code
 #undef verify_code
 
+/* test-add-driver-options.c: We don't use this one, since the extra options
+   affect the whole context.  */
+
 /* test-alignment.c */
 #define create_code create_code_alignment
 #define verify_code verify_code_alignment
index 869d9f693a0145632dc21c8e5b23a96b6eac8e6b..13e8ab4dbfe7f657f5bf90c1c8c36ea5c006a365 100644 (file)
@@ -379,6 +379,19 @@ proc jit-dg-test { prog do_what extra_tool_flags } {
        append extra_tool_flags " -lpthread"
     }
 
+    # test-add-driver-options.c needs a shared library built from
+    # add-driver-options-testlib.c
+    if {[string match "*test-add-driver-options.c" $prog]} {
+       global srcdir
+       global subdir
+
+       set comp_output [gcc_target_compile \
+                            $srcdir/$subdir/add-driver-options-testlib.c \
+                            "libadd-driver-options-testlib.so" \
+                            "executable" \
+                            "additional_flags=-fPIC additional_flags=-shared"]
+    }
+
     # Any test case that uses jit-verify-output-file-was-created
     # needs to call jit-setup-compile-to-file here.
     # (is there a better way to handle setup/finish pairs in dg?)
diff --git a/gcc/testsuite/jit.dg/test-add-driver-options.c b/gcc/testsuite/jit.dg/test-add-driver-options.c
new file mode 100644 (file)
index 0000000..74ac168
--- /dev/null
@@ -0,0 +1,68 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "libgccjit.h"
+#include "harness.h"
+
+#ifndef LIBGCCJIT_HAVE_gcc_jit_context_add_driver_option
+#error LIBGCCJIT_HAVE_gcc_jit_context_add_driver_option was not defined
+#endif
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+
+  gcc_jit_context_add_driver_option (ctxt, "-L./");
+  gcc_jit_context_add_driver_option (ctxt, "-ladd-driver-options-testlib");
+
+  /* Let's try to inject the equivalent of:
+
+      int caller_function (void)
+      {
+        return callee_function ();
+      }
+  */
+  gcc_jit_type *int_type =
+    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+
+  gcc_jit_function *caller_func =
+    gcc_jit_context_new_function (ctxt, NULL,
+                                  GCC_JIT_FUNCTION_EXPORTED,
+                                  int_type,
+                                  "caller_function",
+                                  0, NULL,
+                                  0);
+
+  gcc_jit_block *block =
+    gcc_jit_function_new_block (caller_func, NULL);
+
+  gcc_jit_function *callee_func =
+    gcc_jit_context_new_function(ctxt, NULL,
+                                GCC_JIT_FUNCTION_IMPORTED,
+                                int_type,
+                                "callee_function",
+                                0, NULL,
+                                1);
+
+  gcc_jit_block_end_with_return (block, NULL,
+                                gcc_jit_context_new_call(ctxt,
+                                                         NULL,
+                                                         callee_func,
+                                                         0,
+                                                         0));
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+  typedef int (*my_caller_fn_type) (void);
+
+  CHECK_NON_NULL (result);
+  my_caller_fn_type callee_function_ptr =
+    (my_caller_fn_type)gcc_jit_result_get_code (result, "callee_function");
+  CHECK_NON_NULL (callee_function_ptr);
+
+  int res = callee_function_ptr ();
+
+  CHECK_VALUE (res, 1978);
+}