This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][1/2] Fix PR59058


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  <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.

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;
      }
  }
  


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]