This removes the use of the bogus number_of_exit_cond_executions
function from loop-distribution.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2013-11-21  Richard Biener  <rguent...@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.

Index: gcc/tree-loop-distribution.c
===================================================================
*** gcc/tree-loop-distribution.c        (revision 205118)
--- gcc/tree-loop-distribution.c        (working copy)
*************** typedef struct partition_s
*** 480,485 ****
--- 480,486 ----
    data_reference_p main_dr;
    data_reference_p secondary_dr;
    tree niter;
+   bool plus_one;
  } *partition_t;
  
  
*************** generate_loops_for_partition (struct loo
*** 703,715 ****
  /* 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)
  {
!   tree size;
!   size = fold_build2_loc (loc, MULT_EXPR, sizetype,
!                         fold_convert_loc (loc, sizetype, nb_iter),
                          TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dr))));
!   return fold_convert_loc (loc, size_type_node, size);
  }
  
  /* Build an address argument for a memory operation call.  */
--- 704,719 ----
  /* 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,
!                   bool plus_one)
  {
!   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))));
!   size = fold_convert_loc (loc, size_type_node, size);
!   return size;
  }
  
  /* Build an address argument for a memory operation call.  */
*************** generate_memset_builtin (struct loop *lo
*** 781,787 ****
    /* 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 = 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);
--- 785,792 ----
    /* 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,
!                                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);
*************** generate_memcpy_builtin (struct loop *lo
*** 837,843 ****
    /* 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 = 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);
--- 842,849 ----
    /* 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,
!                                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);
*************** classify_partition (loop_p loop, struct
*** 980,990 ****
--- 986,998 ----
    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)
      {
*************** classify_partition (loop_p loop, struct
*** 1047,1059 ****
    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)
      {
--- 1055,1066 ----
    if (!single_store)
      return;
  
!   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)
      {
*************** classify_partition (loop_p loop, struct
*** 1075,1080 ****
--- 1082,1088 ----
        partition->kind = PKIND_MEMSET;
        partition->main_dr = single_store;
        partition->niter = nb_iter;
+       partition->plus_one = plus_one;
      }
    else if (single_store && single_load)
      {
*************** classify_partition (loop_p loop, struct
*** 1132,1137 ****
--- 1140,1146 ----
        partition->main_dr = single_store;
        partition->secondary_dr = single_load;
        partition->niter = nb_iter;
+       partition->plus_one = plus_one;
      }
  }
  

Reply via email to