diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-10-01 07:41:10 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-10-01 07:41:10 +0000 |
commit | f59ae127f3b98910e29c4b09abc9c330430f8d51 (patch) | |
tree | 4364870cc24e53f1deed7befaaf0e34bc35fad06 /gcc/tree-loop-distribution.c | |
parent | fc502d2f0103d453242454e6097e9d7ca3103e45 (diff) | |
download | gcc-f59ae127f3b98910e29c4b09abc9c330430f8d51.tar.gz |
2013-10-01 Richard Biener <rguenther@suse.de>
PR tree-optimization/58553
* tree-loop-distribution.c (struct partition_s): Add niter member.
(classify_partition): Populate niter member for the partition
and properly identify whether the relevant store happens before
or after the loop exit.
(generate_memset_builtin): Use niter member from the partition.
(generate_memcpy_builtin): Likewise.
* gcc.dg/torture/pr58553.c: New testcase.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@203054 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-loop-distribution.c')
-rw-r--r-- | gcc/tree-loop-distribution.c | 35 |
1 files changed, 19 insertions, 16 deletions
diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c index 964131a1950..fe2f7b65b59 100644 --- a/gcc/tree-loop-distribution.c +++ b/gcc/tree-loop-distribution.c @@ -569,6 +569,7 @@ typedef struct partition_s /* data-references a kind != PKIND_NORMAL partition is about. */ data_reference_p main_dr; data_reference_p secondary_dr; + tree niter; } *partition_t; @@ -848,21 +849,17 @@ generate_memset_builtin (struct loop *loop, partition_t partition) { gimple_stmt_iterator gsi; gimple stmt, fn_call; - tree nb_iter, mem, fn, nb_bytes; + tree mem, fn, nb_bytes; location_t loc; tree val; stmt = DR_STMT (partition->main_dr); loc = gimple_location (stmt); - if (gimple_bb (stmt) == loop->latch) - nb_iter = number_of_latch_executions (loop); - else - nb_iter = number_of_exit_cond_executions (loop); /* The new statements will be placed before LOOP. */ gsi = gsi_last_bb (loop_preheader_edge (loop)->src); - nb_bytes = build_size_arg_loc (loc, partition->main_dr, nb_iter); + nb_bytes = build_size_arg_loc (loc, partition->main_dr, partition->niter); nb_bytes = force_gimple_operand_gsi (&gsi, nb_bytes, true, NULL_TREE, false, GSI_CONTINUE_LINKING); mem = build_addr_arg_loc (loc, partition->main_dr, nb_bytes); @@ -908,21 +905,17 @@ generate_memcpy_builtin (struct loop *loop, partition_t partition) { gimple_stmt_iterator gsi; gimple stmt, fn_call; - tree nb_iter, dest, src, fn, nb_bytes; + tree dest, src, fn, nb_bytes; location_t loc; enum built_in_function kind; stmt = DR_STMT (partition->main_dr); loc = gimple_location (stmt); - if (gimple_bb (stmt) == loop->latch) - nb_iter = number_of_latch_executions (loop); - else - nb_iter = number_of_exit_cond_executions (loop); /* The new statements will be placed before LOOP. */ gsi = gsi_last_bb (loop_preheader_edge (loop)->src); - nb_bytes = build_size_arg_loc (loc, partition->main_dr, nb_iter); + nb_bytes = build_size_arg_loc (loc, partition->main_dr, partition->niter); nb_bytes = force_gimple_operand_gsi (&gsi, nb_bytes, true, NULL_TREE, false, GSI_CONTINUE_LINKING); dest = build_addr_arg_loc (loc, partition->main_dr, nb_bytes); @@ -1125,6 +1118,7 @@ classify_partition (loop_p loop, struct graph *rdg, partition_t partition) partition->kind = PKIND_NORMAL; partition->main_dr = NULL; partition->secondary_dr = NULL; + partition->niter = NULL_TREE; EXECUTE_IF_SET_IN_BITMAP (partition->stmts, 0, i, bi) { @@ -1151,10 +1145,6 @@ classify_partition (loop_p loop, struct graph *rdg, partition_t partition) || !flag_tree_loop_distribute_patterns) return; - nb_iter = number_of_exit_cond_executions (loop); - if (!nb_iter || nb_iter == chrec_dont_know) - return; - /* Detect memset and memcpy. */ single_load = NULL; single_store = NULL; @@ -1193,6 +1183,17 @@ classify_partition (loop_p loop, struct graph *rdg, partition_t partition) } } + if (!single_store) + return; + + if (!dominated_by_p (CDI_DOMINATORS, single_exit (loop)->src, + gimple_bb (DR_STMT (single_store)))) + nb_iter = number_of_latch_executions (loop); + else + nb_iter = number_of_exit_cond_executions (loop); + if (!nb_iter || nb_iter == chrec_dont_know) + return; + if (single_store && !single_load) { gimple stmt = DR_STMT (single_store); @@ -1212,6 +1213,7 @@ classify_partition (loop_p loop, struct graph *rdg, partition_t partition) return; partition->kind = PKIND_MEMSET; partition->main_dr = single_store; + partition->niter = nb_iter; } else if (single_store && single_load) { @@ -1268,6 +1270,7 @@ classify_partition (loop_p loop, struct graph *rdg, partition_t partition) partition->kind = PKIND_MEMCPY; partition->main_dr = single_store; partition->secondary_dr = single_load; + partition->niter = nb_iter; } } |