On Wed, May 9, 2012 at 1:51 AM, Andrew Pinski <pins...@gmail.com> wrote:
> On Tue, May 8, 2012 at 11:46 PM, Sharad Singhai <sing...@google.com> wrote:
>> In response to comments, I have updated the patch to support dumps in
>> user provided files via the option -fdump-xxx=<filename>. The
>> filenames stdout/stderr are treated specially, and are considered
>> standard streams.
>
> I think - should also be treated as special (or maybe the only one
> which should be treated as special).

He originally wanted only "stderr", so treating "-" only specially
would not be in
the line with his original goal.  "-" is equivalent to "stdout", so it
is not like
we don't have the functionally with his revised patch.

>
> Thanks,
> Andrew Pinski
>
>>
>> Also updated documentation and a testcase. Okay for trunk?
>>
>> Thanks,
>> Sharad
>>
>> 2012-05-08   Sharad Singhai  <sing...@google.com>
>>
>>        * doc/invoke.texi: Add documentation for new option.
>>        * tree-dump.c (dump_stream_p): New function.
>>        (dump_files): Update for new field.
>>        (dump_switch_p_1): Handle user provided filenames.
>>        (dump_begin): Likewise.
>>        (get_dump_file_name): Likewise.
>>        (dump_enable_all): Add new parameter USER_FILENAME.
>>        All callers updated.
>>        (dump_end): Remove attribute.
>>        * tree-pass.h (enum tree_dump_index): Add new constant.
>>        (struct dump_file_info): Add new field USER_FILENAME.
>>        * testsuite/g++.dg/other/dump-userfile-1.C: New test.
>>
>> Index: doc/invoke.texi
>> ===================================================================
>> --- doc/invoke.texi     (revision 187265)
>> +++ doc/invoke.texi     (working copy)
>> @@ -5322,20 +5322,24 @@ 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. The filenames stdout and stderr are treated specially. 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
>> @@ -5599,6 +5603,10 @@ These dumps are defined but always produce empty f
>>  @opindex fdump-rtl-all
>>  Produce all the dumps listed above.
>>
>> +@item -fdump-rtl-all=stderr
>> +@opindex fdump-rtl-all=stderr
>> +Produce all RTL dumps on stderr.
>> +
>>  @item -dA
>>  @opindex dA
>>  Annotate the assembler output with miscellaneous debugging information.
>> @@ -5719,15 +5727,19 @@ 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}}, the dump output is on the given file. Note
>> +that the filenames stdout and stderr are treated specially and dumps
>> +are done on standard streams. 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 +5777,56 @@ 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 name for a dump file, use the
>> +provided name. For example:
>> +
>> +@smallexample
>> +gcc -O2 -fdump-tree-pre=foobar.dump
>> +@end smallexample
>> +
>> +produces PRE dump in a file named foobar.dump. Similarly
>> +
>> +@smallexample
>> +gcc -O2 -fdump-tree-all=all.dump
>> +@end smallexample
>> +
>> +produces all tree dumps in a file named all.dump.
>> +
>> +Note that stdout and stderr are treated specially, and the dumps are
>> +done on standard streams. In case of any conflicts, the user provided
>> +filename takes precedence. For example:
>> +
>> +@smallexample
>> +gcc -O2 -fdump-tree-pre=stderr -fdump-tree-pre ...
>> +gcc -O2 -fdump-tree-pre -fdump-tree-pre=stderr ...
>> +@end smallexample
>> +
>> +Both invocations produce the PRE dump on stderr. Similarly, for the
>> +following
>> +
>> +@smallexample
>> +gcc -O2 -fdump-tree-all=stderr -fdump-tree-pre ...
>> +@end smallexample
>> +
>> +All the dumps are output on stderr. In the following example,
>> +
>> +@smallexample
>> +gcc -fdump-tree-all -fdump-tree-pre=stderr ...
>> +@end smallexample
>> +
>> +all the dumps are written into named files except the PRE dump, which
>> +is output on stderr, because @option{-fdump-tree-pre=stderr} takes
>> +precedence.
>> +
>>  @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 +5972,10 @@ 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.
>> +
>> +@item all=stderr
>> +@opindex fdump-tree-all=stderr
>> +Enable all the available tree dumps on the stderr.
>>  @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->user_filename)
>> +    return xstrdup (dfi->user_filename);
>> +
>>   if (dfi->num < 0)
>>     dump_id[0] = '\0';
>>   else
>> @@ -911,6 +914,19 @@ get_dump_file_name (int phase)
>>   return concat (dump_base_name, dump_id, dfi->suffix, NULL);
>>  }
>>
>> +/* 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;
>> +}
>> +
>>  /* 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 +942,28 @@ 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);
>> +  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.  */
>>   int flags;                    /* user flags */
>>   int state;                    /* state of play */
>>   int num;                      /* dump file number */
>> Index: testsuite/g++.dg/other/dump-userfile-1.C
>> ===================================================================
>> --- testsuite/g++.dg/other/dump-userfile-1.C    (revision 0)
>> +++ testsuite/g++.dg/other/dump-userfile-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" } } */
>>
>> --
>> This patch is available for review at http://codereview.appspot.com/6190057

Reply via email to