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]

apply_result_size (Was: Re: [patch RFC] SH: Use FRAME_GROWS_DOWNWARD)


Richard Henderson wrote:

On Thu, Jul 21, 2005 at 09:25:18PM +0100, Joern RENNECKE wrote:


* builtins.c (apply_result_size): Consider modes that span multiple
hard registers.



Ok.




Sorry, I have to withdraw this patch. (This was really meant more as a draft for testing than
an RFA at this stage). sh-elf, sh64-elf and i686 regtests failed. ppc-eabisim wouldn't
build with my baseline. While most ports are broken when it comes to returning values in
multiple hard registers, they still have partial functionality that allows to return values in a single
register, and objc can be built. With the approach in this patch, all ports would have to be fixed
at once. This is just not feasible. Moreover, sh-elf / sh64-elf still need special untyped_call and
untyped_return patterns, which have to tweak the modes back, so there is really no advanatge for
sh*-elf over using APPLY_RETURN_SIZE.


An alternative approach is to use a new target hook apply_result_mode to give the result mode for
a register number for with FUNCTION_VALUE_REGNO_P is true. This could default to the old
behaviour for a transitionary period, and when a sufficent number of ports is fixed, we can explicitly
use the backwards-compatibility hook in the stragglers, and use the safer algotithm from the previous
patch as the default.
Individual parts can also use their own specific definition to avoid excessive copying and register
pressure when there are modes that are valid in the return value register, but are larger than
any return value returned in registers, e.g. use CDI instead of V4DI for sh-elf R0_REG.
This would make it simpler to get a properly working __builtin_apply / __builtin_return,
but functionally it would be redundant with APPLY_RETURN_SIZE, combined with
definitions of untyped_call & untyped_return.


I'm currently bootstrapping the attached patch in i686-pc-linux-gnu. It shouldn't actually
change anything yet, but enables target-specific patches that make use of the new hook.




2005-07-22  J"orn Rennecke <joern.rennecke@st.com>

	* target.h (struct gcc_target): Add new member calls.apply_result_mode.
	* target-def.h (TARGET_APPLY_RESULT_MODE): Define.
	(TARGET_CALLS): Add TARGET_APPLY_RESULT_MODE.
	* targhooks.c (regs.h, hard-reg-set.h): Include.
	(apply_result_mode_1reg, apply_result_mode_scanreg): New functions.
	* targhooks.h (apply_result_mode_1reg): Declare.
	(apply_result_mode_scanreg): Likewise.
	* buitins.c (apply_result_size): Use targetm.apply_result_mode.
	* doc/tm.texi (TARGET_APPLY_RESULT_MODE): Document.

Index: builtins.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/builtins.c,v
retrieving revision 1.468
diff -p -r1.468 builtins.c
*** builtins.c	12 Jul 2005 09:19:59 -0000	1.468
--- builtins.c	22 Jul 2005 16:22:14 -0000
*************** apply_result_size (void)
*** 1119,1125 ****
        for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
  	if (FUNCTION_VALUE_REGNO_P (regno))
  	  {
! 	    mode = reg_raw_mode[regno];
  
  	    gcc_assert (mode != VOIDmode);
  
--- 1119,1125 ----
        for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
  	if (FUNCTION_VALUE_REGNO_P (regno))
  	  {
! 	    mode = targetm.calls.apply_result_mode (regno);
  
  	    gcc_assert (mode != VOIDmode);
  
Index: target-def.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target-def.h,v
retrieving revision 1.132
diff -p -r1.132 target-def.h
*** target-def.h	14 Jul 2005 07:39:54 -0000	1.132
--- target-def.h	22 Jul 2005 16:22:14 -0000
*************** Foundation, 51 Franklin Street, Fifth Fl
*** 439,444 ****
--- 439,445 ----
  #define TARGET_ARG_PARTIAL_BYTES hook_int_CUMULATIVE_ARGS_mode_tree_bool_0
  
  #define TARGET_FUNCTION_VALUE default_function_value
+ #define TARGET_APPLY_RESULT_MODE apply_result_mode_1reg
  
  #define TARGET_CALLS {						\
     TARGET_PROMOTE_FUNCTION_ARGS,				\
*************** Foundation, 51 Franklin Street, Fifth Fl
*** 457,463 ****
     TARGET_CALLEE_COPIES,					\
     TARGET_ARG_PARTIAL_BYTES,					\
     TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN,			\
!    TARGET_FUNCTION_VALUE					\
     }
  
  #ifndef TARGET_UNWIND_TABLES_DEFAULT
--- 458,465 ----
     TARGET_CALLEE_COPIES,					\
     TARGET_ARG_PARTIAL_BYTES,					\
     TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN,			\
!    TARGET_FUNCTION_VALUE,					\
!    TARGET_APPLY_RESULT_MODE					\
     }
  
  #ifndef TARGET_UNWIND_TABLES_DEFAULT
Index: target.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target.h,v
retrieving revision 1.144
diff -p -r1.144 target.h
*** target.h	14 Jul 2005 07:39:55 -0000	1.144
--- target.h	22 Jul 2005 16:22:14 -0000
*************** struct gcc_target
*** 608,613 ****
--- 608,617 ----
         specified by FN_DECL_OR_TYPE with a return type of RET_TYPE.  */
      rtx (*function_value) (tree ret_type, tree fn_decl_or_type,
  			   bool outgoing);
+ 
+     /* For a function value register, return a mode wide enough to copy
+        any function value that it might hold.  */
+     enum machine_mode (*apply_result_mode) (unsigned regno);
    } calls;
  
    /* Return the diagnostic message string if conversion from FROMTYPE
Index: targhooks.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/targhooks.c,v
retrieving revision 2.46
diff -p -r2.46 targhooks.c
*** targhooks.c	14 Jul 2005 07:39:55 -0000	2.46
--- targhooks.c	22 Jul 2005 16:22:14 -0000
*************** Software Foundation, 51 Franklin Street,
*** 62,67 ****
--- 62,69 ----
  #include "tm_p.h"
  #include "target-def.h"
  #include "ggc.h"
+ #include "regs.h"
+ #include "hard-reg-set.h"
  
  
  void
*************** default_function_value (tree ret_type AT
*** 439,442 ****
--- 441,479 ----
  #endif
  }
  
+ /* Implementation of the apply_result_mode which assumes that all
+    return values fit into a single hard register.
+    For the sake of backward compatibility, this his is currently the
+    default.  */
+ enum machine_mode
+ apply_result_mode_1reg (unsigned regno)
+ {
+   return reg_raw_mode[regno];
+ }
+ 
+ /* Implementation of the apply_result_mode which tries to compute
+    a mode for the largest number of hard registers that could
+    hold a return value.
+    At some point, this should become the default, when enough ports have
+    been changed to take advantage of the apply_result_mode hook.  */
+ enum machine_mode
+ apply_result_mode_scanreg (unsigned regno)
+ {
+   unsigned n;
+   enum machine_mode mode, wider_mode;
+ 
+   mode = reg_raw_mode[regno];
+   gcc_assert (mode != VOIDmode);
+ 
+   n = hard_regno_nregs[regno][mode];
+   while (regno + n < FIRST_PSEUDO_REGISTER && call_used_regs[regno + n])
+     {
+       n++;
+       wider_mode = choose_hard_reg_mode (regno, n, false);
+       if (wider_mode != VOIDmode)
+ 	mode = wider_mode;
+     }
+   return mode;
+ }
+ 
  #include "gt-targhooks.h"
Index: targhooks.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/targhooks.h,v
retrieving revision 2.33
diff -p -r2.33 targhooks.h
*** targhooks.h	14 Jul 2005 07:39:56 -0000	2.33
--- targhooks.h	22 Jul 2005 16:22:14 -0000
*************** extern const char *hook_invalid_arg_for_
*** 68,71 ****
--- 68,73 ----
    (tree, tree, tree);
  extern bool hook_bool_rtx_commutative_p (rtx, int);
  extern rtx default_function_value (tree, tree, bool);
+ extern enum machine_mode apply_result_mode_1reg (unsigned regno);
+ extern enum machine_mode apply_result_mode_scanreg (unsigned regno);
  
Index: doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.443
diff -p -r1.443 tm.texi
*** doc/tm.texi	21 Jul 2005 00:55:20 -0000	1.443
--- doc/tm.texi	22 Jul 2005 16:22:15 -0000
*************** The default version of this hook invokes
*** 4405,4410 ****
--- 4405,4432 ----
  normally defined in @file{libgcc2.c}.
  @end deftypefn
  
+ @deftypefn {Target Hook} enum machine_mode TARGET_APPLY_RESULT_MODE (unsigned @var{regno})
+ @var{regno} is a register number for which @code{FUNCTION_VALUE_REGNO_P}
+ is true.
+ This hook is supposed to return a mode wide enough to hold any value that
+ might be returned in this register.
+ Two stock implemetations are available in targhooks.c:
+ @itemize @bullet
+ @item
+ @code{apply_result_mode_1reg}: Use this implementation if no more than
+ one hard register is needed to return any value.  For backwards compatibility
+ reasons, this is currently the default.
+ @item
+ @code{apply_result_mode_scanreg}: This returns the/a largest mode that can
+ be held in the return value register.  This should generally give correct
+ code, but it could lead to register allocation problems if very wide modes
+ are allowed in a return value register according to HARD_REGNO_MODE_OK,
+ but may not actually be used at the point of function return (or not
+ in conjunction with all the other return value registers in their maximum
+ mode).
+ @end itemize
+ @end deftypefn
+ 
  @node Varargs
  @section Implementing the Varargs Macros
  @cindex varargs implementation

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