On Thu, Aug 3, 2023 at 4:24 PM Andrzej Turko via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> Currently fprintf calls logging to a dump file take line numbers
> in the match.pd file directly as arguments.
> When match.pd is edited, referenced code changes line numbers,
> which causes changes to many fprintf calls and, thus, to many
> (usually all) .cc files generated by genmatch. This forces make
> to (unnecessarily) rebuild many .o files.
>
> This change replaces those logging fprintf calls with calls to
> a dedicated logging function. Because it reads the line numbers
> from the lookup table, it is enough to pass a corresponding index.
> Thanks to this, when match.pd changes, it is enough to rebuild
> the file containing the lookup table and, of course, those
> actually affected by the change.
>
> Signed-off-by: Andrzej Turko <andrzej.tu...@gmail.com>
>
> gcc/ChangeLog:
>
>         * genmatch.cc: Log line numbers indirectly.
> ---
>  gcc/genmatch.cc | 89 ++++++++++++++++++++++++++++++++++++++++---------
>  1 file changed, 74 insertions(+), 15 deletions(-)
>
> diff --git a/gcc/genmatch.cc b/gcc/genmatch.cc
> index 1deca505603..63d6ba6dab0 100644
> --- a/gcc/genmatch.cc
> +++ b/gcc/genmatch.cc
> @@ -217,9 +217,57 @@ fp_decl_done (FILE *f, const char *trailer)
>      fprintf (header_file, "%s;", trailer);
>  }
>
> +/* Line numbers for use by indirect line directives.  */
> +static vec<int> dbg_line_numbers;
> +
> +static void
> +write_header_declarations (bool gimple, FILE *f)
> +{
> +  fprintf (f, "\nextern void\n%s_dump_logs (const char *file1, int line1_id, 
> "
> +             "const char *file2, int line2, bool simplify);\n",
> +             gimple ? "gimple" : "generic");
> +}
> +
> +static void
> +define_dump_logs (bool gimple, FILE *f)
> +{
> +

extra vertical space is unwanted here.

> +  if (dbg_line_numbers.is_empty ())
> +    {
> +      fprintf (f, "};\n\n");
> +      return;
> +    }

shouldn't the above come after ...

> +  fprintf (f , "void\n%s_dump_logs (const char *file1, int line1_id, "
> +               "const char *file2, int line2, bool simplify)\n{\n",
> +               gimple ? "gimple" : "generic");

... this?

> +  fprintf_indent (f, 2, "static int dbg_line_numbers[%d] = {",
> +                 dbg_line_numbers.length ());
> +
> +  for (int i = 0; i < (int)dbg_line_numbers.length () - 1; i++)

use an unsigned int to avoid the cast?

> +    {
> +      if (i % 20 == 0)
> +       fprintf (f, "\n\t");
> +
> +      fprintf (f, "%d, ", dbg_line_numbers[i]);
> +    }
> +  fprintf (f, "%d\n  };\n\n", dbg_line_numbers.last ());
> +
> +
> +  fprintf_indent (f, 2, "fprintf (dump_file, \"%%s "
> +                 "%%s:%%d, %%s:%%d\\n\",\n");
> +  fprintf_indent (f, 10, "simplify ? \"Applying pattern\" : "
> +                 "\"Matching expression\", file1, "
> +                 "dbg_line_numbers[line1_id], file2, line2);");
> +
> +  fprintf (f, "\n}\n\n");
> +}
> +
>  static void
>  output_line_directive (FILE *f, location_t location,
> -                      bool dumpfile = false, bool fnargs = false)
> +                     bool dumpfile = false, bool fnargs = false,
> +                     bool indirect_line_numbers = false)
>  {
>    const line_map_ordinary *map;
>    linemap_resolve_location (line_table, location, LRK_SPELLING_LOCATION, 
> &map);
> @@ -239,7 +287,15 @@ output_line_directive (FILE *f, location_t location,
>         ++file;
>
>        if (fnargs)
> -       fprintf (f, "\"%s\", %d", file, loc.line);
> +  {
> +    if (indirect_line_numbers)
> +      {
> +       fprintf (f, "\"%s\", %d", file, dbg_line_numbers.length ());
> +       dbg_line_numbers.safe_push (loc.line);
> +      }
> +    else
> +      fprintf (f, "\"%s\", %d", file, loc.line);
> +  }

The indent is off here.  I notice the same lines often appear repeatedly so
a simple optimization like doing

    if (indirect_line_numbers)
      {
        if (!dbg_line_numbers.is_empty ()
            && dbg_line_numbers.last () == loc.line)
          ;
        else
          dbg_line_numbers.safe_push (loc.line);
        fprintf (f, "\"%s\", %d", file, dbg_line_numbers.length () - 1);
      }

shrinks the table quite a bit (not all duplicates are gone this way).
It doesn't
seem we can easily keep the list sorted, adding another hash-map could
avoid duplicates completely, maybe worth pursuing.

Otherwise the patch series looks fine to me.

Thanks,
Richard.

>        else
>         fprintf (f, "%s:%d", file, loc.line);
>      }
> @@ -3375,20 +3431,19 @@ dt_operand::gen (FILE *f, int indent, bool gimple, 
> int depth)
>      }
>  }
>
> -/* Emit a fprintf to the debug file to the file F, with the INDENT from
> +/* Emit a logging call to the debug file to the file F, with the INDENT from
>     either the RESULT location or the S's match location if RESULT is null. */
>  static void
> -emit_debug_printf (FILE *f, int indent, class simplify *s, operand *result)
> +emit_logging_call (FILE *f, int indent, class simplify *s, operand *result,
> +                                 bool gimple)
>  {
>    fprintf_indent (f, indent, "if (UNLIKELY (debug_dump)) "
> -          "fprintf (dump_file, \"%s ",
> -          s->kind == simplify::SIMPLIFY
> -          ? "Applying pattern" : "Matching expression");
> -  fprintf (f, "%%s:%%d, %%s:%%d\\n\", ");
> +          "%s_dump_logs (", gimple ? "gimple" : "generic");
>    output_line_directive (f,
> -                        result ? result->location : s->match->location, true,
> -                        true);
> -  fprintf (f, ", __FILE__, __LINE__);\n");
> +                       result ? result->location : s->match->location,
> +                       true, true, true);
> +  fprintf (f, ", __FILE__, __LINE__, %s);\n",
> +             s->kind == simplify::SIMPLIFY ? "true" : "false");
>  }
>
>  /* Generate code for the '(if ...)', '(with ..)' and actual transform
> @@ -3524,7 +3579,7 @@ dt_simplify::gen_1 (FILE *f, int indent, bool gimple, 
> operand *result)
>    if (!result)
>      {
>        /* If there is no result then this is a predicate implementation.  */
> -      emit_debug_printf (f, indent, s, result);
> +      emit_logging_call (f, indent, s, result, gimple);
>        fprintf_indent (f, indent, "return true;\n");
>      }
>    else if (gimple)
> @@ -3615,7 +3670,7 @@ dt_simplify::gen_1 (FILE *f, int indent, bool gimple, 
> operand *result)
>         }
>        else
>         gcc_unreachable ();
> -      emit_debug_printf (f, indent, s, result);
> +      emit_logging_call (f, indent, s, result, gimple);
>        fprintf_indent (f, indent, "return true;\n");
>      }
>    else /* GENERIC */
> @@ -3670,7 +3725,7 @@ dt_simplify::gen_1 (FILE *f, int indent, bool gimple, 
> operand *result)
>             }
>           if (is_predicate)
>             {
> -             emit_debug_printf (f, indent, s, result);
> +             emit_logging_call (f, indent, s, result, gimple);
>               fprintf_indent (f, indent, "return true;\n");
>             }
>           else
> @@ -3738,7 +3793,7 @@ dt_simplify::gen_1 (FILE *f, int indent, bool gimple, 
> operand *result)
>                                   i);
>                 }
>             }
> -         emit_debug_printf (f, indent, s, result);
> +         emit_logging_call (f, indent, s, result, gimple);
>           fprintf_indent (f, indent, "return _r;\n");
>         }
>      }
> @@ -5447,6 +5502,7 @@ main (int argc, char **argv)
>        parts.quick_push (stdout);
>        write_header (stdout, s_include_file);
>        write_header_includes (gimple, stdout);
> +      write_header_declarations (gimple, stdout);
>      }
>    else
>      {
> @@ -5460,6 +5516,7 @@ main (int argc, char **argv)
>        fprintf (header_file, "#ifndef GCC_GIMPLE_MATCH_AUTO_H\n"
>                             "#define GCC_GIMPLE_MATCH_AUTO_H\n");
>        write_header_includes (gimple, header_file);
> +      write_header_declarations (gimple, header_file);
>      }
>
>    /* Go over all predicates defined with patterns and perform
> @@ -5502,6 +5559,8 @@ main (int argc, char **argv)
>
>    dt.gen (parts, gimple);
>
> +  define_dump_logs (gimple, choose_output (parts));
> +
>    for (FILE *f : parts)
>      {
>        fprintf (f, "#pragma GCC diagnostic pop\n");
> --
> 2.34.1
>

Reply via email to