summaryrefslogtreecommitdiff
path: root/gcc/tree-loop-distribution.c
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2013-10-01 07:41:10 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2013-10-01 07:41:10 +0000
commitf59ae127f3b98910e29c4b09abc9c330430f8d51 (patch)
tree4364870cc24e53f1deed7befaaf0e34bc35fad06 /gcc/tree-loop-distribution.c
parentfc502d2f0103d453242454e6097e9d7ca3103e45 (diff)
downloadgcc-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.c35
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;
}
}