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] Avoid reevaluations in expand_builtin_mathfn* (take 2)


This patch implements Richard Henderson's suggestions on my patch
to avoid re-evaluation of arguments in expand_builtin_mathfn and
expand_builtin_mathfn2.  As pointed out by RTH, it both simplifies
the code and fixes potential problems with volatile DECLs, if we always
just call save_expr on the arguments.  Then, in attempt to minimize
memory usage, the patch also checks whether the result is unchanged,
in which case we can avoid allocating new tree list nodes.

The following version has been tested on i686-pc-linux-gnu with a
full "make bootstrap", all languages except treelang, and regression
tested with a top-level "make -k check" with no new failures.

Ok for mainline?


2003-06-25  Roger Sayle  <roger@eyesopen.com>
	    Richard Henderson  <rth@redhat.com>

	* builtins.c (expand_builtin_mathfn): Always stabilize the argument
	list against re-evaluation.  If expand_unop fails, call expand_call
	with the stabilized argument list rather than return NULL_RTX.
	(expand_builtin_mathfn2): Likewise, always stabilize the argument
	list, and call expand_call ourselves if expand_binop fails.


Index: builtins.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/builtins.c,v
retrieving revision 1.220
diff -c -3 -p -r1.220 builtins.c
*** builtins.c	24 Jun 2003 02:20:09 -0000	1.220
--- builtins.c	25 Jun 2003 21:47:26 -0000
*************** expand_builtin_mathfn (tree exp, rtx tar
*** 1701,1707 ****
    tree arglist = TREE_OPERAND (exp, 1);
    enum machine_mode mode;
    bool errno_set = false;
!   tree arg;

    if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
      return 0;
--- 1701,1707 ----
    tree arglist = TREE_OPERAND (exp, 1);
    enum machine_mode mode;
    bool errno_set = false;
!   tree arg, narg;

    if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
      return 0;
*************** expand_builtin_mathfn (tree exp, rtx tar
*** 1771,1795 ****
    if (! flag_errno_math || ! HONOR_NANS (mode))
      errno_set = false;

!   /* Stabilize and compute the argument.  */
!   if (errno_set)
!     switch (TREE_CODE (arg))
!       {
!       case VAR_DECL:
!       case PARM_DECL:
!       case SAVE_EXPR:
!       case REAL_CST:
! 	break;
!
!       default:
! 	/* Wrap the computation of the argument in a SAVE_EXPR, as we
! 	   need to expand the argument again in expand_errno_check.  This
! 	   way, we will not perform side-effects more the once.  */
! 	arg = save_expr (arg);
! 	arglist = build_tree_list (NULL_TREE, arg);
! 	exp = build_function_call_expr (fndecl, arglist);
! 	break;
!       }

    op0 = expand_expr (arg, subtarget, VOIDmode, 0);

--- 1771,1785 ----
    if (! flag_errno_math || ! HONOR_NANS (mode))
      errno_set = false;

!   /* Wrap the computation of the argument in a SAVE_EXPR, as we may
!      need to expand the argument again.  This way, we will not perform
!      side-effects more the once.  */
!   narg = save_expr (arg);
!   if (narg != arg)
!     {
!       arglist = build_tree_list (NULL_TREE, arg);
!       exp = build_function_call_expr (fndecl, arglist);
!     }

    op0 = expand_expr (arg, subtarget, VOIDmode, 0);

*************** expand_builtin_mathfn (tree exp, rtx tar
*** 1800,1812 ****
       Set TARGET to wherever the result comes back.  */
    target = expand_unop (mode, builtin_optab, op0, target, 0);

!   /* If we were unable to expand via the builtin, stop the
!      sequence (without outputting the insns) and return 0, causing
!      a call to the library function.  */
    if (target == 0)
      {
        end_sequence ();
!       return 0;
      }

    if (errno_set)
--- 1790,1802 ----
       Set TARGET to wherever the result comes back.  */
    target = expand_unop (mode, builtin_optab, op0, target, 0);

!   /* If we were unable to expand via the builtin, stop the sequence
!      (without outputting the insns) and call to the library function
!      with the stabilized argument list.  */
    if (target == 0)
      {
        end_sequence ();
!       return expand_call (exp, target, target == const0_rtx);
      }

    if (errno_set)
*************** expand_builtin_mathfn_2 (tree exp, rtx t
*** 1834,1840 ****
    rtx op0, op1, insns;
    tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
    tree arglist = TREE_OPERAND (exp, 1);
!   tree arg0, arg1, temp;
    enum machine_mode mode;
    bool errno_set = true;
    bool stable = true;
--- 1824,1830 ----
    rtx op0, op1, insns;
    tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
    tree arglist = TREE_OPERAND (exp, 1);
!   tree arg0, arg1, temp, narg;
    enum machine_mode mode;
    bool errno_set = true;
    bool stable = true;
*************** expand_builtin_mathfn_2 (tree exp, rtx t
*** 1866,1910 ****
    if (! flag_errno_math || ! HONOR_NANS (mode))
      errno_set = false;

!   /* Stabilize the arguments.  */
!   if (errno_set)
      {
!       switch (TREE_CODE (arg1))
! 	{
! 	case VAR_DECL:
! 	case PARM_DECL:
! 	case SAVE_EXPR:
! 	case REAL_CST:
! 	  temp = TREE_CHAIN (arglist);
! 	  break;
!
! 	default:
! 	  stable = false;
! 	  arg1 = save_expr (arg1);
! 	  temp = build_tree_list (NULL_TREE, arg1);
! 	  break;
!         }
!
!       switch (TREE_CODE (arg0))
! 	{
! 	case VAR_DECL:
! 	case PARM_DECL:
! 	case SAVE_EXPR:
! 	case REAL_CST:
! 	  if (! stable)
! 	    arglist = tree_cons (NULL_TREE, arg0, temp);
! 	  break;
!
! 	default:
! 	  stable = false;
! 	  arg0 = save_expr (arg0);
! 	  arglist = tree_cons (NULL_TREE, arg0, temp);
! 	  break;
! 	}

!       if (! stable)
! 	exp = build_function_call_expr (fndecl, arglist);
      }

    op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
    op1 = expand_expr (arg1, 0, VOIDmode, 0);
--- 1856,1882 ----
    if (! flag_errno_math || ! HONOR_NANS (mode))
      errno_set = false;

!   /* Alway stabilize the argument list.  */
!   narg = save_expr (arg1);
!   if (narg != arg1)
      {
!       temp = build_tree_list (NULL_TREE, narg);
!       stable = false;
!     }
!   else
!     temp = TREE_CHAIN (arglist);

!   narg = save_expr (arg0);
!   if (narg != arg0)
!     {
!       arglist = tree_cons (NULL_TREE, narg, temp);
!       stable = false;
      }
+   else if (! stable)
+     arglist = tree_cons (NULL_TREE, arg0, temp);
+
+   if (! stable)
+     exp = build_function_call_expr (fndecl, arglist);

    op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
    op1 = expand_expr (arg1, 0, VOIDmode, 0);
*************** expand_builtin_mathfn_2 (tree exp, rtx t
*** 1917,1929 ****
    target = expand_binop (mode, builtin_optab, op0, op1,
  			 target, 0, OPTAB_DIRECT);

!   /* If we were unable to expand via the builtin, stop the
!      sequence (without outputting the insns) and return 0, causing
!      a call to the library function.  */
    if (target == 0)
      {
        end_sequence ();
!       return 0;
      }

    if (errno_set)
--- 1889,1901 ----
    target = expand_binop (mode, builtin_optab, op0, op1,
  			 target, 0, OPTAB_DIRECT);

!   /* If we were unable to expand via the builtin, stop the sequence
!      (without outputting the insns) and call to the library function
!      with the stabilized argument list.  */
    if (target == 0)
      {
        end_sequence ();
!       return expand_call (exp, target, target == const0_rtx);
      }

    if (errno_set)

Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833


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