diff options
author | Sebastian Pop <sebastian.pop@amd.com> | 2010-12-15 05:04:30 +0000 |
---|---|---|
committer | Sebastian Pop <spop@gcc.gnu.org> | 2010-12-15 05:04:30 +0000 |
commit | ab2210870b28990071af15a53ce817a3fc6d5af8 (patch) | |
tree | b6244af510098066a33efd97408230f217050a23 /gcc/tree-loop-distribution.c | |
parent | 56fb2b3625d4e32d019024e9c5f8a5d07e185f38 (diff) | |
download | gcc-ab2210870b28990071af15a53ce817a3fc6d5af8.zip gcc-ab2210870b28990071af15a53ce817a3fc6d5af8.tar.gz gcc-ab2210870b28990071af15a53ce817a3fc6d5af8.tar.bz2 |
Fix PR45948: add ssa defs from builtin partitions to the last partition.
2010-12-14 Sebastian Pop <sebastian.pop@amd.com>
PR tree-optimization/45948
* tree-loop-distribution.c (ssa_name_has_uses_outside_loop_p): New.
(stmt_has_scalar_dependences_outside_loop): New.
(stmt_generated_in_another_partition): New.
(add_scalar_computations_to_partition): New.
(rdg_build_partitions): Call add_scalar_computations_to_partition.
* gcc.dg/tree-ssa/ldist-pr45948.c: New.
From-SVN: r167842
Diffstat (limited to 'gcc/tree-loop-distribution.c')
-rw-r--r-- | gcc/tree-loop-distribution.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c index b603209..a9ee67f 100644 --- a/gcc/tree-loop-distribution.c +++ b/gcc/tree-loop-distribution.c @@ -808,6 +808,102 @@ fuse_partitions_with_similar_memory_accesses (struct graph *rdg, } } +/* Returns true when DEF is an SSA_NAME defined in LOOP and used after + the LOOP. */ + +static bool +ssa_name_has_uses_outside_loop_p (tree def, loop_p loop) +{ + imm_use_iterator imm_iter; + use_operand_p use_p; + + FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def) + if (loop != loop_containing_stmt (USE_STMT (use_p))) + return true; + + return false; +} + +/* 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_ASSIGN: + name = gimple_assign_lhs (stmt); + break; + + case GIMPLE_PHI: + name = gimple_phi_result (stmt); + break; + + default: + return false; + } + + return TREE_CODE (name) == SSA_NAME + && ssa_name_has_uses_outside_loop_p (name, loop_containing_stmt (stmt)); +} + +/* 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. */ @@ -871,6 +967,8 @@ rdg_build_partitions (struct graph *rdg, VEC (rdgc, heap) *components, 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); |