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]

[jh@suse.cz: Re: [tree-ssa] Make DOM1 pass to CSE pure functions]


Apparently this patch never found it's way to gcc-patches for some
reason.  It is quite important step to remove LIBCALL notes at least for
real function calls.

Honza

----- Forwarded message from Jan Hubicka <jh@suse.cz> -----

Delivered-To: hubicka@kam.mff.cuni.cz
X-Sieve: CMU Sieve 2.2
Date: Wed, 7 Jan 2004 20:08:59 +0100
From: Jan Hubicka <jh@suse.cz>
To: law@redhat.com
Cc: Jan Hubicka <jh@suse.cz>
Subject: Re: [tree-ssa] Make DOM1 pass to CSE pure functions
In-Reply-To: <200401070852.i078qui2024736@speedy.slc.redhat.com>
User-Agent: Mutt/1.3.28i
X-Spam-Status: No, hits=-8.1 required=5.0
	tests=BAYES_00,IN_REP_TO,PATCH_CONTEXT_DIFF,QUOTED_EMAIL_TEXT,
	      REFERENCES,REPLY_WITH_QUOTES,UPPERCASE_25_50,
	      USER_AGENT_MUTT
	autolearn=ham version=2.55
X-Spam-Level: 
X-Spam-Checker-Version: SpamAssassin 2.55 (1.174.2.19-2003-05-19-exp)

Hi,

> If you insist on making this kind of change, then I would strongly recommend

Yes, I need this to get rid of libcall notes that is quite important
goal for me.

> you leave the existing semantics of operands_equal_p unchanged in the
> default case and provide some means (either another function or a new
> argument) to get the behavior you want -- and of course clearly document
> that behavior.

here is alternative version of the patch that adds the argument.  I have
philosophical problem on whether I shall set the argument to false for
all callers even tough when I was asked on each individual of them I
would say that it is safe to set it to true.
This patch sets it all to true (I originally intended to use true only
for obivously safe cases where operands are from the same expression but
it has turned out that only calls failing this are those doing CSE in
DOM and PRE I am interested in changing and one in gimplify that is safe
too), but if it will make it easier to review, I will change all the
callers except the tree-ssa-dom into false.
Using false in most cases will lose few optimization posibilities but
they are not really important I would guess so I don't really care.

The patch is still testing, but since it is equivalent to previous only
in functionality, I expect it to pass.  OK if it passes?

/* { dg-do compile } */ 
/* { dg-options "-O2 -fdump-tree-dom1-details" } */
/* { dg-final { scan-tree-dump-times "Replaced redundant expr.*t (1)" 1 "dom1"} } */
int t(int a) __attribute__ ((pure));
int b;
int
q()
{
	int a = t(1);
	b=1;
	return t(1)+t(1)+a;
}
2004-01-06  Jan Hubicka  <jh@suse.cz>
	* builtins.c (expnad_builtin_memcpy, expand_builtin_memcmp
	expand_builtin_memmove, expand_builtin_strcmp, expand_builtin_strncmp,
	fold_builtin_memcpy, fold_builtin_mempcpy, fold_builtin_memmove,
	fold_builtin_strcpy, fold_builtin_memcmp, fold_builtin_strcmp,
	fold_builtin_strncmp): Update call of operand_eqal_p.
	* c-typeck.c (pointer_diff): Likewise.
	* expr.c (expand_operands, expand_expr_1): Likewise.
	* gimplify.c (gimple_tree_eq): Likewise.
	* tree-cfg.c (cfg_remove_useless_stmts_bb, phi_alternatives_equal):
	Likewise.
	* tree-ssa-dom.c (record_equivalences_from_phis, true_false_expr_eq,
	avail_expr_eq): Likewise.
	* tree-ssa-pre.c (names_match_p): Likewise.
	* tree-ssa.c (raise_value): Likewise.
	* fold-const.c (operand_equal_for_comparison_p, twoval_comparison_p,
	eval_subst, distribute_bit_expr, build_range_check, fold_range_test,
	fold_truthop, fold, fold_initializer, tree_expr_nonnegative_p,
	nondestructive_fold_binary_to_constant): Likewise.
	(operand_equal_p): Consider PURE functions equal
	if operands match.
	* tree.h (operand_equal_p): Update prototype.

	* jcf-write.c (generate_bytecode_insns): Likewise.
Index: builtins.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/builtins.c,v
retrieving revision 1.152.2.45
diff -c -3 -p -r1.152.2.45 builtins.c
*** builtins.c	6 Jan 2004 19:46:05 -0000	1.152.2.45
--- builtins.c	7 Jan 2004 18:52:50 -0000
*************** expand_builtin_memcpy (tree arglist, rtx
*** 2544,2550 ****
  	}
  
        /* If SRC and DEST are the same (and not volatile), return DEST.  */
!       if (operand_equal_p (src, dest, 0))
  	{
  	  /* Evaluate and ignore LEN in case it has side-effects.  */
  	  expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
--- 2544,2550 ----
  	}
  
        /* If SRC and DEST are the same (and not volatile), return DEST.  */
!       if (operand_equal_p (src, dest, 0, true))
  	{
  	  /* Evaluate and ignore LEN in case it has side-effects.  */
  	  expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
*************** expand_builtin_mempcpy (tree arglist, rt
*** 2636,2642 ****
  	return 0;
  
        /* If SRC and DEST are the same (and not volatile), do nothing.  */
!       if (operand_equal_p (src, dest, 0))
  	{
  	  tree expr;
  
--- 2636,2642 ----
  	return 0;
  
        /* If SRC and DEST are the same (and not volatile), do nothing.  */
!       if (operand_equal_p (src, dest, 0, true))
  	{
  	  tree expr;
  
*************** expand_builtin_memmove (tree arglist, rt
*** 2745,2751 ****
  	}
  
        /* If SRC and DEST are the same (and not volatile), return DEST.  */
!       if (operand_equal_p (src, dest, 0))
  	{
  	  /* Evaluate and ignore LEN in case it has side-effects.  */
  	  expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
--- 2745,2751 ----
  	}
  
        /* If SRC and DEST are the same (and not volatile), return DEST.  */
!       if (operand_equal_p (src, dest, 0, true))
  	{
  	  /* Evaluate and ignore LEN in case it has side-effects.  */
  	  expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
*************** expand_builtin_strcpy (tree arglist, rtx
*** 2818,2824 ****
    dst = TREE_VALUE (arglist);
  
    /* If SRC and DST are equal (and not volatile), return DST.  */
!   if (operand_equal_p (src, dst, 0))
      return expand_expr (dst, target, mode, EXPAND_NORMAL);
  
    fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
--- 2818,2824 ----
    dst = TREE_VALUE (arglist);
  
    /* If SRC and DST are equal (and not volatile), return DST.  */
!   if (operand_equal_p (src, dst, 0, true))
      return expand_expr (dst, target, mode, EXPAND_NORMAL);
  
    fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
*************** expand_builtin_memcmp (tree exp ATTRIBUT
*** 3170,3176 ****
      }
  
    /* If both arguments are equal (and not volatile), return zero.  */
!   if (operand_equal_p (arg1, arg2, 0))
      {
        /* Evaluate and ignore len in case it has side-effects.  */
        expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
--- 3170,3176 ----
      }
  
    /* If both arguments are equal (and not volatile), return zero.  */
!   if (operand_equal_p (arg1, arg2, 0, true))
      {
        /* Evaluate and ignore len in case it has side-effects.  */
        expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
*************** expand_builtin_strcmp (tree exp, rtx tar
*** 3307,3313 ****
    arg2 = TREE_VALUE (TREE_CHAIN (arglist));
  
    /* If both arguments are equal (and not volatile), return zero.  */
!   if (operand_equal_p (arg1, arg2, 0))
      return const0_rtx;
  
    p1 = c_getstr (arg1);
--- 3307,3313 ----
    arg2 = TREE_VALUE (TREE_CHAIN (arglist));
  
    /* If both arguments are equal (and not volatile), return zero.  */
!   if (operand_equal_p (arg1, arg2, 0, true))
      return const0_rtx;
  
    p1 = c_getstr (arg1);
*************** expand_builtin_strncmp (tree exp, rtx ta
*** 3464,3470 ****
      }
  
    /* If arg1 and arg2 are equal (and not volatile), return zero.  */
!   if (operand_equal_p (arg1, arg2, 0))
      {
        /* Evaluate and ignore arg3 in case it has side-effects.  */
        expand_expr (arg3, const0_rtx, VOIDmode, EXPAND_NORMAL);
--- 3464,3470 ----
      }
  
    /* If arg1 and arg2 are equal (and not volatile), return zero.  */
!   if (operand_equal_p (arg1, arg2, 0, true))
      {
        /* Evaluate and ignore arg3 in case it has side-effects.  */
        expand_expr (arg3, const0_rtx, VOIDmode, EXPAND_NORMAL);
*************** fold_builtin_memcpy (tree exp)
*** 6339,6345 ****
      return omit_one_operand (TREE_TYPE (exp), dest, src);
  
    /* If SRC and DEST are the same (and not volatile), return DEST.  */
!   if (operand_equal_p (src, dest, 0))
      return omit_one_operand (TREE_TYPE (exp), dest, len);
  
    return 0;
--- 6339,6345 ----
      return omit_one_operand (TREE_TYPE (exp), dest, src);
  
    /* If SRC and DEST are the same (and not volatile), return DEST.  */
!   if (operand_equal_p (src, dest, 0, true))
      return omit_one_operand (TREE_TYPE (exp), dest, len);
  
    return 0;
*************** fold_builtin_mempcpy (tree exp)
*** 6367,6373 ****
      return omit_one_operand (TREE_TYPE (exp), dest, src);
  
    /* If SRC and DEST are the same (and not volatile), return DEST+LEN.  */
!   if (operand_equal_p (src, dest, 0))
      {
        tree temp = convert (TREE_TYPE (dest), len);
        temp = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len));
--- 6367,6373 ----
      return omit_one_operand (TREE_TYPE (exp), dest, src);
  
    /* If SRC and DEST are the same (and not volatile), return DEST+LEN.  */
!   if (operand_equal_p (src, dest, 0, true))
      {
        tree temp = convert (TREE_TYPE (dest), len);
        temp = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len));
*************** fold_builtin_memmove (tree exp)
*** 6399,6405 ****
      return omit_one_operand (TREE_TYPE (exp), dest, src);
  
    /* If SRC and DEST are the same (and not volatile), return DEST.  */
!   if (operand_equal_p (src, dest, 0))
      return omit_one_operand (TREE_TYPE (exp), dest, len);
  
    return 0;
--- 6399,6405 ----
      return omit_one_operand (TREE_TYPE (exp), dest, src);
  
    /* If SRC and DEST are the same (and not volatile), return DEST.  */
!   if (operand_equal_p (src, dest, 0, true))
      return omit_one_operand (TREE_TYPE (exp), dest, len);
  
    return 0;
*************** fold_builtin_strcpy (tree exp)
*** 6422,6428 ****
    src = TREE_VALUE (TREE_CHAIN (arglist));
  
    /* If SRC and DEST are the same (and not volatile), return DEST.  */
!   if (operand_equal_p (src, dest, 0))
      return convert (TREE_TYPE (exp), dest);
  
    return 0;
--- 6422,6428 ----
    src = TREE_VALUE (TREE_CHAIN (arglist));
  
    /* If SRC and DEST are the same (and not volatile), return DEST.  */
!   if (operand_equal_p (src, dest, 0, true))
      return convert (TREE_TYPE (exp), dest);
  
    return 0;
*************** fold_builtin_memcmp (tree exp)
*** 6477,6483 ****
      }
  
    /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
!   if (operand_equal_p (arg1, arg2, 0))
      return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
  
    return 0;
--- 6477,6483 ----
      }
  
    /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
!   if (operand_equal_p (arg1, arg2, 0, true))
      return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
  
    return 0;
*************** fold_builtin_strcmp (tree exp)
*** 6501,6507 ****
    arg2 = TREE_VALUE (TREE_CHAIN (arglist));
  
    /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
!   if (operand_equal_p (arg1, arg2, 0))
      return convert (TREE_TYPE (exp), integer_zero_node);
  
    p1 = c_getstr (arg1);
--- 6501,6507 ----
    arg2 = TREE_VALUE (TREE_CHAIN (arglist));
  
    /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
!   if (operand_equal_p (arg1, arg2, 0, true))
      return convert (TREE_TYPE (exp), integer_zero_node);
  
    p1 = c_getstr (arg1);
*************** fold_builtin_strncmp (tree exp)
*** 6549,6555 ****
      }
  
    /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
!   if (operand_equal_p (arg1, arg2, 0))
      return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
  
    p1 = c_getstr (arg1);
--- 6549,6555 ----
      }
  
    /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
!   if (operand_equal_p (arg1, arg2, 0, true))
      return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
  
    p1 = c_getstr (arg1);
Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.196.2.36
diff -c -3 -p -r1.196.2.36 c-typeck.c
*** c-typeck.c	3 Jan 2004 23:01:37 -0000	1.196.2.36
--- c-typeck.c	7 Jan 2004 18:52:51 -0000
*************** pointer_diff (tree op0, tree op1)
*** 2119,2125 ****
    else
      lit1 = integer_zero_node;
  
!   if (operand_equal_p (con0, con1, 0))
      {
        op0 = lit0;
        op1 = lit1;
--- 2119,2125 ----
    else
      lit1 = integer_zero_node;
  
!   if (operand_equal_p (con0, con1, 0, true))
      {
        op0 = lit0;
        op1 = lit1;
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.467.2.72
diff -c -3 -p -r1.467.2.72 expr.c
*** expr.c	6 Jan 2004 22:52:04 -0000	1.467.2.72
--- expr.c	7 Jan 2004 18:52:51 -0000
*************** expand_operands (tree exp0, tree exp1, r
*** 6184,6190 ****
  {
    if (! safe_from_p (target, exp1, 1))
      target = 0;
!   if (operand_equal_p (exp0, exp1, 0))
      {
        *op0 = expand_expr (exp0, target, VOIDmode, modifier);
        *op1 = copy_rtx (*op0);
--- 6184,6190 ----
  {
    if (! safe_from_p (target, exp1, 1))
      target = 0;
!   if (operand_equal_p (exp0, exp1, 0, true))
      {
        *op0 = expand_expr (exp0, target, VOIDmode, modifier);
        *op1 = copy_rtx (*op0);
*************** expand_expr_1 (tree exp, rtx target, enu
*** 8445,8457 ****
  	  tree iffalse = TREE_OPERAND (TREE_OPERAND (exp, 2), 0);
  
  	  if ((TREE_CODE_CLASS (TREE_CODE (iftrue)) == '2'
! 	       && operand_equal_p (iffalse, TREE_OPERAND (iftrue, 0), 0))
  	      || (TREE_CODE_CLASS (TREE_CODE (iffalse)) == '2'
! 		  && operand_equal_p (iftrue, TREE_OPERAND (iffalse, 0), 0))
  	      || (TREE_CODE_CLASS (TREE_CODE (iftrue)) == '1'
! 		  && operand_equal_p (iffalse, TREE_OPERAND (iftrue, 0), 0))
  	      || (TREE_CODE_CLASS (TREE_CODE (iffalse)) == '1'
! 		  && operand_equal_p (iftrue, TREE_OPERAND (iffalse, 0), 0)))
  	    return expand_expr (build1 (NOP_EXPR, type,
  					build (COND_EXPR, TREE_TYPE (iftrue),
  					       TREE_OPERAND (exp, 0),
--- 8445,8460 ----
  	  tree iffalse = TREE_OPERAND (TREE_OPERAND (exp, 2), 0);
  
  	  if ((TREE_CODE_CLASS (TREE_CODE (iftrue)) == '2'
! 	       && operand_equal_p (iffalse, TREE_OPERAND (iftrue, 0), 0, true))
  	      || (TREE_CODE_CLASS (TREE_CODE (iffalse)) == '2'
! 		  && operand_equal_p (iftrue, TREE_OPERAND (iffalse, 0), 0,
! 			  	      true))
  	      || (TREE_CODE_CLASS (TREE_CODE (iftrue)) == '1'
! 		  && operand_equal_p (iffalse, TREE_OPERAND (iftrue, 0), 0,
! 			  	      true))
  	      || (TREE_CODE_CLASS (TREE_CODE (iffalse)) == '1'
! 		  && operand_equal_p (iftrue, TREE_OPERAND (iffalse, 0), 0,
! 			  	      true)))
  	    return expand_expr (build1 (NOP_EXPR, type,
  					build (COND_EXPR, TREE_TYPE (iftrue),
  					       TREE_OPERAND (exp, 0),
*************** expand_expr_1 (tree exp, rtx target, enu
*** 8504,8522 ****
  
  	if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 1))) == '2'
  	    && operand_equal_p (TREE_OPERAND (exp, 2),
! 				TREE_OPERAND (TREE_OPERAND (exp, 1), 0), 0))
  	  singleton = TREE_OPERAND (exp, 2), binary_op = TREE_OPERAND (exp, 1);
  	else if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 2))) == '2'
  		 && operand_equal_p (TREE_OPERAND (exp, 1),
! 				     TREE_OPERAND (TREE_OPERAND (exp, 2), 0), 0))
  	  singleton = TREE_OPERAND (exp, 1), binary_op = TREE_OPERAND (exp, 2);
  	else if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 1))) == '1'
  		 && operand_equal_p (TREE_OPERAND (exp, 2),
! 				     TREE_OPERAND (TREE_OPERAND (exp, 1), 0), 0))
  	  singleton = TREE_OPERAND (exp, 2), unary_op = TREE_OPERAND (exp, 1);
  	else if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 2))) == '1'
  		 && operand_equal_p (TREE_OPERAND (exp, 1),
! 				     TREE_OPERAND (TREE_OPERAND (exp, 2), 0), 0))
  	  singleton = TREE_OPERAND (exp, 1), unary_op = TREE_OPERAND (exp, 2);
  
  	/* If we are not to produce a result, we have no target.  Otherwise,
--- 8507,8529 ----
  
  	if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 1))) == '2'
  	    && operand_equal_p (TREE_OPERAND (exp, 2),
! 				TREE_OPERAND (TREE_OPERAND (exp, 1), 0), 0,
! 				true))
  	  singleton = TREE_OPERAND (exp, 2), binary_op = TREE_OPERAND (exp, 1);
  	else if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 2))) == '2'
  		 && operand_equal_p (TREE_OPERAND (exp, 1),
! 				     TREE_OPERAND (TREE_OPERAND (exp, 2), 0), 0,
! 				     true))
  	  singleton = TREE_OPERAND (exp, 1), binary_op = TREE_OPERAND (exp, 2);
  	else if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 1))) == '1'
  		 && operand_equal_p (TREE_OPERAND (exp, 2),
! 				     TREE_OPERAND (TREE_OPERAND (exp, 1), 0), 0,
! 				     true))
  	  singleton = TREE_OPERAND (exp, 2), unary_op = TREE_OPERAND (exp, 1);
  	else if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 2))) == '1'
  		 && operand_equal_p (TREE_OPERAND (exp, 1),
! 				     TREE_OPERAND (TREE_OPERAND (exp, 2), 0), 0,
! 				     true))
  	  singleton = TREE_OPERAND (exp, 1), unary_op = TREE_OPERAND (exp, 2);
  
  	/* If we are not to produce a result, we have no target.  Otherwise,
*************** expand_expr_1 (tree exp, rtx target, enu
*** 8650,8656 ****
  		 && TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 0))) == '<'
  		 && integer_zerop (TREE_OPERAND (TREE_OPERAND (exp, 0), 1))
  		 && operand_equal_p (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
! 				     TREE_OPERAND (exp, 1), 0)
  		 && (! TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 0))
  		     || TREE_CODE (TREE_OPERAND (exp, 1)) == SAVE_EXPR)
  		 && safe_from_p (temp, TREE_OPERAND (exp, 2), 1))
--- 8657,8663 ----
  		 && TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 0))) == '<'
  		 && integer_zerop (TREE_OPERAND (TREE_OPERAND (exp, 0), 1))
  		 && operand_equal_p (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
! 				     TREE_OPERAND (exp, 1), 0, true)
  		 && (! TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 0))
  		     || TREE_CODE (TREE_OPERAND (exp, 1)) == SAVE_EXPR)
  		 && safe_from_p (temp, TREE_OPERAND (exp, 2), 1))
*************** expand_expr_1 (tree exp, rtx target, enu
*** 8675,8681 ****
  		 && TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 0))) == '<'
  		 && integer_zerop (TREE_OPERAND (TREE_OPERAND (exp, 0), 1))
  		 && operand_equal_p (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
! 				     TREE_OPERAND (exp, 2), 0)
  		 && (! TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 0))
  		     || TREE_CODE (TREE_OPERAND (exp, 2)) == SAVE_EXPR)
  		 && safe_from_p (temp, TREE_OPERAND (exp, 1), 1))
--- 8682,8688 ----
  		 && TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 0))) == '<'
  		 && integer_zerop (TREE_OPERAND (TREE_OPERAND (exp, 0), 1))
  		 && operand_equal_p (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
! 				     TREE_OPERAND (exp, 2), 0, true)
  		 && (! TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 0))
  		     || TREE_CODE (TREE_OPERAND (exp, 2)) == SAVE_EXPR)
  		 && safe_from_p (temp, TREE_OPERAND (exp, 1), 1))
Index: gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/gimplify.c,v
retrieving revision 1.1.2.131
diff -c -3 -p -r1.1.2.131 gimplify.c
*** gimplify.c	6 Jan 2004 23:27:50 -0000	1.1.2.131
--- gimplify.c	7 Jan 2004 18:52:52 -0000
*************** gimple_tree_eq (const void *p1, const vo
*** 91,97 ****
        || TREE_TYPE (t1) != TREE_TYPE (t2))
      return 0;
  
!   if (!operand_equal_p (t1, t2, 0))
      return 0;
  
    /* Only allow them to compare equal if they also hash equal; otherwise
--- 91,97 ----
        || TREE_TYPE (t1) != TREE_TYPE (t2))
      return 0;
  
!   if (!operand_equal_p (t1, t2, 0, true))
      return 0;
  
    /* Only allow them to compare equal if they also hash equal; otherwise
Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v
retrieving revision 1.1.4.246
diff -c -3 -p -r1.1.4.246 tree-cfg.c
*** tree-cfg.c	6 Jan 2004 23:27:49 -0000	1.1.4.246
--- tree-cfg.c	7 Jan 2004 18:52:53 -0000
*************** cfg_remove_useless_stmts_bb (basic_block
*** 1295,1301 ****
  	 THEN/ELSE clause.  */
        if (TREE_CODE (stmt) == MODIFY_EXPR
  	  && TREE_OPERAND (stmt, 0) == var
! 	  && operand_equal_p (val, TREE_OPERAND (stmt, 1), 0))
  	{
  	  bsi_remove (&bsi);
  	  continue;
--- 1295,1302 ----
  	 THEN/ELSE clause.  */
        if (TREE_CODE (stmt) == MODIFY_EXPR
  	  && TREE_OPERAND (stmt, 0) == var
! 	  && operand_equal_p (val, TREE_OPERAND (stmt, 1), 0,
! 		  	      true /*value is constant*/))
  	{
  	  bsi_remove (&bsi);
  	  continue;
*************** phi_alternatives_equal (basic_block dest
*** 1724,1730 ****
        val1 = PHI_ARG_DEF (phi, n1);
        val2 = PHI_ARG_DEF (phi, n2);
  
!       if (!operand_equal_p (val1, val2, false))
  	return false;
      }
  
--- 1725,1731 ----
        val1 = PHI_ARG_DEF (phi, n1);
        val2 = PHI_ARG_DEF (phi, n2);
  
!       if (!operand_equal_p (val1, val2, false, true))
  	return false;
      }
  
Index: tree-ssa-dom.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-dom.c,v
retrieving revision 1.1.2.106
diff -c -3 -p -r1.1.2.106 tree-ssa-dom.c
*** tree-ssa-dom.c	6 Jan 2004 07:32:15 -0000	1.1.2.106
--- tree-ssa-dom.c	7 Jan 2004 18:52:53 -0000
*************** record_equivalences_from_phis (basic_blo
*** 932,938 ****
  	  if (TREE_CODE (t) == SSA_NAME || is_gimple_min_invariant (t))
  	    {
  	      /* Ignore alternatives which are the same as our LHS.  */
! 	      if (operand_equal_p (lhs, t, 0))
  		continue;
  
  	      /* If we have not processed an alternative yet, then set
--- 932,938 ----
  	  if (TREE_CODE (t) == SSA_NAME || is_gimple_min_invariant (t))
  	    {
  	      /* Ignore alternatives which are the same as our LHS.  */
! 	      if (operand_equal_p (lhs, t, 0, true))
  		continue;
  
  	      /* If we have not processed an alternative yet, then set
*************** record_equivalences_from_phis (basic_blo
*** 942,948 ****
  	      /* If we have processed an alternative (stored in RHS), then
  		 see if it is equal to this one.  If it isn't, then stop
  		 the search.  */
! 	      else if (! operand_equal_p (rhs, t, 0))
  		break;
  	    }
  	  else
--- 942,948 ----
  	      /* If we have processed an alternative (stored in RHS), then
  		 see if it is equal to this one.  If it isn't, then stop
  		 the search.  */
! 	      else if (! operand_equal_p (rhs, t, 0, true))
  		break;
  	    }
  	  else
*************** true_false_expr_eq (const void *p1, cons
*** 2699,2705 ****
        && (TREE_TYPE (rhs1) == TREE_TYPE (rhs2)
  	  || (TYPE_MAIN_VARIANT (TREE_TYPE (rhs1))
  	      == TYPE_MAIN_VARIANT (TREE_TYPE (rhs2))))
!       && operand_equal_p (rhs1, rhs2, 0))
      {
  #ifdef ENABLE_CHECKING
  	  if (true_false_expr_hash (rhs1) != true_false_expr_hash (rhs2))
--- 2699,2705 ----
        && (TREE_TYPE (rhs1) == TREE_TYPE (rhs2)
  	  || (TYPE_MAIN_VARIANT (TREE_TYPE (rhs1))
  	      == TYPE_MAIN_VARIANT (TREE_TYPE (rhs2))))
!       && operand_equal_p (rhs1, rhs2, 0, true))
      {
  #ifdef ENABLE_CHECKING
  	  if (true_false_expr_hash (rhs1) != true_false_expr_hash (rhs2))
*************** avail_expr_eq (const void *p1, const voi
*** 2787,2793 ****
        && (TREE_TYPE (rhs1) == TREE_TYPE (rhs2)
  	  || (TYPE_MAIN_VARIANT (TREE_TYPE (rhs1))
  	      == TYPE_MAIN_VARIANT (TREE_TYPE (rhs2))))
!       && operand_equal_p (rhs1, rhs2, 0))
      {
        vuse_optype ops1 = STMT_VUSE_OPS (s1);
        vuse_optype ops2 = STMT_VUSE_OPS (s2);
--- 2787,2793 ----
        && (TREE_TYPE (rhs1) == TREE_TYPE (rhs2)
  	  || (TYPE_MAIN_VARIANT (TREE_TYPE (rhs1))
  	      == TYPE_MAIN_VARIANT (TREE_TYPE (rhs2))))
!       && operand_equal_p (rhs1, rhs2, 0, true))
      {
        vuse_optype ops1 = STMT_VUSE_OPS (s1);
        vuse_optype ops2 = STMT_VUSE_OPS (s2);
Index: tree-ssa-pre.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-pre.c,v
retrieving revision 1.1.4.119
diff -c -3 -p -r1.1.4.119 tree-ssa-pre.c
*** tree-ssa-pre.c	5 Jan 2004 19:45:23 -0000	1.1.4.119
--- tree-ssa-pre.c	7 Jan 2004 18:52:53 -0000
*************** names_match_p (const tree t1, const tree
*** 462,468 ****
    if (name2 == NULL_TREE && name1 != NULL_TREE)
      return false;
    if (name1 == NULL_TREE && name2 == NULL_TREE)
!     return operand_equal_p (t1, t2, 0);
  
    return name1 == name2;
  }
--- 462,469 ----
    if (name2 == NULL_TREE && name1 != NULL_TREE)
      return false;
    if (name1 == NULL_TREE && name2 == NULL_TREE)
!     /* pure functions are safe here as we require virtual operands to match.  */
!     return operand_equal_p (t1, t2, 0, true);
  
    return name1 == name2;
  }
Index: tree-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa.c,v
retrieving revision 1.1.4.181
diff -c -3 -p -r1.1.4.181 tree-ssa.c
*** tree-ssa.c	7 Jan 2004 08:30:45 -0000	1.1.4.181
--- tree-ssa.c	7 Jan 2004 18:52:53 -0000
*************** raise_value (tree phi, tree val, tree *e
*** 3665,3671 ****
  
    if (eq_to[ver])
      {
!       if (operand_equal_p (eq_to[ver], val, 0))
  	return;
  
        eq_to[ver] = var;
--- 3665,3671 ----
  
    if (eq_to[ver])
      {
!       if (operand_equal_p (eq_to[ver], val, 0, true))
  	return;
  
        eq_to[ver] = var;
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.342.2.157
diff -c -3 -p -r1.342.2.157 tree.h
*** tree.h	6 Jan 2004 23:27:49 -0000	1.342.2.157
--- tree.h	7 Jan 2004 18:52:54 -0000
*************** extern int div_and_round_double (enum tr
*** 3299,3305 ****
  				 HOST_WIDE_INT *, unsigned HOST_WIDE_INT *,
  				 HOST_WIDE_INT *);
  
! extern int operand_equal_p (tree, tree, int);
  extern tree omit_one_operand (tree, tree, tree);
  extern tree invert_truthvalue (tree);
  extern tree nondestructive_fold_unary_to_constant (enum tree_code, tree, tree);
--- 3299,3305 ----
  				 HOST_WIDE_INT *, unsigned HOST_WIDE_INT *,
  				 HOST_WIDE_INT *);
  
! extern int operand_equal_p (tree, tree, int, bool);
  extern tree omit_one_operand (tree, tree, tree);
  extern tree invert_truthvalue (tree);
  extern tree nondestructive_fold_unary_to_constant (enum tree_code, tree, tree);
Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.213.2.67
diff -c -3 -p -r1.213.2.67 fold-const.c
*** fold-const.c	6 Jan 2004 13:03:08 -0000	1.213.2.67
--- fold-const.c	7 Jan 2004 19:01:06 -0000
*************** truth_value_p (enum tree_code code)
*** 1960,1969 ****
     same value in each operand/subexpression.  Hence a zero value for
     ONLY_CONST assumes isochronic (or instantaneous) tree equivalence.
     If comparing arbitrary expression trees, such as from different
!    statements, ONLY_CONST must usually be nonzero.  */
  
  int
! operand_equal_p (tree arg0, tree arg1, int only_const)
  {
    tree fndecl;
  
--- 1960,1975 ----
     same value in each operand/subexpression.  Hence a zero value for
     ONLY_CONST assumes isochronic (or instantaneous) tree equivalence.
     If comparing arbitrary expression trees, such as from different
!    statements, ONLY_CONST must usually be nonzero.
! 
!    Checking equivalence of memory values refered by operands is out of scope of
!    this function and thus calling this with ONLY_CONST nonzero for operands of
!    different statement needs special check that memory locations accessed
!    didn't change.  This include locations implied by pure function call and
!    thus ACCEPT_PURE_CALLs can be used to control this behaviour.  */
  
  int
! operand_equal_p (tree arg0, tree arg1, int only_const, bool accept_pure_calls)
  {
    tree fndecl;
  
*************** operand_equal_p (tree arg0, tree arg1, i
*** 2024,2030 ****
  	  v2 = TREE_VECTOR_CST_ELTS (arg1);
  	  while (v1 && v2)
  	    {
! 	      if (!operand_equal_p (v1, v2, only_const))
  		return 0;
  	      v1 = TREE_CHAIN (v1);
  	      v2 = TREE_CHAIN (v2);
--- 2030,2036 ----
  	  v2 = TREE_VECTOR_CST_ELTS (arg1);
  	  while (v1 && v2)
  	    {
! 	      if (!operand_equal_p (v1, v2, only_const, accept_pure_calls))
  		return 0;
  	      v1 = TREE_CHAIN (v1);
  	      v2 = TREE_CHAIN (v2);
*************** operand_equal_p (tree arg0, tree arg1, i
*** 2035,2043 ****
  
        case COMPLEX_CST:
  	return (operand_equal_p (TREE_REALPART (arg0), TREE_REALPART (arg1),
! 				 only_const)
  		&& operand_equal_p (TREE_IMAGPART (arg0), TREE_IMAGPART (arg1),
! 				    only_const));
  
        case STRING_CST:
  	return (TREE_STRING_LENGTH (arg0) == TREE_STRING_LENGTH (arg1)
--- 2041,2049 ----
  
        case COMPLEX_CST:
  	return (operand_equal_p (TREE_REALPART (arg0), TREE_REALPART (arg1),
! 				 only_const, accept_pure_calls)
  		&& operand_equal_p (TREE_IMAGPART (arg0), TREE_IMAGPART (arg1),
! 				    only_const, accept_pure_calls));
  
        case STRING_CST:
  	return (TREE_STRING_LENGTH (arg0) == TREE_STRING_LENGTH (arg1)
*************** operand_equal_p (tree arg0, tree arg1, i
*** 2047,2053 ****
  
        case ADDR_EXPR:
  	return operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0),
! 				0);
        default:
  	break;
        }
--- 2053,2059 ----
  
        case ADDR_EXPR:
  	return operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0),
! 				0, accept_pure_calls);
        default:
  	break;
        }
*************** operand_equal_p (tree arg0, tree arg1, i
*** 2065,2085 ****
  	return 0;
  
        return operand_equal_p (TREE_OPERAND (arg0, 0),
! 			      TREE_OPERAND (arg1, 0), 0);
  
      case '<':
      case '2':
!       if (operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0), 0)
  	  && operand_equal_p (TREE_OPERAND (arg0, 1), TREE_OPERAND (arg1, 1),
! 			      0))
  	return 1;
  
        /* For commutative ops, allow the other order.  */
        return (commutative_tree_code (TREE_CODE (arg0))
  	      && operand_equal_p (TREE_OPERAND (arg0, 0),
! 				  TREE_OPERAND (arg1, 1), 0)
  	      && operand_equal_p (TREE_OPERAND (arg0, 1),
! 				  TREE_OPERAND (arg1, 0), 0));
  
      case 'r':
        /* If either of the pointer (or reference) expressions we are
--- 2071,2093 ----
  	return 0;
  
        return operand_equal_p (TREE_OPERAND (arg0, 0),
! 			      TREE_OPERAND (arg1, 0), 0, accept_pure_calls);
  
      case '<':
      case '2':
!       if (operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0), 0,
! 			   accept_pure_calls)
  	  && operand_equal_p (TREE_OPERAND (arg0, 1), TREE_OPERAND (arg1, 1),
! 			      0, accept_pure_calls))
  	return 1;
  
        /* For commutative ops, allow the other order.  */
        return (commutative_tree_code (TREE_CODE (arg0))
  	      && operand_equal_p (TREE_OPERAND (arg0, 0),
! 				  TREE_OPERAND (arg1, 1), 0, accept_pure_calls)
  	      && operand_equal_p (TREE_OPERAND (arg0, 1),
! 				  TREE_OPERAND (arg1, 0), 0,
! 				  accept_pure_calls));
  
      case 'r':
        /* If either of the pointer (or reference) expressions we are
*************** operand_equal_p (tree arg0, tree arg1, i
*** 2092,2114 ****
  	{
  	case INDIRECT_REF:
  	  return operand_equal_p (TREE_OPERAND (arg0, 0),
! 				  TREE_OPERAND (arg1, 0), 0);
  
  	case COMPONENT_REF:
  	case ARRAY_REF:
  	case ARRAY_RANGE_REF:
  	  return (operand_equal_p (TREE_OPERAND (arg0, 0),
! 				   TREE_OPERAND (arg1, 0), 0)
  		  && operand_equal_p (TREE_OPERAND (arg0, 1),
! 				      TREE_OPERAND (arg1, 1), 0));
  
  	case BIT_FIELD_REF:
  	  return (operand_equal_p (TREE_OPERAND (arg0, 0),
! 				   TREE_OPERAND (arg1, 0), 0)
  		  && operand_equal_p (TREE_OPERAND (arg0, 1),
! 				      TREE_OPERAND (arg1, 1), 0)
  		  && operand_equal_p (TREE_OPERAND (arg0, 2),
! 				      TREE_OPERAND (arg1, 2), 0));
  	default:
  	  return 0;
  	}
--- 2100,2126 ----
  	{
  	case INDIRECT_REF:
  	  return operand_equal_p (TREE_OPERAND (arg0, 0),
! 				  TREE_OPERAND (arg1, 0), 0,
! 				  accept_pure_calls);
  
  	case COMPONENT_REF:
  	case ARRAY_REF:
  	case ARRAY_RANGE_REF:
  	  return (operand_equal_p (TREE_OPERAND (arg0, 0),
! 				   TREE_OPERAND (arg1, 0), 0, accept_pure_calls)
  		  && operand_equal_p (TREE_OPERAND (arg0, 1),
! 				      TREE_OPERAND (arg1, 1), 0,
! 				      accept_pure_calls));
  
  	case BIT_FIELD_REF:
  	  return (operand_equal_p (TREE_OPERAND (arg0, 0),
! 				   TREE_OPERAND (arg1, 0), 0, accept_pure_calls)
  		  && operand_equal_p (TREE_OPERAND (arg0, 1),
! 				      TREE_OPERAND (arg1, 1), 0,
! 				      accept_pure_calls)
  		  && operand_equal_p (TREE_OPERAND (arg0, 2),
! 				      TREE_OPERAND (arg1, 2), 0,
! 				      accept_pure_calls));
  	default:
  	  return 0;
  	}
*************** operand_equal_p (tree arg0, tree arg1, i
*** 2119,2125 ****
  	case ADDR_EXPR:
  	case TRUTH_NOT_EXPR:
  	  return operand_equal_p (TREE_OPERAND (arg0, 0),
! 				  TREE_OPERAND (arg1, 0), 0);
  
  	case RTL_EXPR:
  	  return rtx_equal_p (RTL_EXPR_RTL (arg0), RTL_EXPR_RTL (arg1));
--- 2131,2137 ----
  	case ADDR_EXPR:
  	case TRUTH_NOT_EXPR:
  	  return operand_equal_p (TREE_OPERAND (arg0, 0),
! 				  TREE_OPERAND (arg1, 0), 0, accept_pure_calls);
  
  	case RTL_EXPR:
  	  return rtx_equal_p (RTL_EXPR_RTL (arg0), RTL_EXPR_RTL (arg1));
*************** operand_equal_p (tree arg0, tree arg1, i
*** 2128,2140 ****
  	  /* If the CALL_EXPRs call different functions, then they
  	     clearly can not be equal.  */
  	  if (! operand_equal_p (TREE_OPERAND (arg0, 0),
! 				 TREE_OPERAND (arg1, 0), 0))
  	    return 0;
  
! 	  /* Only consider const functions equivalent.  */
  	  fndecl = get_callee_fndecl (arg0);
  	  if (fndecl == NULL_TREE
! 	      || ! (flags_from_decl_or_type (fndecl) & ECF_CONST))
  	    return 0;
  
  	  /* Now see if all the arguments are the same.  operand_equal_p
--- 2140,2153 ----
  	  /* If the CALL_EXPRs call different functions, then they
  	     clearly can not be equal.  */
  	  if (! operand_equal_p (TREE_OPERAND (arg0, 0),
! 				 TREE_OPERAND (arg1, 0), 0, accept_pure_calls))
  	    return 0;
  
! 	  /* Only consider const or pure functions equivalent.  */
  	  fndecl = get_callee_fndecl (arg0);
  	  if (fndecl == NULL_TREE
! 	      || ! (flags_from_decl_or_type (fndecl)
! 		    & (ECF_CONST | (accept_pure_calls ? ECF_PURE : 0))))
  	    return 0;
  
  	  /* Now see if all the arguments are the same.  operand_equal_p
*************** operand_equal_p (tree arg0, tree arg1, i
*** 2144,2150 ****
  	  arg1 = TREE_OPERAND (arg1, 1);
  	  while (arg0 && arg1)
  	    {
! 	      if (! operand_equal_p (TREE_VALUE (arg0), TREE_VALUE (arg1), 0))
  		return 0;
  
  	      arg0 = TREE_CHAIN (arg0);
--- 2157,2164 ----
  	  arg1 = TREE_OPERAND (arg1, 1);
  	  while (arg0 && arg1)
  	    {
! 	      if (! operand_equal_p (TREE_VALUE (arg0), TREE_VALUE (arg1), 0,
! 				     accept_pure_calls))
  		return 0;
  
  	      arg0 = TREE_CHAIN (arg0);
*************** operand_equal_for_comparison_p (tree arg
*** 2183,2189 ****
    tree primarg0, primarg1, primother;
    unsigned int correct_width;
  
!   if (operand_equal_p (arg0, arg1, 0))
      return 1;
  
    if (! INTEGRAL_TYPE_P (TREE_TYPE (arg0))
--- 2197,2203 ----
    tree primarg0, primarg1, primother;
    unsigned int correct_width;
  
!   if (operand_equal_p (arg0, arg1, 0, true))
      return 1;
  
    if (! INTEGRAL_TYPE_P (TREE_TYPE (arg0))
*************** operand_equal_for_comparison_p (tree arg
*** 2196,2202 ****
    primarg0 = arg0, primarg1 = arg1;
    STRIP_NOPS (primarg0);
    STRIP_NOPS (primarg1);
!   if (operand_equal_p (primarg0, primarg1, 0))
      return 1;
  
    /* Duplicate what shorten_compare does to ARG1 and see if that gives the
--- 2210,2216 ----
    primarg0 = arg0, primarg1 = arg1;
    STRIP_NOPS (primarg0);
    STRIP_NOPS (primarg1);
!   if (operand_equal_p (primarg0, primarg1, 0, true))
      return 1;
  
    /* Duplicate what shorten_compare does to ARG1 and see if that gives the
*************** operand_equal_for_comparison_p (tree arg
*** 2220,2226 ****
        primarg1 = convert ((*lang_hooks.types.signed_or_unsigned_type)
  			  (unsignedp1, TREE_TYPE (primarg1)), primarg1);
  
!       if (operand_equal_p (arg0, convert (type, primarg1), 0))
  	return 1;
      }
  
--- 2234,2240 ----
        primarg1 = convert ((*lang_hooks.types.signed_or_unsigned_type)
  			  (unsignedp1, TREE_TYPE (primarg1)), primarg1);
  
!       if (operand_equal_p (arg0, convert (type, primarg1), 0, true))
  	return 1;
      }
  
*************** twoval_comparison_p (tree arg, tree *cva
*** 2294,2318 ****
  	 are the same.  */
  
        if (operand_equal_p (TREE_OPERAND (arg, 0),
! 			   TREE_OPERAND (arg, 1), 0))
  	return 0;
  
        if (*cval1 == 0)
  	*cval1 = TREE_OPERAND (arg, 0);
!       else if (operand_equal_p (*cval1, TREE_OPERAND (arg, 0), 0))
  	;
        else if (*cval2 == 0)
  	*cval2 = TREE_OPERAND (arg, 0);
!       else if (operand_equal_p (*cval2, TREE_OPERAND (arg, 0), 0))
  	;
        else
  	return 0;
  
!       if (operand_equal_p (*cval1, TREE_OPERAND (arg, 1), 0))
  	;
        else if (*cval2 == 0)
  	*cval2 = TREE_OPERAND (arg, 1);
!       else if (operand_equal_p (*cval2, TREE_OPERAND (arg, 1), 0))
  	;
        else
  	return 0;
--- 2308,2332 ----
  	 are the same.  */
  
        if (operand_equal_p (TREE_OPERAND (arg, 0),
! 			   TREE_OPERAND (arg, 1), 0, true))
  	return 0;
  
        if (*cval1 == 0)
  	*cval1 = TREE_OPERAND (arg, 0);
!       else if (operand_equal_p (*cval1, TREE_OPERAND (arg, 0), 0, true))
  	;
        else if (*cval2 == 0)
  	*cval2 = TREE_OPERAND (arg, 0);
!       else if (operand_equal_p (*cval2, TREE_OPERAND (arg, 0), 0, true))
  	;
        else
  	return 0;
  
!       if (operand_equal_p (*cval1, TREE_OPERAND (arg, 1), 0, true))
  	;
        else if (*cval2 == 0)
  	*cval2 = TREE_OPERAND (arg, 1);
!       else if (operand_equal_p (*cval2, TREE_OPERAND (arg, 1), 0, true))
  	;
        else
  	return 0;
*************** eval_subst (tree arg, tree old0, tree ne
*** 2388,2401 ****
  	   former will be true if the operand has a side-effect.  In that
  	   case, we know the operand occurred exactly once.  */
  
! 	if (arg0 == old0 || operand_equal_p (arg0, old0, 0))
  	  arg0 = new0;
! 	else if (arg0 == old1 || operand_equal_p (arg0, old1, 0))
  	  arg0 = new1;
  
! 	if (arg1 == old0 || operand_equal_p (arg1, old0, 0))
  	  arg1 = new0;
! 	else if (arg1 == old1 || operand_equal_p (arg1, old1, 0))
  	  arg1 = new1;
  
  	return fold (build (code, type, arg0, arg1));
--- 2402,2415 ----
  	   former will be true if the operand has a side-effect.  In that
  	   case, we know the operand occurred exactly once.  */
  
! 	if (arg0 == old0 || operand_equal_p (arg0, old0, 0, true))
  	  arg0 = new0;
! 	else if (arg0 == old1 || operand_equal_p (arg0, old1, 0, true))
  	  arg0 = new1;
  
! 	if (arg1 == old0 || operand_equal_p (arg1, old0, 0, true))
  	  arg1 = new0;
! 	else if (arg1 == old1 || operand_equal_p (arg1, old1, 0, true))
  	  arg1 = new1;
  
  	return fold (build (code, type, arg0, arg1));
*************** distribute_bit_expr (enum tree_code code
*** 2575,2599 ****
  	  && TREE_CODE (arg0) != BIT_IOR_EXPR))
      return 0;
  
!   if (operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0), 0))
      {
        common = TREE_OPERAND (arg0, 0);
        left = TREE_OPERAND (arg0, 1);
        right = TREE_OPERAND (arg1, 1);
      }
!   else if (operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 1), 0))
      {
        common = TREE_OPERAND (arg0, 0);
        left = TREE_OPERAND (arg0, 1);
        right = TREE_OPERAND (arg1, 0);
      }
!   else if (operand_equal_p (TREE_OPERAND (arg0, 1), TREE_OPERAND (arg1, 0), 0))
      {
        common = TREE_OPERAND (arg0, 1);
        left = TREE_OPERAND (arg0, 0);
        right = TREE_OPERAND (arg1, 1);
      }
!   else if (operand_equal_p (TREE_OPERAND (arg0, 1), TREE_OPERAND (arg1, 1), 0))
      {
        common = TREE_OPERAND (arg0, 1);
        left = TREE_OPERAND (arg0, 0);
--- 2589,2617 ----
  	  && TREE_CODE (arg0) != BIT_IOR_EXPR))
      return 0;
  
!   if (operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0), 0,
! 		       true))
      {
        common = TREE_OPERAND (arg0, 0);
        left = TREE_OPERAND (arg0, 1);
        right = TREE_OPERAND (arg1, 1);
      }
!   else if (operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 1), 0,
! 			    true))
      {
        common = TREE_OPERAND (arg0, 0);
        left = TREE_OPERAND (arg0, 1);
        right = TREE_OPERAND (arg1, 0);
      }
!   else if (operand_equal_p (TREE_OPERAND (arg0, 1), TREE_OPERAND (arg1, 0), 0,
! 			    true))
      {
        common = TREE_OPERAND (arg0, 1);
        left = TREE_OPERAND (arg0, 0);
        right = TREE_OPERAND (arg1, 1);
      }
!   else if (operand_equal_p (TREE_OPERAND (arg0, 1), TREE_OPERAND (arg1, 1), 0,
! 			    true))
      {
        common = TREE_OPERAND (arg0, 1);
        left = TREE_OPERAND (arg0, 0);
*************** build_range_check (tree type, tree exp, 
*** 3378,3384 ****
    if (high == 0)
      return fold (build (GE_EXPR, type, exp, low));
  
!   if (operand_equal_p (low, high, 0))
      return fold (build (EQ_EXPR, type, exp, low));
  
    if (integer_zerop (low))
--- 3396,3402 ----
    if (high == 0)
      return fold (build (GE_EXPR, type, exp, low));
  
!   if (operand_equal_p (low, high, 0, true))
      return fold (build (EQ_EXPR, type, exp, low));
  
    if (integer_zerop (low))
*************** fold_range_test (tree exp)
*** 3592,3598 ****
       can build the range test, return it or it inverted.  If one of the
       ranges is always true or always false, consider it to be the same
       expression as the other.  */
!   if ((lhs == 0 || rhs == 0 || operand_equal_p (lhs, rhs, 0))
        && merge_ranges (&in_p, &low, &high, in0_p, low0, high0,
  		       in1_p, low1, high1)
        && 0 != (tem = (build_range_check (TREE_TYPE (exp),
--- 3610,3616 ----
       can build the range test, return it or it inverted.  If one of the
       ranges is always true or always false, consider it to be the same
       expression as the other.  */
!   if ((lhs == 0 || rhs == 0 || operand_equal_p (lhs, rhs, 0, true))
        && merge_ranges (&in_p, &low, &high, in0_p, low0, high0,
  		       in1_p, low1, high1)
        && 0 != (tem = (build_range_check (TREE_TYPE (exp),
*************** fold_range_test (tree exp)
*** 3608,3614 ****
  	   && lhs != 0 && rhs != 0
  	   && (TREE_CODE (exp) == TRUTH_ANDIF_EXPR
  	       || TREE_CODE (exp) == TRUTH_ORIF_EXPR)
! 	   && operand_equal_p (lhs, rhs, 0))
      {
        /* If simple enough, just rewrite.  Otherwise, make a SAVE_EXPR
  	 unless we are at top level or LHS contains a PLACEHOLDER_EXPR, in
--- 3626,3632 ----
  	   && lhs != 0 && rhs != 0
  	   && (TREE_CODE (exp) == TRUTH_ANDIF_EXPR
  	       || TREE_CODE (exp) == TRUTH_ORIF_EXPR)
! 	   && operand_equal_p (lhs, rhs, 0, true))
      {
        /* If simple enough, just rewrite.  Otherwise, make a SAVE_EXPR
  	 unless we are at top level or LHS contains a PLACEHOLDER_EXPR, in
*************** fold_truthop (enum tree_code code, tree 
*** 3768,3775 ****
      {
        int compcode;
  
!       if (operand_equal_p (ll_arg, rl_arg, 0)
!           && operand_equal_p (lr_arg, rr_arg, 0))
          {
            int lcompcode, rcompcode;
  
--- 3786,3793 ----
      {
        int compcode;
  
!       if (operand_equal_p (ll_arg, rl_arg, 0, true)
!           && operand_equal_p (lr_arg, rr_arg, 0, true))
          {
            int lcompcode, rcompcode;
  
*************** fold_truthop (enum tree_code code, tree 
*** 3779,3786 ****
                       ? lcompcode & rcompcode
                       : lcompcode | rcompcode;
          }
!       else if (operand_equal_p (ll_arg, rr_arg, 0)
!                && operand_equal_p (lr_arg, rl_arg, 0))
          {
            int lcompcode, rcompcode;
  
--- 3797,3804 ----
                       ? lcompcode & rcompcode
                       : lcompcode | rcompcode;
          }
!       else if (operand_equal_p (ll_arg, rr_arg, 0, true)
!                && operand_equal_p (lr_arg, rl_arg, 0, true))
          {
            int lcompcode, rcompcode;
  
*************** fold_truthop (enum tree_code code, tree 
*** 3867,3880 ****
       Then see if we have constants.  If not, the same must be true for
       the rhs's.  */
    if (volatilep || ll_inner == 0 || rl_inner == 0
!       || ! operand_equal_p (ll_inner, rl_inner, 0))
      return 0;
  
    if (TREE_CODE (lr_arg) == INTEGER_CST
        && TREE_CODE (rr_arg) == INTEGER_CST)
      l_const = lr_arg, r_const = rr_arg;
    else if (lr_inner == 0 || rr_inner == 0
! 	   || ! operand_equal_p (lr_inner, rr_inner, 0))
      return 0;
    else
      l_const = r_const = 0;
--- 3885,3898 ----
       Then see if we have constants.  If not, the same must be true for
       the rhs's.  */
    if (volatilep || ll_inner == 0 || rl_inner == 0
!       || ! operand_equal_p (ll_inner, rl_inner, 0, true))
      return 0;
  
    if (TREE_CODE (lr_arg) == INTEGER_CST
        && TREE_CODE (rr_arg) == INTEGER_CST)
      l_const = lr_arg, r_const = rr_arg;
    else if (lr_inner == 0 || rr_inner == 0
! 	   || ! operand_equal_p (lr_inner, rr_inner, 0, true))
      return 0;
    else
      l_const = r_const = 0;
*************** fold (tree expr)
*** 5587,5593 ****
  	  tree s0 = TYPE_SIZE (tt0);
  	  tree s1 = TYPE_SIZE (tt1);
  
! 	  if (s0 && s1 && operand_equal_p (s0, s1, 1))
  	    return build (TREE_CODE (arg0), t0, convert (t0, arg00),
  		          TREE_OPERAND (arg0, 1));
  	}
--- 5605,5611 ----
  	  tree s0 = TYPE_SIZE (tt0);
  	  tree s1 = TYPE_SIZE (tt1);
  
! 	  if (s0 && s1 && operand_equal_p (s0, s1, 1, true))
  	    return build (TREE_CODE (arg0), t0, convert (t0, arg00),
  		          TREE_OPERAND (arg0, 1));
  	}
*************** fold (tree expr)
*** 5768,5780 ****
  	      arg11 = TREE_OPERAND (arg1, 1);
  	      same = NULL_TREE;
  
! 	      if (operand_equal_p (arg01, arg11, 0))
  		same = arg01, alt0 = arg00, alt1 = arg10;
! 	      else if (operand_equal_p (arg00, arg10, 0))
  		same = arg00, alt0 = arg01, alt1 = arg11;
! 	      else if (operand_equal_p (arg00, arg11, 0))
  		same = arg00, alt0 = arg01, alt1 = arg10;
! 	      else if (operand_equal_p (arg01, arg10, 0))
  		same = arg01, alt0 = arg00, alt1 = arg11;
  
  	      /* No identical multiplicands; see if we can find a common
--- 5786,5798 ----
  	      arg11 = TREE_OPERAND (arg1, 1);
  	      same = NULL_TREE;
  
! 	      if (operand_equal_p (arg01, arg11, 0, true))
  		same = arg01, alt0 = arg00, alt1 = arg10;
! 	      else if (operand_equal_p (arg00, arg10, 0, true))
  		same = arg00, alt0 = arg01, alt1 = arg11;
! 	      else if (operand_equal_p (arg00, arg11, 0, true))
  		same = arg00, alt0 = arg01, alt1 = arg10;
! 	      else if (operand_equal_p (arg01, arg10, 0, true))
  		same = arg01, alt0 = arg00, alt1 = arg11;
  
  	      /* No identical multiplicands; see if we can find a common
*************** fold (tree expr)
*** 5824,5830 ****
  	    return non_lvalue (convert (type, arg1));
  
  	  /* Convert x+x into x*2.0.  */
! 	  if (operand_equal_p (arg0, arg1, 0)
  	      && SCALAR_FLOAT_TYPE_P (type))
  	    return fold (build (MULT_EXPR, type, arg0,
  				build_real (type, dconst2)));
--- 5842,5848 ----
  	    return non_lvalue (convert (type, arg1));
  
  	  /* Convert x+x into x*2.0.  */
! 	  if (operand_equal_p (arg0, arg1, 0, true)
  	      && SCALAR_FLOAT_TYPE_P (type))
  	    return fold (build (MULT_EXPR, type, arg0,
  				build_real (type, dconst2)));
*************** fold (tree expr)
*** 5834,5840 ****
  	      && TREE_CODE (arg0) == MULT_EXPR
  	      && TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST
  	      && ! TREE_CONSTANT_OVERFLOW (TREE_OPERAND (arg0, 1))
! 	      && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
  	    {
  	      REAL_VALUE_TYPE c;
  
--- 5852,5858 ----
  	      && TREE_CODE (arg0) == MULT_EXPR
  	      && TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST
  	      && ! TREE_CONSTANT_OVERFLOW (TREE_OPERAND (arg0, 1))
! 	      && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0, true))
  	    {
  	      REAL_VALUE_TYPE c;
  
*************** fold (tree expr)
*** 5849,5855 ****
  	      && TREE_CODE (arg1) == MULT_EXPR
  	      && TREE_CODE (TREE_OPERAND (arg1, 1)) == REAL_CST
  	      && ! TREE_CONSTANT_OVERFLOW (TREE_OPERAND (arg1, 1))
! 	      && operand_equal_p (TREE_OPERAND (arg1, 0), arg0, 0))
  	    {
  	      REAL_VALUE_TYPE c;
  
--- 5867,5873 ----
  	      && TREE_CODE (arg1) == MULT_EXPR
  	      && TREE_CODE (TREE_OPERAND (arg1, 1)) == REAL_CST
  	      && ! TREE_CONSTANT_OVERFLOW (TREE_OPERAND (arg1, 1))
! 	      && operand_equal_p (TREE_OPERAND (arg1, 0), arg0, 0, true))
  	    {
  	      REAL_VALUE_TYPE c;
  
*************** fold (tree expr)
*** 5868,5874 ****
  	      && TREE_CODE (TREE_OPERAND (arg1, 1)) == REAL_CST
  	      && ! TREE_CONSTANT_OVERFLOW (TREE_OPERAND (arg1, 1))
  	      && operand_equal_p (TREE_OPERAND (arg0, 0),
! 				  TREE_OPERAND (arg1, 0), 0))
  	    {
  	      REAL_VALUE_TYPE c1, c2;
  
--- 5886,5892 ----
  	      && TREE_CODE (TREE_OPERAND (arg1, 1)) == REAL_CST
  	      && ! TREE_CONSTANT_OVERFLOW (TREE_OPERAND (arg1, 1))
  	      && operand_equal_p (TREE_OPERAND (arg0, 0),
! 				  TREE_OPERAND (arg1, 0), 0, true))
  	    {
  	      REAL_VALUE_TYPE c1, c2;
  
*************** fold (tree expr)
*** 5893,5899 ****
  	if (((code0 == RSHIFT_EXPR && code1 == LSHIFT_EXPR)
  	     || (code1 == RSHIFT_EXPR && code0 == LSHIFT_EXPR))
  	    && operand_equal_p (TREE_OPERAND (arg0, 0),
! 			        TREE_OPERAND (arg1, 0), 0)
  	    && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg0, 0))))
  	  {
  	    tree tree01, tree11;
--- 5911,5917 ----
  	if (((code0 == RSHIFT_EXPR && code1 == LSHIFT_EXPR)
  	     || (code1 == RSHIFT_EXPR && code0 == LSHIFT_EXPR))
  	    && operand_equal_p (TREE_OPERAND (arg0, 0),
! 			        TREE_OPERAND (arg1, 0), 0, true)
  	    && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg0, 0))))
  	  {
  	    tree tree01, tree11;
*************** fold (tree expr)
*** 5925,5931 ****
  					      TYPE_PRECISION
  					      (TREE_TYPE (TREE_OPERAND
  							  (arg0, 0))))
! 		    && operand_equal_p (tree01, tree111, 0))
  		  return build ((code0 == LSHIFT_EXPR
  				 ? LROTATE_EXPR
  				 : RROTATE_EXPR),
--- 5943,5949 ----
  					      TYPE_PRECISION
  					      (TREE_TYPE (TREE_OPERAND
  							  (arg0, 0))))
! 		    && operand_equal_p (tree01, tree111, 0, true))
  		  return build ((code0 == LSHIFT_EXPR
  				 ? LROTATE_EXPR
  				 : RROTATE_EXPR),
*************** fold (tree expr)
*** 5943,5949 ****
  					      TYPE_PRECISION
  					      (TREE_TYPE (TREE_OPERAND
  							  (arg0, 0))))
! 		    && operand_equal_p (tree11, tree011, 0))
  		  return build ((code0 != LSHIFT_EXPR
  				 ? LROTATE_EXPR
  				 : RROTATE_EXPR),
--- 5961,5967 ----
  					      TYPE_PRECISION
  					      (TREE_TYPE (TREE_OPERAND
  							  (arg0, 0))))
! 		    && operand_equal_p (tree11, tree011, 0, true))
  		  return build ((code0 != LSHIFT_EXPR
  				 ? LROTATE_EXPR
  				 : RROTATE_EXPR),
*************** fold (tree expr)
*** 6070,6076 ****
  
  	  if (TREE_CODE (arg0) == MULT_EXPR && TREE_CODE (arg1) == MULT_EXPR
  	      && operand_equal_p (TREE_OPERAND (arg0, 1),
! 				  TREE_OPERAND (arg1, 1), 0))
  	    return fold (build (MULT_EXPR, type,
  				fold (build (MINUS_EXPR, type,
  					     TREE_OPERAND (arg0, 0),
--- 6088,6094 ----
  
  	  if (TREE_CODE (arg0) == MULT_EXPR && TREE_CODE (arg1) == MULT_EXPR
  	      && operand_equal_p (TREE_OPERAND (arg0, 1),
! 				  TREE_OPERAND (arg1, 1), 0, true))
  	    return fold (build (MULT_EXPR, type,
  				fold (build (MINUS_EXPR, type,
  					     TREE_OPERAND (arg0, 0),
*************** fold (tree expr)
*** 6081,6092 ****
  	  if (!TREE_SIDE_EFFECTS (arg0)
  	      && TREE_CODE (arg1) == BIT_AND_EXPR)
  	    {
! 	      if (operand_equal_p (arg0, TREE_OPERAND (arg1, 1), 0))
  		return fold (build (BIT_AND_EXPR, type,
  				    fold (build1 (BIT_NOT_EXPR, type,
  						  TREE_OPERAND (arg1, 0))),
  				    arg0));
! 	      if (operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
  		return fold (build (BIT_AND_EXPR, type,
  				    fold (build1 (BIT_NOT_EXPR, type,
  						  TREE_OPERAND (arg1, 1))),
--- 6099,6110 ----
  	  if (!TREE_SIDE_EFFECTS (arg0)
  	      && TREE_CODE (arg1) == BIT_AND_EXPR)
  	    {
! 	      if (operand_equal_p (arg0, TREE_OPERAND (arg1, 1), 0, true))
  		return fold (build (BIT_AND_EXPR, type,
  				    fold (build1 (BIT_NOT_EXPR, type,
  						  TREE_OPERAND (arg1, 0))),
  				    arg0));
! 	      if (operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0, true))
  		return fold (build (BIT_AND_EXPR, type,
  				    fold (build1 (BIT_NOT_EXPR, type,
  						  TREE_OPERAND (arg1, 1))),
*************** fold (tree expr)
*** 6098,6110 ****
  	  if (TREE_CODE (arg0) == BIT_AND_EXPR
  	      && TREE_CODE (arg1) == BIT_AND_EXPR
  	      && operand_equal_p (TREE_OPERAND (arg0, 0),
! 				  TREE_OPERAND (arg1, 0), 0))
  	    {
  	      tree mask0 = TREE_OPERAND (arg0, 1);
  	      tree mask1 = TREE_OPERAND (arg1, 1);
  	      tree tem = fold (build1 (BIT_NOT_EXPR, type, mask0));
  	      
! 	      if (operand_equal_p (tem, mask1, 0))
  		{
  		  tem = fold (build (BIT_XOR_EXPR, type,
  				     TREE_OPERAND (arg0, 0), mask1));
--- 6116,6128 ----
  	  if (TREE_CODE (arg0) == BIT_AND_EXPR
  	      && TREE_CODE (arg1) == BIT_AND_EXPR
  	      && operand_equal_p (TREE_OPERAND (arg0, 0),
! 				  TREE_OPERAND (arg1, 0), 0, true))
  	    {
  	      tree mask0 = TREE_OPERAND (arg0, 1);
  	      tree mask1 = TREE_OPERAND (arg1, 1);
  	      tree tem = fold (build1 (BIT_NOT_EXPR, type, mask0));
  	      
! 	      if (operand_equal_p (tem, mask1, 0, true))
  		{
  		  tem = fold (build (BIT_XOR_EXPR, type,
  				     TREE_OPERAND (arg0, 0), mask1));
*************** fold (tree expr)
*** 6130,6136 ****
  	 is volatile.  */
  
        if ((! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
! 	  && operand_equal_p (arg0, arg1, 0))
  	return convert (type, integer_zero_node);
  
        goto associate;
--- 6148,6154 ----
  	 is volatile.  */
  
        if ((! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
! 	  && operand_equal_p (arg0, arg1, 0, true))
  	return convert (type, integer_zero_node);
  
        goto associate;
*************** fold (tree expr)
*** 6218,6224 ****
  		  tree arg10 = TREE_VALUE (TREE_OPERAND (arg1, 1));
  
  		  /* Optimize sqrt(x)*sqrt(x) as x.  */
! 		  if (operand_equal_p (arg00, arg10, 0)
  		      && ! HONOR_SNANS (TYPE_MODE (type)))
  		    return arg00;
  
--- 6236,6242 ----
  		  tree arg10 = TREE_VALUE (TREE_OPERAND (arg1, 1));
  
  		  /* Optimize sqrt(x)*sqrt(x) as x.  */
! 		  if (operand_equal_p (arg00, arg10, 0, true)
  		      && ! HONOR_SNANS (TYPE_MODE (type)))
  		    return arg00;
  
*************** fold (tree expr)
*** 6265,6271 ****
  								     1)));
  
  		  /* Optimize pow(x,y)*pow(z,y) as pow(x*z,y).  */
! 		  if (operand_equal_p (arg01, arg11, 0))
  		    {
  		      tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
  		      tree arg = build (MULT_EXPR, type, arg00, arg10);
--- 6283,6289 ----
  								     1)));
  
  		  /* Optimize pow(x,y)*pow(z,y) as pow(x*z,y).  */
! 		  if (operand_equal_p (arg01, arg11, 0, true))
  		    {
  		      tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
  		      tree arg = build (MULT_EXPR, type, arg00, arg10);
*************** fold (tree expr)
*** 6276,6282 ****
  		    }
  
  		  /* Optimize pow(x,y)*pow(x,z) as pow(x,y+z).  */
! 		  if (operand_equal_p (arg00, arg10, 0))
  		    {
  		      tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
  		      tree arg = fold (build (PLUS_EXPR, type, arg01, arg11));
--- 6294,6300 ----
  		    }
  
  		  /* Optimize pow(x,y)*pow(x,z) as pow(x,y+z).  */
! 		  if (operand_equal_p (arg00, arg10, 0, true))
  		    {
  		      tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
  		      tree arg = fold (build (PLUS_EXPR, type, arg01, arg11));
*************** fold (tree expr)
*** 6295,6301 ****
  		   || (fcode0 == BUILT_IN_COSF && fcode1 == BUILT_IN_TANF)
  		   || (fcode0 == BUILT_IN_COSL && fcode1 == BUILT_IN_TANL))
  		  && operand_equal_p (TREE_VALUE (TREE_OPERAND (arg0, 1)),
! 				      TREE_VALUE (TREE_OPERAND (arg1, 1)), 0))
  		{
  		  tree sinfn;
  
--- 6313,6320 ----
  		   || (fcode0 == BUILT_IN_COSF && fcode1 == BUILT_IN_TANF)
  		   || (fcode0 == BUILT_IN_COSL && fcode1 == BUILT_IN_TANL))
  		  && operand_equal_p (TREE_VALUE (TREE_OPERAND (arg0, 1)),
! 				      TREE_VALUE (TREE_OPERAND (arg1, 1)), 0,
! 				      true))
  		{
  		  tree sinfn;
  
*************** fold (tree expr)
*** 6332,6338 ****
  								     1)));
  		  if (TREE_CODE (arg11) == REAL_CST
  		      && ! TREE_CONSTANT_OVERFLOW (arg11)
! 		      && operand_equal_p (arg0, arg10, 0))
  		    {
  		      tree powfn = TREE_OPERAND (TREE_OPERAND (arg1, 0), 0);
  		      REAL_VALUE_TYPE c;
--- 6351,6357 ----
  								     1)));
  		  if (TREE_CODE (arg11) == REAL_CST
  		      && ! TREE_CONSTANT_OVERFLOW (arg11)
! 		      && operand_equal_p (arg0, arg10, 0, true))
  		    {
  		      tree powfn = TREE_OPERAND (TREE_OPERAND (arg1, 0), 0);
  		      REAL_VALUE_TYPE c;
*************** fold (tree expr)
*** 6357,6363 ****
  								     1)));
  		  if (TREE_CODE (arg01) == REAL_CST
  		      && ! TREE_CONSTANT_OVERFLOW (arg01)
! 		      && operand_equal_p (arg1, arg00, 0))
  		    {
  		      tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
  		      REAL_VALUE_TYPE c;
--- 6376,6382 ----
  								     1)));
  		  if (TREE_CODE (arg01) == REAL_CST
  		      && ! TREE_CONSTANT_OVERFLOW (arg01)
! 		      && operand_equal_p (arg1, arg00, 0, true))
  		    {
  		      tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
  		      REAL_VALUE_TYPE c;
*************** fold (tree expr)
*** 6374,6380 ****
  
  	      /* Optimize x*x as pow(x,2.0), which is expanded as x*x.  */
  	      if (! optimize_size
! 		  && operand_equal_p (arg0, arg1, 0))
  		{
  		  tree powfn;
  
--- 6393,6399 ----
  
  	      /* Optimize x*x as pow(x,2.0), which is expanded as x*x.  */
  	      if (! optimize_size
! 		  && operand_equal_p (arg0, arg1, 0, true))
  		{
  		  tree powfn;
  
*************** fold (tree expr)
*** 6622,6628 ****
  	       || (fcode0 == BUILT_IN_SINF && fcode1 == BUILT_IN_COSF)
  	       || (fcode0 == BUILT_IN_SINL && fcode1 == BUILT_IN_COSL))
  	      && operand_equal_p (TREE_VALUE (TREE_OPERAND (arg0, 1)),
! 				  TREE_VALUE (TREE_OPERAND (arg1, 1)), 0))
  	    {
  	      tree tanfn;
  
--- 6641,6647 ----
  	       || (fcode0 == BUILT_IN_SINF && fcode1 == BUILT_IN_COSF)
  	       || (fcode0 == BUILT_IN_SINL && fcode1 == BUILT_IN_COSL))
  	      && operand_equal_p (TREE_VALUE (TREE_OPERAND (arg0, 1)),
! 				  TREE_VALUE (TREE_OPERAND (arg1, 1)), 0, true))
  	    {
  	      tree tanfn;
  
*************** fold (tree expr)
*** 6645,6651 ****
  	       || (fcode0 == BUILT_IN_COSF && fcode1 == BUILT_IN_SINF)
  	       || (fcode0 == BUILT_IN_COSL && fcode1 == BUILT_IN_SINL))
  	      && operand_equal_p (TREE_VALUE (TREE_OPERAND (arg0, 1)),
! 				  TREE_VALUE (TREE_OPERAND (arg1, 1)), 0))
  	    {
  	      tree tanfn;
  
--- 6664,6670 ----
  	       || (fcode0 == BUILT_IN_COSF && fcode1 == BUILT_IN_SINF)
  	       || (fcode0 == BUILT_IN_COSL && fcode1 == BUILT_IN_SINL))
  	      && operand_equal_p (TREE_VALUE (TREE_OPERAND (arg0, 1)),
! 				  TREE_VALUE (TREE_OPERAND (arg1, 1)), 0, true))
  	    {
  	      tree tanfn;
  
*************** fold (tree expr)
*** 6677,6683 ****
  	      tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
  	      if (TREE_CODE (arg01) == REAL_CST
  		  && ! TREE_CONSTANT_OVERFLOW (arg01)
! 		  && operand_equal_p (arg1, arg00, 0))
  		{
  		  tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
  		  REAL_VALUE_TYPE c;
--- 6696,6702 ----
  	      tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
  	      if (TREE_CODE (arg01) == REAL_CST
  		  && ! TREE_CONSTANT_OVERFLOW (arg01)
! 		  && operand_equal_p (arg1, arg00, 0, true))
  		{
  		  tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
  		  REAL_VALUE_TYPE c;
*************** fold (tree expr)
*** 6799,6817 ****
        goto binary;
  
      case MIN_EXPR:
!       if (operand_equal_p (arg0, arg1, 0))
  	return omit_one_operand (type, arg0, arg1);
        if (INTEGRAL_TYPE_P (type)
! 	  && operand_equal_p (arg1, TYPE_MIN_VALUE (type), 1))
  	return omit_one_operand (type, arg1, arg0);
        goto associate;
  
      case MAX_EXPR:
!       if (operand_equal_p (arg0, arg1, 0))
  	return omit_one_operand (type, arg0, arg1);
        if (INTEGRAL_TYPE_P (type)
  	  && TYPE_MAX_VALUE (type)
! 	  && operand_equal_p (arg1, TYPE_MAX_VALUE (type), 1))
  	return omit_one_operand (type, arg1, arg0);
        goto associate;
  
--- 6818,6836 ----
        goto binary;
  
      case MIN_EXPR:
!       if (operand_equal_p (arg0, arg1, 0, true))
  	return omit_one_operand (type, arg0, arg1);
        if (INTEGRAL_TYPE_P (type)
! 	  && operand_equal_p (arg1, TYPE_MIN_VALUE (type), 1, true))
  	return omit_one_operand (type, arg1, arg0);
        goto associate;
  
      case MAX_EXPR:
!       if (operand_equal_p (arg0, arg1, 0, true))
  	return omit_one_operand (type, arg0, arg1);
        if (INTEGRAL_TYPE_P (type)
  	  && TYPE_MAX_VALUE (type)
! 	  && operand_equal_p (arg1, TYPE_MAX_VALUE (type), 1, true))
  	return omit_one_operand (type, arg1, arg0);
        goto associate;
  
*************** fold (tree expr)
*** 6882,6894 ****
  			     && (code == TRUTH_AND_EXPR
  				 || code == TRUTH_OR_EXPR));
  
! 	  if (operand_equal_p (a00, a10, 0))
  	    return fold (build (TREE_CODE (arg0), type, a00,
  				fold (build (code, type, a01, a11))));
! 	  else if (commutative && operand_equal_p (a00, a11, 0))
  	    return fold (build (TREE_CODE (arg0), type, a00,
  				fold (build (code, type, a01, a10))));
! 	  else if (commutative && operand_equal_p (a01, a10, 0))
  	    return fold (build (TREE_CODE (arg0), type, a01,
  				fold (build (code, type, a00, a11))));
  
--- 6901,6913 ----
  			     && (code == TRUTH_AND_EXPR
  				 || code == TRUTH_OR_EXPR));
  
! 	  if (operand_equal_p (a00, a10, 0, true))
  	    return fold (build (TREE_CODE (arg0), type, a00,
  				fold (build (code, type, a01, a11))));
! 	  else if (commutative && operand_equal_p (a00, a11, 0, true))
  	    return fold (build (TREE_CODE (arg0), type, a00,
  				fold (build (code, type, a01, a10))));
! 	  else if (commutative && operand_equal_p (a01, a10, 0, true))
  	    return fold (build (TREE_CODE (arg0), type, a01,
  				fold (build (code, type, a00, a11))));
  
*************** fold (tree expr)
*** 6896,6902 ****
  	     operators or else A10 must not have side-effects.  */
  
  	  else if ((commutative || ! TREE_SIDE_EFFECTS (a10))
! 		   && operand_equal_p (a01, a11, 0))
  	    return fold (build (TREE_CODE (arg0), type,
  				fold (build (code, type, a00, a10)),
  				a01));
--- 6915,6921 ----
  	     operators or else A10 must not have side-effects.  */
  
  	  else if ((commutative || ! TREE_SIDE_EFFECTS (a10))
! 		   && operand_equal_p (a01, a11, 0, true))
  	    return fold (build (TREE_CODE (arg0), type,
  				fold (build (code, type, a00, a10)),
  				a01));
*************** fold (tree expr)
*** 7392,7398 ****
        if ((code == EQ_EXPR || code == NE_EXPR)
  	  && TREE_CODE (arg0) == BIT_AND_EXPR
  	  && integer_pow2p (TREE_OPERAND (arg0, 1))
! 	  && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
  	return fold (build (code == EQ_EXPR ? NE_EXPR : EQ_EXPR, type,
  			    arg0, integer_zero_node));
  
--- 7411,7417 ----
        if ((code == EQ_EXPR || code == NE_EXPR)
  	  && TREE_CODE (arg0) == BIT_AND_EXPR
  	  && integer_pow2p (TREE_OPERAND (arg0, 1))
! 	  && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0, true))
  	return fold (build (code == EQ_EXPR ? NE_EXPR : EQ_EXPR, type,
  			    arg0, integer_zero_node));
  
*************** fold (tree expr)
*** 7461,7467 ****
  
        /* Simplify comparison of something with itself.  (For IEEE
  	 floating-point, we can only do some of these simplifications.)  */
!       if (operand_equal_p (arg0, arg1, 0))
  	{
  	  switch (code)
  	    {
--- 7480,7486 ----
  
        /* Simplify comparison of something with itself.  (For IEEE
  	 floating-point, we can only do some of these simplifications.)  */
!       if (operand_equal_p (arg0, arg1, 0, true))
  	{
  	  switch (code)
  	    {
*************** fold (tree expr)
*** 7521,7527 ****
  	      && TYPE_MAX_VALUE (TREE_TYPE (cval1))
  	      && TYPE_MAX_VALUE (TREE_TYPE (cval2))
  	      && ! operand_equal_p (TYPE_MIN_VALUE (TREE_TYPE (cval1)),
! 				    TYPE_MAX_VALUE (TREE_TYPE (cval2)), 0))
  	    {
  	      tree maxval = TYPE_MAX_VALUE (TREE_TYPE (cval1));
  	      tree minval = TYPE_MIN_VALUE (TREE_TYPE (cval1));
--- 7540,7547 ----
  	      && TYPE_MAX_VALUE (TREE_TYPE (cval1))
  	      && TYPE_MAX_VALUE (TREE_TYPE (cval2))
  	      && ! operand_equal_p (TYPE_MIN_VALUE (TREE_TYPE (cval1)),
! 				    TYPE_MAX_VALUE (TREE_TYPE (cval2)), 0,
! 				    true))
  	    {
  	      tree maxval = TYPE_MAX_VALUE (TREE_TYPE (cval1));
  	      tree minval = TYPE_MIN_VALUE (TREE_TYPE (cval1));
*************** fold (tree expr)
*** 7680,7686 ****
  	    return pedantic_non_lvalue (tem);
  	  return t;
  	}
!       if (operand_equal_p (arg1, TREE_OPERAND (expr, 2), 0))
  	return pedantic_omit_one_operand (type, arg1, arg0);
  
        /* If we have A op B ? A : C, we may be able to convert this to a
--- 7700,7706 ----
  	    return pedantic_non_lvalue (tem);
  	  return t;
  	}
!       if (operand_equal_p (arg1, TREE_OPERAND (expr, 2), 0, true))
  	return pedantic_omit_one_operand (type, arg1, arg0);
  
        /* If we have A op B ? A : C, we may be able to convert this to a
*************** fold (tree expr)
*** 7721,7727 ****
  	       ? real_zerop (TREE_OPERAND (arg0, 1))
  	       : integer_zerop (TREE_OPERAND (arg0, 1)))
  	      && TREE_CODE (arg2) == NEGATE_EXPR
! 	      && operand_equal_p (TREE_OPERAND (arg2, 0), arg1, 0))
  	    switch (comp_code)
  	      {
  	      case EQ_EXPR:
--- 7741,7747 ----
  	       ? real_zerop (TREE_OPERAND (arg0, 1))
  	       : integer_zerop (TREE_OPERAND (arg0, 1)))
  	      && TREE_CODE (arg2) == NEGATE_EXPR
! 	      && operand_equal_p (TREE_OPERAND (arg2, 0), arg1, 0, true))
  	    switch (comp_code)
  	      {
  	      case EQ_EXPR:
*************** fold (tree expr)
*** 7863,7902 ****
  
  	      case LT_EXPR:
  		/* If C1 is C2 + 1, this is min(A, C2).  */
! 		if (! operand_equal_p (arg2, TYPE_MAX_VALUE (type), 1)
  		    && operand_equal_p (TREE_OPERAND (arg0, 1),
  					const_binop (PLUS_EXPR, arg2,
! 						     integer_one_node, 0), 1))
  		  return pedantic_non_lvalue
  		    (fold (build (MIN_EXPR, type, arg1, arg2)));
  		break;
  
  	      case LE_EXPR:
  		/* If C1 is C2 - 1, this is min(A, C2).  */
! 		if (! operand_equal_p (arg2, TYPE_MIN_VALUE (type), 1)
  		    && operand_equal_p (TREE_OPERAND (arg0, 1),
  					const_binop (MINUS_EXPR, arg2,
! 						     integer_one_node, 0), 1))
  		  return pedantic_non_lvalue
  		    (fold (build (MIN_EXPR, type, arg1, arg2)));
  		break;
  
  	      case GT_EXPR:
  		/* If C1 is C2 - 1, this is max(A, C2).  */
! 		if (! operand_equal_p (arg2, TYPE_MIN_VALUE (type), 1)
  		    && operand_equal_p (TREE_OPERAND (arg0, 1),
  					const_binop (MINUS_EXPR, arg2,
! 						     integer_one_node, 0), 1))
  		  return pedantic_non_lvalue
  		    (fold (build (MAX_EXPR, type, arg1, arg2)));
  		break;
  
  	      case GE_EXPR:
  		/* If C1 is C2 + 1, this is max(A, C2).  */
! 		if (! operand_equal_p (arg2, TYPE_MAX_VALUE (type), 1)
  		    && operand_equal_p (TREE_OPERAND (arg0, 1),
  					const_binop (PLUS_EXPR, arg2,
! 						     integer_one_node, 0), 1))
  		  return pedantic_non_lvalue
  		    (fold (build (MAX_EXPR, type, arg1, arg2)));
  		break;
--- 7883,7926 ----
  
  	      case LT_EXPR:
  		/* If C1 is C2 + 1, this is min(A, C2).  */
! 		if (! operand_equal_p (arg2, TYPE_MAX_VALUE (type), 1, true)
  		    && operand_equal_p (TREE_OPERAND (arg0, 1),
  					const_binop (PLUS_EXPR, arg2,
! 						     integer_one_node, 0), 1,
! 						     true))
  		  return pedantic_non_lvalue
  		    (fold (build (MIN_EXPR, type, arg1, arg2)));
  		break;
  
  	      case LE_EXPR:
  		/* If C1 is C2 - 1, this is min(A, C2).  */
! 		if (! operand_equal_p (arg2, TYPE_MIN_VALUE (type), 1, true)
  		    && operand_equal_p (TREE_OPERAND (arg0, 1),
  					const_binop (MINUS_EXPR, arg2,
! 						     integer_one_node, 0), 1,
! 						     true))
  		  return pedantic_non_lvalue
  		    (fold (build (MIN_EXPR, type, arg1, arg2)));
  		break;
  
  	      case GT_EXPR:
  		/* If C1 is C2 - 1, this is max(A, C2).  */
! 		if (! operand_equal_p (arg2, TYPE_MIN_VALUE (type), 1, true)
  		    && operand_equal_p (TREE_OPERAND (arg0, 1),
  					const_binop (MINUS_EXPR, arg2,
! 						     integer_one_node, 0),
! 						     1, true))
  		  return pedantic_non_lvalue
  		    (fold (build (MAX_EXPR, type, arg1, arg2)));
  		break;
  
  	      case GE_EXPR:
  		/* If C1 is C2 + 1, this is max(A, C2).  */
! 		if (! operand_equal_p (arg2, TYPE_MAX_VALUE (type), 1, true)
  		    && operand_equal_p (TREE_OPERAND (arg0, 1),
  					const_binop (PLUS_EXPR, arg2,
! 						     integer_one_node, 0), 1,
! 						     true))
  		  return pedantic_non_lvalue
  		    (fold (build (MAX_EXPR, type, arg1, arg2)));
  		break;
*************** fold (tree expr)
*** 7949,7955 ****
  	  && integer_pow2p (arg1)
  	  && TREE_CODE (TREE_OPERAND (arg0, 0)) == BIT_AND_EXPR
  	  && operand_equal_p (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1),
! 			      arg1, 1))
  	return pedantic_non_lvalue (convert (type, TREE_OPERAND (arg0, 0)));
  
        /* Convert A ? B : 0 into A && B if A and B are truth values.  */
--- 7973,7979 ----
  	  && integer_pow2p (arg1)
  	  && TREE_CODE (TREE_OPERAND (arg0, 0)) == BIT_AND_EXPR
  	  && operand_equal_p (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1),
! 			      arg1, 1, true))
  	return pedantic_non_lvalue (convert (type, TREE_OPERAND (arg0, 0)));
  
        /* Convert A ? B : 0 into A && B if A and B are truth values.  */
*************** fold_initializer (tree expr)
*** 8340,8346 ****
  static int
  multiple_of_p (tree type, tree top, tree bottom)
  {
!   if (operand_equal_p (top, bottom, 0))
      return 1;
  
    if (TREE_CODE (type) != INTEGER_TYPE)
--- 8364,8370 ----
  static int
  multiple_of_p (tree type, tree top, tree bottom)
  {
!   if (operand_equal_p (top, bottom, 0, true))
      return 1;
  
    if (TREE_CODE (type) != INTEGER_TYPE)
*************** tree_expr_nonnegative_p (tree t)
*** 8445,8451 ****
        if (FLOAT_TYPE_P (TREE_TYPE (t)))
  	{
  	  /* x * x for floating point x is always non-negative.  */
! 	  if (operand_equal_p (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1), 0))
  	    return 1;
  	  return tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
  		 && tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
--- 8469,8476 ----
        if (FLOAT_TYPE_P (TREE_TYPE (t)))
  	{
  	  /* x * x for floating point x is always non-negative.  */
! 	  if (operand_equal_p (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1), 0,
! 			       true))
  	    return 1;
  	  return tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
  		 && tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
*************** nondestructive_fold_binary_to_constant (
*** 9182,9188 ****
           In IEEE, it is unsafe because it does wrong for NaNs.
           Also note that operand_equal_p is always false if an
           operand is volatile.  */
!       if (! FLOAT_TYPE_P (type) && operand_equal_p (op0, op1, 0))
  	return convert (type, integer_zero_node);
  
        goto binary;
--- 9207,9213 ----
           In IEEE, it is unsafe because it does wrong for NaNs.
           Also note that operand_equal_p is always false if an
           operand is volatile.  */
!       if (! FLOAT_TYPE_P (type) && operand_equal_p (op0, op1, 0, true))
  	return convert (type, integer_zero_node);
  
        goto binary;
*************** nondestructive_fold_binary_to_constant (
*** 9231,9237 ****
  
      case MIN_EXPR:
        if (INTEGRAL_TYPE_P (type)
! 	  && operand_equal_p (op1, TYPE_MIN_VALUE (type), 1))
  	return omit_one_operand (type, op1, op0);
  
        goto binary;
--- 9256,9262 ----
  
      case MIN_EXPR:
        if (INTEGRAL_TYPE_P (type)
! 	  && operand_equal_p (op1, TYPE_MIN_VALUE (type), 1, true))
  	return omit_one_operand (type, op1, op0);
  
        goto binary;
*************** nondestructive_fold_binary_to_constant (
*** 9239,9245 ****
      case MAX_EXPR:
        if (INTEGRAL_TYPE_P (type)
  	  && TYPE_MAX_VALUE (type)
! 	  && operand_equal_p (op1, TYPE_MAX_VALUE (type), 1))
  	return omit_one_operand (type, op1, op0);
  
        goto binary;
--- 9264,9270 ----
      case MAX_EXPR:
        if (INTEGRAL_TYPE_P (type)
  	  && TYPE_MAX_VALUE (type)
! 	  && operand_equal_p (op1, TYPE_MAX_VALUE (type), 1, true))
  	return omit_one_operand (type, op1, op0);
  
        goto binary;
Index: java/jcf-write.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/jcf-write.c,v
retrieving revision 1.107.2.20
diff -c -3 -p -r1.107.2.20 jcf-write.c
*** java/jcf-write.c	3 Jan 2004 23:03:30 -0000	1.107.2.20
--- java/jcf-write.c	7 Jan 2004 19:07:26 -0000
*************** generate_bytecode_insns (tree exp, int t
*** 2093,2099 ****
        tree arg0 = TREE_OPERAND (exp, 0);
        tree arg1 = TREE_OPERAND (exp, 1);
        jopcode += adjust_typed_op (type, 3);
!       if (arg0 != NULL_TREE && operand_equal_p (arg0, arg1, 0))
  	{
  	  /* fold may (e.g) convert 2*x to x+x. */
  	  generate_bytecode_insns (arg0, target, state);
--- 2093,2099 ----
        tree arg0 = TREE_OPERAND (exp, 0);
        tree arg1 = TREE_OPERAND (exp, 1);
        jopcode += adjust_typed_op (type, 3);
!       if (arg0 != NULL_TREE && operand_equal_p (arg0, arg1, 0, false))
  	{
  	  /* fold may (e.g) convert 2*x to x+x. */
  	  generate_bytecode_insns (arg0, target, state);

----- End forwarded message -----


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