aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-loop-distribution.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2013-11-21 09:15:05 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2013-11-21 09:15:05 +0000
commitd995e887cb937a630aaf1fc9a78d4bd166f12a83 (patch)
tree1f8c0d81378b597d7ea98fdbd5f698eba2cccdf1 /gcc/tree-loop-distribution.c
parentd091cd30a1a183ecfbc3adcc28e4bfd9fb86aee0 (diff)
downloadgcc-d995e887cb937a630aaf1fc9a78d4bd166f12a83.zip
gcc-d995e887cb937a630aaf1fc9a78d4bd166f12a83.tar.gz
gcc-d995e887cb937a630aaf1fc9a78d4bd166f12a83.tar.bz2
re PR tree-optimization/59058 (wrong code at -O3 on x86_64-linux-gnu (affecting gcc 4.6 to trunk))
2013-11-21 Richard Biener <rguenther@suse.de> PR tree-optimization/59058 * tree-loop-distribution.c (struct partition_s): Add plus_one member. (build_size_arg_loc): Apply niter adjustment here. (generate_memset_builtin): Adjust. (generate_memcpy_builtin): Likewise. (classify_partition): Do not use number_of_exit_cond_executions but record whether niter needs to be adjusted. From-SVN: r205197
Diffstat (limited to 'gcc/tree-loop-distribution.c')
-rw-r--r--gcc/tree-loop-distribution.c33
1 files changed, 21 insertions, 12 deletions
diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c
index 0afa52a..b4ca211 100644
--- a/gcc/tree-loop-distribution.c
+++ b/gcc/tree-loop-distribution.c
@@ -480,6 +480,7 @@ typedef struct partition_s
data_reference_p main_dr;
data_reference_p secondary_dr;
tree niter;
+ bool plus_one;
} *partition_t;
@@ -703,13 +704,16 @@ generate_loops_for_partition (struct loop *loop, partition_t partition,
/* Build the size argument for a memory operation call. */
static tree
-build_size_arg_loc (location_t loc, data_reference_p dr, tree nb_iter)
+build_size_arg_loc (location_t loc, data_reference_p dr, tree nb_iter,
+ bool plus_one)
{
- tree size;
- size = fold_build2_loc (loc, MULT_EXPR, sizetype,
- fold_convert_loc (loc, sizetype, nb_iter),
+ tree size = fold_convert_loc (loc, sizetype, nb_iter);
+ if (plus_one)
+ size = size_binop (PLUS_EXPR, size, size_one_node);
+ size = fold_build2_loc (loc, MULT_EXPR, sizetype, size,
TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dr))));
- return fold_convert_loc (loc, size_type_node, size);
+ size = fold_convert_loc (loc, size_type_node, size);
+ return size;
}
/* Build an address argument for a memory operation call. */
@@ -781,7 +785,8 @@ generate_memset_builtin (struct loop *loop, partition_t partition)
/* 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, partition->niter);
+ nb_bytes = build_size_arg_loc (loc, partition->main_dr, partition->niter,
+ partition->plus_one);
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);
@@ -837,7 +842,8 @@ generate_memcpy_builtin (struct loop *loop, partition_t partition)
/* 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, partition->niter);
+ nb_bytes = build_size_arg_loc (loc, partition->main_dr, partition->niter,
+ partition->plus_one);
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);
@@ -980,11 +986,13 @@ classify_partition (loop_p loop, struct graph *rdg, partition_t partition)
tree nb_iter;
data_reference_p single_load, single_store;
bool volatiles_p = false;
+ bool plus_one = false;
partition->kind = PKIND_NORMAL;
partition->main_dr = NULL;
partition->secondary_dr = NULL;
partition->niter = NULL_TREE;
+ partition->plus_one = false;
EXECUTE_IF_SET_IN_BITMAP (partition->stmts, 0, i, bi)
{
@@ -1047,13 +1055,12 @@ 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);
+ nb_iter = number_of_latch_executions (loop);
if (!nb_iter || nb_iter == chrec_dont_know)
return;
+ if (dominated_by_p (CDI_DOMINATORS, single_exit (loop)->src,
+ gimple_bb (DR_STMT (single_store))))
+ plus_one = true;
if (single_store && !single_load)
{
@@ -1075,6 +1082,7 @@ classify_partition (loop_p loop, struct graph *rdg, partition_t partition)
partition->kind = PKIND_MEMSET;
partition->main_dr = single_store;
partition->niter = nb_iter;
+ partition->plus_one = plus_one;
}
else if (single_store && single_load)
{
@@ -1132,6 +1140,7 @@ classify_partition (loop_p loop, struct graph *rdg, partition_t partition)
partition->main_dr = single_store;
partition->secondary_dr = single_load;
partition->niter = nb_iter;
+ partition->plus_one = plus_one;
}
}