On Tue, Jul 3, 2012 at 11:07 PM, Sharad Singhai <sing...@google.com> wrote:
> Apologies for the spam. Attempting to resend the patch after shrinking it.
>
> I have updated the attached patch to use a new dump message
> classification system for the vectorizer. It currently uses four
> classes, viz, MSG_OPTIMIZED_LOCATIONS, MSG_UNOPTIMIZED_LOCATION,
> MSG_MISSING_OPTIMIZATION, and MSG_NOTE. I have gone through the
> vectorizer passes and have converted each call to fprintf (dump_file,
> ....) to a message classification matching in spirit. Most often, it
> is MSG_OPTIMIZED_LOCATIONS, but occasionally others as well.
>
> For example, the following
>
> if (vect_print_dump_info (REPORT_DETAILS))
>   {
>     fprintf (vect_dump, "niters for prolog loop: ");
>     print_generic_expr (vect_dump, iters, TDF_SLIM);
>   }
>
> gets converted to
>
> if (dump_kind (MSG_OPTIMIZED_LOCATIONS))
>   {
>      dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
>                       "niters for prolog loop: ");
>      dump_generic_expr (MSG_OPTIMIZED_LOCATIONS, TDF_SLIM, iters);
>   }
>
> The asymmetry between the first printf and the second is due to the
> fact that 'vect_print_dump_info (xxx)' prints the location as a
> "side-effect". To preserve the original intent somewhat, I have
> converted the first call within a dump sequence to a dump_printf_loc
> (xxx) which prints the location while the subsequence calls within the
> same conditional get converted to the corresponding plain variants.

Ok, that looks reasonable.

> I considered removing the support for alternate dump file, but ended
> up preserving it instead since it is needed for setting the alternate
> dump file to stderr for the case when -fopt-info is given but no dump
> file is available.
>
> The following invocation
> g++ ... -ftree-vectorize -fopt-info=4
>
> dumps *all* available information to stderr. Currently, the opt-info
> level is common to all passes, i.e., a pass can't specify if wants a
> different level of diagnostic info. This can be added as an
> enhancement with a suitable syntax for selecting passes.
>
> I haven't fixed up the documentation/tests but wanted to get some
> feedback about the current state of patch before doing that.

Some comments / questions.

+  if (dump_file && (dump_kind & opt_info_flags))
+    {
+      dump_loc (dump_kind, dump_file, loc);
+      print_generic_expr (dump_file, t, dump_flags | extra_dump_flags);
+    }
+
+  if (alt_dump_file && (dump_kind & opt_info_flags))
+    {

you always test dump_kind against the same opt_info_flags variable.
I would have thought that the alternate dump file has a different opt_info_flags
setting so I can have -fdump-tree-vect-details -fopt-info=1.  Am I missing
something?

If I do

> gcc file1.c file2.c -O3 -fdump-tree-vectorize=foo

what will foo contain afterwards?  I think you need to document the behavior
when such redirection is used with the compiler-driver feature of handling
multiple translation units.  Especially the difference (or not difference) to

> gcc file1.c -O3 -fdump-tree-vectorize=foo
> gcc file2.c -O3 -fdump-tree-vectorize=foo

I suppose we do not want to append to foo (but eventually support that
with some alternate syntax?  Like -fdump-tree-vectorize=+foo?)

+
+static void
+set_opt_info (int opt_info_level)
+{

This function needs a comment.  How do the dump flags translate to
the opt-info flags?  Is this documented anywhere?  I only see

+/* Different types of dump classifications.  */
+enum dump_msg_kind {
+  MSG_NONE                     = 1 << 0,
+  MSG_OPTIMIZED_LOCATIONS      = 1 << 1,
+  MSG_UNOPTIMIZED_LOCATIONS    = 1 << 2,
+  MSG_MISSED_OPTIMIZATION      = 1 << 3,
+  MSG_NOTE                     = 1 << 4
+};

I suppose the TDF_* flags would all map to
MSG_OPTIMIZED_LOCATIONS|MSG_UNOPTIMIZED_LOCATIONS|MSG_MISSED_OPTIMIZATION
and only TDF_DETAILS would enable MSG_NOTE?

In the above a flag for MSG_NONE does not make much sense?

How would we map TDF_SCEV?  I suppose we'd add MSG_SCEV for this
(we talked about the possibility of having some special flags for
special passes).

But this also means a linear "opt-info-level" as in

+static void
+set_opt_info (int opt_info_level)

may not be a good representation.  Not a pass-ignorant opt_info_flags
value, if you consider -fopt-info=vect,3 (details from the vectorizer please).

+}
+
+
+
+DEBUG_FUNCTION void
+dump_combine_stats (int flags)

debug functions should be called debug_*, please add a comment and
avoid excessive vertical space

Index: tree-pass.h
===================================================================
--- tree-pass.h (revision 188966)
+++ tree-pass.h (working copy)
@@ -85,7 +85,6 @@ enum tree_dump_index
 #define TDF_CSELIB     (1 << 23)       /* Dump cselib details.  */
 #define TDF_SCEV       (1 << 24)       /* Dump SCEV details.  */

-
 /* In tree-dump.c */

 extern char *get_dump_file_name (int);

please avoid whitespace-only changes (also elsewhere).

 /* Global variables used to communicate with passes.  */
 extern FILE *dump_file;
+extern FILE *alt_dump_file;
 extern int dump_flags;
+extern int opt_info_flags;

so I expected the primary dump_file to be controlled with dump_flags,
or with a (cached) translation of them to a primary_opt_info_flags.

Index: gimple-pretty-print.h
===================================================================
--- gimple-pretty-print.h       (revision 188966)
+++ gimple-pretty-print.h       (working copy)
@@ -31,6 +31,6 @@ extern void debug_gimple_seq (gimple_seq);
 extern void print_gimple_seq (FILE *, gimple_seq, int, int);
 extern void print_gimple_stmt (FILE *, gimple, int, int);
 extern void print_gimple_expr (FILE *, gimple, int, int);
-extern void dump_gimple_stmt (pretty_printer *, gimple, int, int);
+extern void print_gimple_stmt_1 (pretty_printer *, gimple, int, int);

I'd call this pp_gimple_stmt instead.

@@ -1418,6 +1419,16 @@ init_branch_prob (void)
 void
 end_branch_prob (void)
 {
+  end_branch_prob_1 (dump_file);
+  end_branch_prob_1 (alt_dump_file);
+}
+
+/* Helper function for file-level cleanup for DUMP_FILE after
+   branch-prob processing is completed. */
+
+static void
+end_branch_prob_1 (FILE *dump_file)
+{
   if (dump_file)
     {
       fprintf (dump_file, "\n");

That change looks odd ;)  Can you instead use the new dump_printf
interface?  (side-note: we should not need to export alt_dump_file at all!)

@@ -2166,10 +2177,6 @@ ftree-vect-loop-version
 Common Report Var(flag_tree_vect_loop_version) Init(1) Optimization
 Enable loop versioning when doing loop vectorization on trees

-ftree-vectorizer-verbose=
-Common RejectNegative Joined UInteger
--ftree-vectorizer-verbose=<number>     Set the verbosity level of the
vectorizer
-

we need to preserve old switches for backward compatibility, I suggest
to alias it to -fopt-info for now.

@@ -13909,7 +13909,7 @@ unmentioned_reg_p (rtx equiv, rtx expr)
 }
 ^L
 DEBUG_FUNCTION void
-dump_combine_stats (FILE *file)
+print_combine_stats (FILE *file)

see above, debug_combine_stats.

Index: system.h
===================================================================
--- system.h    (revision 188966)
+++ system.h    (working copy)
@@ -669,6 +669,7 @@ extern int vsnprintf(char *, size_t, const char *,
    except, maybe, something to the dump file.  */
 #ifdef BUFSIZ
 extern FILE *dump_file;
+extern FILE *alt_dump_file;

see above - we should not need to export this (nor opt_info_flags).

Overall I like the patch!

Thanks,
Richard.

> Thanks,
> Sharad
>
> On Fri, Jun 15, 2012 at 1:18 AM, Richard Guenther
> <richard.guent...@gmail.com> wrote:
>> On Fri, Jun 15, 2012 at 7:47 AM, Sharad Singhai <sing...@google.com> wrote:
>>> On Wed, Jun 13, 2012 at 4:48 AM, Richard Guenther
>>> <richard.guent...@gmail.com> wrote:
>>>> On Fri, Jun 8, 2012 at 7:16 AM, Sharad Singhai <sing...@google.com> wrote:
>>>>> Okay, I have updated the attached patch so that the output from
>>>>> -ftree-vectorizer-verbose is considered diagnostic information and is
>>>>> always
>>>>> sent to stderr. Other functionality remains unchanged. Here is some
>>>>> more context about this patch.
>>>>>
>>>>> This patch improves the dump infrastructure and public interfaces so
>>>>> that the existing private pass-specific dump stream is separated from
>>>>> the diagnostic dump stream (typically stderr).  The optimization
>>>>> passes can output information on the two streams independently.
>>>>>
>>>>> The newly defined interfaces are:
>>>>>
>>>>> Individual passes do not need to access the dump file directly. Thus 
>>>>> Instead
>>>>> of doing
>>>>>
>>>>>   if (dump_file && (flags & dump_flags))
>>>>>      fprintf (dump_file, ...);
>>>>>
>>>>> they can do
>>>>>
>>>>>     dump_printf (flags, ...);
>>>>>
>>>>> If the current pass has FLAGS enabled then the information gets
>>>>> printed into the dump file otherwise not.
>>>>>
>>>>> Similar to the dump_printf (), another function is defined, called
>>>>>
>>>>>        diag_printf (dump_flags, ...)
>>>>>
>>>>> This prints information only onto the diagnostic stream, typically
>>>>> standard error. It is useful for separating pass-specific dump
>>>>> information from
>>>>> the diagnostic information.
>>>>>
>>>>> Currently, as a proof of concept, I have converted vectorizer passes
>>>>> to use the new dump format. For this, I have considered
>>>>> information printed in vect_dump file as diagnostic. Thus 'fprintf'
>>>>> calls are changed to 'diag_printf'. Some other information printed to
>>>>> dump_file is sent to the regular dump file via 'dump_printf ()'. It
>>>>> helps to separate the two streams because they might serve different
>>>>> purposes and might have different formatting requirements.
>>>>>
>>>>> For example, using the trunk compiler, the following invocation
>>>>>
>>>>> g++ -S v.cc -ftree-vectorize -fdump-tree-vect -ftree-vectorizer-verbose=2
>>>>>
>>>>> prints tree vectorizer dump into a file named 'v.cc.113t.vect'.
>>>>> However, the verbose diagnostic output is silently
>>>>> ignored. This is not desirable as the two types of dump should not 
>>>>> interfere.
>>>>>
>>>>> After this patch, the vectorizer dump is available in 'v.cc.113t.vect'
>>>>> as before, but the verbose vectorizer diagnostic is additionally
>>>>> printed on stderr. Thus both types of dump information are output.
>>>>>
>>>>> An additional feature of this patch is that individual passes can
>>>>> print dump information into command-line named files instead of auto
>>>>> numbered filename. For example,
>>>>
>>>> I'd wish you'd leave out this part for a followup.
>>>>
>>>>>
>>>>> g++ -S -O2 v.cc -ftree-vectorize -fdump-tree-vect=foo.vect
>>>>>     -ftree-vectorizer-verbose=2
>>>>>     -fdump-tree-pre=foo.pre
>>>>>
>>>>> This prints the tree vectorizer dump into 'foo.vect', PRE dump into
>>>>> 'foo.pre', and the vectorizer verbose diagnostic dump onto stderr.
>>>>>
>>>>> Please take another look.
>>>>
>>>> --- tree-vect-loop-manip.c      (revision 188325)
>>>> +++ tree-vect-loop-manip.c      (working copy)
>>>> @@ -789,14 +789,11 @@ slpeel_make_loop_iterate_ntimes (struct loop *loop
>>>>   gsi_remove (&loop_cond_gsi, true);
>>>>
>>>>   loop_loc = find_loop_location (loop);
>>>> -  if (dump_file && (dump_flags & TDF_DETAILS))
>>>> -    {
>>>> -      if (loop_loc != UNKNOWN_LOC)
>>>> -        fprintf (dump_file, "\nloop at %s:%d: ",
>>>> +  if (loop_loc != UNKNOWN_LOC)
>>>> +    dump_printf (TDF_DETAILS, "\nloop at %s:%d: ",
>>>>                  LOC_FILE (loop_loc), LOC_LINE (loop_loc));
>>>> -      print_gimple_stmt (dump_file, cond_stmt, 0, TDF_SLIM);
>>>> -    }
>>>> -
>>>> +  if (dump_flags & TDF_DETAILS)
>>>> +    dump_gimple_stmt (TDF_SLIM, cond_stmt, 0);
>>>>   loop->nb_iterations = niters;
>>>>
>>>> I'm confused by this.  Why is this not simply
>>>>
>>>>  if (loop_loc != UNKNOWN_LOC)
>>>>    dump_printf (dump_flags, "\nloop at %s:%d: ",
>>>>                       LOC_FILE (loop_loc), LOC_LINE (loop_loc));
>>>>  dump_gimple_stmt (dump_flags | TDF_SLIM, cond_stmt, 0);
>>>>
>>>> for example.  I notice that you maybe mis-understood the message 
>>>> classification
>>>> I asked you to add (maybe I confused you by mentioning to eventually re-use
>>>> the TDF_* flags).  I think you basically provided this message 
>>>> classification
>>>> by adding two classes by providing both dump_gimple_stmt and 
>>>> diag_gimple_stmt.
>>>> But still in the above you keep a dump_flags test _and_ you pass in
>>>> (altered) dump_flags to the dump/diag_gimple_stmt routines.  Let me quote 
>>>> them:
>>>>
>>>> +void
>>>> +dump_gimple_stmt (int flags, gimple gs, int spc)
>>>> +{
>>>> +  if (dump_file)
>>>> +    print_gimple_stmt (dump_file, gs, spc, flags);
>>>> +}
>>>>
>>>> +void
>>>> +diag_gimple_stmt (int flags, gimple gs, int spc)
>>>> +{
>>>> +  if (alt_dump_file)
>>>> +    print_gimple_stmt (alt_dump_file, gs, spc, flags);
>>>> +}
>>>>
>>>> I'd say it should have been a single function:
>>>>
>>>> void
>>>> dump_gimple_stmt (enum msg_classification, int additional_flags,
>>>> gimple gs, int spc)
>>>> {
>>>>  if (msg_classification & go-to-dumpfile
>>>>      && dump_file)
>>>>    print_gimple_stmt (dump_file, gs, spc, dump_flags | additional_flags);
>>>>  if (msg_classification & go-to-alt-dump-file
>>>>      && alt_dump_file && (alt_dump_flags & msg_classification))
>>>>    print_gimple_stmt (alt_dump_file, gs, spc, alt_dump_flags |
>>>> additional_flags);
>>>> }
>>>
>>> Yes,  I can make the single function work for both regular (dump_file)
>>> and diagnostic (stderr for now) dump streams. In fact, my original
>>> patch did just that. However, it duplicated output on *both* the
>>> streams. For example,
>>>
>>> gcc -O2 -ftree-vectorize -fdump-tree-vect=foo.vect
>>> -ftree-vectorizer-verbose=2 foo.c
>>>
>>> Since both streams are enabled in this case, a call to dump_printf ()
>>> would duplicate the information to both files, i.e., the dump and
>>> diagnostic will be intermixed. Is that intended? My first thought was
>>> to keep them separated via dump_*() and diag_* () methods.
>>
>> No, I think that's intended.  The regular dump-files should contain
>> everything, the secondary stream (eventually enabled by -fopt-info)
>> should be a filtered regular dump-file.
>>
>> Thanks,
>> Richard.
>>
>>> Thanks,
>>> Sharad
>>>
>>>> where msg_classification would include things to suitably classify messages
>>>> for -fopt-info, like MSG_MISSED_OPTIMIZATION, MSG_OPTIMIZED, MSG_NOTE.
>>>>
>>>> In another place we have
>>>>
>>>> @@ -1648,7 +1642,7 @@ vect_can_advance_ivs_p (loop_vec_info loop_vinfo)
>>>>   /* Analyze phi functions of the loop header.  */
>>>>
>>>>   if (vect_print_dump_info (REPORT_DETAILS))
>>>> -    fprintf (vect_dump, "vect_can_advance_ivs_p:");
>>>> +    diag_printf (TDF_TREE, "vect_can_advance_ivs_p:");
>>>>
>>>> so why's that diag_printf and why TDF_TREE?  I suppose you made all
>>>> dumps to vect_dump diag_* and all dumps to dump_file dump_*?  I
>>>> think it should have been
>>>>
>>>>   dump_printf (REPORT_DETAILS, "vect_can_advance_ivs_p:");
>>>>
>>>> thus dump_printf only gets the msg-classification and the printf args
>>>> (dump-flags
>>>> are only meaningful when passed down to pretty-printers).  Thus
>>>>
>>>> @@ -1658,8 +1652,8 @@ vect_can_advance_ivs_p (loop_vec_info loop_vinfo)
>>>>       phi = gsi_stmt (gsi);
>>>>       if (vect_print_dump_info (REPORT_DETAILS))
>>>>        {
>>>> -          fprintf (vect_dump, "Analyze phi: ");
>>>> -          print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
>>>> +          diag_printf (TDF_TREE, "Analyze phi: ");
>>>> +          diag_gimple_stmt (TDF_SLIM, phi, 0);
>>>>        }
>>>>
>>>> should be
>>>>
>>>>  dump_printf (REPORT_DETAILS, "Analyze phi: ");
>>>>  dump_gimple_stmt (REPORT_DETAILS, TDF_SLIM, phi, 0);
>>>>
>>>> and the if (vect_print_dump_info (REPORT_DETAILS)) should be what
>>>> the dump infrastructure provides and thus hidden.  Eventually we should
>>>> have a dump_kind (msg-classification) so we can replace it with
>>>>
>>>>   if (dump_kind (REPORT_DETAILS))
>>>>     {
>>>>       dump_printf (REPORT_DETAILS, "Analyze phi: ");
>>>>       dump_gimple_stmt (REPORT_DETAILS, TDF_SLIM, phi, 0);
>>>>     }
>>>>
>>>> to reduce the runtime overhead when not diagnosing/dumping.
>>>>
>>>> @@ -2464,8 +2458,8 @@ vect_create_cond_for_alias_checks (loop_vec_info l
>>>>     }
>>>>
>>>>   if (vect_print_dump_info (REPORT_VECTORIZED_LOCATIONS))
>>>> -    fprintf (vect_dump, "created %u versioning for alias checks.\n",
>>>> -             VEC_length (ddr_p, may_alias_ddrs));
>>>> +    diag_printf (TDF_TREE, "created %u versioning for alias checks.\n",
>>>> +                 VEC_length (ddr_p, may_alias_ddrs));
>>>>  }
>>>>
>>>> so here we have a different msg-classification,
>>>> REPORT_VECTORIZED_LOCATIONS.  As we eventually want a central
>>>> -fopt-report=... we do not want to leave this implementation detail to
>>>> individual passes but gather them in a central place.
>>>>
>>>> Thanks,
>>>> Richard.
>>>>
>>>>> Thanks,
>>>>> Sharad
>>>>>
>>>>>
>>>>> On Thu, Jun 7, 2012 at 12:19 AM, Xinliang David Li <davi...@google.com> 
>>>>> wrote:
>>>>>> On Wed, Jun 6, 2012 at 10:58 PM, Sharad Singhai <sing...@google.com> 
>>>>>> wrote:
>>>>>>> Sorry about the delay. I have finally incorporated all the suggestions
>>>>>>> and reorganized the dump infrastructure a bit. The attached patch
>>>>>>> updates vectorizer passes so that instead of accessing global
>>>>>>> dump_file directly, these passes call dump_printf (FLAG, format, ...).
>>>>>>> The dump_printf can choose between two streams, one regular pass dump
>>>>>>> file, and another optional command line provided file. Currently, it
>>>>>>> doesn't discriminate and all the dump information goes to both the
>>>>>>> streams.
>>>>>>>
>>>>>>> Thus, for example,
>>>>>>>
>>>>>>> g++ -O2 v.cc -ftree-vectorize -fdump-tree-vect=foo.v 
>>>>>>> -ftree-vectorizer-verbose=3
>>>>>>
>>>>>> But the default form of dump option (-fdump-tree-vect) no longer
>>>>>> interferes with -ftree-vectorize-verbose=xxx output right? (this is
>>>>>> one of the main requirements). One dumped to the primary stream (named
>>>>>> dump file) and the other to the stderr -- the default diagnostic (alt)
>>>>>> stream.
>>>>>>
>>>>>> David
>>>>>>
>>>>>>>
>>>>>>> will output the verbose vectorizer information in both *.vect file and
>>>>>>> foo.v file. However, as I have converted only vectorizer passes so
>>>>>>> far, there is additional information in *.vect file which is not
>>>>>>> present in foo.v file. Once other passes are converted to use this
>>>>>>> scheme, then these two dump files should have identical output.
>>>>>>>
>>>>>>> Also note that in this patch -fdump-xxx=yyy format does not override
>>>>>>> any auto named dump files as in my earlier patches. Instead the dump
>>>>>>> information is output to both places when a command line dump file
>>>>>>> option is provided.
>>>>>>>
>>>>>>> To summarize:
>>>>>>> - instead of using dump_begin () / dump_end (), the passes should use
>>>>>>> dump_start ()/dump_finish (). These new variants do not return the
>>>>>>> dump_file. However, they still set the global dump_file/dump_flags for
>>>>>>> the benefit of other passes during the transition.
>>>>>>> - instead of directly printing to the dump_file, as in
>>>>>>> if (dump_file)
>>>>>>>  fprintf (dump_file, ...);
>>>>>>>
>>>>>>> The passes should do
>>>>>>>
>>>>>>> dump_printf (dump_flag, ...);
>>>>>>> This will output to dump file(s) only when dump_flag is enabled for a
>>>>>>> given pass.
>>>>>>>
>>>>>>> I have bootstrapped and tested it on x86_64. Does it look okay?
>>>>>>>
>>>>>>> Thanks,
>>>>>>> Sharad
>>>>>>>
>>>>>>>
>>>>>>> On Mon, May 14, 2012 at 12:26 AM, Richard Guenther
>>>>>>> <richard.guent...@gmail.com> wrote:
>>>>>>>> On Sat, May 12, 2012 at 6:39 PM, Xinliang David Li 
>>>>>>>> <davi...@google.com> wrote:
>>>>>>>>> On Sat, May 12, 2012 at 9:26 AM, Gabriel Dos Reis
>>>>>>>>> <g...@integrable-solutions.net> wrote:
>>>>>>>>>> On Sat, May 12, 2012 at 11:05 AM, Xinliang David Li 
>>>>>>>>>> <davi...@google.com> wrote:
>>>>>>>>>>
>>>>>>>>>>> The downside is that the dump file format will look different from 
>>>>>>>>>>> the
>>>>>>>>>>> stderr output which is less than ideal.
>>>>>>>>>>
>>>>>>>>>> BTW, why do people want to use stderr for dumping internal IRs,
>>>>>>>>>> as opposed to stdout or other files?  That does not sound right.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> I was talking about the transformation information difference. In
>>>>>>>>> stderr (where diagnostics go to), we may have
>>>>>>>>>
>>>>>>>>> foo.c: in function 'foo':
>>>>>>>>> foo.c:5:6: note: loop was vectorized
>>>>>>>>>
>>>>>>>>> but in dump file the format for the information may be different,
>>>>>>>>> unless we want to duplicate the machinery in diagnostics.
>>>>>>>>
>>>>>>>> So?  What's the problem with that ("different" diagnostics)?
>>>>>>>>
>>>>>>>> Richard.
>>>>>>>>
>>>>>>>>> David
>>>>>>>>>
>>>>>>>>>> -- Gaby

Reply via email to