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]

[PATCH] allow passing argument to the JIT linker


If you generate code with the JIT which references outside symbols there
is currently no way to have a self-contained DSO created.  The command
line to invoke the linker is fixed.

The patch below would change that.  It builds upon the existing
framework to specify options for the compiler.  The linker optimization
flag fits fully into the existing functionality.  For additional files
to link with I had to extend the mechanism a bit since it is not just
one string that needs to be remembered.

I've also added the set_str_option member function to the C++ interface
of the library.  That must have been an oversight.


What do you think?


gcc/ChangeLog:

2014-12-05  Ulrich Drepper  <drepper@gmail.com>

	* jit/libgccjit++.h (context): Add missing set_str_option
	member function.

	* jit/libgccjit.h (gcc_jit_int_option): Add
	GCC_JIT_INT_OPTION_LINK_OPTIMIZATION_LEVEL.
	(gcc_jit_str_option): Add GCC_JIT_STR_OPTION_LINKFILE.
	* jit/jit-playback.c (convert_to_dso): Use auto_vec instead
	of fixed-sized array for arguments.  Define ADD_ARG macro
	to add to it.  Adjust existing code.  Additionally add
	optimization level and additional link files to the list.
	* jit/jit-playback.h (context::get_linkfiles): New member
	function.
	* jit/jit-recording.c (recording::context:set_str_option):
	Handle GCC_JIT_STR_OPTION_LINKFILE.
	* jit/jit-recording.h (recording::context:set_str_option):
	Add get_linkfiles member function.

diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c
index ecdae80..9c4e45f 100644
--- a/gcc/jit/jit-playback.c
+++ b/gcc/jit/jit-playback.c
@@ -1726,18 +1726,19 @@ convert_to_dso (const char *ctxt_progname)
      TV_ASSEMBLE.  */
   auto_timevar assemble_timevar (TV_ASSEMBLE);
   const char *errmsg;
-  const char *argv[7];
+  auto_vec <const char *> argvec;
+#define ADD_ARG(arg) argvec.safe_push (arg)
   int exit_status = 0;
   int err = 0;
   const char *gcc_driver_name = GCC_DRIVER_NAME;
 
-  argv[0] = gcc_driver_name;
-  argv[1] = "-shared";
+  ADD_ARG (gcc_driver_name);
+  ADD_ARG ("-shared");
   /* The input: assembler.  */
-  argv[2] = m_path_s_file;
+  ADD_ARG (m_path_s_file);
   /* The output: shared library.  */
-  argv[3] = "-o";
-  argv[4] = m_path_so_file;
+  ADD_ARG ("-o");
+  ADD_ARG (m_path_so_file);
 
   /* Don't use the linker plugin.
      If running with just a "make" and not a "make install", then we'd
@@ -1746,17 +1747,39 @@ convert_to_dso (const char *ctxt_progname)
      libto_plugin is a .la at build time, with it becoming installed with
      ".so" suffix: i.e. it doesn't exist with a .so suffix until install
      time.  */
-  argv[5] = "-fno-use-linker-plugin";
+  ADD_ARG ("-fno-use-linker-plugin");
+
+  /* Linker int options.  */
+  switch (get_int_option (GCC_JIT_INT_OPTION_LINK_OPTIMIZATION_LEVEL))
+    {
+    default:
+      add_error (NULL,
+		 "unrecognized linker optimization level: %i",
+		 get_int_option (GCC_JIT_INT_OPTION_LINK_OPTIMIZATION_LEVEL));
+      return;
+
+    case 0:
+      break;
+
+    case 1:
+      ADD_ARG ("-Wl,-O");
+      break;
+    }
+
+  const char *elt;
+  const auto_vec<const char *>& linkfiles = get_linkfiles();
+  for (unsigned ix = 0; linkfiles.iterate(ix, &elt); ++ix)
+    ADD_ARG (elt);
 
   /* pex argv arrays are NULL-terminated.  */
-  argv[6] = NULL;
+  ADD_ARG (NULL);
 
   /* pex_one's error-handling requires pname to be non-NULL.  */
   gcc_assert (ctxt_progname);
 
   errmsg = pex_one (PEX_SEARCH, /* int flags, */
 		    gcc_driver_name,
-		    const_cast<char * const *> (argv),
+		    const_cast <char *const *> (argvec.address ()),
 		    ctxt_progname, /* const char *pname */
 		    NULL, /* const char *outname */
 		    NULL, /* const char *errname */
@@ -1783,6 +1806,7 @@ convert_to_dso (const char *ctxt_progname)
 		 getenv ("PATH"));
       return;
     }
+#undef ADD_ARG
 }
 
 /* Top-level hook for playing back a recording context.
diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
index 02f08ba..2726347 100644
--- a/gcc/jit/jit-playback.h
+++ b/gcc/jit/jit-playback.h
@@ -175,6 +175,12 @@ public:
     return m_recording_ctxt->get_bool_option (opt);
   }
 
+  const auto_vec <const char *>&
+  get_linkfiles () const
+  {
+    return m_recording_ctxt->get_linkfiles ();
+  }
+
   builtins_manager *get_builtins_manager () const
   {
     return m_recording_ctxt->get_builtins_manager ();
diff --git a/gcc/jit/jit-recording.c b/gcc/jit/jit-recording.c
index 82ec399..a6d64f9 100644
--- a/gcc/jit/jit-recording.c
+++ b/gcc/jit/jit-recording.c
@@ -827,7 +827,17 @@ recording::context::set_str_option (enum gcc_jit_str_option opt,
 		 "unrecognized (enum gcc_jit_str_option) value: %i", opt);
       return;
     }
+
+  switch (opt)
+    {
+    default:
       m_str_options[opt] = value;
+      break;
+
+    case GCC_JIT_STR_OPTION_LINKFILE:
+      m_linkfiles.safe_push (value);
+      break;
+    }
 }
 
 /* Set the given integer option for this context, or add an error if
diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h
index 31fb304..4b21248 100644
--- a/gcc/jit/jit-recording.h
+++ b/gcc/jit/jit-recording.h
@@ -209,6 +209,12 @@ public:
     return m_bool_options[opt];
   }
 
+  const auto_vec<const char *>&
+  get_linkfiles (void) const
+  {
+    return m_linkfiles;
+  }
+
   result *
   compile ();
 
@@ -249,6 +255,7 @@ private:
   const char *m_str_options[GCC_JIT_NUM_STR_OPTIONS];
   int m_int_options[GCC_JIT_NUM_INT_OPTIONS];
   bool m_bool_options[GCC_JIT_NUM_BOOL_OPTIONS];
+  auto_vec <const char *> m_linkfiles;
 
   /* Recorded API usage.  */
   auto_vec<memento *> m_mementos;
@@ -1584,4 +1591,3 @@ private:
 } // namespace gcc
 
 #endif /* JIT_RECORDING_H */
-
diff --git a/gcc/jit/libgccjit++.h b/gcc/jit/libgccjit++.h
index 67ed5d5..232bb0f 100644
--- a/gcc/jit/libgccjit++.h
+++ b/gcc/jit/libgccjit++.h
@@ -99,6 +99,9 @@ namespace gccjit
     void dump_to_file (const std::string &path,
 		       bool update_locations);
 
+    void set_str_option (enum gcc_jit_str_option opt,
+			 const char *value);
+
     void set_int_option (enum gcc_jit_int_option opt,
 			 int value);
 
@@ -535,6 +538,14 @@ context::dump_to_file (const std::string &path,
 }
 
 inline void
+context::set_str_option (enum gcc_jit_str_option opt,
+			 const char *value)
+{
+  gcc_jit_context_set_str_option (m_inner_ctxt, opt, value);
+
+}
+
+inline void
 context::set_int_option (enum gcc_jit_int_option opt,
 			 int value)
 {
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index ed6390e..da3a2bf 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -139,6 +139,11 @@ enum gcc_jit_str_option
      messages to stderr.  If NULL, or default, "libgccjit.so" is used.  */
   GCC_JIT_STR_OPTION_PROGNAME,
 
+  /* Additional files added to the link command line.  To be used to
+     name libraries needed to satisfy dependencies in the generated
+     code.  */
+  GCC_JIT_STR_OPTION_LINKFILE,
+
   GCC_JIT_NUM_STR_OPTIONS
 };
 
@@ -152,6 +157,11 @@ enum gcc_jit_int_option
      The default value is 0 (unoptimized).  */
   GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL,
 
+  /* Optimization level for the linker.
+
+     The default value is 0 (unoptimized).  */
+  GCC_JIT_INT_OPTION_LINK_OPTIMIZATION_LEVEL,
+
   GCC_JIT_NUM_INT_OPTIONS
 };
 


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