On April 25, 2019 11:13:34 AM GMT+02:00, Jakub Jelinek <ja...@redhat.com> wrote:
>Hi!
>
>The introduction of -gstatement-frontiers (and making it the default)
>regressed debug info experience on the attached testcases (not
>including
>in the testsuite, as not sure how to model that in the guality
>testsuite).
>The current behavior is that
>b test
>r
>n
>n
>n
>shows the first iteration and then executes the rest of the loop
>iteration
>in one go and breaks next time on __libc_start_main.
>
>The following patch fixes that by adding DEBUG_BEGIN_STMTs not just at
>the
>start of the loop, but also at the start of the incr-expr and
>cond-expr;
>the DWARF standard says that is_stmt 1 is a recommended breakpoint
>location,
>doesn't necessarily mean full statement, but also a part of it if it is
>a
>recommended breakpoint location there.  And the loop expressions
>clearly
>must be recommended breakpoint locations.
>
>The difference in *.gimple dumps on the 3 testcases is:
>--- pr90197-1.c.005t.gimple_   2019-04-25 10:55:55.087978371 +0200
>+++ pr90197-1.c.005t.gimple    2019-04-25 10:56:08.845759542 +0200
>@@ -7,23 +7,25 @@ test (unsigned int * dst, unsigned int b
> 
>     # DEBUG BEGIN_STMT
>     i = 0;
>     goto <D.1912>;
>     <D.1911>:
>     # DEBUG BEGIN_STMT
>     _1 = (long unsigned int) i;
>     _2 = _1 * 4;
>     _3 = dst + _2;
>     *_3 = base;
>+    # DEBUG BEGIN_STMT
>     i = i + 1;
>     base = base + 15;
>     <D.1912>:
>+    # DEBUG BEGIN_STMT
>     if (i < count) goto <D.1911>; else goto <D.1913>;
>     <D.1913>:
>   }
> }
> 
> 
> main ()
> {
>   int D.1919;
> 
>--- pr90197-2.c.005t.gimple_   2019-04-25 10:55:55.192976701 +0200
>+++ pr90197-2.c.005t.gimple    2019-04-25 10:56:08.925758270 +0200
>@@ -10,20 +10,21 @@ test (unsigned int * dst, unsigned int b
>   <D.1911>:
>   # DEBUG BEGIN_STMT
>   base = base + 15;
>   i.0_1 = i;
>   i = i.0_1 + 1;
>   _2 = (long unsigned int) i.0_1;
>   _3 = _2 * 4;
>   _4 = dst + _3;
>   *_4 = base;
>   <D.1912>:
>+  # DEBUG BEGIN_STMT
>   if (i < count) goto <D.1911>; else goto <D.1913>;
>   <D.1913>:
> }
> 
> 
> main ()
> {
>   int D.1919;
> 
>   {
>--- pr90197-3.c.005t.gimple_   2019-04-25 10:55:55.298975015 +0200
>+++ pr90197-3.c.005t.gimple    2019-04-25 10:56:09.000757077 +0200
>@@ -8,20 +8,21 @@ test (unsigned int * dst, unsigned int b
>   # DEBUG BEGIN_STMT
>   <D.1911>:
>   # DEBUG BEGIN_STMT
>   base = base + 15;
>   i.0_1 = i;
>   i = i.0_1 + 1;
>   _2 = (long unsigned int) i.0_1;
>   _3 = _2 * 4;
>   _4 = dst + _3;
>   *_4 = base;
>+  # DEBUG BEGIN_STMT
>   if (i < count) goto <D.1911>; else goto <D.1912>;
>   <D.1912>:
> }
> 
> 
> main ()
> {
>   int D.1918;
> 
>   {
>so it basically adds a DEBUG_BEGIN_STMT for the increment expression
>in for (if not empty) and for the condition in all kinds of loop (both
>if it
>is empty and if it is not).
>
>The assembly changes are:
>--- pr90197-1.s1       2019-04-25 11:09:54.749622921 +0200
>+++ pr90197-1.s2       2019-04-25 11:09:46.569753036 +0200
>@@ -13,6 +13,7 @@ test:
>       .loc 1 5 3
> .LBB2:
>       .loc 1 5 8
>+      .loc 1 5 19
>       .loc 1 5 3 is_stmt 0
>       testl   %edx, %edx
>       jle     .L1
>@@ -27,11 +28,13 @@ test:
>       .loc 1 6 5 is_stmt 1 discriminator 3
>       .loc 1 6 12 is_stmt 0 discriminator 3
>       movl    %esi, (%rdi)
>-      .loc 1 5 40 discriminator 3
>+      .loc 1 5 30 is_stmt 1 discriminator 3
>+      .loc 1 5 40 is_stmt 0 discriminator 3
>       addl    $15, %esi
> .LVL2:
>+      .loc 1 5 19 is_stmt 1 discriminator 3
>       addq    $4, %rdi
>-      .loc 1 5 3 discriminator 3
>+      .loc 1 5 3 is_stmt 0 discriminator 3
>       cmpl    %eax, %esi
>       jne     .L3
> .L1:
>--- pr90197-2.s1       2019-04-25 11:09:54.791622253 +0200
>+++ pr90197-2.s2       2019-04-25 11:09:46.611752367 +0200
>@@ -12,7 +12,7 @@ test:
> .LVL0:
>       .loc 1 5 3
>       .loc 1 6 3
>-      .loc 1 6 9 is_stmt 0
>+      .loc 1 6 9
>       testl   %edx, %edx
>       jle     .L1
>       movl    %edx, %eax
>@@ -23,18 +23,18 @@ test:
>       .p2align 4,,10
>       .p2align 3
> .L3:
>-      .loc 1 7 5 is_stmt 1
>+      .loc 1 7 5
>       .loc 1 7 22 is_stmt 0
>       addl    $15, %esi
> .LVL2:
>       addq    $4, %rdi
>       .loc 1 7 14
>       movl    %esi, -4(%rdi)
>-      .loc 1 6 9
>+      .loc 1 6 9 is_stmt 1
>       cmpl    %eax, %esi
>       jne     .L3
> .L1:
>-      .loc 1 8 1
>+      .loc 1 8 1 is_stmt 0
>       ret
>       .cfi_endproc
> .LFE0:
>--- pr90197-3.s1       2019-04-25 11:09:54.828621665 +0200
>+++ pr90197-3.s2       2019-04-25 11:09:46.647751794 +0200
>@@ -24,9 +24,10 @@ test:
> .LVL2:
>       .loc 1 7 14 discriminator 1
>       movl    %esi, (%rdi,%rax,4)
>+      .loc 1 8 9 is_stmt 1 discriminator 1
>       addq    $1, %rax
> .LVL3:
>-      .loc 1 8 3 discriminator 1
>+      .loc 1 8 3 is_stmt 0 discriminator 1
>       cmpl    %eax, %edx
>       jg      .L2
>       .loc 1 9 1
>
>Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

So if you put a breakpoint on the for line is the behavior after the patch now 
the same as before stmt frontiers if you do 'continue' repeatedly? 

Richard. 

>I'll work on a C++ FE version of this next (needed as well).
>
>2019-04-25  Jakub Jelinek  <ja...@redhat.com>
>
>       PR debug/90197
>       * c-tree.h (c_finish_loop): Add 2 further location_t arguments.
>       * c-parser.c (c_parser_while_statement): Adjust c_finish_loop caller.
>       (c_parser_do_statement): Likewise.
>       (c_parser_for_statement): Likewise.  Formatting fixes.
>       * c-typeck.c (c_finish_loop): Add COND_LOCUS and INCR_LOCUS arguments,
>       emit DEBUG_BEGIN_STMTs if needed.
>
>--- gcc/c/c-tree.h.jj  2019-04-08 10:11:26.942246707 +0200
>+++ gcc/c/c-tree.h     2019-04-24 13:35:02.313565354 +0200
>@@ -694,7 +694,8 @@ extern int c_types_compatible_p (tree, t
> extern tree c_begin_compound_stmt (bool);
> extern tree c_end_compound_stmt (location_t, tree, bool);
> extern void c_finish_if_stmt (location_t, tree, tree, tree);
>-extern void c_finish_loop (location_t, tree, tree, tree, tree, tree,
>bool);
>+extern void c_finish_loop (location_t, location_t, tree, location_t,
>tree,
>+                         tree, tree, tree, bool);
> extern tree c_begin_stmt_expr (void);
> extern tree c_finish_stmt_expr (location_t, tree);
> extern tree c_process_expr_stmt (location_t, tree);
>--- gcc/c/c-parser.c.jj        2019-03-14 23:44:26.876575932 +0100
>+++ gcc/c/c-parser.c   2019-04-24 13:43:05.136794313 +0200
>@@ -6001,7 +6001,8 @@ c_parser_while_statement (c_parser *pars
>   location_t loc_after_labels;
>   bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
> body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
>-  c_finish_loop (loc, cond, NULL, body, c_break_label, c_cont_label,
>true);
>+  c_finish_loop (loc, loc, cond, UNKNOWN_LOCATION, NULL, body,
>+               c_break_label, c_cont_label, true);
>   add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
>   c_parser_maybe_reclassify_token (parser);
> 
>@@ -6046,6 +6047,7 @@ c_parser_do_statement (c_parser *parser,
>   c_break_label = save_break;
>   new_cont = c_cont_label;
>   c_cont_label = save_cont;
>+  location_t cond_loc = c_parser_peek_token (parser)->location;
>   cond = c_parser_paren_condition (parser);
>   if (ivdep && cond != error_mark_node)
>     cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
>@@ -6059,7 +6061,8 @@ c_parser_do_statement (c_parser *parser,
>                  build_int_cst (integer_type_node, unroll));
>   if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
>     c_parser_skip_to_end_of_block_or_statement (parser);
>-  c_finish_loop (loc, cond, NULL, body, new_break, new_cont, false);
>+  c_finish_loop (loc, cond_loc, cond, UNKNOWN_LOCATION, NULL, body,
>+               new_break, new_cont, false);
>   add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
> }
> 
>@@ -6132,7 +6135,9 @@ c_parser_for_statement (c_parser *parser
>   /* Silence the bogus uninitialized warning.  */
>   tree collection_expression = NULL;
>   location_t loc = c_parser_peek_token (parser)->location;
>-  location_t for_loc = c_parser_peek_token (parser)->location;
>+  location_t for_loc = loc;
>+  location_t cond_loc = UNKNOWN_LOCATION;
>+  location_t incr_loc = UNKNOWN_LOCATION;
>   bool is_foreach_statement = false;
>   gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
>   token_indent_info for_tinfo
>@@ -6166,7 +6171,8 @@ c_parser_for_statement (c_parser *parser
>             c_parser_consume_token (parser);
>             is_foreach_statement = true;
>             if (check_for_loop_decls (for_loc, true) == NULL_TREE)
>-              c_parser_error (parser, "multiple iterating variables in fast
>enumeration");
>+              c_parser_error (parser, "multiple iterating variables in "
>+                                      "fast enumeration");
>           }
>         else
>           check_for_loop_decls (for_loc, flag_isoc99);
>@@ -6196,7 +6202,8 @@ c_parser_for_statement (c_parser *parser
>                 c_parser_consume_token (parser);
>                 is_foreach_statement = true;
>                 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
>-                  c_parser_error (parser, "multiple iterating variables in 
>fast
>enumeration");
>+                  c_parser_error (parser, "multiple iterating variables in "
>+                                          "fast enumeration");
>               }
>             else
>               check_for_loop_decls (for_loc, flag_isoc99);
>@@ -6218,15 +6225,18 @@ c_parser_for_statement (c_parser *parser
>               c_parser_consume_token (parser);
>               is_foreach_statement = true;
>               if (! lvalue_p (init_expression))
>-                c_parser_error (parser, "invalid iterating variable in fast
>enumeration");
>-              object_expression = c_fully_fold (init_expression, false, NULL);
>+                c_parser_error (parser, "invalid iterating variable in "
>+                                        "fast enumeration");
>+              object_expression
>+                = c_fully_fold (init_expression, false, NULL);
>             }
>           else
>             {
>               ce = convert_lvalue_to_rvalue (loc, ce, true, false);
>               init_expression = ce.value;
>               c_finish_expr_stmt (loc, init_expression);
>-              c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected 
>%<;%>");
>+              c_parser_skip_until_found (parser, CPP_SEMICOLON,
>+                                         "expected %<;%>");
>             }
>         }
>       }
>@@ -6235,18 +6245,19 @@ c_parser_for_statement (c_parser *parser
>       gcc_assert (!parser->objc_could_be_foreach_context);
>       if (!is_foreach_statement)
>       {
>+        cond_loc = c_parser_peek_token (parser)->location;
>         if (c_parser_next_token_is (parser, CPP_SEMICOLON))
>           {
>             if (ivdep)
>               {
>-                c_parser_error (parser, "missing loop condition in loop with "
>-                                "%<GCC ivdep%> pragma");
>+                c_parser_error (parser, "missing loop condition in loop "
>+                                        "with %<GCC ivdep%> pragma");
>                 cond = error_mark_node;
>               }
>             else if (unroll)
>               {
>-                c_parser_error (parser, "missing loop condition in loop with "
>-                                "%<GCC unroll%> pragma");
>+                c_parser_error (parser, "missing loop condition in loop "
>+                                        "with %<GCC unroll%> pragma");
>                 cond = error_mark_node;
>               }
>             else
>@@ -6275,11 +6286,13 @@ c_parser_for_statement (c_parser *parser
>       /* Parse the increment expression (the third expression in a
>        for-statement).  In the case of a foreach-statement, this is
>        the expression that follows the 'in'.  */
>+      loc = incr_loc = c_parser_peek_token (parser)->location;
>       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
>       {
>         if (is_foreach_statement)
>           {
>-            c_parser_error (parser, "missing collection in fast
>enumeration");
>+            c_parser_error (parser,
>+                            "missing collection in fast enumeration");
>             collection_expression = error_mark_node;
>           }
>         else
>@@ -6288,8 +6301,8 @@ c_parser_for_statement (c_parser *parser
>       else
>       {
>         if (is_foreach_statement)
>-          collection_expression = c_fully_fold (c_parser_expression
>(parser).value,
>-                                                false, NULL);
>+          collection_expression
>+            = c_fully_fold (c_parser_expression (parser).value, false,
>NULL);
>         else
>           {
>             struct c_expr ce = c_parser_expression (parser);
>@@ -6312,10 +6325,14 @@ c_parser_for_statement (c_parser *parser
> body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
> 
>   if (is_foreach_statement)
>-    objc_finish_foreach_loop (loc, object_expression,
>collection_expression, body, c_break_label, c_cont_label);
>+    objc_finish_foreach_loop (for_loc, object_expression,
>+                            collection_expression, body, c_break_label,
>+                            c_cont_label);
>   else
>-    c_finish_loop (loc, cond, incr, body, c_break_label, c_cont_label,
>true);
>-  add_stmt (c_end_compound_stmt (loc, block, flag_isoc99 ||
>c_dialect_objc ()));
>+    c_finish_loop (for_loc, cond_loc, cond, incr_loc, incr, body,
>+                 c_break_label, c_cont_label, true);
>+  add_stmt (c_end_compound_stmt (for_loc, block,
>+                               flag_isoc99 || c_dialect_objc ()));
>   c_parser_maybe_reclassify_token (parser);
> 
>   token_indent_info next_tinfo
>--- gcc/c/c-typeck.c.jj        2019-04-19 13:54:36.543027196 +0200
>+++ gcc/c/c-typeck.c   2019-04-24 14:52:26.412862798 +0200
>@@ -10858,11 +10858,14 @@ c_finish_if_stmt (location_t if_locus, t
> the beginning of the loop.  COND is the loop condition.  COND_IS_FIRST
> is false for DO loops.  INCR is the FOR increment expression.  BODY is
>the statement controlled by the loop.  BLAB is the break label.  CLAB
>is
>-   the continue label.  Everything is allowed to be NULL.  */
>+   the continue label.  Everything is allowed to be NULL.
>+   COND_LOCUS is the location of the loop condition, INCR_LOCUS is the
>+   location of the FOR increment expression.  */
> 
> void
>-c_finish_loop (location_t start_locus, tree cond, tree incr, tree
>body,
>-             tree blab, tree clab, bool cond_is_first)
>+c_finish_loop (location_t start_locus, location_t cond_locus, tree
>cond,
>+             location_t incr_locus, tree incr, tree body, tree blab,
>+             tree clab, bool cond_is_first)
> {
>   tree entry = NULL, exit = NULL, t;
> 
>@@ -10904,12 +10907,8 @@ c_finish_loop (location_t start_locus, t
>           }
> 
>         t = build_and_jump (&blab);
>-        if (cond_is_first)
>-          exit = fold_build3_loc (start_locus,
>-                              COND_EXPR, void_type_node, cond, exit, t);
>-        else
>-          exit = fold_build3_loc (input_location,
>-                              COND_EXPR, void_type_node, cond, exit, t);
>+        exit = fold_build3_loc (cond_is_first ? start_locus :
>input_location,
>+                                COND_EXPR, void_type_node, cond, exit, t);
>       }
>       else
>       {
>@@ -10930,9 +10929,23 @@ c_finish_loop (location_t start_locus, t
>   if (clab)
>     add_stmt (build1 (LABEL_EXPR, void_type_node, clab));
>   if (incr)
>-    add_stmt (incr);
>+    {
>+      if (MAY_HAVE_DEBUG_MARKER_STMTS && incr_locus !=
>UNKNOWN_LOCATION)
>+      {
>+        t = build0 (DEBUG_BEGIN_STMT, void_type_node);
>+        SET_EXPR_LOCATION (t, incr_locus);
>+        add_stmt (t);
>+      }
>+      add_stmt (incr);
>+    }
>   if (entry)
>     add_stmt (entry);
>+  if (MAY_HAVE_DEBUG_MARKER_STMTS && cond_locus != UNKNOWN_LOCATION)
>+    {
>+      t = build0 (DEBUG_BEGIN_STMT, void_type_node);
>+      SET_EXPR_LOCATION (t, cond_locus);
>+      add_stmt (t);
>+    }
>   if (exit)
>     add_stmt (exit);
>   if (blab)
>
>       Jakub

Reply via email to