fold-const.c (operand_equal_p): Consider two calls to "const" functions with identica...
authorRoger Sayle <roger@eyesopen.com>
Mon, 16 Jun 2003 12:42:48 +0000 (12:42 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Mon, 16 Jun 2003 12:42:48 +0000 (12:42 +0000)
* fold-const.c (operand_equal_p): Consider two calls to "const"
functions with identical non-volatile arguments to be equal.
Consider the FUNCTION_DECL for the "__builtin_foo" form of a
built-in function to be equal to the "foo" form.

Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r68011

gcc/ChangeLog
gcc/fold-const.c

index 13b971f..2501744 100644 (file)
@@ -1,3 +1,11 @@
+2003-06-16  Roger Sayle  <roger@eyesopen.com>
+           Jeff Law  <law@redhat.com>
+
+       * fold-const.c (operand_equal_p): Consider two calls to "const"
+       functions with identical non-volatile arguments to be equal.
+       Consider the FUNCTION_DECL for the "__builtin_foo" form of a
+       built-in function to be equal to the "foo" form.
+
 2003-06-16  Nathanael Nerode  <neroden@gcc.gnu.org>
 
        * config/rs6000/sysv4le.h: Remove target-independent comment.
index bdc84de..0e53f41 100644 (file)
@@ -1968,8 +1968,8 @@ operand_equal_p (arg0, arg1, only_const)
                                  TREE_OPERAND (arg1, 0), 0));
 
     case 'r':
-      /* If either of the pointer (or reference) expressions we are dereferencing
-        contain a side effect, these cannot be equal.  */
+      /* If either of the pointer (or reference) expressions we are
+        dereferencing contain a side effect, these cannot be equal.  */
       if (TREE_SIDE_EFFECTS (arg0)
          || TREE_SIDE_EFFECTS (arg1))
        return 0;
@@ -2010,10 +2010,52 @@ operand_equal_p (arg0, arg1, only_const)
        case RTL_EXPR:
          return rtx_equal_p (RTL_EXPR_RTL (arg0), RTL_EXPR_RTL (arg1));
 
+       case CALL_EXPR:
+         /* 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.  */
+         if (TREE_CODE (TREE_OPERAND (arg0, 0)) == ADDR_EXPR)
+           {
+             tree fndecl = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
+             if (! (flags_from_decl_or_type (fndecl) & ECF_CONST))
+               return 0;
+           }
+         else
+           return 0;
+
+         /* Now see if all the arguments are the same.  operand_equal_p
+            does not handle TREE_LIST, so we walk the operands here
+            feeding them to operand_equal_p.  */
+         arg0 = TREE_OPERAND (arg0, 1);
+         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);
+             arg1 = TREE_CHAIN (arg1);
+           }
+
+         /* If we get here and both argument lists are exhausted
+            then the CALL_EXPRs are equal.  */
+         return ! (arg0 || arg1);
+
        default:
          return 0;
        }
 
+    case 'd':
+       /* Consider __builtin_sqrt equal to sqrt.  */
+       return TREE_CODE (arg0) == FUNCTION_DECL
+              && DECL_BUILT_IN (arg0) && DECL_BUILT_IN (arg1)
+              && DECL_BUILT_IN_CLASS (arg0) == DECL_BUILT_IN_CLASS (arg1)
+              && DECL_FUNCTION_CODE (arg0) == DECL_FUNCTION_CODE (arg1);
+
     default:
       return 0;
     }