2012-12-10 Richard Biener <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 10 Dec 2012 14:00:25 +0000 (14:00 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 10 Dec 2012 14:00:25 +0000 (14:00 +0000)
PR tree-optimization/55107
* tree-ssa-pre.c (struct pre_stats): Remove constified field.
(bitmap_set_replace_value): Add gcc_unreachable.
(do_regular_insertion): Re-write all_same handling.  Insert
an assignment instead of a PHI in this case.
(eliminate_bb): Record availability also for SSA names defined
by a constant.
(do_pre): Do not record constified events.
(execute_fre): Likewise.

* gcc.dg/torture/pr55107.c: New testcase.
* gcc.dg/tree-ssa/ssa-pre-5.c: Adjust.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@194358 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr55107.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-5.c
gcc/tree-ssa-pre.c

index 9eefc51..00c7fef 100644 (file)
@@ -1,3 +1,15 @@
+2012-12-10  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/55107
+       * tree-ssa-pre.c (struct pre_stats): Remove constified field.
+       (bitmap_set_replace_value): Add gcc_unreachable.
+       (do_regular_insertion): Re-write all_same handling.  Insert
+       an assignment instead of a PHI in this case.
+       (eliminate_bb): Record availability also for SSA names defined
+       by a constant.
+       (do_pre): Do not record constified events.
+       (execute_fre): Likewise.
+
 2012-12-10  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
 
        * config/spu/spu.md: Replace "operands" with "operands != NULL" in
index 60d95ae..5ada4db 100644 (file)
@@ -1,3 +1,9 @@
+2012-12-10  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/55107
+       * gcc.dg/torture/pr55107.c: New testcase.
+       * gcc.dg/tree-ssa/ssa-pre-5.c: Adjust.
+
 2012-12-10  Jakub Jelinek  <jakub@redhat.com>
 
        * g++.dg/asan/asan_test.cc: Sync from upstream.
diff --git a/gcc/testsuite/gcc.dg/torture/pr55107.c b/gcc/testsuite/gcc.dg/torture/pr55107.c
new file mode 100644 (file)
index 0000000..2402716
--- /dev/null
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+
+typedef unsigned short uint16_t;
+
+uint16_t a, b;
+
+uint16_t f(void)
+{
+  int c, **p;
+  short d = 2, e = 4;
+
+  for (;; b++)
+    {
+      int *j, k = 0;
+
+      for (; *j; j++)
+       {
+         for(; c; c++)
+           for(; k < 1; k++)
+             {
+               short *f = &d;
+
+               if(b)
+                 return *f;
+             }
+       }
+
+      if(!c)
+       d *= e;
+
+      ((a = d) ? b = 0 : (**p ? : 1) != (d != 1 ? : (a = 0))) != (k ? a : 0)
+         < (a *= c = k) && (**p = 0);
+    }
+}
index 8756944..d0e985f 100644 (file)
@@ -12,5 +12,6 @@ foo (int i)
 }
 /* We should detect that a+b is the same along both edges, and replace it with
    5  */
-/* { dg-final { scan-tree-dump-times "Constified: 1" 1 "pre"} } */
+/* { dg-final { scan-tree-dump-times "Eliminated: 1" 1 "pre"} } */
+/* { dg-final { scan-tree-dump-times "Insertions" 0 "pre"} } */
 /* { dg-final { cleanup-tree-dump "pre" } } */
index 9cc795b..689d170 100644 (file)
@@ -446,10 +446,6 @@ static struct
 
   /* The number of new PHI nodes added by PRE.  */
   int phis;
-
-  /* The number of values found constant.  */
-  int constified;
-
 } pre_stats;
 
 static bool do_partial_partial;
@@ -867,6 +863,8 @@ bitmap_set_replace_value (bitmap_set_t set, unsigned int lookfor,
          return;
        }
     }
+
+  gcc_unreachable ();
 }
 
 /* Return true if two bitmap sets are equal.  */
@@ -3325,7 +3323,8 @@ do_regular_insertion (basic_block block, basic_block dom)
 
   FOR_EACH_VEC_ELT (exprs, i, expr)
     {
-      if (expr->kind != NAME)
+      if (expr->kind == NARY
+         || expr->kind == REFERENCE)
        {
          unsigned int val;
          bool by_some = false;
@@ -3435,35 +3434,28 @@ do_regular_insertion (basic_block block, basic_block dom)
          /* If all edges produce the same value and that value is
             an invariant, then the PHI has the same value on all
             edges.  Note this.  */
-         else if (!cant_insert && all_same && eprime
-                  && (edoubleprime->kind == CONSTANT
-                      || edoubleprime->kind == NAME)
-                  && !value_id_constant_p (val))
+         else if (!cant_insert && all_same)
            {
-             unsigned int j;
-             bitmap_iterator bi;
-             bitmap exprset = value_expressions[val];
-
-             unsigned int new_val = get_expr_value_id (edoubleprime);
-             EXECUTE_IF_SET_IN_BITMAP (exprset, 0, j, bi)
-               {
-                 pre_expr expr = expression_for_id (j);
-
-                 if (expr->kind == NAME)
-                   {
-                     vn_ssa_aux_t info = VN_INFO (PRE_EXPR_NAME (expr));
-                     /* Just reset the value id and valnum so it is
-                        the same as the constant we have discovered.  */
-                     if (edoubleprime->kind == CONSTANT)
-                       {
-                         info->valnum = PRE_EXPR_CONSTANT (edoubleprime);
-                         pre_stats.constified++;
-                       }
-                     else
-                       info->valnum = VN_INFO (PRE_EXPR_NAME (edoubleprime))->valnum;
-                     info->value_id = new_val;
-                   }
-               }
+             gcc_assert (edoubleprime->kind == CONSTANT
+                         || edoubleprime->kind == NAME);
+
+             tree temp = make_temp_ssa_name (get_expr_type (expr),
+                                             NULL, "pretmp");
+             gimple assign = gimple_build_assign (temp,
+                                                  edoubleprime->kind == CONSTANT ? PRE_EXPR_CONSTANT (edoubleprime) : PRE_EXPR_NAME (edoubleprime));
+             gimple_stmt_iterator gsi = gsi_after_labels (block);
+             gsi_insert_before (&gsi, assign, GSI_NEW_STMT);
+
+             gimple_set_plf (assign, NECESSARY, false);
+             VN_INFO_GET (temp)->value_id = val;
+             VN_INFO (temp)->valnum = sccvn_valnum_from_value_id (val);
+             if (VN_INFO (temp)->valnum == NULL_TREE)
+               VN_INFO (temp)->valnum = temp;
+             bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (temp));
+             pre_expr newe = get_or_alloc_expr_for_name (temp);
+             add_to_value (val, newe);
+             bitmap_value_replace_in_set (AVAIL_OUT (block), newe);
+             bitmap_insert_into_set (NEW_SETS (block), newe);
            }
        }
     }
@@ -3495,7 +3487,8 @@ do_partial_partial_insertion (basic_block block, basic_block dom)
 
   FOR_EACH_VEC_ELT (exprs, i, expr)
     {
-      if (expr->kind != NAME)
+      if (expr->kind == NARY
+         || expr->kind == REFERENCE)
        {
          unsigned int val;
          bool by_all = true;
@@ -4142,26 +4135,32 @@ eliminate_bb (dom_walk_data *, basic_block b)
 
       /* Lookup the RHS of the expression, see if we have an
         available computation for it.  If so, replace the RHS with
-        the available computation.
-
-        See PR43491.
-        We don't replace global register variable when it is a the RHS of
-        a single assign. We do replace local register variable since gcc
-        does not guarantee local variable will be allocated in register.  */
+        the available computation.  */
       if (gimple_has_lhs (stmt)
          && TREE_CODE (lhs) == SSA_NAME
-         && !gimple_assign_ssa_name_copy_p (stmt)
-         && (!gimple_assign_single_p (stmt)
-             || (!is_gimple_min_invariant (rhs)
-                 && (gimple_assign_rhs_code (stmt) != VAR_DECL
-                     || !is_global_var (rhs)
-                     || !DECL_HARD_REGISTER (rhs))))
          && !gimple_has_volatile_ops  (stmt))
        {
          tree sprime;
          gimple orig_stmt = stmt;
 
          sprime = eliminate_avail (lhs);
+         /* If there is no usable leader mark lhs as leader for its value.  */
+         if (!sprime)
+           eliminate_push_avail (lhs);
+
+         /* See PR43491.  Do not replace a global register variable when
+            it is a the RHS of an assignment.  Do replace local register
+            variables since gcc does not guarantee a local variable will
+            be allocated in register.
+            Do not perform copy propagation or undo constant propagation.  */
+         if (gimple_assign_single_p (stmt)
+             && (TREE_CODE (rhs) == SSA_NAME
+                 || is_gimple_min_invariant (rhs)
+                 || (TREE_CODE (rhs) == VAR_DECL
+                     && is_global_var (rhs)
+                     && DECL_HARD_REGISTER (rhs))))
+           continue;
+
          if (!sprime)
            {
              /* If there is no existing usable leader but SCCVN thinks
@@ -4208,10 +4207,6 @@ eliminate_bb (dom_walk_data *, basic_block b)
              continue;
            }
 
-         /* If there is no usable leader mark lhs as leader for its value.  */
-         if (!sprime)
-           eliminate_push_avail (lhs);
-
          if (sprime
              && sprime != lhs
              && (rhs == NULL_TREE
@@ -4742,7 +4737,6 @@ do_pre (void)
   statistics_counter_event (cfun, "PA inserted", pre_stats.pa_insert);
   statistics_counter_event (cfun, "New PHIs", pre_stats.phis);
   statistics_counter_event (cfun, "Eliminated", pre_stats.eliminations);
-  statistics_counter_event (cfun, "Constified", pre_stats.constified);
 
   clear_expression_ids ();
   remove_dead_inserted_code ();
@@ -4823,7 +4817,6 @@ execute_fre (void)
 
   statistics_counter_event (cfun, "Insertions", pre_stats.insertions);
   statistics_counter_event (cfun, "Eliminated", pre_stats.eliminations);
-  statistics_counter_event (cfun, "Constified", pre_stats.constified);
 
   return todo;
 }