This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PR 32919 - value numbering versus computed goto


I think that Andrew Pinski's analysis of this bug is correct and that
the solution is not trying to value number the results of abnormal
PHIs.  Before PRE we have:

<bb 3>:
  f.0_4 = f;
  f.1_5 = f.0_4 + 1;
  f = f.1_5;
  spec_7(ab) = *f.1_5;
  goto ptr_3;

  # spec_28(ab) = PHI <spec_7(ab)(3)>
do_flag_plus:;
  read_int (&f);

Invalid sum of incoming frequencies 8999, should be 3333
  # spec_1 = PHI <spec_28(ab)(4), 120(11)>
do_number:;
  D.1636_9 = (int) spec_1;
  _itoa_word (D.1636_9);

After:

<bb 3>:
  f.0_4 = f;
  f.1_5 = f.0_4 + 1;
  f = f.1_5;
  spec_7(ab) = *f.1_5;
  goto ptr_3;

  # spec_28(ab) = PHI <spec_7(ab)(3)>
do_flag_plus:;
  read_int (&f);
  pretmp.28_11 = (int) spec_7(ab);

Invalid sum of incoming frequencies 8999, should be 3333
  # prephitmp.29_6 = PHI <pretmp.28_11(4), 120(11)>
  # spec_1 = PHI <spec_28(ab)(4), 120(11)>
do_number:;
  D.1636_9 = prephitmp.29_6;
  _itoa_word (D.1636_9);

Later on (loopinit) this turns into:

  # BLOCK 4 freq:3333
  # PRED: 3 [33.3%]  (ab,exec)
  # spec_29(ab) = PHI <spec_7(ab)(3)>
  # spec_28(ab) = PHI <spec_7(ab)(3)>
do_flag_plus:;
  read_int (&f);
  prephitmp.29_11 = (int) spec_29(ab);
  # SUCC: 5 [100.0%]  (fallthru,exec)


At this point the problem is pretty obvious.  spec_28 and spec_29 have
overlapping live ranges but both must be coalesced with spec_7.  I
think that we shouldn't be creating the prephitmp PHI along an
abnormal edge at all.  I don't think it's loopinit's fault; for
instance, if I disable the loop optimizers, VRP does the same thing.

Is this patch OK, assuming test results look good?  My PPC build
scripts build glibc during the build process, and thus hit the ICE, so
I do not have a baseline at the moment.  I'll have testsuite results
soon though.

-- 
Daniel Jacobowitz
CodeSourcery

2007-08-01  Daniel Jacobowitz  <dan@codesourcery.com>

	PR tree-optimization/32919
	* tree-ssa-sccvn.c (visit_phi): Do not visit abnormal PHIs.
	* tree-ssa-coalesce.c (ssa_conflicts_dump): New.
	(coalesce_ssa_name): Call it.

Index: tree-ssa-sccvn.c
===================================================================
--- tree-ssa-sccvn.c	(revision 127028)
+++ tree-ssa-sccvn.c	(working copy)
@@ -1259,6 +1259,9 @@ visit_phi (tree phi)
   bool allsame = true;
   int i;
 
+  if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi)))
+    return set_ssa_val_to (PHI_RESULT (phi), PHI_RESULT (phi));
+
   /* See if all non-TOP arguments have the same value.  TOP is
      equivalent to everything, so we can ignore it.  */
   for (i = 0; i < PHI_NUM_ARGS (phi); i++)
Index: tree-ssa-coalesce.c
===================================================================
--- tree-ssa-coalesce.c	(revision 127028)
+++ tree-ssa-coalesce.c	(working copy)
@@ -589,6 +589,24 @@ ssa_conflicts_merge (ssa_conflicts_p ptr
 }
 
 
+/* Dump a conflicts graph.  */
+
+static void
+ssa_conflicts_dump (FILE *file, ssa_conflicts_p ptr)
+{
+  unsigned x;
+
+  fprintf (file, "\nConflict graph:\n");
+
+  for (x = 0; x < ptr->size; x++)
+    if (ptr->conflicts[x])
+      {
+	fprintf (dump_file, "%d: ", x);
+	dump_bitmap (file, ptr->conflicts[x]);
+      }
+}
+
+
 /* This structure is used to efficiently record the current status of live 
    SSA_NAMES when building a conflict graph.  
    LIVE_BASE_VAR has a bit set for each base variable which has at least one
@@ -1302,6 +1320,8 @@ coalesce_ssa_name (void)
   /* Build a conflict graph.  */
   graph = build_ssa_conflict_graph (liveinfo);
   delete_tree_live_info (liveinfo);
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    ssa_conflicts_dump (dump_file, graph);
 
   sort_coalesce_list (cl);
 
Index: testsuite/gcc.c-torture/compile/pr32919.c
===================================================================
--- testsuite/gcc.c-torture/compile/pr32919.c	(revision 0)
+++ testsuite/gcc.c-torture/compile/pr32919.c	(revision 0)
@@ -0,0 +1,26 @@
+void _IO_vfprintf_internal ( char *f )
+{
+  static const void *const step0_jumps[] = { &&do_form_unknown, &&do_flag_plus, &&do_form_float };
+  const void * ptr = step0_jumps[0];
+  do {
+    char spec;
+    spec = (*++f);
+    goto *ptr;
+do_flag_plus:
+     read_int (&f);
+do_number:
+    _itoa_word (spec);
+do_form_float:
+    if (ptr != ((void *)0))
+    {
+      spec = 'x';
+      goto do_number;
+    }
+    if (spec != 'S')
+      __strnlen ();
+    return;
+    do_form_unknown:;
+  }
+  while (*f != '\0');
+}
+


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]