From patchwork Sat Dec 6 20:56:39 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulrich Drepper X-Patchwork-Id: 418414 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id E83D8140119 for ; Sun, 7 Dec 2014 07:56:53 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type; q=dns; s= default; b=Z4B2dPm/Sk6VJq4ABuQSo9fZa+O9QgnG56+VZQ6IEIkV6ntiS7R82 QNXrRn2I5wwTpzvvQIiDl1oSCHjYi99ILhInWKKXeEif1zXfKogrfZjo5QGnT9Ag tpyjjomHHaBJGfAKrKYYTwuIch13xg3L/w7Yd8fDwZxtl137VbT3s8= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type; s= default; bh=Q+8evLQtLFQG3LPFpaAWawA7rDc=; b=TfA48Zm9sRVPif9cmdpq SnptSToTwv1y71dhNwdqf3LxR7882Yg7NAVXh/mLNRfiY3tTEnGVDSH6Yw1nMdy5 SbgtMDDoOhNi8GnLwS7TLWh2bYFCbyX9dG9pNB7Hk55saO90H+pwSXNJklYQA642 nixGCYPdXqj06vYImyOVKsQ= Received: (qmail 4869 invoked by alias); 6 Dec 2014 20:56:46 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 4859 invoked by uid 89); 6 Dec 2014 20:56:44 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-qg0-f44.google.com Received: from mail-qg0-f44.google.com (HELO mail-qg0-f44.google.com) (209.85.192.44) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Sat, 06 Dec 2014 20:56:42 +0000 Received: by mail-qg0-f44.google.com with SMTP id z60so2019269qgd.31 for ; Sat, 06 Dec 2014 12:56:40 -0800 (PST) X-Received: by 10.140.94.117 with SMTP id f108mr37404124qge.50.1417899400443; Sat, 06 Dec 2014 12:56:40 -0800 (PST) Received: from myware.local (pool-100-37-161-222.nycmny.fios.verizon.net. [100.37.161.222]) by mx.google.com with ESMTPSA id c75sm33392117qge.20.2014.12.06.12.56.39 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 06 Dec 2014 12:56:40 -0800 (PST) Received: from myware.local (localhost.localdomain [127.0.0.1]) by myware.local (8.14.9/8.14.9) with ESMTP id sB6Kudck021521 for ; Sat, 6 Dec 2014 15:56:39 -0500 Received: (from drepper@localhost) by myware.local (8.14.9/8.14.9/Submit) id sB6Kudgi021520; Sat, 6 Dec 2014 15:56:39 -0500 From: Ulrich Drepper To: gcc-patches@gcc.gnu.org Subject: [PATCH] influence JIT linker command line Date: Sat, 06 Dec 2014 15:56:39 -0500 Message-ID: <87fvcsebug.fsf@gmail.com> MIME-Version: 1.0 This patch supercedes the patch I sent earlier this week to add dependencies to the linker command line. The implementation is different. First, based on Dave's comment that he wants to keep the interface simple, to enable the linker optimizations no new interface is added. Instead optimizations are enabled in the linker whenever the compiler optimizes, too. I don't think this will create problems at all since the time it takes nowadays is really low; it's only really measurable for extremely large files. The way to add dependencies is changed. Instead of allowing an unstructured string parameter to be added to the command line the new proposed interface allows to introduce a dependency with possibly information about the path the dependency is found. This should be useful and implementable if at some point the explicit linker invocation is replaced by a library implementation. The path argument of the new interface is used differently depending on the name. If the name is of the form -l* then the -L option is used and a runpath is added. Otherwise the path is used to locate the file. Comments? gcc/ChangeLog: 2014-12-06 Ulrich Drepper * jit/jit-recording.c (recording::context::add_dependency): New function. (recording::context::~context): Free newly added lists. * jit/jit-recording.h (recording::context): Add new member functions. * jit/libgccjit++.h (context): Add add_dependency member function. * jit/libgccjit.h: Declare gcc_jit_context_add_dependency. * jit/libgccjit.c: Define gcc_jit_context_add_dependency. * jit/libgccjit.map: Add gcc_jit_context_add_dependency. * jit/jit-playback.c (convert_to_dso): Add dependencies and library path arguments to the command line. * docs/topics/contexts.rst: Document new interface. diff -u b/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c --- b/gcc/jit/jit-playback.c +++ b/gcc/jit/jit-playback.c @@ -1749,6 +1749,18 @@ time. */ ADD_ARG ("-fno-use-linker-plugin"); + /* Linker optimization. We always tell the linker to optimize if the + compiler is optimizing, too. */ + if (get_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL) > 0) + ADD_ARG ("-Wl,-O"); + + const char *s; + for (unsigned i = 0; (s = get_dependency (i)); ++i) + ADD_ARG (s); + + for (unsigned i = 0; (s = get_library_path (i)); ++i) + ADD_ARG (s); + /* pex argv arrays are NULL-terminated. */ ADD_ARG (NULL); diff -u b/gcc/jit/jit-recording.c b/gcc/jit/jit-recording.c --- b/gcc/jit/jit-recording.c +++ b/gcc/jit/jit-recording.c @@ -218,6 +218,17 @@ for (i = 0; i < GCC_JIT_NUM_STR_OPTIONS; ++i) free (m_str_options[i]); + char *s; + FOR_EACH_VEC_ELT (m_dependencies, i, s) + { + free (s); + } + + FOR_EACH_VEC_ELT (m_library_path, i, s) + { + free (s); + } + if (m_builtins_manager) delete m_builtins_manager; @@ -871,7 +882,66 @@ m_bool_options[opt] = value ? true : false; } -/* This mutex guards gcc::jit::recording::context::compile, so that only +/* Add the given library to the set of dependencies, or add an error + if it's not recognized. + + Implements the post-error-checking part of + gcc_jit_context_add_dependency. */ +void +recording::context::add_dependency (const char *name, int flags, + const char *path) +{ + if (name == NULL) + { + add_error (NULL, "NULL library name"); + return; + } + /* So far no flags are defined. */ + if (flags != 0) + { + add_error (NULL, + "unrecognized flags value: %i", flags); + return; + } + + bool named_library = strncmp (name, "-l", 2); + + if (strchr (name, '/') != NULL && (named_library || path != NULL)) + { + add_error (NULL, + "path must be NULL unless simple file name is used"); + return; + } + if (named_library == 0 || path == NULL) + { + m_dependencies.safe_push (xstrdup (name)); + + if (named_library) + { + char *v; + asprintf (&v, "-Wl,-R,%s -L %s", path, path); + if (v == NULL) + { + add_error (NULL, "cannot allocate memory"); + return; + } + m_library_path.safe_push (v); + } + } + else + { + char *v; + asprintf (&v, "%s/%s", path, name); + if (v == NULL) + { + add_error (NULL, "cannot allocate memory"); + return; + } + m_dependencies.safe_push (v); + } +} + + /* This mutex guards gcc::jit::recording::context::compile, so that only one thread can be accessing the bulk of GCC's state at once. */ static pthread_mutex_t jit_mutex = PTHREAD_MUTEX_INITIALIZER; diff -u b/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h --- b/gcc/jit/jit-recording.h +++ b/gcc/jit/jit-recording.h @@ -191,6 +191,10 @@ set_bool_option (enum gcc_jit_bool_option opt, int value); + void + add_dependency (const char *name, int flags, + const char *path); + const char * get_str_option (enum gcc_jit_str_option opt) const { @@ -209,6 +213,22 @@ return m_bool_options[opt]; } + const char * + get_dependency (unsigned idx) const + { + if (idx >= m_dependencies.length ()) + return NULL; + return m_dependencies[idx]; + } + + const char * + get_library_path (unsigned idx) const + { + if (idx >= m_library_path.length ()) + return NULL; + return m_library_path[idx]; + } + result * compile (); @@ -250,6 +270,9 @@ int m_int_options[GCC_JIT_NUM_INT_OPTIONS]; bool m_bool_options[GCC_JIT_NUM_BOOL_OPTIONS]; + auto_vec m_dependencies; + auto_vec m_library_path; + /* Recorded API usage. */ auto_vec m_mementos; diff -u b/gcc/jit/libgccjit++.h b/gcc/jit/libgccjit++.h --- b/gcc/jit/libgccjit++.h +++ b/gcc/jit/libgccjit++.h @@ -108,6 +108,9 @@ void set_bool_option (enum gcc_jit_bool_option opt, int value); + void add_dependency (const char *name, int flags = 0, + const char *path = NULL); + location new_location (const std::string &filename, int line, @@ -561,6 +564,12 @@ } +inline void +context::add_dependency (const char *name, int flags, const char *path) +{ + gcc_jit_context_add_dependency (m_inner_ctxt, name, flags, path); +} + inline location context::new_location (const std::string &filename, int line, diff -u b/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h --- b/gcc/jit/libgccjit.h +++ b/gcc/jit/libgccjit.h @@ -234,6 +234,16 @@ enum gcc_jit_bool_option opt, int value); +/* Add object as dependency. + + The (const char *) values are not needed anymore after the call + returns. */ +extern void +gcc_jit_context_add_dependency (gcc_jit_context *ctxt, + const char *name, + int flags, + const char *path); + /* This actually calls into GCC and runs the build, all in a mutex for now. The result is a wrapper around a .so file. It can only be called once on a given context. */ only in patch2: unchanged: --- a/gcc/jit/docs/topics/contexts.rst +++ b/gcc/jit/docs/topics/contexts.rst @@ -325,3 +325,47 @@ Integer options -O0 through -O3. The default value is 0 (unoptimized). + + .. macro:: GCC_JIT_INT_OPTION_LINK_OPTIMIZATION_LEVEL + + How much to optimize the code at the linking phase. + + Valid values are 0 and 1. + + The default value is 0 (unoptimized). + +Dependencies +------------ + +The JIT-created code might reference functions which are provided by +external libraries or is available in object files. + +.. function:: void gcc_jit_context_add_dependency (gcc_jit_context *ctxt, \ + const char *name, \ + int flags, \ + const char *path) + + Add the named object to the list of dependencies for the context. + + .. name:: name of the file with the object to be added. The string can + have multiple forms: + + - if the string starts with "-l" it names a library which + is looked up using the usual rules a linker would follow, + possibly extended by the :name `path` parameter. The + :name `name` must consist only of valid characters for a + library name. + + - if the string is a general file name it names a file + available in the file system which can be accessible. The + file can be a library or an object file. + + - if the string is a path name it must name the file. In this + case the :name `path` must be :macro:`NULL`. + + .. flags:: this parameter is reserved for future use and for now must + always be zero. + + .. path:: this parameter provides the path of the file named in the + ``name`` parameter. See above for the rules for when this + parameter must be set to :macro:`NULL`. only in patch2: unchanged: --- a/gcc/jit/jit-playback.h +++ b/gcc/jit/jit-playback.h @@ -175,6 +175,18 @@ public: return m_recording_ctxt->get_bool_option (opt); } + const char * + get_dependency (unsigned idx) const + { + return m_recording_ctxt->get_dependency (idx); + } + + const char * + get_library_path (unsigned idx) const + { + return m_recording_ctxt->get_library_path (idx); + } + builtins_manager *get_builtins_manager () const { return m_recording_ctxt->get_builtins_manager (); @@ -586,4 +598,3 @@ extern playback::context *active_playback_ctxt; } // namespace gcc #endif /* JIT_PLAYBACK_H */ - only in patch2: unchanged: --- a/gcc/jit/libgccjit.c +++ b/gcc/jit/libgccjit.c @@ -2004,6 +2004,24 @@ gcc_jit_context_set_bool_option (gcc_jit_context *ctxt, /* Public entrypoint. See description in libgccjit.h. After error-checking, the real work is done by the + gcc::jit::recording::context::add_library_dependency method in + jit-recording.c. */ + +void gcc_jit_context_add_dependency (gcc_jit_context *ctxt, + const char *name, + int flags, + const char *path) +{ + RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context"); + /* flags is checked in the inner function. */ + + ctxt->add_dependency (name, flags, path); +} + + +/* Public entrypoint. See description in libgccjit.h. + + After error-checking, the real work is done by the gcc::jit::recording::context::compile method in jit-recording.c. */ only in patch2: unchanged: --- a/gcc/jit/libgccjit.map +++ b/gcc/jit/libgccjit.map @@ -31,6 +31,7 @@ gcc_jit_block_end_with_void_return; gcc_jit_block_get_function; gcc_jit_context_acquire; + gcc_jit_context_add_dependency; gcc_jit_context_compile; gcc_jit_context_dump_to_file; gcc_jit_context_get_builtin_function; @@ -97,4 +98,4 @@ gcc_jit_type_get_volatile; local: *; -}; \ No newline at end of file +};