sibcall vs function cse

Richard Henderson rth@redhat.com
Tue Jul 17 20:31:00 GMT 2001


Sibcalls are supposed to be direct only, since we don't really 
have a good way to control which register will be clobbered in
the process.  But if !NO_FUNCTION_CSE, we force the address into
a register.  Oops.

The fix being to stop prepare_call_address from being helpful here.

Originally tested on a part under nda; sanity checked on alpha
to see that the patch compiles in the fsf tree.


r~


        * calls.c (prepare_call_address): New parameter SIBCALLP.  If true,
        don't force the function address into a register.
        (expand_call, emit_library_call_value_1): Update callers.
        * builtins.c (expand_builtin_apply): Likewise.
        * expr.h (prepare_call_address): Update decl.

Index: builtins.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/builtins.c,v
retrieving revision 1.105
diff -c -p -d -r1.105 builtins.c
*** builtins.c	2001/07/11 20:35:51	1.105
--- builtins.c	2001/07/18 03:15:17
*************** expand_builtin_apply (function, argument
*** 1138,1144 ****
      }
  
    /* All arguments and registers used for the call are set up by now!  */
!   function = prepare_call_address (function, NULL_TREE, &call_fusage, 0);
  
    /* Ensure address is valid.  SYMBOL_REF is already valid, so no need,
       and we don't want to load it into a register as an optimization,
--- 1138,1144 ----
      }
  
    /* All arguments and registers used for the call are set up by now!  */
!   function = prepare_call_address (function, NULL_TREE, &call_fusage, 0, 0);
  
    /* Ensure address is valid.  SYMBOL_REF is already valid, so no need,
       and we don't want to load it into a register as an optimization,
Index: calls.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/calls.c,v
retrieving revision 1.187
diff -c -p -d -r1.187 calls.c
*** calls.c	2001/07/11 20:35:51	1.187
--- calls.c	2001/07/18 03:15:17
*************** calls_function_1 (exp, which)
*** 355,365 ****
     CALL_INSN_FUNCTION_USAGE information.  */
  
  rtx
! prepare_call_address (funexp, fndecl, call_fusage, reg_parm_seen)
       rtx funexp;
       tree fndecl;
       rtx *call_fusage;
       int reg_parm_seen;
  {
    rtx static_chain_value = 0;
  
--- 355,366 ----
     CALL_INSN_FUNCTION_USAGE information.  */
  
  rtx
! prepare_call_address (funexp, fndecl, call_fusage, reg_parm_seen, sibcallp)
       rtx funexp;
       tree fndecl;
       rtx *call_fusage;
       int reg_parm_seen;
+      int sibcallp;
  {
    rtx static_chain_value = 0;
  
*************** prepare_call_address (funexp, fndecl, ca
*** 377,383 ****
      funexp = ((SMALL_REGISTER_CLASSES && reg_parm_seen)
  	      ? force_not_mem (memory_address (FUNCTION_MODE, funexp))
  	      : memory_address (FUNCTION_MODE, funexp));
!   else
      {
  #ifndef NO_FUNCTION_CSE
        if (optimize && ! flag_no_function_cse)
--- 378,384 ----
      funexp = ((SMALL_REGISTER_CLASSES && reg_parm_seen)
  	      ? force_not_mem (memory_address (FUNCTION_MODE, funexp))
  	      : memory_address (FUNCTION_MODE, funexp));
!   else if (! sibcallp)
      {
  #ifndef NO_FUNCTION_CSE
        if (optimize && ! flag_no_function_cse)
*************** expand_call (exp, target, ignore)
*** 3038,3044 ****
  	}
  
        funexp = prepare_call_address (funexp, fndecl, &call_fusage,
! 				     reg_parm_seen);
  
        load_register_parameters (args, num_actuals, &call_fusage, flags);
  
--- 3039,3045 ----
  	}
  
        funexp = prepare_call_address (funexp, fndecl, &call_fusage,
! 				     reg_parm_seen, pass == 0);
  
        load_register_parameters (args, num_actuals, &call_fusage, flags);
  
*************** emit_library_call_value_1 (retval, orgfu
*** 4005,4011 ****
    else
      argnum = 0;
  
!   fun = prepare_call_address (fun, NULL_TREE, &call_fusage, 0);
  
    /* Now load any reg parms into their regs.  */
  
--- 4006,4012 ----
    else
      argnum = 0;
  
!   fun = prepare_call_address (fun, NULL_TREE, &call_fusage, 0, 0);
  
    /* Now load any reg parms into their regs.  */
  
Index: expr.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/expr.h,v
retrieving revision 1.85
diff -c -p -d -r1.85 expr.h
*** expr.h	2001/07/10 06:18:32	1.85
--- expr.h	2001/07/18 03:15:17
*************** extern rtx trampoline_address PARAMS ((t
*** 1112,1118 ****
     in its original home.  This becomes invalid if any more code is emitted.  */
  extern rtx hard_function_value PARAMS ((tree, tree, int));
  
! extern rtx prepare_call_address	PARAMS ((rtx, tree, rtx *, int));
  
  extern rtx expand_call PARAMS ((tree, rtx, int));
  
--- 1112,1118 ----
     in its original home.  This becomes invalid if any more code is emitted.  */
  extern rtx hard_function_value PARAMS ((tree, tree, int));
  
! extern rtx prepare_call_address	PARAMS ((rtx, tree, rtx *, int, int));
  
  extern rtx expand_call PARAMS ((tree, rtx, int));
  



More information about the Gcc-patches mailing list