diff options
author | Richard Biener <rguenther@suse.de> | 2013-11-21 09:15:05 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2013-11-21 09:15:05 +0000 |
commit | d995e887cb937a630aaf1fc9a78d4bd166f12a83 (patch) | |
tree | 1f8c0d81378b597d7ea98fdbd5f698eba2cccdf1 /gcc/tree-loop-distribution.c | |
parent | d091cd30a1a183ecfbc3adcc28e4bfd9fb86aee0 (diff) | |
download | gcc-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.c | 33 |
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; } } |