[PR86064] split single cross-partition range with nonzero locviews
authorAlexandre Oliva <aoliva@redhat.com>
Tue, 26 Jun 2018 05:44:26 +0000 (05:44 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Tue, 26 Jun 2018 05:44:26 +0000 (05:44 +0000)
We didn't split cross-partition ranges in loclists to output a
whole-function location expression, but with nonzero locviews, we
force loclists, and then we have to split to avoid cross-partition
list entries.

for  gcc/ChangeLog

PR debug/86064
* dwarf2out.c (loc_list_has_views): Adjust comments.
(dw_loc_list): Split single cross-partition range with
nonzero locview.

for  gcc/testsuite/ChangeLog

PR debug/86064
* gcc.dg/pr86064.c: New.

From-SVN: r262130

gcc/ChangeLog
gcc/dwarf2out.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr86064.c [new file with mode: 0644]

index b5f073d..d420310 100644 (file)
@@ -1,3 +1,10 @@
+2018-06-26  Alexandre Oliva <aoliva@redhat.com>
+
+       PR debug/86064
+       * dwarf2out.c (loc_list_has_views): Adjust comments.
+       (dw_loc_list): Split single cross-partition range with
+       nonzero locview.
+
 2018-06-25  Jeff Law  <law@redhat.com>
 
        * config/v850/predicates.md (const_float_1_operand): Fix match_code
index 8032364..b5e3134 100644 (file)
@@ -10029,7 +10029,15 @@ new_loc_list (dw_loc_descr_ref expr, const char *begin, var_loc_view vbegin,
   return retlist;
 }
 
-/* Return true iff there's any nonzero view number in the loc list.  */
+/* Return true iff there's any nonzero view number in the loc list.
+
+   ??? When views are not enabled, we'll often extend a single range
+   to the entire function, so that we emit a single location
+   expression rather than a location list.  With views, even with a
+   single range, we'll output a list if start or end have a nonzero
+   view.  If we change this, we may want to stop splitting a single
+   range in dw_loc_list just because of a nonzero view, even if it
+   straddles across hot/cold partitions.  */
 
 static bool
 loc_list_has_views (dw_loc_list_ref list)
@@ -17139,7 +17147,13 @@ dw_loc_list (var_loc_list *loc_list, tree decl, int want_address)
                 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)
+                 && (node != loc_list->first || loc_list->first->next
+                     /* If we are to emit a view number, we will emit
+                        a loclist rather than a single location
+                        expression for the entire function (see
+                        loc_list_has_views), so we have to split the
+                        range that straddles across partitions.  */
+                     || !ZERO_VIEW_P (node->view))
                  && current_function_decl)
                {
                  endname = cfun->fde->dw_fde_end;
index 5c0de04..5d5ed66 100644 (file)
@@ -1,3 +1,8 @@
+2018-06-26  Alexandre Oliva <aoliva@redhat.com>
+
+       PR debug/86064
+       * gcc.dg/pr86064.c: New.
+
 2018-06-25  Jeff Law  <law@redhat.com>
 
        * lib/target-supports.exp
diff --git a/gcc/testsuite/gcc.dg/pr86064.c b/gcc/testsuite/gcc.dg/pr86064.c
new file mode 100644 (file)
index 0000000..5be820c
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-g -O2 -fno-var-tracking-assignments -gsplit-dwarf" } */
+
+/* This used to fail with location views (implicitly) enabled, because
+   var-tracking (not at assignments) creates a range for d starting at
+   the load after the first call, and we did not split the range,
+   despite its crossing between hot and cold partitions, because it's
+   a single range, that we normally extend to the entire function.
+   However, because the range starts at a (presumed) nonzero view, we
+   end up outputting a loclist instead of a single location entry.
+   But then, -gsplit-dwarf selects (startx,length) loclist entries,
+   and the length ends up computing the difference between symbols in
+   different subsections.  */
+
+int a;
+__attribute__((__cold__)) void b();
+
+void e(int *);
+int f();
+
+void c() {
+  int d;
+  e(&d);
+  a = d;
+  if (f())
+    b();
+}