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]

Re: Patch to fix emit_library_call_value_1 for const functions


> On Tue, Apr 04, 2000 at 09:29:53PM +0200, Jan Hubicka wrote:
> > +   if (flags & (ECF_CONST | ECF_PURE | ECF_MALLOC))
> > +     start_sequence ();
> 
> I don't think you meant ECF_MALLOC here.
It is mostly meaningless (since ECF_MALLOC may not be set)
I only wanted to keep code in sync with expand_call. We use sequence
for malloc calls there to make them removable (I doubt it is usefull, but
we do that). It may be usefull for new operator.
> 
> > !   valreg = (mem_value == 0 && outmode != VOIDmode
> > !         ? hard_libcall_value (outmode) : NULL_RTX),
> ...
> > -            FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
> > +            valreg,
> 
> This is wrong.  FUNCTION_ARG with VOIDmode does magic target-specific
> stuff, and has nothing to do with hard_libcall_value.
Oops! I see, I've replaced wrong arg. Silly.
I wonder why this didn't show up in the regression tests.
> 
> > +       /* Construct an "equal form" for the value which mentions all the
> > + 	 arguments in order as well as the function name.  */
> > +       if (PUSH_ARGS_REVERSED)
> > + 	for (i = 0; i < nargs; i++)
> 
> There's no point ordering the list based on PUSH_ARGS_REVERSED.
> Although I see that expand_call does.  Though that's pointless too.
OK.

Here is updated patch.  Ok to install?


Tue Apr  4 20:49:01 MET DST 2000  Jan Hubicka  <jh@suse.cz>
	(expand_call): Do not reverze args in "equal from" field.
	(emit_library_call_value_1): Emit_libcall_block for const and pure
	function.
Index: egcs/gcc/calls.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/calls.c,v
retrieving revision 1.116
diff -c -3 -p -r1.116 calls.c
*** calls.c	2000/04/07 17:44:14	1.116
--- calls.c	2000/04/08 13:00:51
*************** expand_call (exp, target, ignore)
*** 2829,2840 ****
  
  	  /* Construct an "equal form" for the value which mentions all the
  	     arguments in order as well as the function name.  */
! 	  if (PUSH_ARGS_REVERSED)
! 	    for (i = 0; i < num_actuals; i++)
! 	      note = gen_rtx_EXPR_LIST (VOIDmode, args[i].initial_value, note);
! 	  else
! 	    for (i = num_actuals - 1; i >= 0; i--)
! 	      note = gen_rtx_EXPR_LIST (VOIDmode, args[i].initial_value, note);
  	  note = gen_rtx_EXPR_LIST (VOIDmode, funexp, note);
  
  	  insns = get_insns ();
--- 2829,2836 ----
  
  	  /* Construct an "equal form" for the value which mentions all the
  	     arguments in order as well as the function name.  */
! 	  for (i = 0; i < num_actuals; i++)
! 	    note = gen_rtx_EXPR_LIST (VOIDmode, args[i].initial_value, note);
  	  note = gen_rtx_EXPR_LIST (VOIDmode, funexp, note);
  
  	  insns = get_insns ();
*************** emit_library_call_value_1 (retval, orgfu
*** 3197,3202 ****
--- 3193,3199 ----
    int old_inhibit_defer_pop = inhibit_defer_pop;
    rtx call_fusage = 0;
    rtx mem_value = 0;
+   rtx valreg;
    int pcc_struct_value = 0;
    int struct_value_size = 0;
    int flags = 0;
*************** emit_library_call_value_1 (retval, orgfu
*** 3279,3284 ****
--- 3276,3286 ----
  
    count = 0;
  
+   /* Now we are about to start emitting insns that can be deleted
+      if a libcall is deleted.  */
+   if (flags & ECF_CONST)
+     start_sequence ();
+ 
    push_temp_slots ();
  
    /* If there's a structure value address to be passed,
*************** emit_library_call_value_1 (retval, orgfu
*** 3655,3666 ****
        NO_DEFER_POP;
      }
  
- #if 0
-   /* For version 1.37, try deleting this entirely.  */
-   if (! no_queue)
-     emit_queue ();
- #endif
- 
    /* Any regs containing parms remain in use through the call.  */
    for (count = 0; count < nargs; count++)
      {
--- 3657,3662 ----
*************** emit_library_call_value_1 (retval, orgfu
*** 3685,3691 ****
    /* Don't allow popping to be deferred, since then
       cse'ing of library calls could delete a call and leave the pop.  */
    NO_DEFER_POP;
! 
    /* We pass the old value of inhibit_defer_pop + 1 to emit_call_1, which
       will set inhibit_defer_pop to that value.  */
    /* The return type is needed to decide how many bytes the function pops.
--- 3681,3688 ----
    /* Don't allow popping to be deferred, since then
       cse'ing of library calls could delete a call and leave the pop.  */
    NO_DEFER_POP;
!   valreg = (mem_value == 0 && outmode != VOIDmode
! 	    ? hard_libcall_value (outmode) : NULL_RTX),
    /* We pass the old value of inhibit_defer_pop + 1 to emit_call_1, which
       will set inhibit_defer_pop to that value.  */
    /* The return type is needed to decide how many bytes the function pops.
*************** emit_library_call_value_1 (retval, orgfu
*** 3700,3711 ****
                 original_args_size.constant, args_size.constant,
  	       struct_value_size,
  	       FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
! 	       mem_value == 0 && outmode != VOIDmode ? hard_libcall_value (outmode) : NULL_RTX,
  	       old_inhibit_defer_pop + 1, call_fusage, flags);
  
    /* Now restore inhibit_defer_pop to its actual original value.  */
    OK_DEFER_POP;
  
    pop_temp_slots ();
  
    /* Copy the value to the right place.  */
--- 3697,3741 ----
                 original_args_size.constant, args_size.constant,
  	       struct_value_size,
  	       FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
! 	       valreg,
  	       old_inhibit_defer_pop + 1, call_fusage, flags);
  
    /* Now restore inhibit_defer_pop to its actual original value.  */
    OK_DEFER_POP;
  
+   /* If call is cse'able, make appropriate pair of reg-notes around it.
+      Test valreg so we don't crash; may safely ignore `const'
+      if return type is void.  Disable for PARALLEL return values, because
+      we have no way to move such values into a pseudo register.  */
+   if ((flags & ECF_CONST)
+       && valreg != 0 && GET_CODE (valreg) != PARALLEL)
+     {
+       rtx note = 0;
+       rtx temp = gen_reg_rtx (GET_MODE (valreg));
+       rtx insns;
+       int i;
+ 
+       /* Construct an "equal form" for the value which mentions all the
+ 	 arguments in order as well as the function name.  */
+       for (i = 0; i < nargs; i++)
+ 	note = gen_rtx_EXPR_LIST (VOIDmode, argvec[i].value, note);
+       note = gen_rtx_EXPR_LIST (VOIDmode, fun, note);
+ 
+       insns = get_insns ();
+       end_sequence ();
+ 
+       emit_libcall_block (insns, temp, valreg, note);
+ 
+       valreg = temp;
+     }
+   else if (flags & ECF_CONST)
+     {
+       /* Otherwise, just write out the sequence without a note.  */
+       rtx insns = get_insns ();
+ 
+       end_sequence ();
+       emit_insns (insns);
+     }
    pop_temp_slots ();
  
    /* Copy the value to the right place.  */

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