From patchwork Thu Mar 20 16:59:16 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernd Schmidt X-Patchwork-Id: 332312 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 F12F82C00AB for ; Fri, 21 Mar 2014 04:01:37 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:content-type; q=dns; s=default; b=cPHXGAgMFj6wTghegV/BB5nN/WFkDtpPIqEKRNduCbB uamFiInmpVmfUFAxYEc6M3VX1D5XZaZpP69cx/n72ttDrGwQGzqSnk32vi/2HIQs SrSUVKlAtR1aDkRSQeuR3Rg6Sp3qubJ6Flguoip/1KRjqr0Ycx8u1aJuc7eVxNpQ = 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 :message-id:date:from:mime-version:to:cc:subject:content-type; s=default; bh=GqMyJzGeDU9yIlcuLU8q3t3zCnE=; b=DD2B+RdWIVvD4+ZYO AVC3050jEt6qOs1xvJT9/umO2kiv5ZODT1FMby6QEvhxCGa/sZ2OhhQRPnYqTSsu +4q/86gpE79g3yMmeJ0lsoFUjsojbgqliih7s4cC9aD2hN7AqJQV18mgI/V/QXYt 4uNOjGLE+Y5n7bYuYCRCbPrEog= Received: (qmail 31968 invoked by alias); 20 Mar 2014 17:01:30 -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 31949 invoked by uid 89); 20 Mar 2014 17:01:27 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.9 required=5.0 tests=AWL, BAYES_00, UNSUBSCRIBE_BODY autolearn=no version=3.3.2 X-HELO: relay1.mentorg.com Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 20 Mar 2014 17:01:25 +0000 Received: from svr-orw-fem-01.mgc.mentorg.com ([147.34.98.93]) by relay1.mentorg.com with esmtp id 1WQgLI-0005rw-FB from Bernd_Schmidt@mentor.com ; Thu, 20 Mar 2014 10:01:20 -0700 Received: from SVR-IES-FEM-01.mgc.mentorg.com ([137.202.0.104]) by svr-orw-fem-01.mgc.mentorg.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Thu, 20 Mar 2014 10:01:20 -0700 Received: from [127.0.0.1] (137.202.0.76) by SVR-IES-FEM-01.mgc.mentorg.com (137.202.0.104) with Microsoft SMTP Server id 14.2.247.3; Thu, 20 Mar 2014 17:01:17 +0000 Message-ID: <532B1E64.8030407@codesourcery.com> Date: Thu, 20 Mar 2014 17:59:16 +0100 From: Bernd Schmidt User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.3.0 MIME-Version: 1.0 To: GCC Patches CC: Ilya Verbin Subject: [gomp4/stage1] Utility functions for collect2/lto-wrapper/mkoffload 1/2 Since we're about to introduce new mkoffload programs, and they're going to require a lot of functionality that's already present in lto-wrapper and collect2, I've decided to make a new set of utility functions that can be linked in with these programs. This is the first step, splitting off code from lto-wrapper into a new collect-utils.c file. The next step will replace some of these with almost-identical ones from collect2 and make that tool also link with collect-utils. Committed on gomp-4_0-branch; ok for stage1? Bernd Index: gcc/ChangeLog =================================================================== --- gcc/ChangeLog (revision 208723) +++ gcc/ChangeLog (working copy) @@ -1,5 +1,17 @@ 2014-03-20 Bernd Schmidt + * Makefile.in (ALL_HOST_BACKEND_OBJS): Add collect-utils.o. + (lto-wrapper$(exeext)): Link with collect-utils.o. + * collect-utils.c: New file. + * collect-utils.h: New file. + * lto-wrapper.c: Include "collect-utils.h". + (args_name): Delete variable. + (tool_name): New variable. + (tool_cleanup): New function. + (maybe_unlink): Renamed from maybe_unlink_file. All callers changed. + (lto_wrapper_cleanup, fatal_signal, fatal, fatal_perror, + collect_execute, collect_wait, fork_execute): Remove functions. + Mostly by Michael Zolotukhin: * omp-low.c: Include "common/common-target.h". (expand_omp_target): Pass in address of __OPENMP_TARGET__. Index: gcc/Makefile.in =================================================================== --- gcc/Makefile.in (revision 208715) +++ gcc/Makefile.in (working copy) @@ -1496,7 +1496,7 @@ ALL_HOST_FRONTEND_OBJS = $(foreach v,$(C ALL_HOST_BACKEND_OBJS = $(GCC_OBJS) $(OBJS) $(OBJS-libcommon) \ $(OBJS-libcommon-target) @TREEBROWSER@ main.o c-family/cppspec.o \ $(COLLECT2_OBJS) $(EXTRA_GCC_OBJS) $(GCOV_OBJS) $(GCOV_DUMP_OBJS) \ - lto-wrapper.o + lto-wrapper.o collect-utils.o # This lists all host object files, whether they are included in this # compilation or not. @@ -1915,9 +1915,11 @@ collect2$(exeext): $(COLLECT2_OBJS) $(LI CFLAGS-collect2.o += -DTARGET_MACHINE=\"$(target_noncanonical)\" \ @TARGET_SYSTEM_ROOT_DEFINE@ -lto-wrapper$(exeext): lto-wrapper.o ggc-none.o libcommon-target.a $(LIBDEPS) +lto-wrapper$(exeext): lto-wrapper.o collect-utils.o ggc-none.o \ + libcommon-target.a $(LIBDEPS) +$(LINKER) $(ALL_COMPILERFLAGS) $(LDFLAGS) -o T$@ \ - lto-wrapper.o ggc-none.o libcommon-target.a $(LIBS) + lto-wrapper.o collect-utils.o ggc-none.o libcommon-target.a \ + $(LIBS) mv -f T$@ $@ # Files used by all variants of C or by the stand-alone pre-processor. Index: gcc/collect-utils.c =================================================================== --- gcc/collect-utils.c (revision 0) +++ gcc/collect-utils.c (working copy) @@ -0,0 +1,259 @@ +/* Utility functions used by tools like collect2 and lto-wrapper. + Copyright (C) 2009-2014 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "intl.h" +#include "diagnostic.h" +#include "obstack.h" +#include "opts.h" +#include "options.h" +#include "simple-object.h" +#include "lto-section-names.h" +#include "collect-utils.h" + +static char *response_file; + +bool debug; +bool verbose; + +/* Delete tempfiles. */ + +void +utils_cleanup (void) +{ + static bool cleanup_done = false; + + if (cleanup_done) + return; + + /* Setting cleanup_done prevents an infinite loop if one of the + calls to maybe_unlink fails. */ + cleanup_done = true; + + if (response_file) + maybe_unlink (response_file); + tool_cleanup (); +} + +/* Notify user of a non-error. */ +void +notice (const char *cmsgid, ...) +{ + va_list ap; + + va_start (ap, cmsgid); + vfprintf (stderr, _(cmsgid), ap); + va_end (ap); +} + +void +fatal_signal (int signum) +{ + signal (signum, SIG_DFL); + utils_cleanup (); + /* Get the same signal again, this time not handled, + so its normal effect occurs. */ + kill (getpid (), signum); +} + +/* Just die. CMSGID is the error message. */ + +void __attribute__ ((format (printf, 1, 2))) +fatal (const char * cmsgid, ...) +{ + va_list ap; + + va_start (ap, cmsgid); + fprintf (stderr, "%s: ", tool_name); + vfprintf (stderr, _(cmsgid), ap); + fprintf (stderr, "\n"); + va_end (ap); + + utils_cleanup (); + exit (FATAL_EXIT_CODE); +} + + +/* Die when sys call fails. CMSGID is the error message. */ + +void __attribute__ ((format (printf, 1, 2))) +fatal_perror (const char *cmsgid, ...) +{ + int e = errno; + va_list ap; + + va_start (ap, cmsgid); + fprintf (stderr, "%s: ", tool_name); + vfprintf (stderr, _(cmsgid), ap); + fprintf (stderr, ": %s\n", xstrerror (e)); + va_end (ap); + + utils_cleanup (); + exit (FATAL_EXIT_CODE); +} + + +/* Execute a program, and wait for the reply. ARGV are the arguments. The + last one must be NULL. */ + +struct pex_obj * +collect_execute (char **argv) +{ + struct pex_obj *pex; + const char *errmsg; + int err; + + if (verbose) + { + char **p_argv; + const char *str; + + for (p_argv = argv; (str = *p_argv) != (char *) 0; p_argv++) + fprintf (stderr, " %s", str); + + fprintf (stderr, "\n"); + } + + fflush (stdout); + fflush (stderr); + + pex = pex_init (0, tool_name, NULL); + if (pex == NULL) + fatal_perror ("pex_init failed"); + + /* Do not use PEX_LAST here, we use our stdout for communicating with + collect2 or the linker-plugin. Any output from the sub-process + will confuse that. */ + errmsg = pex_run (pex, PEX_SEARCH, argv[0], argv, NULL, + NULL, &err); + if (errmsg != NULL) + { + if (err != 0) + { + errno = err; + fatal_perror (errmsg); + } + else + fatal (errmsg); + } + + return pex; +} + + +/* Wait for a process to finish, and exit if a nonzero status is found. + PROG is the program name. PEX is the process we should wait for. */ + +int +collect_wait (const char *prog, struct pex_obj *pex) +{ + int status; + + if (!pex_get_status (pex, 1, &status)) + fatal_perror ("can't get program status"); + pex_free (pex); + + if (status) + { + if (WIFSIGNALED (status)) + { + int sig = WTERMSIG (status); + if (WCOREDUMP (status)) + fatal ("%s terminated with signal %d [%s], core dumped", + prog, sig, strsignal (sig)); + else + fatal ("%s terminated with signal %d [%s]", + prog, sig, strsignal (sig)); + } + + if (WIFEXITED (status)) + fatal ("%s returned %d exit status", prog, WEXITSTATUS (status)); + } + + return 0; +} + +void +do_wait (const char *prog, struct pex_obj *pex) +{ + int ret = collect_wait (prog, pex); + if (ret != 0) + { + error ("%s returned %d exit status", prog, ret); + exit (ret); + } + + if (response_file && !debug) + { + unlink (response_file); + response_file = NULL; + } +} + +/* Unlink a temporary LTRANS file unless requested otherwise. */ + +void +maybe_unlink_file (const char *file) +{ + if (!debug) + { + if (unlink_if_ordinary (file) + && errno != ENOENT) + fatal_perror ("deleting file %s", file); + } + else + fprintf (stderr, "[Leaving %s]\n", file); +} + + +/* Execute program ARGV[0] with arguments ARGV. Wait for it to finish. */ + +void +fork_execute (char **argv) +{ + struct pex_obj *pex; + char *new_argv[3]; + char *at_args; + FILE *args; + int status; + + response_file = make_temp_file (".args"); + at_args = concat ("@", response_file, NULL); + args = fopen (response_file, "w"); + if (args == NULL) + fatal ("failed to open %s", response_file); + + status = writeargv (&argv[1], args); + + if (status) + fatal ("could not write to temporary file %s", response_file); + + fclose (args); + + new_argv[0] = argv[0]; + new_argv[1] = at_args; + new_argv[2] = NULL; + + pex = collect_execute (new_argv); + do_wait (new_argv[0], pex); + + free (at_args); +} Index: gcc/collect-utils.h =================================================================== --- gcc/collect-utils.h (revision 0) +++ gcc/collect-utils.h (working copy) @@ -0,0 +1,44 @@ +/* Utility functions used by tools like collect2 and lto-wrapper. + Copyright (C) 2009-2014 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +/* Provided in collect-utils.c. */ +extern void notice (const char *, ...) + __attribute__ ((format (printf, 1, 2))); +extern void fatal_signal (int); +extern void fatal (const char *, ...) + __attribute__ ((format (printf, 1, 2))); +extern void fatal_perror (const char *, ...) + __attribute__ ((format (printf, 1, 2))); + +extern struct pex_obj *collect_execute (char **); +extern int collect_wait (const char *, struct pex_obj *); +extern void do_wait (const char *, struct pex_obj *); +extern void fork_execute (char **); +extern void utils_cleanup (void); + +extern bool debug; +extern bool verbose; + +/* Provided by the tool itself. */ + +/* The name of the tool, printed in error messages. */ +extern const char tool_name[]; +/* Called by utils_cleanup. */ +extern void tool_cleanup (void); +extern void maybe_unlink (const char *); Index: gcc/lto-wrapper.c =================================================================== --- gcc/lto-wrapper.c (revision 208720) +++ gcc/lto-wrapper.c (working copy) @@ -47,9 +47,7 @@ along with GCC; see the file COPYING3. #include "options.h" #include "simple-object.h" #include "lto-section-names.h" - -int debug; /* true if -save-temps. */ -int verbose; /* true if -v. */ +#include "collect-utils.h" enum lto_mode_d { LTO_MODE_NONE, /* Not doing LTO. */ @@ -62,177 +60,38 @@ static enum lto_mode_d lto_mode = LTO_MO static char *ltrans_output_file; static char *flto_out; -static char *args_name; static unsigned int nr; static char **input_names; static char **output_names; static char *makefile; -static void maybe_unlink_file (const char *); +const char tool_name[] = "lto-wrapper"; - /* Delete tempfiles. */ +/* Delete tempfiles. Called from utils_cleanup. */ -static void -lto_wrapper_cleanup (void) +void +tool_cleanup (void) { - static bool cleanup_done = false; unsigned int i; - if (cleanup_done) - return; - - /* Setting cleanup_done prevents an infinite loop if one of the - calls to maybe_unlink_file fails. */ - cleanup_done = true; - if (ltrans_output_file) - maybe_unlink_file (ltrans_output_file); + maybe_unlink (ltrans_output_file); if (flto_out) - maybe_unlink_file (flto_out); - if (args_name) - maybe_unlink_file (args_name); + maybe_unlink (flto_out); if (makefile) - maybe_unlink_file (makefile); + maybe_unlink (makefile); for (i = 0; i < nr; ++i) { - maybe_unlink_file (input_names[i]); + maybe_unlink (input_names[i]); if (output_names[i]) - maybe_unlink_file (output_names[i]); - } -} - -static void -fatal_signal (int signum) -{ - signal (signum, SIG_DFL); - lto_wrapper_cleanup (); - /* Get the same signal again, this time not handled, - so its normal effect occurs. */ - kill (getpid (), signum); -} - -/* Just die. CMSGID is the error message. */ - -static void __attribute__ ((format (printf, 1, 2))) -fatal (const char * cmsgid, ...) -{ - va_list ap; - - va_start (ap, cmsgid); - fprintf (stderr, "lto-wrapper: "); - vfprintf (stderr, _(cmsgid), ap); - fprintf (stderr, "\n"); - va_end (ap); - - lto_wrapper_cleanup (); - exit (FATAL_EXIT_CODE); -} - - -/* Die when sys call fails. CMSGID is the error message. */ - -static void __attribute__ ((format (printf, 1, 2))) -fatal_perror (const char *cmsgid, ...) -{ - int e = errno; - va_list ap; - - va_start (ap, cmsgid); - fprintf (stderr, "lto-wrapper: "); - vfprintf (stderr, _(cmsgid), ap); - fprintf (stderr, ": %s\n", xstrerror (e)); - va_end (ap); - - lto_wrapper_cleanup (); - exit (FATAL_EXIT_CODE); -} - - -/* Execute a program, and wait for the reply. ARGV are the arguments. The - last one must be NULL. */ - -static struct pex_obj * -collect_execute (char **argv) -{ - struct pex_obj *pex; - const char *errmsg; - int err; - - if (verbose) - { - char **p_argv; - const char *str; - - for (p_argv = argv; (str = *p_argv) != (char *) 0; p_argv++) - fprintf (stderr, " %s", str); - - fprintf (stderr, "\n"); - } - - fflush (stdout); - fflush (stderr); - - pex = pex_init (0, "lto-wrapper", NULL); - if (pex == NULL) - fatal_perror ("pex_init failed"); - - /* Do not use PEX_LAST here, we use our stdout for communicating with - collect2 or the linker-plugin. Any output from the sub-process - will confuse that. */ - errmsg = pex_run (pex, PEX_SEARCH, argv[0], argv, NULL, - NULL, &err); - if (errmsg != NULL) - { - if (err != 0) - { - errno = err; - fatal_perror (errmsg); - } - else - fatal (errmsg); + maybe_unlink (output_names[i]); } - - return pex; } - -/* Wait for a process to finish, and exit if a nonzero status is found. - PROG is the program name. PEX is the process we should wait for. */ - -static int -collect_wait (const char *prog, struct pex_obj *pex) -{ - int status; - - if (!pex_get_status (pex, 1, &status)) - fatal_perror ("can't get program status"); - pex_free (pex); - - if (status) - { - if (WIFSIGNALED (status)) - { - int sig = WTERMSIG (status); - if (WCOREDUMP (status)) - fatal ("%s terminated with signal %d [%s], core dumped", - prog, sig, strsignal (sig)); - else - fatal ("%s terminated with signal %d [%s]", - prog, sig, strsignal (sig)); - } - - if (WIFEXITED (status)) - fatal ("%s returned %d exit status", prog, WEXITSTATUS (status)); - } - - return 0; -} - - /* Unlink a temporary LTRANS file unless requested otherwise. */ -static void -maybe_unlink_file (const char *file) +void +maybe_unlink (const char *file) { if (! debug) { @@ -244,43 +103,6 @@ maybe_unlink_file (const char *file) fprintf (stderr, "[Leaving LTRANS %s]\n", file); } - -/* Execute program ARGV[0] with arguments ARGV. Wait for it to finish. */ - -static void -fork_execute (char **argv) -{ - struct pex_obj *pex; - char *new_argv[3]; - char *at_args; - FILE *args; - int status; - - args_name = make_temp_file (".args"); - at_args = concat ("@", args_name, NULL); - args = fopen (args_name, "w"); - if (args == NULL) - fatal ("failed to open %s", args_name); - - status = writeargv (&argv[1], args); - - if (status) - fatal ("could not write to temporary file %s", args_name); - - fclose (args); - - new_argv[0] = argv[0]; - new_argv[1] = at_args; - new_argv[2] = NULL; - - pex = collect_execute (new_argv); - collect_wait (new_argv[0], pex); - - maybe_unlink_file (args_name); - args_name = NULL; - free (at_args); -} - /* Template of LTRANS dumpbase suffix. */ #define DUMPBASE_SUFFIX ".ltrans18446744073709551615" @@ -827,7 +649,7 @@ cont: output_names[nr-1] = output_name; } fclose (stream); - maybe_unlink_file (ltrans_output_file); + maybe_unlink (ltrans_output_file); ltrans_output_file = NULL; if (parallel) @@ -886,7 +708,7 @@ cont: else { fork_execute (CONST_CAST (char **, new_argv)); - maybe_unlink_file (input_name); + maybe_unlink (input_name); } output_names[i] = output_name; @@ -923,10 +745,10 @@ cont: new_argv[i++] = NULL; pex = collect_execute (CONST_CAST (char **, new_argv)); collect_wait (new_argv[0], pex); - maybe_unlink_file (makefile); + maybe_unlink (makefile); makefile = NULL; for (i = 0; i < nr; ++i) - maybe_unlink_file (input_names[i]); + maybe_unlink (input_names[i]); } for (i = 0; i < nr; ++i) {