From patchwork Thu May 10 08:18:44 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Sharad Singhai X-Patchwork-Id: 158224 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]) by ozlabs.org (Postfix) with SMTP id 766CEB6FA3 for ; Thu, 10 May 2012 18:19:55 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1337242795; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:MIME-Version:Received:In-Reply-To:References:From:Date: Message-ID:Subject:To:Cc:Content-Type:Content-Transfer-Encoding: Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:Sender:Delivered-To; bh=zSQBPcIS/Laonxj4KGBf tZQdMgM=; b=m4O80zjm9FIv58li4Zhq1nmtD3CZKhzOvuFhEySb0DVNkGPLT6eI 2FwLMH4O/qXITe26lek0suHKzaoKluJbmHZiTdsc4NwEy5FnAaY93VUmOpSEhA6J xOW42wV8uK2JgaOGugPlmf5X1908o7fABuqjb5sKKcZSNdwDXBaZ4dc= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:X-Google-DKIM-Signature:Received:Received:MIME-Version:Received:In-Reply-To:References:From:Date:Message-ID:Subject:To:Cc:Content-Type:Content-Transfer-Encoding:X-System-Of-Record:X-Gm-Message-State:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=LJQp9s4Dj/PUwlyuNMWlBf6osuZwUjtRdPs5ewkc4NiK6ybrmVsjvwnaapiYUs 0m8pVpCGjlkpSpCcfNFUztvhsXwqrJdWYVRJbH4EFAss357uE7yRN3odH5o/ZJyl qn/ILkVo0vArCqOdXVTNNvy6bT9pC8OBXr2Pd8uTKNafw=; Received: (qmail 18973 invoked by alias); 10 May 2012 08:19:50 -0000 Received: (qmail 18911 invoked by uid 22791); 10 May 2012 08:19:42 -0000 X-SWARE-Spam-Status: No, hits=-5.9 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, KHOP_RCVD_TRUST, KHOP_THREADED, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail-vb0-f47.google.com (HELO mail-vb0-f47.google.com) (209.85.212.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 10 May 2012 08:19:25 +0000 Received: by vbbfr13 with SMTP id fr13so1453461vbb.20 for ; Thu, 10 May 2012 01:19:24 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type:content-transfer-encoding:x-system-of-record :x-gm-message-state; bh=FpB73V5taoRgxu2/1VpIUBIwDPXpTyJhwEQd68QNtbI=; b=f5QdhwznJoykhqXR8fFRqvOSmjJ+4IM/g2tNsBNzoF6GNLHPJn1m38YUHUmyYkeZ+1 KASe5/T/7AGIyQMfwimWMe2vDjwDBAYVubwr04rubwSQBfN21nevSyTAODLI7uv/OdoU Hn1qoTfUZ/H8oiYV7a5RDQ55JNCtjzveHkhnShTXjMb0HMGQ1QdUcR9azOWGFNrQ85gi M0BoodQWuxysXBsZOZJGBlzY/xU4Gid55648w0p2wBU0COosu76kV/1ciQhvHJkc+znk l8UFYCqk05maOsK4A7jsHrzDYqH8QZFSYu0lMDt5gcLmTJcJbBsa4vleO2IqLHsloJgl vVzQ== Received: by 10.220.38.138 with SMTP id b10mr2013957vce.23.1336637964615; Thu, 10 May 2012 01:19:24 -0700 (PDT) Received: by 10.220.38.138 with SMTP id b10mr2013941vce.23.1336637964441; Thu, 10 May 2012 01:19:24 -0700 (PDT) MIME-Version: 1.0 Received: by 10.52.177.7 with HTTP; Thu, 10 May 2012 01:18:44 -0700 (PDT) In-Reply-To: References: <20120509064637.22949A2081@nabu.mtv.corp.google.com> From: Sharad Singhai Date: Thu, 10 May 2012 01:18:44 -0700 Message-ID: Subject: Re: [PATCH] Add option for dumping to stderr (issue6190057) To: Xinliang David Li Cc: Gabriel Dos Reis , gcc-patches@gcc.gnu.org, Richard Guenther , reply@codereview.appspotmail.com, Andrew Pinski X-System-Of-Record: true X-Gm-Message-State: ALoCoQme98QemVqUrDcgnp+uGMkv4nxReqGQ9Pt+DMMHV6wPtrDmkkUUN3O9HA56/+WWF1ZjrSFg6rzywZM6wTWOnteMUN2FFk/HolkNPTZkg+Nfehr2W0sHjRYtPJC2n9u0zQxkkGka9LMZ3LKfBstXZtRHQDd99A== 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 Okay, I have restored the original behavior where standard streams were considered weak. Thus in case of a conflict, the standard streams have lower precedence. For example, gcc -O2 -fdump-tree-pre=stdout -fdump-tree-pre ... does the PRE dump in auto numbered file since stdout has lower precedence. Also this works as expected, gcc -O2 -fdump-tree-pre=pre.txt -fdump-tree-all=stderr ... It outputs PRE dump to pre.txt while the remaining tree dumps are output on to stderr. Does it look okay? Thanks, Sharad 2012-05-09 Sharad Singhai * doc/invoke.texi: Add documentation for the new option. * tree-dump.c (dump_get_standard_stream): New function. (dump_files): Update for new field. (dump_switch_p_1): Handle dump filenames. (dump_begin): Likewise. (get_dump_file_name): Likewise. (dump_end): Remove attribute. (dump_enable_all): Add new parameter FILENAME. All callers updated. * tree-pass.h (enum tree_dump_index): Add new constant. (struct dump_file_info): Add new field FILENAME. * testsuite/g++.dg/other/dump-filename-1.C: New test. Sharad On Wed, May 9, 2012 at 5:31 PM, Xinliang David Li wrote: > Bummer.  I was thinking to reserve '=' for selective  dumping: > > -fdump-tree-pre= > > I guess this can be achieved via @ > > -fdump-tree-pre@ > > -fdump-tree-pre=@ > > > Another issue -- I don't think the current precedence rule is correct. > Consider that -fopt-info=2 will be mapped to > > -fdump-tree-all-transform-verbose2=stderr > -fdump-rtl-all-transform-verbose2=stderr > > then > > the current precedence rule will cause surprise when the following is used > > -fopt-info -fdump-tree-pre > > The PRE dump will be emitted to stderr which is not what user wants. > In short, special streams should be treated as 'weak' the same way as > your previous implementation. > > thanks, > > David > > > > On Wed, May 9, 2012 at 4:56 PM, Sharad Singhai wrote: >> Thanks for your suggestions/comments. I have updated the patch and >> documentation. It supports the following usage: >> >> gcc .... -fdump-tree-all=tree.dump -fdump-tree-pre=stdout >> -fdump-rtl-ira=ira.dump >> >> Here all tree dumps except the PRE are output into tree.dump, PRE dump >> goes to stdout and the IRA dump goes to ira.dump. >> >> Thanks, >> Sharad >> >> 2012-05-09   Sharad Singhai   >> >>        * doc/invoke.texi: Add documentation for the new option. >>        * tree-dump.c (dump_get_standard_stream): New function. >>        (dump_files): Update for new field. >>        (dump_switch_p_1): Handle dump filenames. >>        (dump_begin): Likewise. >>        (get_dump_file_name): Likewise. >>        (dump_end): Remove attribute. >>        (dump_enable_all): Add new parameter FILENAME. >>        All callers updated. >>        (enable_rtl_dump_file): >>        * tree-pass.h (enum tree_dump_index): Add new constant. >>        (struct dump_file_info): Add new field FILENAME. >>        * testsuite/g++.dg/other/dump-filename-1.C: New test. >> >> Index: doc/invoke.texi >> =================================================================== >> --- doc/invoke.texi     (revision 187265) >> +++ doc/invoke.texi     (working copy) >> @@ -5322,20 +5322,23 @@ Here are some examples showing uses of these optio >> >>  @item -d@var{letters} >>  @itemx -fdump-rtl-@var{pass} >> +@itemx -fdump-rtl-@var{pass}=@var{filename} >>  @opindex d >>  Says to make debugging dumps during compilation at times specified by >>  @var{letters}.  This is used for debugging the RTL-based passes of the >>  compiler.  The file names for most of the dumps are made by appending >>  a pass number and a word to the @var{dumpname}, and the files are >> -created in the directory of the output file.  Note that the pass >> -number is computed statically as passes get registered into the pass >> -manager.  Thus the numbering is not related to the dynamic order of >> -execution of passes.  In particular, a pass installed by a plugin >> -could have a number over 200 even if it executed quite early. >> -@var{dumpname} is generated from the name of the output file, if >> -explicitly specified and it is not an executable, otherwise it is the >> -basename of the source file. These switches may have different effects >> -when @option{-E} is used for preprocessing. >> +created in the directory of the output file. If the >> +@option{=@var{filename}} is appended to the longer form of the dump >> +option then the dump is done on that file instead of numbered >> +files. Note that the pass number is computed statically as passes get >> +registered into the pass manager.  Thus the numbering is not related >> +to the dynamic order of execution of passes.  In particular, a pass >> +installed by a plugin could have a number over 200 even if it executed >> +quite early.  @var{dumpname} is generated from the name of the output >> +file, if explicitly specified and it is not an executable, otherwise >> +it is the basename of the source file. These switches may have >> +different effects when @option{-E} is used for preprocessing. >> >>  Debug dumps can be enabled with a @option{-fdump-rtl} switch or some >>  @option{-d} option @var{letters}.  Here are the possible >> @@ -5719,15 +5722,18 @@ counters for each function compiled. >> >>  @item -fdump-tree-@var{switch} >>  @itemx -fdump-tree-@var{switch}-@var{options} >> +@itemx -fdump-tree-@var{switch}-@var{options}=@var{filename} >>  @opindex fdump-tree >>  Control the dumping at various stages of processing the intermediate >>  language tree to a file.  The file name is generated by appending a >>  switch specific suffix to the source file name, and the file is >> -created in the same directory as the output file.  If the >> -@samp{-@var{options}} form is used, @var{options} is a list of >> -@samp{-} separated options which control the details of the dump.  Not >> -all options are applicable to all dumps; those that are not >> -meaningful are ignored.  The following options are available >> +created in the same directory as the output file. In case of >> +@option{=@var{filename}} option, the dump is output on the given file >> +name instead.  If the @samp{-@var{options}} form is used, >> +@var{options} is a list of @samp{-} separated options which control >> +the details or location of the dump.  Not all options are applicable >> +to all dumps; those that are not meaningful are ignored.  The >> +following options are available >> >>  @table @samp >>  @item address >> @@ -5765,9 +5771,46 @@ Enable showing the tree dump for each statement. >>  Enable showing the EH region number holding each statement. >>  @item scev >>  Enable showing scalar evolution analysis details. >> +@item slim >> +Inhibit dumping of members of a scope or body of a function merely >> +because that scope has been reached.  Only dump such items when they >> +are directly reachable by some other path.  When dumping pretty-printed >> +trees, this option inhibits dumping the bodies of control structures. >> +@item =@var{filename} >> +Instead of using an auto generated dump file name, use the given file >> +name. The file names @file{stdout} and @file{stderr} are treated >> +specially and are considered already open standard streams. For >> +example: >> + >> +@smallexample >> +gcc -O2 -fdump-tree-pre=stderr -fdump-rtl-ira=ira.txt ... >> +@end smallexample >> + >> +outputs PRE dump on @file{stderr}, while the IRA dump is output in a >> +file named @file{ira.txt}. >> + >> +In case of any conflicts, the command line file name takes precedence >> +over generated file names. For example: >> + >> +@smallexample >> +gcc -O2 -fdump-tree-pre=stdout -fdump-tree-pre ... >> +gcc -O2 -fdump-tree-pre -fdump-tree-pre=stdout ... >> +@end smallexample >> + >> +Both of the above output the PRE dump on @file{stdout}. However, if >> +there are multiple command line file names are applicable then the >> +last one is used. Thus the command >> + >> +@smallexample >> +gcc -O2 -fdump-tree-pre=stderr -fdump-tree-all=all.txt >> +@end smallexample >> + >> +outputs all the dumps in @file{all.txt} because the stderr option for >> +PRE dump is overridden by a later option. >> + >>  @item all >> -Turn on all options, except @option{raw}, @option{slim}, @option{verbose} >> -and @option{lineno}. >> +Turn on all options, except @option{raw}, @option{slim}, @option{verbose}, >> +@option{lineno}. >>  @end table >> >>  The following tree dumps are possible: >> @@ -5913,6 +5956,7 @@ is made by appending @file{.vrp} to the source fil >>  @item all >>  @opindex fdump-tree-all >>  Enable all the available tree dumps with the flags provided in this option. >> + >>  @end table >> >>  @item -ftree-vectorizer-verbose=@var{n} >> Index: tree-dump.c >> =================================================================== >> --- tree-dump.c (revision 187265) >> +++ tree-dump.c (working copy) >> @@ -773,20 +773,20 @@ dump_node (const_tree t, int flags, FILE *stream) >>    tree_dump_index enumeration in tree-pass.h.  */ >>  static struct dump_file_info dump_files[TDI_end] = >>  { >> -  {NULL, NULL, NULL, 0, 0, 0}, >> -  {".cgraph", "ipa-cgraph", NULL, TDF_IPA, 0,  0}, >> -  {".tu", "translation-unit", NULL, TDF_TREE, 0, 1}, >> -  {".class", "class-hierarchy", NULL, TDF_TREE, 0, 2}, >> -  {".original", "tree-original", NULL, TDF_TREE, 0, 3}, >> -  {".gimple", "tree-gimple", NULL, TDF_TREE, 0, 4}, >> -  {".nested", "tree-nested", NULL, TDF_TREE, 0, 5}, >> -  {".vcg", "tree-vcg", NULL, TDF_TREE, 0, 6}, >> -  {".ads", "ada-spec", NULL, 0, 0, 7}, >> +  {NULL, NULL, NULL, NULL, 0, 0, 0}, >> +  {".cgraph", "ipa-cgraph", NULL, NULL, TDF_IPA, 0,  0}, >> +  {".tu", "translation-unit", NULL, NULL, TDF_TREE, 0, 1}, >> +  {".class", "class-hierarchy", NULL, NULL, TDF_TREE, 0, 2}, >> +  {".original", "tree-original", NULL, NULL, TDF_TREE, 0, 3}, >> +  {".gimple", "tree-gimple", NULL, NULL, TDF_TREE, 0, 4}, >> +  {".nested", "tree-nested", NULL, NULL, TDF_TREE, 0, 5}, >> +  {".vcg", "tree-vcg", NULL, NULL, TDF_TREE, 0, 6}, >> +  {".ads", "ada-spec", NULL, NULL, 0, 0, 7}, >>  #define FIRST_AUTO_NUMBERED_DUMP 8 >> >> -  {NULL, "tree-all", NULL, TDF_TREE, 0, 0}, >> -  {NULL, "rtl-all", NULL, TDF_RTL, 0, 0}, >> -  {NULL, "ipa-all", NULL, TDF_IPA, 0, 0}, >> +  {NULL, "tree-all", NULL, NULL, TDF_TREE, 0, 0}, >> +  {NULL, "rtl-all", NULL, NULL, TDF_RTL, 0, 0}, >> +  {NULL, "ipa-all", NULL, NULL, TDF_IPA, 0, 0}, >>  }; >> >>  /* Dynamically registered tree dump files and switches.  */ >> @@ -802,7 +802,7 @@ struct dump_option_value_info >>  }; >> >>  /* Table of dump options. This must be consistent with the TDF_* flags >> -   in tree.h */ >> +   in tree-pass.h */ >>  static const struct dump_option_value_info dump_options[] = >>  { >>   {"address", TDF_ADDRESS}, >> @@ -892,6 +892,9 @@ get_dump_file_name (int phase) >>   if (dfi->state == 0) >>     return NULL; >> >> +  if (dfi->filename) >> +    return xstrdup (dfi->filename); >> + >>   if (dfi->num < 0) >>     dump_id[0] = '\0'; >>   else >> @@ -911,6 +914,22 @@ get_dump_file_name (int phase) >>   return concat (dump_base_name, dump_id, dfi->suffix, NULL); >>  } >> >> +/* If the DFI dump output corresponds to stdout or stderr stream, >> +   return that stream, NULL otherwise.  */ >> + >> +static FILE * >> +dump_get_standard_stream (struct dump_file_info *dfi) >> +{ >> +  if (!dfi->filename) >> +    return NULL; >> + >> +  return strcmp("stderr", dfi->filename) == 0 >> +    ? stderr >> +    : strcmp("stdout", dfi->filename) == 0 >> +    ?  stdout >> +    : NULL; >> +} >> + >>  /* Begin a tree dump for PHASE. Stores any user supplied flag in >>    *FLAG_PTR and returns a stream to write to. If the dump is not >>    enabled, returns NULL. >> @@ -926,14 +945,20 @@ dump_begin (int phase, int *flag_ptr) >>   if (phase == TDI_none || !dump_enabled_p (phase)) >>     return NULL; >> >> -  name = get_dump_file_name (phase); >>   dfi = get_dump_file_info (phase); >> -  stream = fopen (name, dfi->state < 0 ? "w" : "a"); >> -  if (!stream) >> -    error ("could not open dump file %qs: %m", name); >> +  stream = dump_get_standard_stream (dfi); >> +  if (stream) >> +    dfi->state = 1; >>   else >> -    dfi->state = 1; >> -  free (name); >> +    { >> +      name = get_dump_file_name (phase); >> +      stream = fopen (name, dfi->state < 0 ? "w" : "a"); >> +      if (!stream) >> +        error ("could not open dump file %qs: %m", name); >> +      else >> +        dfi->state = 1; >> +      free (name); >> +    } >> >>   if (flag_ptr) >>     *flag_ptr = dfi->flags; >> @@ -987,35 +1012,46 @@ dump_flag_name (int phase) >>    dump_begin.  */ >> >>  void >> -dump_end (int phase ATTRIBUTE_UNUSED, FILE *stream) >> +dump_end (int phase, FILE *stream) >>  { >> -  fclose (stream); >> +  struct dump_file_info *dfi = get_dump_file_info (phase); >> +  if (!dump_get_standard_stream (dfi)) >> +    fclose (stream); >>  } >> >> -/* Enable all tree dumps.  Return number of enabled tree dumps.  */ >> +/* Enable all tree dumps with FLAGS on FILENAME.  Return number of >> +   enabled tree dumps.  */ >> >>  static int >> -dump_enable_all (int flags) >> +dump_enable_all (int flags, const char *filename) >>  { >>   int ir_dump_type = (flags & (TDF_TREE | TDF_RTL | TDF_IPA)); >>   int n = 0; >>   size_t i; >> >>   for (i = TDI_none + 1; i < (size_t) TDI_end; i++) >> -    if ((dump_files[i].flags & ir_dump_type)) >> -      { >> -        dump_files[i].state = -1; >> -        dump_files[i].flags |= flags; >> -        n++; >> -      } >> +    { >> +      if ((dump_files[i].flags & ir_dump_type)) >> +        { >> +          dump_files[i].state = -1; >> +          dump_files[i].flags |= flags; >> +          n++; >> +          if (filename) >> +            dump_files[i].filename = xstrdup (filename); >> +        } >> +    } >> >>   for (i = 0; i < extra_dump_files_in_use; i++) >> -    if ((extra_dump_files[i].flags & ir_dump_type)) >> -      { >> -        extra_dump_files[i].state = -1; >> -        extra_dump_files[i].flags |= flags; >> -       n++; >> -      } >> +    { >> +      if ((extra_dump_files[i].flags & ir_dump_type)) >> +        { >> +          extra_dump_files[i].state = -1; >> +          extra_dump_files[i].flags |= flags; >> +          n++; >> +          if (filename) >> +            extra_dump_files[i].filename = xstrdup (filename); >> +        } >> +    } >> >>   return n; >>  } >> @@ -1037,7 +1073,7 @@ dump_switch_p_1 (const char *arg, struct dump_file >>   if (!option_value) >>     return 0; >> >> -  if (*option_value && *option_value != '-') >> +  if (*option_value && *option_value != '-' && *option_value != '=') >>     return 0; >> >>   ptr = option_value; >> @@ -1052,17 +1088,30 @@ dump_switch_p_1 (const char *arg, struct dump_file >>       while (*ptr == '-') >>        ptr++; >>       end_ptr = strchr (ptr, '-'); >> + >>       if (!end_ptr) >>        end_ptr = ptr + strlen (ptr); >>       length = end_ptr - ptr; >> >> +      if (*ptr == '=') >> +        { >> +          /* Interpret rest of the argument as a dump filename.  This >> +             filename overrides generated dump names as well as other >> +             command line filenames.  */ >> +          flags |= TDF_FILENAME; >> +          if (dfi->filename) >> +            free (dfi->filename); >> +          dfi->filename = xstrdup (ptr + 1); >> +          break; >> +        } >> + >>       for (option_ptr = dump_options; option_ptr->name; option_ptr++) >>        if (strlen (option_ptr->name) == length >>            && !memcmp (option_ptr->name, ptr, length)) >> -         { >> -           flags |= option_ptr->value; >> +          { >> +            flags |= option_ptr->value; >>            goto found; >> -         } >> +          } >>       warning (0, "ignoring unknown option %q.*s in %<-fdump-%s%>", >>               length, ptr, dfi->swtch); >>     found:; >> @@ -1075,7 +1124,7 @@ dump_switch_p_1 (const char *arg, struct dump_file >>   /* Process -fdump-tree-all and -fdump-rtl-all, by enabling all the >>      known dumps.  */ >>   if (dfi->suffix == NULL) >> -    dump_enable_all (dfi->flags); >> +    dump_enable_all (dfi->flags, dfi->filename); >> >>   return 1; >>  } >> @@ -1124,5 +1173,5 @@ dump_function (int phase, tree fn) >>  bool >>  enable_rtl_dump_file (void) >>  { >> -  return dump_enable_all (TDF_RTL | TDF_DETAILS | TDF_BLOCKS) > 0; >> +  return dump_enable_all (TDF_RTL | TDF_DETAILS | TDF_BLOCKS, NULL) > 0; >>  } >> Index: tree-pass.h >> =================================================================== >> --- tree-pass.h (revision 187265) >> +++ tree-pass.h (working copy) >> @@ -84,8 +84,9 @@ enum tree_dump_index >>  #define TDF_ENUMERATE_LOCALS (1 << 22) /* Enumerate locals by uid.  */ >>  #define TDF_CSELIB     (1 << 23)       /* Dump cselib details.  */ >>  #define TDF_SCEV       (1 << 24)       /* Dump SCEV details.  */ >> +#define TDF_FILENAME    (1 << 25)      /* Dump on provided filename >> +                                           instead of constructing one. */ >> >> - >>  /* In tree-dump.c */ >> >>  extern char *get_dump_file_name (int); >> @@ -222,6 +223,8 @@ struct dump_file_info >>   const char *suffix;           /* suffix to give output file.  */ >>   const char *swtch;            /* command line switch */ >>   const char *glob;             /* command line glob  */ >> +  const char *filename;         /* use this filename instead of making >> +                                   up one using dump_base_name + suffix.  */ >>   int flags;                    /* user flags */ >>   int state;                    /* state of play */ >>   int num;                      /* dump file number */ >> Index: testsuite/g++.dg/other/dump-filename-1.C >> =================================================================== >> --- testsuite/g++.dg/other/dump-filename-1.C    (revision 0) >> +++ testsuite/g++.dg/other/dump-filename-1.C    (revision 0) >> @@ -0,0 +1,11 @@ >> +// Test that the dump to a user-defined file works correctly. >> +/* { dg-options "-O2 -fdump-tree-original=foobar.dump" } */ >> + >> +void test (int *b, int *e, int stride) >> +  { >> +    for (int *p = b; p != e; p += stride) >> +      *p = 1; >> +  } >> + >> +/* { dg-final { scan-file foobar.dump ";; Function void test" } } */ >> +/* { dg-final { remove-build-file "foobar.dump" } } */ >> >> >> On Wed, May 9, 2012 at 12:22 AM, Gabriel Dos Reis >> wrote: >>> On Wed, May 9, 2012 at 1:46 AM, Sharad Singhai wrote: >>> [...] >>> >>>> +@item -fdump-rtl-all=stderr >>>> +@opindex fdump-rtl-all=stderr >>> >>> You do not need to have a separate index entry for '=stderr' or '=stdout'. >>> Rather, expand the description to state this in all the documentation >>> for -fdump-xxx=yyy. >>> >>> [...] >>> >>>> +/* Return non-zero iff the USER_FILENAME corresponds to stdout or >>>> +   stderr stream.  */ >>>> + >>>> +static int >>>> +dump_stream_p (const char *user_filename) >>>> +{ >>>> +  if (user_filename) >>>> +    return !strncmp ("stderr", user_filename, 6) || >>>> +      !strncmp ("stdout", user_filename, 6); >>>> +  else >>>> +    return 0; >>>> +} >>> >>> The name is ambiguous. >>> This function is testing whether its string argument designates one of >>> the *standard* output streams.  Name it to reflect that.. >>> Have it take the dump state context. Also the coding convention: the binary >>> operator "||" should be on next line.  In fact the thing could be >>> simpler.   Instead of >>> testing over and over again against "stderr" (once in this function, then again >>> later), just return the corresponding standard FILE* pointer. >>> Also, this is a case of overuse of strncmp.  If you name the function >>> dump_get_standard_stream: >>> >>>    return strcmp("stderr", dfi->user_filename) == 0 >>>       ? stderr >>>        : stdcmp("stdout", dfi->use_filename) >>>        ?  stdout >>>        : NULL; >>> >>> you can simplify: >>> >>>> -  name = get_dump_file_name (phase); >>>>   dfi = get_dump_file_info (phase); >>>> -  stream = fopen (name, dfi->state < 0 ? "w" : "a"); >>>> -  if (!stream) >>>> -    error ("could not open dump file %qs: %m", name); >>>> +  if (dump_stream_p (dfi->user_filename)) >>>> +    { >>>> +      if (!strncmp ("stderr", dfi->user_filename, 6)) >>>> +        stream = stderr; >>>> +      else >>>> +        if (!strncmp ("stdout", dfi->user_filename, 6)) >>>> +          stream = stdout; >>>> +        else >>>> +          error ("unknown stream: %qs: %m", dfi->user_filename); >>>> +      dfi->state = 1; >>>> +    } >>>>   else >>>> -    dfi->state = 1; >>>> -  free (name); >>>> +    { >>>> +      name = get_dump_file_name (phase); >>>> +      stream = fopen (name, dfi->state < 0 ? "w" : "a"); >>>> +      if (!stream) >>>> +        error ("could not open dump file %qs: %m", name); >>>> +      else >>>> +        dfi->state = 1; >>>> +      free (name); >>>> +    } >>>> >>>>   if (flag_ptr) >>>>     *flag_ptr = dfi->flags; >>>> @@ -987,35 +1017,45 @@ dump_flag_name (int phase) >>>>    dump_begin.  */ >>>> >>>>  void >>>> -dump_end (int phase ATTRIBUTE_UNUSED, FILE *stream) >>>> +dump_end (int phase, FILE *stream) >>>>  { >>>> -  fclose (stream); >>>> +  struct dump_file_info *dfi = get_dump_file_info (phase); >>>> +  if (!dump_stream_p (dfi->user_filename)) >>>> +    fclose (stream); >>>>  } >>>> >>>>  /* Enable all tree dumps.  Return number of enabled tree dumps.  */ >>>> >>>>  static int >>>> -dump_enable_all (int flags) >>>> +dump_enable_all (int flags, const char *user_filename) >>>>  { >>>>   int ir_dump_type = (flags & (TDF_TREE | TDF_RTL | TDF_IPA)); >>>>   int n = 0; >>>>   size_t i; >>>> >>>>   for (i = TDI_none + 1; i < (size_t) TDI_end; i++) >>>> -    if ((dump_files[i].flags & ir_dump_type)) >>>> -      { >>>> -        dump_files[i].state = -1; >>>> -        dump_files[i].flags |= flags; >>>> -        n++; >>>> -      } >>>> +    { >>>> +      if ((dump_files[i].flags & ir_dump_type)) >>>> +        { >>>> +          dump_files[i].state = -1; >>>> +          dump_files[i].flags |= flags; >>>> +          n++; >>>> +        } >>>> +      if (user_filename) >>>> +        dump_files[i].user_filename = user_filename; >>>> +    } >>>> >>>>   for (i = 0; i < extra_dump_files_in_use; i++) >>>> -    if ((extra_dump_files[i].flags & ir_dump_type)) >>>> -      { >>>> -        extra_dump_files[i].state = -1; >>>> -        extra_dump_files[i].flags |= flags; >>>> -       n++; >>>> -      } >>>> +    { >>>> +      if ((extra_dump_files[i].flags & ir_dump_type)) >>>> +        { >>>> +          extra_dump_files[i].state = -1; >>>> +          extra_dump_files[i].flags |= flags; >>>> +          n++; >>>> +        } >>>> +      if (user_filename) >>>> +        extra_dump_files[i].user_filename = user_filename; >>>> +    } >>>> >>>>   return n; >>>>  } >>>> @@ -1037,7 +1077,7 @@ dump_switch_p_1 (const char *arg, struct dump_file >>>>   if (!option_value) >>>>     return 0; >>>> >>>> -  if (*option_value && *option_value != '-') >>>> +  if (*option_value && *option_value != '-' && *option_value != '=') >>>>     return 0; >>>> >>>>   ptr = option_value; >>>> @@ -1052,17 +1092,30 @@ dump_switch_p_1 (const char *arg, struct dump_file >>>>       while (*ptr == '-') >>>>        ptr++; >>>>       end_ptr = strchr (ptr, '-'); >>>> + >>>>       if (!end_ptr) >>>>        end_ptr = ptr + strlen (ptr); >>>>       length = end_ptr - ptr; >>>> >>>> +      if (*ptr == '=') >>>> +        { >>>> +          /* Interpret rest of the argument as a dump filename.  The >>>> +             user provided filename overrides generated dump names as >>>> +             well as other command line filenames.  */ >>>> +          flags |= TDF_USER_FILENAME; >>>> +          if (dfi->user_filename) >>>> +            free (dfi->user_filename); >>>> +          dfi->user_filename = xstrdup (ptr + 1); >>>> +          break; >>>> +        } >>>> + >>>>       for (option_ptr = dump_options; option_ptr->name; option_ptr++) >>>>        if (strlen (option_ptr->name) == length >>>>            && !memcmp (option_ptr->name, ptr, length)) >>>> -         { >>>> -           flags |= option_ptr->value; >>>> +          { >>>> +            flags |= option_ptr->value; >>>>            goto found; >>>> -         } >>>> +          } >>>>       warning (0, "ignoring unknown option %q.*s in %<-fdump-%s%>", >>>>               length, ptr, dfi->swtch); >>>>     found:; >>>> @@ -1075,7 +1128,7 @@ dump_switch_p_1 (const char *arg, struct dump_file >>>>   /* Process -fdump-tree-all and -fdump-rtl-all, by enabling all the >>>>      known dumps.  */ >>>>   if (dfi->suffix == NULL) >>>> -    dump_enable_all (dfi->flags); >>>> +    dump_enable_all (dfi->flags, dfi->user_filename); >>>> >>>>   return 1; >>>>  } >>>> @@ -1124,5 +1177,5 @@ dump_function (int phase, tree fn) >>>>  bool >>>>  enable_rtl_dump_file (void) >>>>  { >>>> -  return dump_enable_all (TDF_RTL | TDF_DETAILS | TDF_BLOCKS) > 0; >>>> +  return dump_enable_all (TDF_RTL | TDF_DETAILS | TDF_BLOCKS, NULL) > 0; >>>>  } >>>> Index: tree-pass.h >>>> =================================================================== >>>> --- tree-pass.h (revision 187265) >>>> +++ tree-pass.h (working copy) >>>> @@ -84,8 +84,9 @@ enum tree_dump_index >>>>  #define TDF_ENUMERATE_LOCALS (1 << 22) /* Enumerate locals by uid.  */ >>>>  #define TDF_CSELIB     (1 << 23)       /* Dump cselib details.  */ >>>>  #define TDF_SCEV       (1 << 24)       /* Dump SCEV details.  */ >>>> +#define TDF_USER_FILENAME    (1 << 25) /* Dump on user provided filename, >>>> +                                           instead of constructing one. */ >>>> >>>> - >>>>  /* In tree-dump.c */ >>>> >>>>  extern char *get_dump_file_name (int); >>>> @@ -222,6 +223,8 @@ struct dump_file_info >>>>   const char *suffix;           /* suffix to give output file.  */ >>>>   const char *swtch;            /* command line switch */ >>>>   const char *glob;             /* command line glob  */ >>>> +  const char *user_filename;    /* user provided filename instead of making >>>> +                                   up one using dump_base_name + suffix.  */ >>> >>> There is "no user" here: we are the users :-)  Just call it "filename". >>> >>> -- Gaby Index: doc/invoke.texi =================================================================== --- doc/invoke.texi (revision 187265) +++ doc/invoke.texi (working copy) @@ -5322,20 +5322,23 @@ Here are some examples showing uses of these optio @item -d@var{letters} @itemx -fdump-rtl-@var{pass} +@itemx -fdump-rtl-@var{pass}=@var{filename} @opindex d Says to make debugging dumps during compilation at times specified by @var{letters}. This is used for debugging the RTL-based passes of the compiler. The file names for most of the dumps are made by appending a pass number and a word to the @var{dumpname}, and the files are -created in the directory of the output file. Note that the pass -number is computed statically as passes get registered into the pass -manager. Thus the numbering is not related to the dynamic order of -execution of passes. In particular, a pass installed by a plugin -could have a number over 200 even if it executed quite early. -@var{dumpname} is generated from the name of the output file, if -explicitly specified and it is not an executable, otherwise it is the -basename of the source file. These switches may have different effects -when @option{-E} is used for preprocessing. +created in the directory of the output file. If the +@option{=@var{filename}} is appended to the longer form of the dump +option then the dump is done on that file instead of numbered +files. Note that the pass number is computed statically as passes get +registered into the pass manager. Thus the numbering is not related +to the dynamic order of execution of passes. In particular, a pass +installed by a plugin could have a number over 200 even if it executed +quite early. @var{dumpname} is generated from the name of the output +file, if explicitly specified and it is not an executable, otherwise +it is the basename of the source file. These switches may have +different effects when @option{-E} is used for preprocessing. Debug dumps can be enabled with a @option{-fdump-rtl} switch or some @option{-d} option @var{letters}. Here are the possible @@ -5719,15 +5722,18 @@ counters for each function compiled. @item -fdump-tree-@var{switch} @itemx -fdump-tree-@var{switch}-@var{options} +@itemx -fdump-tree-@var{switch}-@var{options}=@var{filename} @opindex fdump-tree Control the dumping at various stages of processing the intermediate language tree to a file. The file name is generated by appending a switch specific suffix to the source file name, and the file is -created in the same directory as the output file. If the -@samp{-@var{options}} form is used, @var{options} is a list of -@samp{-} separated options which control the details of the dump. Not -all options are applicable to all dumps; those that are not -meaningful are ignored. The following options are available +created in the same directory as the output file. In case of +@option{=@var{filename}} option, the dump is output on the given file +name instead. If the @samp{-@var{options}} form is used, +@var{options} is a list of @samp{-} separated options which control +the details or location of the dump. Not all options are applicable +to all dumps; those that are not meaningful are ignored. The +following options are available @table @samp @item address @@ -5765,9 +5771,49 @@ Enable showing the tree dump for each statement. Enable showing the EH region number holding each statement. @item scev Enable showing scalar evolution analysis details. +@item slim +Inhibit dumping of members of a scope or body of a function merely +because that scope has been reached. Only dump such items when they +are directly reachable by some other path. When dumping pretty-printed +trees, this option inhibits dumping the bodies of control structures. +@item =@var{filename} +Instead of using an auto generated dump file name, use the given file +name. The file names @file{stdout} and @file{stderr} are treated +specially and are considered already open standard streams. In +addition, the standard streams @file{stdout} and @file{stderr} are +considered weak, i.e., in case of a conflict, some other applicable +dump file is used instead. For example: + +@smallexample +gcc -O2 -fdump-tree-pre=stderr -fdump-rtl-ira=ira.txt ... +@end smallexample + +outputs PRE dump on @file{stderr}, while the IRA dump is output in a +file named @file{ira.txt}. + +Usually the command line file names have precedence over automatic +file names unless the command line file name is a standard stream. For +example: + +@smallexample +gcc -O2 -fdump-tree-pre=stdout -fdump-tree-pre ... +gcc -O2 -fdump-tree-pre -fdump-tree-pre=stdout ... +@end smallexample + +Both of the above output the PRE dump into an auto generated file name +since the @file{stdout} stream has lower precedence. As another +example, + +@smallexample +gcc -O2 -fdump-tree-pre=pre.txt -fdump-tree-all=stderr ... +@end smallexample + +outputs all the tree dumps on @file{stderr}, except the PRE dump, +which is output into @file{pre.txt}. + @item all -Turn on all options, except @option{raw}, @option{slim}, @option{verbose} -and @option{lineno}. +Turn on all options, except @option{raw}, @option{slim}, @option{verbose}, +@option{lineno}. @end table The following tree dumps are possible: @@ -5913,6 +5959,7 @@ is made by appending @file{.vrp} to the source fil @item all @opindex fdump-tree-all Enable all the available tree dumps with the flags provided in this option. + @end table @item -ftree-vectorizer-verbose=@var{n} Index: tree-dump.c =================================================================== --- tree-dump.c (revision 187265) +++ tree-dump.c (working copy) @@ -773,20 +773,20 @@ dump_node (const_tree t, int flags, FILE *stream) tree_dump_index enumeration in tree-pass.h. */ static struct dump_file_info dump_files[TDI_end] = { - {NULL, NULL, NULL, 0, 0, 0}, - {".cgraph", "ipa-cgraph", NULL, TDF_IPA, 0, 0}, - {".tu", "translation-unit", NULL, TDF_TREE, 0, 1}, - {".class", "class-hierarchy", NULL, TDF_TREE, 0, 2}, - {".original", "tree-original", NULL, TDF_TREE, 0, 3}, - {".gimple", "tree-gimple", NULL, TDF_TREE, 0, 4}, - {".nested", "tree-nested", NULL, TDF_TREE, 0, 5}, - {".vcg", "tree-vcg", NULL, TDF_TREE, 0, 6}, - {".ads", "ada-spec", NULL, 0, 0, 7}, + {NULL, NULL, NULL, NULL, 0, 0, 0}, + {".cgraph", "ipa-cgraph", NULL, NULL, TDF_IPA, 0, 0}, + {".tu", "translation-unit", NULL, NULL, TDF_TREE, 0, 1}, + {".class", "class-hierarchy", NULL, NULL, TDF_TREE, 0, 2}, + {".original", "tree-original", NULL, NULL, TDF_TREE, 0, 3}, + {".gimple", "tree-gimple", NULL, NULL, TDF_TREE, 0, 4}, + {".nested", "tree-nested", NULL, NULL, TDF_TREE, 0, 5}, + {".vcg", "tree-vcg", NULL, NULL, TDF_TREE, 0, 6}, + {".ads", "ada-spec", NULL, NULL, 0, 0, 7}, #define FIRST_AUTO_NUMBERED_DUMP 8 - {NULL, "tree-all", NULL, TDF_TREE, 0, 0}, - {NULL, "rtl-all", NULL, TDF_RTL, 0, 0}, - {NULL, "ipa-all", NULL, TDF_IPA, 0, 0}, + {NULL, "tree-all", NULL, NULL, TDF_TREE, 0, 0}, + {NULL, "rtl-all", NULL, NULL, TDF_RTL, 0, 0}, + {NULL, "ipa-all", NULL, NULL, TDF_IPA, 0, 0}, }; /* Dynamically registered tree dump files and switches. */ @@ -802,7 +802,7 @@ struct dump_option_value_info }; /* Table of dump options. This must be consistent with the TDF_* flags - in tree.h */ + in tree-pass.h */ static const struct dump_option_value_info dump_options[] = { {"address", TDF_ADDRESS}, @@ -892,6 +892,9 @@ get_dump_file_name (int phase) if (dfi->state == 0) return NULL; + if (dfi->filename) + return xstrdup (dfi->filename); + if (dfi->num < 0) dump_id[0] = '\0'; else @@ -911,6 +914,22 @@ get_dump_file_name (int phase) return concat (dump_base_name, dump_id, dfi->suffix, NULL); } +/* If FILENAME is a standard stream (stdout or stderr), return that + stream, otherwise return NULL. */ + +static FILE * +dump_get_standard_stream (const char *filename) +{ + if (!filename) + return NULL; + + return strcmp("stderr", filename) == 0 + ? stderr + : strcmp("stdout", filename) == 0 + ? stdout + : NULL; +} + /* Begin a tree dump for PHASE. Stores any user supplied flag in *FLAG_PTR and returns a stream to write to. If the dump is not enabled, returns NULL. @@ -926,14 +945,20 @@ dump_begin (int phase, int *flag_ptr) if (phase == TDI_none || !dump_enabled_p (phase)) return NULL; - name = get_dump_file_name (phase); dfi = get_dump_file_info (phase); - stream = fopen (name, dfi->state < 0 ? "w" : "a"); - if (!stream) - error ("could not open dump file %qs: %m", name); + stream = dump_get_standard_stream (dfi->filename); + if (stream) + dfi->state = 1; else - dfi->state = 1; - free (name); + { + name = get_dump_file_name (phase); + stream = fopen (name, dfi->state < 0 ? "w" : "a"); + if (!stream) + error ("could not open dump file %qs: %m", name); + else + dfi->state = 1; + free (name); + } if (flag_ptr) *flag_ptr = dfi->flags; @@ -987,35 +1012,60 @@ dump_flag_name (int phase) dump_begin. */ void -dump_end (int phase ATTRIBUTE_UNUSED, FILE *stream) +dump_end (int phase, FILE *stream) { - fclose (stream); + struct dump_file_info *dfi = get_dump_file_info (phase); + if (!dump_get_standard_stream (dfi->filename)) + fclose (stream); } -/* Enable all tree dumps. Return number of enabled tree dumps. */ +/* Enable all tree dumps with FLAGS on FILENAME. Return number of + enabled tree dumps. */ static int -dump_enable_all (int flags) +dump_enable_all (int flags, const char *filename) { int ir_dump_type = (flags & (TDF_TREE | TDF_RTL | TDF_IPA)); int n = 0; size_t i; for (i = TDI_none + 1; i < (size_t) TDI_end; i++) - if ((dump_files[i].flags & ir_dump_type)) - { - dump_files[i].state = -1; - dump_files[i].flags |= flags; - n++; - } + { + if ((dump_files[i].flags & ir_dump_type)) + { + const char *old_filename = dump_files[i].filename; + dump_files[i].state = -1; + dump_files[i].flags |= flags; + n++; + /* Do we need to override an existing filename? */ + if (filename && (!old_filename + || dump_get_standard_stream (old_filename))) + { + dump_files[i].filename = xstrdup (filename); + if (filename != old_filename) + free ((void *)old_filename); + } + } + } for (i = 0; i < extra_dump_files_in_use; i++) - if ((extra_dump_files[i].flags & ir_dump_type)) - { - extra_dump_files[i].state = -1; - extra_dump_files[i].flags |= flags; - n++; - } + { + if ((extra_dump_files[i].flags & ir_dump_type)) + { + const char *old_filename = extra_dump_files[i].filename; + extra_dump_files[i].state = -1; + extra_dump_files[i].flags |= flags; + n++; + /* Do we need to override an existing filename? */ + if (filename && (!old_filename + || dump_get_standard_stream (old_filename))) + { + extra_dump_files[i].filename = xstrdup (filename); + if (filename != old_filename) + free ((void *)old_filename); + } + } + } return n; } @@ -1037,7 +1087,7 @@ dump_switch_p_1 (const char *arg, struct dump_file if (!option_value) return 0; - if (*option_value && *option_value != '-') + if (*option_value && *option_value != '-' && *option_value != '=') return 0; ptr = option_value; @@ -1052,30 +1102,61 @@ dump_switch_p_1 (const char *arg, struct dump_file while (*ptr == '-') ptr++; end_ptr = strchr (ptr, '-'); + if (!end_ptr) end_ptr = ptr + strlen (ptr); length = end_ptr - ptr; + if (*ptr == '=') + { + /* Interpret rest of the argument as a dump filename. This + filename overrides generated dump names as well as other + command line filenames. However, the standard streams are + considered weak, i.e. they do not override other + filenames. */ + const char *filename = ptr + 1; + + if (!dump_get_standard_stream (filename) + || !dfi->state + || dump_get_standard_stream (dfi->filename)) + { + free ((void *)dfi->filename); + dfi->filename = xstrdup (ptr + 1); + } + flags |= TDF_FILENAME; + break; + } + for (option_ptr = dump_options; option_ptr->name; option_ptr++) if (strlen (option_ptr->name) == length && !memcmp (option_ptr->name, ptr, length)) - { - flags |= option_ptr->value; + { + flags |= option_ptr->value; goto found; - } + } warning (0, "ignoring unknown option %q.*s in %<-fdump-%s%>", length, ptr, dfi->swtch); found:; ptr = end_ptr; } + /* For the same dump seen again, override the standard stream + because it is considered as a weak filename. */ + if ((dfi->flags & TDF_FILENAME) + && !(flags & TDF_FILENAME) + && dump_get_standard_stream (dfi->filename)) + { + dfi->flags &= ~TDF_FILENAME; + free ((void *)dfi->filename); + dfi->filename = NULL; + } dfi->state = -1; dfi->flags |= flags; /* Process -fdump-tree-all and -fdump-rtl-all, by enabling all the known dumps. */ if (dfi->suffix == NULL) - dump_enable_all (dfi->flags); + dump_enable_all (dfi->flags, dfi->filename); return 1; } @@ -1124,5 +1205,5 @@ dump_function (int phase, tree fn) bool enable_rtl_dump_file (void) { - return dump_enable_all (TDF_RTL | TDF_DETAILS | TDF_BLOCKS) > 0; + return dump_enable_all (TDF_RTL | TDF_DETAILS | TDF_BLOCKS, NULL) > 0; } Index: tree-pass.h =================================================================== --- tree-pass.h (revision 187265) +++ tree-pass.h (working copy) @@ -84,8 +84,9 @@ enum tree_dump_index #define TDF_ENUMERATE_LOCALS (1 << 22) /* Enumerate locals by uid. */ #define TDF_CSELIB (1 << 23) /* Dump cselib details. */ #define TDF_SCEV (1 << 24) /* Dump SCEV details. */ +#define TDF_FILENAME (1 << 25) /* Dump on provided filename + instead of constructing one. */ - /* In tree-dump.c */ extern char *get_dump_file_name (int); @@ -222,6 +223,8 @@ struct dump_file_info const char *suffix; /* suffix to give output file. */ const char *swtch; /* command line switch */ const char *glob; /* command line glob */ + const char *filename; /* use this filename instead of making + up one using dump_base_name + suffix. */ int flags; /* user flags */ int state; /* state of play */ int num; /* dump file number */ Index: testsuite/g++.dg/other/dump-filename-1.C =================================================================== --- testsuite/g++.dg/other/dump-filename-1.C (revision 0) +++ testsuite/g++.dg/other/dump-filename-1.C (revision 0) @@ -0,0 +1,11 @@ +// Test that the dump to a user-defined file works correctly. +/* { dg-options "-O2 -fdump-tree-original=foobar.dump" } */ + +void test (int *b, int *e, int stride) + { + for (int *p = b; p != e; p += stride) + *p = 1; + } + +/* { dg-final { scan-file foobar.dump ";; Function void test" } } */ +/* { dg-final { remove-build-file "foobar.dump" } } */