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]); + }