This applies some TLC to loop distribution mainly to make pattern
recognition more sane and not so costly.  This first patch revisits
the fix for PR45948 which turned out not effective later and
effectively fixed by another patch, too (see the ??? marker for
how that patch was overly conservative).  Thus this first patch
removes the original fix and re-instantiates a testcase that would
still ICE.  Conveniently it also removes a few callers of 
can_generate_builtin - which followups concentrate on.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2012-05-31  Richard Guenther  <rguent...@suse.de>

        * tree-loop-distribution.c (stmt_has_scalar_dependences_outside_loop):
        Use FOR_EACH_SSA_DEF_OPERAND.
        (generate_builtin): Adjust.
        (stmt_generated_in_another_partition): Remove.
        (add_scalar_computations_to_partition): Likewise.
        (rdg_build_partitions): Do not call
        add_scalar_computations_to_partition.

        * gcc.dg/tree-ssa/ldist-pr45948-2.c: New testcase copy of
        ldist-pr45948.c with disabled SCCP.

Index: gcc/tree-loop-distribution.c
===================================================================
*** gcc/tree-loop-distribution.c.orig   2012-05-31 14:51:19.000000000 +0200
--- gcc/tree-loop-distribution.c        2012-05-31 15:44:52.007545525 +0200
*************** ssa_name_has_uses_outside_loop_p (tree d
*** 80,111 ****
  }
  
  /* Returns true when STMT defines a scalar variable used after the
!    loop.  */
  
  static bool
! stmt_has_scalar_dependences_outside_loop (gimple stmt)
  {
!   tree name;
  
!   switch (gimple_code (stmt))
!     {
!     case GIMPLE_CALL:
!     case GIMPLE_ASSIGN:
!       name = gimple_get_lhs (stmt);
!       break;
! 
!     case GIMPLE_PHI:
!       name = gimple_phi_result (stmt);
!       break;
! 
!     default:
!       return false;
!     }
  
!   return (name
!         && TREE_CODE (name) == SSA_NAME
!         && ssa_name_has_uses_outside_loop_p (name,
!                                              loop_containing_stmt (stmt)));
  }
  
  /* Update the PHI nodes of NEW_LOOP.  NEW_LOOP is a duplicate of
--- 80,98 ----
  }
  
  /* Returns true when STMT defines a scalar variable used after the
!    loop LOOP.  */
  
  static bool
! stmt_has_scalar_dependences_outside_loop (loop_p loop, gimple stmt)
  {
!   def_operand_p def_p;
!   ssa_op_iter op_iter;
  
!   FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, op_iter, SSA_OP_DEF)
!     if (ssa_name_has_uses_outside_loop_p (DEF_FROM_PTR (def_p), loop))
!       return true;
  
!   return false;
  }
  
  /* Update the PHI nodes of NEW_LOOP.  NEW_LOOP is a duplicate of
*************** generate_builtin (struct loop *loop, bit
*** 382,390 ****
          if (!bitmap_bit_p (partition, x++))
            continue;
  
!         /* If the stmt has uses outside of the loop fail.  */
!         if (stmt_has_scalar_dependences_outside_loop (stmt))
!           goto end;
  
          if (is_gimple_assign (stmt)
              && !is_gimple_reg (gimple_assign_lhs (stmt)))
--- 369,384 ----
          if (!bitmap_bit_p (partition, x++))
            continue;
  
!         /* If the stmt has uses outside of the loop fail.
!            ???  If the stmt is generated in another partition that
!            is not created as builtin we can ignore this.  */
!         if (stmt_has_scalar_dependences_outside_loop (loop, stmt))
!           {
!             if (dump_file && (dump_flags & TDF_DETAILS))
!               fprintf (dump_file, "not generating builtin, partition has "
!                        "scalar uses outside of the loop\n");
!             goto end;
!           }
  
          if (is_gimple_assign (stmt)
              && !is_gimple_reg (gimple_assign_lhs (stmt)))
*************** fuse_partitions_with_similar_memory_acce
*** 879,938 ****
          }
  }
  
- /* Returns true when STMT will be code generated in a partition of RDG
-    different than PART and that will not be code generated as a
-    builtin.  */
- 
- static bool
- stmt_generated_in_another_partition (struct graph *rdg, gimple stmt, int part,
-                                    VEC (bitmap, heap) *partitions)
- {
-   int p;
-   bitmap pp;
-   unsigned i;
-   bitmap_iterator bi;
- 
-   FOR_EACH_VEC_ELT (bitmap, partitions, p, pp)
-     if (p != part
-       && !can_generate_builtin (rdg, pp))
-       EXECUTE_IF_SET_IN_BITMAP (pp, 0, i, bi)
-       if (stmt == RDG_STMT (rdg, i))
-         return true;
- 
-   return false;
- }
- 
- /* For each partition in PARTITIONS that will be code generated using
-    a builtin, add its scalar computations used after the loop to
-    PARTITION.  */
- 
- static void
- add_scalar_computations_to_partition (struct graph *rdg,
-                                     VEC (bitmap, heap) *partitions,
-                                     bitmap partition)
- {
-   int p;
-   bitmap pp;
-   unsigned i;
-   bitmap_iterator bi;
-   bitmap l = BITMAP_ALLOC (NULL);
-   bitmap pr = BITMAP_ALLOC (NULL);
-   bool f = false;
- 
-   FOR_EACH_VEC_ELT (bitmap, partitions, p, pp)
-     if (can_generate_builtin (rdg, pp))
-       EXECUTE_IF_SET_IN_BITMAP (pp, 0, i, bi)
-       if (stmt_has_scalar_dependences_outside_loop (RDG_STMT (rdg, i))
-           && !stmt_generated_in_another_partition (rdg, RDG_STMT (rdg, i), p,
-                                                    partitions))
-         rdg_flag_vertex_and_dependent (rdg, i, partition, l, pr, &f);
- 
-   rdg_flag_loop_exits (rdg, l, partition, pr, &f);
- 
-   BITMAP_FREE (pr);
-   BITMAP_FREE (l);
- }
- 
  /* Aggregate several components into a useful partition that is
     registered in the PARTITIONS vector.  Partitions will be
     distributed in different loops.  */
--- 873,878 ----
*************** rdg_build_partitions (struct graph *rdg,
*** 996,1003 ****
        free_rdg_components (comps);
      }
  
-   add_scalar_computations_to_partition (rdg, *partitions, partition);
- 
    /* If there is something left in the last partition, save it.  */
    if (bitmap_count_bits (partition) > 0)
      VEC_safe_push (bitmap, heap, *partitions, partition);
--- 936,941 ----
Index: gcc/testsuite/gcc.dg/tree-ssa/ldist-pr45948-2.c
===================================================================
*** /dev/null   1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.dg/tree-ssa/ldist-pr45948-2.c     2012-05-31 
15:45:51.650543465 +0200
***************
*** 0 ****
--- 1,17 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O2 -ftree-loop-distribution -fno-tree-scev-cprop" } */
+ 
+ extern void bar(int);
+ 
+ void
+ foo (int i, int n)
+ {
+   int a[30];
+   int b[30];
+   for (; i < n; i++)
+     a[i] = b[i] = 0;
+ 
+   while (1)
+     if (b[0])
+       bar (a[i - 1]);
+ }

Reply via email to