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]

sh-elf-4_1-branch: applied patch for warnings / unroll_max adjustment


2005-04-11  J"orn Rennecke <joern.rennecke@st.com>

	* sh.c (print_operand): Remove sh_rep_vec extraction.
	(sh_output_mi_thunk): Make i unsigned.


	* target.h (struct gcc_target): New member adjust_unroll_max.
	* target-def.h (TARGET_ADJUST_UNROLL_MAX): Define.
	(TARGET_INITIALIZER): Include TARGET_ADJUST_UNROLL_MAX.
	* loop-unroll.c (target.h): #include.
	(decide_unroll_constant_iterations, decide_unroll_runtime_iterations):
	Check / call targetm.adjust_unroll_max.
	(decide_unroll_stupid): Likewise.

	* sh.c (TARGET_ADJUST_UNROLL_MAX): Only redefine if already defined.
	(sh_adjust_unroll_max): Only define if TARGET_ADJUST_UNROLL_MAX
	is defined.  Update label detection code and iteration lookup,
	enable basic functionality, but without IV analysis.

Index: loop-unroll.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/loop-unroll.c,v
retrieving revision 1.29
diff -p -r1.29 loop-unroll.c
*** loop-unroll.c	1 Apr 2005 14:17:35 -0000	1.29
--- loop-unroll.c	11 Apr 2005 19:59:47 -0000
*************** Software Foundation, 59 Temple Place - S
*** 34,39 ****
--- 34,40 ----
  #include "hashtab.h"
  #include "recog.h"    
  #include "varray.h"                        
+ #include "target.h"
  
  /* This pass performs loop unrolling and peeling.  We only perform these
     optimizations on innermost loops (with single exception) because
*************** decide_unroll_constant_iterations (struc
*** 547,552 ****
--- 548,554 ----
  {
    unsigned nunroll, nunroll_by_av, best_copies, best_unroll = 0, n_copies, i;
    struct niter_desc *desc;
+   int max_unrolled_insns;
  
    if (!(flags & UAP_UNROLL))
      {
*************** decide_unroll_constant_iterations (struc
*** 559,567 ****
  	     "\n;; Considering unrolling loop with constant "
  	     "number of iterations\n");
  
    /* nunroll = total number of copies of the original loop body in
       unrolled loop (i.e. if it is 2, we have to duplicate loop body once.  */
!   nunroll = PARAM_VALUE (PARAM_MAX_UNROLLED_INSNS) / loop->ninsns;
    nunroll_by_av
      = PARAM_VALUE (PARAM_MAX_AVERAGE_UNROLLED_INSNS) / loop->av_ninsns;
    if (nunroll > nunroll_by_av)
--- 561,575 ----
  	     "\n;; Considering unrolling loop with constant "
  	     "number of iterations\n");
  
+   max_unrolled_insns = MAX_UNROLLED_INSNS;
+   if (targetm.adjust_unroll_max)
+     max_unrolled_insns
+       = (*targetm.adjust_unroll_max) (loop, loop->ninsns, max_unrolled_insns,
+ 				      flag_strength_reduce,
+ 				      LPT_UNROLL_CONSTANT);
    /* nunroll = total number of copies of the original loop body in
       unrolled loop (i.e. if it is 2, we have to duplicate loop body once.  */
!   nunroll = max_unrolled_insns / loop->ninsns;
    nunroll_by_av
      = PARAM_VALUE (PARAM_MAX_AVERAGE_UNROLLED_INSNS) / loop->av_ninsns;
    if (nunroll > nunroll_by_av)
*************** decide_unroll_runtime_iterations (struct
*** 816,821 ****
--- 824,830 ----
  {
    unsigned nunroll, nunroll_by_av, i;
    struct niter_desc *desc;
+   int max_unrolled_insns;
  
    if (!(flags & UAP_UNROLL))
      {
*************** decide_unroll_runtime_iterations (struct
*** 828,836 ****
  	     "\n;; Considering unrolling loop with runtime "
  	     "computable number of iterations\n");
  
    /* nunroll = total number of copies of the original loop body in
       unrolled loop (i.e. if it is 2, we have to duplicate loop body once.  */
!   nunroll = PARAM_VALUE (PARAM_MAX_UNROLLED_INSNS) / loop->ninsns;
    nunroll_by_av = PARAM_VALUE (PARAM_MAX_AVERAGE_UNROLLED_INSNS) / loop->av_ninsns;
    if (nunroll > nunroll_by_av)
      nunroll = nunroll_by_av;
--- 837,850 ----
  	     "\n;; Considering unrolling loop with runtime "
  	     "computable number of iterations\n");
  
+   max_unrolled_insns = MAX_UNROLLED_INSNS;
+   if (targetm.adjust_unroll_max)
+     max_unrolled_insns
+       = (*targetm.adjust_unroll_max) (loop, loop->ninsns, max_unrolled_insns,
+ 				      flag_strength_reduce, LPT_UNROLL_RUNTIME);
    /* nunroll = total number of copies of the original loop body in
       unrolled loop (i.e. if it is 2, we have to duplicate loop body once.  */
!   nunroll = max_unrolled_insns / loop->ninsns;
    nunroll_by_av = PARAM_VALUE (PARAM_MAX_AVERAGE_UNROLLED_INSNS) / loop->av_ninsns;
    if (nunroll > nunroll_by_av)
      nunroll = nunroll_by_av;
*************** decide_unroll_stupid (struct loop *loop,
*** 1291,1296 ****
--- 1305,1311 ----
  {
    unsigned nunroll, nunroll_by_av, i;
    struct niter_desc *desc;
+   int max_unrolled_insns;
  
    if (!(flags & UAP_UNROLL_ALL))
      {
*************** decide_unroll_stupid (struct loop *loop,
*** 1301,1309 ****
    if (dump_file)
      fprintf (dump_file, "\n;; Considering unrolling loop stupidly\n");
  
    /* nunroll = total number of copies of the original loop body in
       unrolled loop (i.e. if it is 2, we have to duplicate loop body once.  */
!   nunroll = PARAM_VALUE (PARAM_MAX_UNROLLED_INSNS) / loop->ninsns;
    nunroll_by_av
      = PARAM_VALUE (PARAM_MAX_AVERAGE_UNROLLED_INSNS) / loop->av_ninsns;
    if (nunroll > nunroll_by_av)
--- 1316,1329 ----
    if (dump_file)
      fprintf (dump_file, "\n;; Considering unrolling loop stupidly\n");
  
+   max_unrolled_insns = MAX_UNROLLED_INSNS;
+   if (targetm.adjust_unroll_max)
+     max_unrolled_insns
+       = (*targetm.adjust_unroll_max) (loop, loop->ninsns, max_unrolled_insns,
+ 				      flag_strength_reduce, LPT_UNROLL_STUPID);
    /* nunroll = total number of copies of the original loop body in
       unrolled loop (i.e. if it is 2, we have to duplicate loop body once.  */
!   nunroll = max_unrolled_insns / loop->ninsns;
    nunroll_by_av
      = PARAM_VALUE (PARAM_MAX_AVERAGE_UNROLLED_INSNS) / loop->av_ninsns;
    if (nunroll > nunroll_by_av)
Index: target-def.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target-def.h,v
retrieving revision 1.117
diff -p -r1.117 target-def.h
*** target-def.h	23 Mar 2005 03:55:30 -0000	1.117
--- target-def.h	11 Apr 2005 19:59:47 -0000
*************** Foundation, 59 Temple Place - Suite 330,
*** 375,380 ****
--- 375,382 ----
  #define TARGET_GET_PCH_VALIDITY default_get_pch_validity
  #define TARGET_PCH_VALID_P default_pch_valid_p
  
+ #define TARGET_ADJUST_UNROLL_MAX 0
+ 
  #define TARGET_DEFAULT_SHORT_ENUMS hook_bool_void_false
  
  #define TARGET_BUILTIN_SETJMP_FRAME_VALUE default_builtin_setjmp_frame_value
*************** Foundation, 59 Temple Place - Suite 330,
*** 533,538 ****
--- 535,541 ----
    TARGET_GIMPLIFY_VA_ARG_EXPR,			\
    TARGET_GET_PCH_VALIDITY,			\
    TARGET_PCH_VALID_P,				\
+   TARGET_ADJUST_UNROLL_MAX,			\
    TARGET_DEFAULT_SHORT_ENUMS,			\
    TARGET_BUILTIN_SETJMP_FRAME_VALUE,		\
    TARGET_MD_ASM_CLOBBERS,			\
Index: target.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target.h,v
retrieving revision 1.129
diff -p -r1.129 target.h
*** target.h	23 Mar 2005 03:55:30 -0000	1.129
--- target.h	11 Apr 2005 19:59:47 -0000
*************** Foundation, 59 Temple Place - Suite 330,
*** 50,55 ****
--- 50,57 ----
  #include "tm.h"
  #include "insn-modes.h"
  
+ struct loop;
+ 
  struct gcc_target
  {
    /* Functions that output assembler for the target.  */
*************** struct gcc_target
*** 477,482 ****
--- 479,486 ----
    void * (* get_pch_validity) (size_t *);
    const char * (* pch_valid_p) (const void *, size_t);
  
+   int (* adjust_unroll_max) (struct loop *, int, int, int, int);
+ 
    /* True if the compiler should give an enum type only as many
       bytes as it takes to represent the range of possible values of
       that type.  */
Index: config/sh/sh.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.c,v
retrieving revision 1.319.2.1
diff -p -r1.319.2.1 sh.c
*** config/sh/sh.c	8 Apr 2005 17:41:26 -0000	1.319.2.1
--- config/sh/sh.c	11 Apr 2005 20:17:31 -0000
*************** static int hard_regs_intersect_p (HARD_R
*** 482,489 ****
--- 482,491 ----
  
  #endif /* SYMBIAN */
  
+ #ifdef TARGET_ADJUST_UNROLL_MAX
  #undef TARGET_ADJUST_UNROLL_MAX
  #define TARGET_ADJUST_UNROLL_MAX sh_adjust_unroll_max
+ #endif
  
  struct gcc_target targetm = TARGET_INITIALIZER;
  
*************** print_operand (FILE *stream, rtx x, int 
*** 571,580 ****
    int regno;
    enum machine_mode mode;
  
-   if (x
-       && (GET_CODE (x) == PARALLEL || GET_CODE (x) == CONST_VECTOR)
-       && sh_rep_vec (x, GET_MODE (x)))
-     /* FIXME: What about a byte vector with two different bytes? */ abort (); // x = XVECEXP (x, 0, 0);
    switch (code)
      {
      case '.':
--- 573,578 ----
*************** sh_output_mi_thunk (FILE *file, tree thu
*** 10128,10134 ****
    int simple_add = CONST_OK_FOR_ADD (delta);
    int did_load = 0;
    rtx scratch0, scratch1, scratch2;
!   int i;
  
    reload_completed = 1;
    epilogue_completed = 1;
--- 10126,10132 ----
    int simple_add = CONST_OK_FOR_ADD (delta);
    int did_load = 0;
    rtx scratch0, scratch1, scratch2;
!   unsigned i;
  
    reload_completed = 1;
    epilogue_completed = 1;
*************** lose:
*** 10670,10692 ****
    return 0;
  }
  
  static int
  sh_adjust_unroll_max (struct loop * loop, int insn_count,
  		      int max_unrolled_insns, int strength_reduce_p,
  		      int unroll_type)
  {
  /* This doesn't work in 4.0 because the old unroller & loop.h  is gone.  */
- #if 0
    if (TARGET_ADJUST_UNROLL && TARGET_SHMEDIA)
      {
        /* Throttle back loop unrolling so that the costs of using more
  	 targets than the eight target register we have don't outweigh
  	 the benefits of unrolling.  */
!       rtx insn, end = loop->end;
        int n_labels = 0, n_calls = 0, n_exit_dest = 0, n_inner_loops = -1;
        int n_barriers = 0;
!       int i, j;
!       basic_block exit_dest[8];
        int threshold;
        int unroll_benefit = 0, mem_latency = 0;
        int base_cost, best_cost, cost;
--- 10668,10691 ----
    return 0;
  }
  
+ #ifdef TARGET_ADJUST_UNROLL_MAX
  static int
  sh_adjust_unroll_max (struct loop * loop, int insn_count,
  		      int max_unrolled_insns, int strength_reduce_p,
  		      int unroll_type)
  {
  /* This doesn't work in 4.0 because the old unroller & loop.h  is gone.  */
    if (TARGET_ADJUST_UNROLL && TARGET_SHMEDIA)
      {
        /* Throttle back loop unrolling so that the costs of using more
  	 targets than the eight target register we have don't outweigh
  	 the benefits of unrolling.  */
!       rtx insn;
        int n_labels = 0, n_calls = 0, n_exit_dest = 0, n_inner_loops = -1;
        int n_barriers = 0;
!       rtx dest;
!       int i;
!       rtx exit_dest[8];
        int threshold;
        int unroll_benefit = 0, mem_latency = 0;
        int base_cost, best_cost, cost;
*************** sh_adjust_unroll_max (struct loop * loop
*** 10695,10700 ****
--- 10694,10701 ----
        unsigned max_iterations = 32767;
        int n_iterations;
        int need_precond = 0, precond = 0;
+       basic_block * bbs = get_loop_body (loop);
+       struct niter_desc *desc;
  
        /* Assume that all labels inside the loop are used from inside the
  	 loop.  If the loop has multiple entry points, it is unlikely to
*************** sh_adjust_unroll_max (struct loop * loop
*** 10702,10708 ****
  	 Also assume that all calls are to different functions.  That is
  	 somewhat pessimistic, but if you have lots of calls, unrolling the
  	 loop is not likely to gain you much in the first place.  */
!       for (insn = loop->start; insn != end; insn = NEXT_INSN (insn))
  	{
  	  if (GET_CODE (insn) == CODE_LABEL)
  	    n_labels++;
--- 10703,10710 ----
  	 Also assume that all calls are to different functions.  That is
  	 somewhat pessimistic, but if you have lots of calls, unrolling the
  	 loop is not likely to gain you much in the first place.  */
!       i = loop->num_nodes - 1;
!       for (insn = BB_HEAD (bbs[i]); ; )
  	{
  	  if (GET_CODE (insn) == CODE_LABEL)
  	    n_labels++;
*************** sh_adjust_unroll_max (struct loop * loop
*** 10713,10732 ****
  	    n_inner_loops++;
  	  else if (GET_CODE (insn) == BARRIER)
  	    n_barriers++;
  	}
        /* One label for the loop top is normal, and it won't be duplicated by
  	 unrolling.  */
        if (n_labels <= 1)
  	return max_unrolled_insns;
!       if (n_inner_loops)
  	return 0;
!       for (i = loop->num_exits - 1; i >= 0 && n_exit_dest < 8; i--)
  	{
! 	  basic_block dest = loop->exit_edges[i]->dest;
! 
! 	  for (j = n_exit_dest - 1; j >= 0 && dest != exit_dest[j]; j--);
! 	  if (j >= 0)
! 	    exit_dest[j++] = dest;
  	}
        /* If the loop top and call and exit destinations are enough to fill up
  	 the target registers, we're unlikely to do any more damage by
--- 10715,10741 ----
  	    n_inner_loops++;
  	  else if (GET_CODE (insn) == BARRIER)
  	    n_barriers++;
+ 	  if (insn != BB_END (bbs[i]))
+ 	    insn = NEXT_INSN (insn);
+ 	  else if (--i >= 0)
+ 	    insn = BB_HEAD (bbs[i]);
+ 	   else
+ 	    break;
  	}
+       free (bbs);
        /* One label for the loop top is normal, and it won't be duplicated by
  	 unrolling.  */
        if (n_labels <= 1)
  	return max_unrolled_insns;
!       if (n_inner_loops > 0)
  	return 0;
!       for (dest = loop->exit_labels; dest && n_exit_dest < 8;
! 	   dest = LABEL_NEXTREF (dest))
  	{
! 	  for (i = n_exit_dest - 1;
! 	       i >= 0 && XEXP (dest, 0) != XEXP (exit_dest[i], 0); i--);
! 	  if (i < 0)
! 	    exit_dest[n_exit_dest++] = dest;
  	}
        /* If the loop top and call and exit destinations are enough to fill up
  	 the target registers, we're unlikely to do any more damage by
*************** sh_adjust_unroll_max (struct loop * loop
*** 10734,10742 ****
        if (n_calls + n_exit_dest >= 7)
  	return max_unrolled_insns;
  
        if (strength_reduce_p
! 	  && (unroll_type == UNROLL_MODULO
! 	      || unroll_type == UNROLL_COMPLETELY))
  	{
  	  struct loop_ivs *ivs = LOOP_IVS (loop);
  	  struct iv_class *bl;
--- 10743,10756 ----
        if (n_calls + n_exit_dest >= 7)
  	return max_unrolled_insns;
  
+       /* ??? In the new loop unroller, there is no longer any strength
+          reduction information available.  Thus, when it comes to unrolling,
+          we know the cost of everything, but we know the value of nothing.  */
+ #if 0
        if (strength_reduce_p
! 	  && (unroll_type == LPT_UNROLL_RUNTIME
! 	      || unroll_type == LPT_UNROLL_CONSTANT
! 	      || unroll_type == LPT_PEEL_COMPLETELY))
  	{
  	  struct loop_ivs *ivs = LOOP_IVS (loop);
  	  struct iv_class *bl;
*************** sh_adjust_unroll_max (struct loop * loop
*** 10794,10801 ****
  		}
  	    }
  	}
  
-       n_iterations = LOOP_INFO (loop)->n_iterations;
        if (! strength_reduce_p || ! n_iterations)
  	need_precond = 1;
        if (! n_iterations)
--- 10808,10823 ----
  		}
  	    }
  	}
+ #else /* 0 */
+       /* Assume there is at least some benefit.  */
+       unroll_benefit = 1;
+ #endif /* 0 */
+ 
+       desc = get_simple_loop_desc (loop);
+       n_iterations = desc->const_iter ? desc->niter : 0;
+       max_iterations
+ 	= max_iterations < desc->niter_max ? max_iterations : desc->niter_max;
  
        if (! strength_reduce_p || ! n_iterations)
  	need_precond = 1;
        if (! n_iterations)
*************** sh_adjust_unroll_max (struct loop * loop
*** 10805,10810 ****
--- 10827,10833 ----
  	  if (! n_iterations)
  	    return 0;
  	}
+ #if 0 /* ??? See above - missing induction variable information.  */
        while (unroll_benefit > 1) /* no loop */
  	{
  	  /* We include the benefit of biv/ giv updates.  Check if some or
*************** sh_adjust_unroll_max (struct loop * loop
*** 10868,10873 ****
--- 10891,10897 ----
  	    mem_latency = unroll_benefit - 1;
  	  break;
  	}
+ #endif /* 0 */
        if (n_labels + (unroll_benefit + n_labels * 8) / n_iterations
  	  <= unroll_benefit)
  	return max_unrolled_insns;
*************** sh_adjust_unroll_max (struct loop * loop
*** 10881,10892 ****
        for (factor = 2; factor <= 8; factor++)
  	{
  	  /* Bump up preconditioning cost for each power of two.  */
! 	  if (! (factor & factor-1))
  	    precond += 4;
  	  /* When preconditioning, only powers of two will be considered.  */
  	  else if (need_precond)
  	    continue;
! 	  n_dest = ((unroll_type != UNROLL_COMPLETELY)
  		    + (n_labels - 1) * factor + n_calls + n_exit_dest
  		    - (n_barriers * factor >> 1)
  		    + need_precond);
--- 10905,10916 ----
        for (factor = 2; factor <= 8; factor++)
  	{
  	  /* Bump up preconditioning cost for each power of two.  */
! 	  if (! (factor & (factor-1)))
  	    precond += 4;
  	  /* When preconditioning, only powers of two will be considered.  */
  	  else if (need_precond)
  	    continue;
! 	  n_dest = ((unroll_type != LPT_PEEL_COMPLETELY)
  		    + (n_labels - 1) * factor + n_calls + n_exit_dest
  		    - (n_barriers * factor >> 1)
  		    + need_precond);
*************** sh_adjust_unroll_max (struct loop * loop
*** 10894,10900 ****
  	    = ((n_dest <= 8 ? 0 : n_dest - 7)
  	       - base_cost * factor
  	       - ((factor > 2 ? unroll_benefit - mem_latency : unroll_benefit)
! 		  * (factor - (unroll_type != UNROLL_COMPLETELY)))
  	       + ((unroll_benefit + 1 + (n_labels - 1) * factor)
  		  / n_iterations));
  	  if (need_precond)
--- 10918,10924 ----
  	    = ((n_dest <= 8 ? 0 : n_dest - 7)
  	       - base_cost * factor
  	       - ((factor > 2 ? unroll_benefit - mem_latency : unroll_benefit)
! 		  * (factor - (unroll_type != LPT_PEEL_COMPLETELY)))
  	       + ((unroll_benefit + 1 + (n_labels - 1) * factor)
  		  / n_iterations));
  	  if (need_precond)
*************** sh_adjust_unroll_max (struct loop * loop
*** 10909,10917 ****
        if (max_unrolled_insns > threshold)
  	max_unrolled_insns = threshold;
      }
- #endif
    return max_unrolled_insns;
  }
  
  /* Replace any occurrence of FROM(n) in X with TO(n).  The function does
     not enter into CONST_DOUBLE for the replace.
--- 10933,10941 ----
        if (max_unrolled_insns > threshold)
  	max_unrolled_insns = threshold;
      }
    return max_unrolled_insns;
  }
+ #endif /* TARGET_ADJUST_UNROLL_MAX */
  
  /* Replace any occurrence of FROM(n) in X with TO(n).  The function does
     not enter into CONST_DOUBLE for the replace.
*************** replace_n_hard_rtx (rtx x, rtx *replacem
*** 10994,11000 ****
  	      if (to_regno < FIRST_PSEUDO_REGISTER)
  		{
  		  new_regno = regno + to_regno - from_regno;
! 		  if (HARD_REGNO_NREGS (new_regno, GET_MODE (x)) != nregs)
  		    return NULL_RTX;
  		  result = gen_rtx_REG (GET_MODE (x), new_regno);
  		}
--- 11018,11025 ----
  	      if (to_regno < FIRST_PSEUDO_REGISTER)
  		{
  		  new_regno = regno + to_regno - from_regno;
! 		  if ((unsigned) HARD_REGNO_NREGS (new_regno, GET_MODE (x))
! 		      != nregs)
  		    return NULL_RTX;
  		  result = gen_rtx_REG (GET_MODE (x), new_regno);
  		}

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