On Mon, Nov 20, 2017 at 02:58:22PM -0800, Jim Wilson wrote:
> On 11/19/2017 11:55 PM, Jakub Jelinek wrote:
> > I'd like to ping the following patches:
> > 
> >    http://gcc.gnu.org/ml/gcc-patches/2017-10/msg01895.html
> >    PR debug/82718
> >    Fix DWARF5 .debug_loclist handling with hot/cold partitioning
> 
> I already responded to this one.
> https://gcc.gnu.org/ml/gcc-patches/2017-11/msg01268.html

Sorry for missing that.

> The dwarf2out.c patch looks good to me, though the testcase does not fail on
> unpatched mainline anymore.  I had to go back to the 2017-10-22 snapshot to
> see the failure.  There was a followup from Mark Wielaard mentioning that
> elfutils still fails on mainline, so maybe we can get a testcase from there.

Committed both with the old and your new testcase after verifying your new
one still fails without the patch.

Thanks.

2017-11-21  Jakub Jelinek  <ja...@redhat.com>

        PR debug/82718
        * dwarf2out.c (dw_loc_list): If crtl->has_bb_partition, temporarily
        set in_cold_section_p to the partition containing loc_list->first.
        When seeing loc_list->last_before_switch node, update secname and
        perform range_across_switch second partition handling only after that.

        * gcc.dg/debug/dwarf2/pr82718-1.c: New test.
        * gcc.dg/debug/dwarf2/pr82718-2.c: New test.

--- gcc/dwarf2out.c.jj  2017-10-23 22:39:27.000000000 +0200
+++ gcc/dwarf2out.c     2017-10-25 21:01:13.237929750 +0200
@@ -16333,92 +16333,111 @@ dw_loc_list (var_loc_list *loc_list, tre
      This means we have to special case the last node, and generate
      a range of [last location start, end of function label].  */
 
-  secname = secname_for_decl (decl);
+  if (cfun && crtl->has_bb_partition)
+    {
+      bool save_in_cold_section_p = in_cold_section_p;
+      in_cold_section_p = first_function_block_is_cold;
+      if (loc_list->last_before_switch == NULL)
+       in_cold_section_p = !in_cold_section_p;
+      secname = secname_for_decl (decl);
+      in_cold_section_p = save_in_cold_section_p;
+    }
+  else
+    secname = secname_for_decl (decl);
 
   for (node = loc_list->first; node; node = node->next)
-    if (GET_CODE (node->loc) == EXPR_LIST
-       || NOTE_VAR_LOCATION_LOC (node->loc) != NULL_RTX)
-      {
-       if (GET_CODE (node->loc) == EXPR_LIST)
-         {
-           /* This requires DW_OP_{,bit_}piece, which is not usable
-              inside DWARF expressions.  */
-           if (want_address != 2)
-             continue;
+    {
+      bool range_across_switch = false;
+      if (GET_CODE (node->loc) == EXPR_LIST
+         || NOTE_VAR_LOCATION_LOC (node->loc) != NULL_RTX)
+       {
+         if (GET_CODE (node->loc) == EXPR_LIST)
+           {
+             descr = NULL;
+             /* This requires DW_OP_{,bit_}piece, which is not usable
+                inside DWARF expressions.  */
+             if (want_address == 2)
+               descr = dw_sra_loc_expr (decl, node->loc);
+           }
+         else
+           {
+             initialized = NOTE_VAR_LOCATION_STATUS (node->loc);
+             varloc = NOTE_VAR_LOCATION (node->loc);
+             descr = dw_loc_list_1 (decl, varloc, want_address, initialized);
+           }
+         if (descr)
+           {
+             /* If section switch happens in between node->label
+                and node->next->label (or end of function) and
+                we can't emit it as a single entry list,
+                emit two ranges, first one ending at the end
+                of first partition and second one starting at the
+                beginning of second partition.  */
+             if (node == loc_list->last_before_switch
+                 && (node != loc_list->first || loc_list->first->next)
+                 && current_function_decl)
+               {
+                 endname = cfun->fde->dw_fde_end;
+                 range_across_switch = true;
+               }
+             /* The variable has a location between NODE->LABEL and
+                NODE->NEXT->LABEL.  */
+             else if (node->next)
+               endname = node->next->label;
+             /* If the variable has a location at the last label
+                it keeps its location until the end of function.  */
+             else if (!current_function_decl)
+               endname = text_end_label;
+             else
+               {
+                 ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_END_LABEL,
+                                              current_function_funcdef_no);
+                 endname = ggc_strdup (label_id);
+               }
+
+             *listp = new_loc_list (descr, node->label, endname, secname);
+             if (TREE_CODE (decl) == PARM_DECL
+                 && node == loc_list->first
+                 && NOTE_P (node->loc)
+                 && strcmp (node->label, endname) == 0)
+               (*listp)->force = true;
+             listp = &(*listp)->dw_loc_next;
+           }
+       }
+
+      if (cfun
+         && crtl->has_bb_partition
+         && node == loc_list->last_before_switch)
+       {
+         bool save_in_cold_section_p = in_cold_section_p;
+         in_cold_section_p = !first_function_block_is_cold;
+         secname = secname_for_decl (decl);
+         in_cold_section_p = save_in_cold_section_p;
+       }
+
+      if (range_across_switch)
+       {
+         if (GET_CODE (node->loc) == EXPR_LIST)
            descr = dw_sra_loc_expr (decl, node->loc);
-           if (descr == NULL)
-             continue;
-         }
-       else
-         {
-           initialized = NOTE_VAR_LOCATION_STATUS (node->loc);
-           varloc = NOTE_VAR_LOCATION (node->loc);
-           descr = dw_loc_list_1 (decl, varloc, want_address, initialized);
-         }
-       if (descr)
-         {
-           bool range_across_switch = false;
-           /* If section switch happens in between node->label
-              and node->next->label (or end of function) and
-              we can't emit it as a single entry list,
-              emit two ranges, first one ending at the end
-              of first partition and second one starting at the
-              beginning of second partition.  */
-           if (node == loc_list->last_before_switch
-               && (node != loc_list->first || loc_list->first->next)
-               && current_function_decl)
-             {
-               endname = cfun->fde->dw_fde_end;
-               range_across_switch = true;
-             }
-           /* The variable has a location between NODE->LABEL and
-              NODE->NEXT->LABEL.  */
-           else if (node->next)
-             endname = node->next->label;
-           /* If the variable has a location at the last label
-              it keeps its location until the end of function.  */
-           else if (!current_function_decl)
-             endname = text_end_label;
-           else
-             {
-               ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_END_LABEL,
-                                            current_function_funcdef_no);
-               endname = ggc_strdup (label_id);
-             }
-
-           *listp = new_loc_list (descr, node->label, endname, secname);
-           if (TREE_CODE (decl) == PARM_DECL
-               && node == loc_list->first
-               && NOTE_P (node->loc)
-               && strcmp (node->label, endname) == 0)
-             (*listp)->force = true;
-           listp = &(*listp)->dw_loc_next;
-
-           if (range_across_switch)
-             {
-               if (GET_CODE (node->loc) == EXPR_LIST)
-                 descr = dw_sra_loc_expr (decl, node->loc);
-               else
-                 {
-                   initialized = NOTE_VAR_LOCATION_STATUS (node->loc);
-                   varloc = NOTE_VAR_LOCATION (node->loc);
-                   descr = dw_loc_list_1 (decl, varloc, want_address,
-                                          initialized);
-                 }
-               gcc_assert (descr);
-               /* The variable has a location between NODE->LABEL and
-                  NODE->NEXT->LABEL.  */
-               if (node->next)
-                 endname = node->next->label;
-               else
-                 endname = cfun->fde->dw_fde_second_end;
-               *listp = new_loc_list (descr,
-                                      cfun->fde->dw_fde_second_begin,
-                                      endname, secname);
-               listp = &(*listp)->dw_loc_next;
-             }
-         }
-      }
+         else
+           {
+             initialized = NOTE_VAR_LOCATION_STATUS (node->loc);
+             varloc = NOTE_VAR_LOCATION (node->loc);
+             descr = dw_loc_list_1 (decl, varloc, want_address,
+                                    initialized);
+           }
+         gcc_assert (descr);
+         /* The variable has a location between NODE->LABEL and
+            NODE->NEXT->LABEL.  */
+         if (node->next)
+           endname = node->next->label;
+         else
+           endname = cfun->fde->dw_fde_second_end;
+         *listp = new_loc_list (descr, cfun->fde->dw_fde_second_begin,
+                                endname, secname);
+         listp = &(*listp)->dw_loc_next;
+       }
+    }
 
   /* Try to avoid the overhead of a location list emitting a location
      expression instead, but only if we didn't have more than one
--- gcc/testsuite/gcc.dg/debug/dwarf2/pr82718-1.c.jj    2017-10-25 
21:10:53.324920386 +0200
+++ gcc/testsuite/gcc.dg/debug/dwarf2/pr82718-1.c       2017-10-25 
21:10:25.000000000 +0200
@@ -0,0 +1,41 @@
+/* PR debug/82718 */
+/* { dg-do assemble } */
+/* { dg-options "-O2 -gdwarf-5" } */
+
+extern int e;
+extern long foo (int, void *, unsigned long, unsigned long);
+struct S
+{
+  int f;
+  unsigned long t, s;
+};
+
+static inline long
+bv (int x, void *y, unsigned long z, unsigned long w)
+{
+  long a = 0;
+  do
+    {
+      long g;
+      do
+       g = (long int) (foo (x, y + a, z - a, w + a));
+      while (g == -1L && e == 9959);
+      if (g <= 0)
+       return g < 0 ? g : a;
+      a += g;
+    }
+  while ((unsigned long) a < z);
+  return a;
+}
+
+const char *
+baz (struct S *x)
+{
+  unsigned long h = 8;
+  char *j = 0;
+  unsigned long z = x->f;
+  if (__builtin_expect (!!((unsigned long) bv (x->f, j, z, x->t + h + 10) != 
z), 0))
+    return 0;
+  x->s = z;
+  return j;
+}
--- gcc/testsuite/gcc.dg/debug/dwarf2/pr82718-2.c.jj    2017-08-31 
21:08:14.436950781 +0200
+++ gcc/testsuite/gcc.dg/debug/dwarf2/pr82718-2.c       2017-11-21 
08:55:47.433967007 +0100
@@ -0,0 +1,12 @@
+/* PR debug/82718 */
+/* { dg-do assemble } */
+/* { dg-options "-O2 -gdwarf-5" } */
+
+extern int bar (void);
+
+int
+foo (int x)
+{
+  if (bar ())
+    __builtin_abort ();
+}


        Jakub

Reply via email to