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: RTL loop optimizer - new target hook in doloop_valid_p


Hi,

Attached is a patch to define a new target hook to let the back end
decide which insns to accept within a low-overhead loop.

The function 'doloop_valid_p' checks for call and branch on table
instructions. The second check is already somewhat target specific, at
least the comment states so. The check for calls is not needed for S/390
and may be unnecessary for other targets as well. Therefore, it seems
useful to define a new target hook to do the whole testing.

The current behaviour is the default and moved to
'default_insn_valid_within_doloop'.  The hook 'hook_bool_rtx_true' is
added to provide an easy way to allow all insns. It may as well be
useful elsewhere.

The patch is bootstrapped and regtested on mainline for s390, s390x.
Given tests finish sucessfully on i686-pc-linux-gnu: 
Okay for mainline? Comments?

Bye,
Adrian


2005-05-12  Adrian Straetling  <straetling@de.ibm.com>

	* loop-doloop.c: Include "target.h". 
	  (doloop_valid_p): Move tests to function in targhooks.c.
	* target.h: (struct gcc_target): New target hook
	  "insn_valid_within_doloop".
	* target-def.h: Define default value for "insn_valid_within_doloop".
	  (TARGET_INITIALIZER): Insert new target hook into initializer.
	* targhooks.c: (default_insn_valid_within_doloop): New function.
	* targhooks.h: Declare "default_insn_valid_within_doloop".
	* hooks.c: (hook_bool_rtx_true): New function.
	* hooks.h: Declare "hook_bool_rtx_true".
	* doc/tm.texi: Add documentation for new target hook.


Index: gcc/loop-doloop.c
===================================================================
*** gcc/loop-doloop.c.orig	2005-05-17 13:58:37.000000000 +0200
--- gcc/loop-doloop.c	2005-05-18 11:05:45.531486453 +0200
*************** Software Foundation, 59 Temple Place - S
*** 33,38 ****
--- 33,39 ----
  #include "cfgloop.h"
  #include "output.h"
  #include "params.h"
+ #include "target.h"
  
  /* This module is used to modify loops with a determinable number of
     iterations to use special low-overhead looping instructions.
*************** doloop_valid_p (struct loop *loop, struc
*** 187,213 ****
  	   insn != NEXT_INSN (BB_END (bb));
  	   insn = NEXT_INSN (insn))
  	{
! 	  /* A called function may clobber any special registers required for
! 	     low-overhead looping.  */
! 	  if (CALL_P (insn))
! 	    {
! 	      if (dump_file)
! 		fprintf (dump_file, "Doloop: Function call in loop.\n");
  	      result = false;
  	      goto cleanup;
! 	    }
! 
! 	  /* Some targets (eg, PPC) use the count register for branch on table
! 	     instructions.  ??? This should be a target specific check.  */
! 	  if (JUMP_P (insn)
! 	      && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
! 		  || GET_CODE (PATTERN (insn)) == ADDR_VEC))
! 	    {
! 	      if (dump_file)
! 		fprintf (dump_file, "Doloop: Computed branch in the loop.\n");
! 	      result = false;
! 	      goto cleanup;
! 	    }
  	}
      }
    result = true;
--- 188,201 ----
  	   insn != NEXT_INSN (BB_END (bb));
  	   insn = NEXT_INSN (insn))
  	{
! 	  /* Different targets have different necessities for low-overhead
! 	     looping.  Call the back end for each instruction within the loop
! 	     to let it decide whether the insn is valid.  */
! 	  if (!targetm.insn_valid_within_doloop (insn))
! 	  {
  	      result = false;
  	      goto cleanup;
! 	  }
  	}
      }
    result = true;
Index: gcc/target.h
===================================================================
*** gcc/target.h.orig	2005-05-17 13:58:37.000000000 +0200
--- gcc/target.h	2005-05-17 15:53:41.000000000 +0200
*************** struct gcc_target
*** 520,525 ****
--- 520,528 ----
       to be checked for va_list references.  */
    bool (*stdarg_optimize_hook) (struct stdarg_info *ai, tree lhs, tree rhs);
  
+   /* Returns true if target supports the insn within a doloop block.  */
+   bool (*insn_valid_within_doloop) (rtx);
+     
    /* Functions relating to calls - argument passing, returns, etc.  */
    struct calls {
      bool (*promote_function_args) (tree fntype);
Index: gcc/target-def.h
===================================================================
*** gcc/target-def.h.orig	2005-05-17 13:58:37.000000000 +0200
--- gcc/target-def.h	2005-05-17 15:30:59.000000000 +0200
*************** Foundation, 59 Temple Place - Suite 330,
*** 137,142 ****
--- 137,146 ----
  #define TARGET_HAVE_NAMED_SECTIONS false
  #endif
  
+ #ifndef TARGET_INSN_VALID_WITHIN_DOLOOP
+ #define TARGET_INSN_VALID_WITHIN_DOLOOP default_insn_valid_within_doloop
+ #endif
+ 
  #ifndef TARGET_HAVE_TLS
  #define TARGET_HAVE_TLS false
  #endif
*************** Foundation, 59 Temple Place - Suite 330,
*** 553,558 ****
--- 557,563 ----
    TARGET_DWARF_CALLING_CONVENTION,              \
    TARGET_DWARF_HANDLE_FRAME_UNSPEC,		\
    TARGET_STDARG_OPTIMIZE_HOOK,			\
+   TARGET_INSN_VALID_WITHIN_DOLOOP,		\
    TARGET_CALLS,					\
    TARGET_CXX,					\
    TARGET_HAVE_NAMED_SECTIONS,			\
Index: gcc/targhooks.c
===================================================================
*** gcc/targhooks.c.orig	2005-03-12 01:34:04.000000000 +0100
--- gcc/targhooks.c	2005-05-18 11:03:46.021486453 +0200
*************** default_scalar_mode_supported_p (enum ma
*** 262,267 ****
--- 262,297 ----
      }
  }
  
+ /* TRUE if INSN insn is valid within a low-overhead loop.
+   
+    This function checks wheter a given INSN is valid within a low-overhead
+    loop.  A called function may clobber any special registers required for
+    low-overhead looping. Additionally, some targets (eg, PPC) use the count
+    register for branch on table instructions. We reject the doloop pattern in
+    these cases.  */
+ 
+ bool 
+ default_insn_valid_within_doloop (rtx insn)
+ {
+   if (CALL_P (insn))
+     {
+       if (dump_file)
+ 	fprintf (dump_file, "Doloop: Function call in loop.\n");
+ 	return false;
+     }
+   
+   if (JUMP_P (insn)
+       && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
+ 	  || GET_CODE (PATTERN (insn)) == ADDR_VEC))
+     {
+       if (dump_file)
+ 	fprintf (dump_file, "Doloop: Computed branch in the loop.\n");
+       return false;
+     }
+   
+   return true;
+ }
+ 
  bool
  hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false (
  	CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
Index: gcc/hooks.c
===================================================================
*** gcc/hooks.c.orig	2005-03-23 04:55:30.000000000 +0100
--- gcc/hooks.c	2005-05-17 15:23:59.000000000 +0200
*************** hook_bool_rtx_false (rtx a ATTRIBUTE_UNU
*** 192,197 ****
--- 192,203 ----
  }
  
  bool
+ hook_bool_rtx_true (rtx a ATTRIBUTE_UNUSED)
+ {
+   return true;
+ }
+ 
+ bool
  hook_bool_uintp_uintp_false (unsigned int *a ATTRIBUTE_UNUSED,
  			     unsigned int *b ATTRIBUTE_UNUSED)
  {
Index: gcc/hooks.h
===================================================================
*** gcc/hooks.h.orig	2005-03-23 04:55:30.000000000 +0100
--- gcc/hooks.h	2005-05-17 15:59:19.000000000 +0200
*************** extern bool hook_bool_tree_hwi_hwi_tree_
*** 35,40 ****
--- 35,41 ----
  extern bool hook_bool_tree_hwi_hwi_tree_true (tree, HOST_WIDE_INT, HOST_WIDE_INT,
  				       tree);
  extern bool hook_bool_rtx_false (rtx);
+ extern bool hook_bool_rtx_true (rtx);
  extern bool hook_bool_uintp_uintp_false (unsigned int *, unsigned int *);
  extern bool hook_bool_rtx_int_int_intp_false (rtx, int, int, int *);
  extern bool hook_bool_constcharptr_size_t_false (const char *, size_t);
Index: gcc/targhooks.h
===================================================================
*** gcc/targhooks.h.orig	2005-03-08 22:01:42.000000000 +0100
--- gcc/targhooks.h	2005-05-17 16:35:24.000000000 +0200
*************** extern void default_unwind_emit (FILE *,
*** 46,51 ****
--- 46,53 ----
  
  extern bool default_scalar_mode_supported_p (enum machine_mode);
  
+ extern bool default_insn_valid_within_doloop (rtx);
+ 
  /* These are here, and not in hooks.[ch], because not all users of
     hooks.h include tm.h, and thus we don't have CUMULATIVE_ARGS.  */
  
Index: gcc/doc/tm.texi
===================================================================
*** gcc/doc/tm.texi.orig	2005-05-04 18:27:21.000000000 +0200
--- gcc/doc/tm.texi	2005-05-17 19:22:15.000000000 +0200
*************** simplified expression for the call's res
*** 9511,9516 ****
--- 9511,9527 ----
  the value will be ignored.
  @end deftypefn
  
+ @deftypefn {Target Hook} bool TARGET_INSN_VALID_WITHIN_DOLOOP (rtx @var{insn})
+ 
+ Take an instruction in @var{insn} and return true if it is valid within a
+ low-overhead loop.
+ 
+ Many targets use special registers for low-overhead looping. This function
+ should return false for any instruction that clobbers these. 
+ By default, the RTL loop optimizer does not use a present doloop pattern for
+ loops containing function calls or brach on table instructions.  
+ @end deftypefn
+ 
  @defmac MD_CAN_REDIRECT_BRANCH (@var{branch1}, @var{branch2})
  
  Take a branch insn in @var{branch1} and another in @var{branch2}.


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