diff options
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/tree-loop-distribution.c | 33 |
2 files changed, 32 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 03e590b..1cfbefef 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +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. + 2013-11-21 Eric Botcazou <ebotcazou@adacore.com> * tree-ssa-tail-merge.c (stmt_local_def): Return false if the statement 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; } } |