]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree.c (skip_simple_arithmetics_at, [...]): New functions.
authorOlivier Hainque <hainque@act-europe.fr>
Wed, 16 Apr 2003 21:33:19 +0000 (23:33 +0200)
committerRichard Kenner <kenner@gcc.gnu.org>
Wed, 16 Apr 2003 21:33:19 +0000 (17:33 -0400)
        * tree.c (skip_simple_arithmetics_at, saved_expr_p): New functions.
        (save_expr): Replace loop by call to skip_simple_arithmetics_at.
        * tree.h: Add prototypes for the two new functions.
        * fold-const.c (fold_binary_op_with_conditional_arg): Replace test
        updates introduced in the previous revision by call to saved_expr_p.
        * stor-layout.c (put_pending_size): Use skip_simple_arithmetics_at.

From-SVN: r65702

gcc/ChangeLog
gcc/fold-const.c
gcc/stor-layout.c
gcc/tree.c
gcc/tree.h

index bb692cf621d6bfb04f1b3b9befd8edda9f4182b4..19fdf5af8fcdf030e718d8c93475727de27009f2 100644 (file)
@@ -1,5 +1,12 @@
 2003-04-16  Olivier Hainque <hainque@act-europe.fr>
 
+        * tree.c (skip_simple_arithmetics_at, saved_expr_p): New functions.
+        (save_expr): Replace loop by call to skip_simple_arithmetics_at.
+        * tree.h: Add prototypes for the two new functions.
+        * fold-const.c (fold_binary_op_with_conditional_arg): Replace test
+        updates introduced in the previous revision by call to saved_expr_p.
+        * stor-layout.c (put_pending_size): Use skip_simple_arithmetics_at.
+
         * expr.c (store_field): Force usage of bitfield instructions when
         the field position requires it, whatever SLOW_UNALIGNED_ACCESS.
         (expand_expr, case BIT_FIELD_REF): likewise.
index 065a4fc527d32b5276558e1af480dd5ec768c89d..fa64fd2b956bb707b6404bbbe34444c5a07f4fd3 100644 (file)
@@ -4568,21 +4568,19 @@ fold_binary_op_with_conditional_arg (code, type, cond, arg, cond_first_p)
       false_value = convert (testtype, integer_zero_node);
     }
 
-  /* If ARG is complex we want to make sure we only evaluate
-     it once.  Though this is only required if it is volatile, it
-     might be more efficient even if it is not.  However, if we
-     succeed in folding one part to a constant, we do not need
-     to make this SAVE_EXPR.  Since we do this optimization
-     primarily to see if we do end up with constant and this
-     SAVE_EXPR interferes with later optimizations, suppressing
-     it when we can is important.
-
-     If we are not in a function, we can't make a SAVE_EXPR, so don't
-     try to do so.  Don't try to see if the result is a constant
-     if an arm is a COND_EXPR since we get exponential behavior
-     in that case.  */
-
-  if (TREE_CODE (arg) == SAVE_EXPR)
+  /* If ARG is complex we want to make sure we only evaluate it once.  Though
+     this is only required if it is volatile, it might be more efficient even
+     if it is not.  However, if we succeed in folding one part to a constant,
+     we do not need to make this SAVE_EXPR.  Since we do this optimization
+     primarily to see if we do end up with constant and this SAVE_EXPR
+     interferes with later optimizations, suppressing it when we can is
+     important.
+
+     If we are not in a function, we can't make a SAVE_EXPR, so don't try to
+     do so.  Don't try to see if the result is a constant if an arm is a
+     COND_EXPR since we get exponential behavior in that case.  */
+
+  if (saved_expr_p (arg))
     save = 1;
   else if (lhs == 0 && rhs == 0
           && !TREE_CONSTANT (arg)
index 7ebdda845d181cbb2dac0e3967604d4cc889c733..66067d6f276e140e6f43dba1ca1be9a95ddea08f 100644 (file)
@@ -128,10 +128,7 @@ put_pending_size (expr)
 {
   /* Strip any simple arithmetic from EXPR to see if it has an underlying
      SAVE_EXPR.  */
-  while (TREE_CODE_CLASS (TREE_CODE (expr)) == '1'
-        || (TREE_CODE_CLASS (TREE_CODE (expr)) == '2'
-           && TREE_CONSTANT (TREE_OPERAND (expr, 1))))
-    expr = TREE_OPERAND (expr, 0);
+  expr = skip_simple_arithmetic (expr);
 
   if (TREE_CODE (expr) == SAVE_EXPR)
     pending_sizes = tree_cons (NULL_TREE, expr, pending_sizes);
index 09c239e743f404a5adf81abc2bac19f28270fda6..ce5e21997b13b28081cbdddff2f15f17ecd7ac8b 100644 (file)
@@ -1379,34 +1379,7 @@ save_expr (expr)
      tree expr;
 {
   tree t = fold (expr);
-  tree inner;
-
-  /* We don't care about whether this can be used as an lvalue in this
-     context.  */
-  while (TREE_CODE (t) == NON_LVALUE_EXPR)
-    t = TREE_OPERAND (t, 0);
-
-  /* If we have simple operations applied to a SAVE_EXPR or to a SAVE_EXPR and
-     a constant, it will be more efficient to not make another SAVE_EXPR since
-     it will allow better simplification and GCSE will be able to merge the
-     computations if they actually occur.  */
-  inner = t;
-  while (1)
-    {
-      if (TREE_CODE_CLASS (TREE_CODE (inner)) == '1')
-       inner = TREE_OPERAND (inner, 0);
-      else if (TREE_CODE_CLASS (TREE_CODE (inner)) == '2')
-       {
-         if (TREE_CONSTANT (TREE_OPERAND (inner, 1)))
-           inner = TREE_OPERAND (inner, 0);
-         else if (TREE_CONSTANT (TREE_OPERAND (inner, 0)))
-           inner = TREE_OPERAND (inner, 1);
-         else
-           break;
-       }
-      else
-       break;
-    }
+  tree inner = skip_simple_arithmetic (t);
 
   /* If the tree evaluates to a constant, then we don't want to hide that
      fact (i.e. this allows further folding, and direct checks for constants).
@@ -1419,7 +1392,7 @@ save_expr (expr)
       || TREE_CODE (inner) == ERROR_MARK)
     return t;
 
-  /* If T contains a PLACEHOLDER_EXPR, we must evaluate it each time, since
+  /* If INNER contains a PLACEHOLDER_EXPR, we must evaluate it each time, since
      it means that the size or offset of some field of an object depends on
      the value within another field.
 
@@ -1428,7 +1401,7 @@ save_expr (expr)
      evaluated more than once.  Front-ends must assure this case cannot
      happen by surrounding any such subexpressions in their own SAVE_EXPR
      and forcing evaluation at the proper time.  */
-  if (contains_placeholder_p (t))
+  if (contains_placeholder_p (inner))
     return t;
 
   t = build (SAVE_EXPR, TREE_TYPE (expr), t, current_function_decl, NULL_TREE);
@@ -1441,6 +1414,55 @@ save_expr (expr)
   return t;
 }
 
+/* Look inside EXPR and into any simple arithmetic operations.  Return
+   the innermost non-arithmetic node.  */
+
+tree
+skip_simple_arithmetic (expr)
+     tree expr;
+{
+  tree inner;
+  
+  /* We don't care about whether this can be used as an lvalue in this
+     context.  */
+  while (TREE_CODE (expr) == NON_LVALUE_EXPR)
+    expr = TREE_OPERAND (expr, 0);
+
+  /* If we have simple operations applied to a SAVE_EXPR or to a SAVE_EXPR and
+     a constant, it will be more efficient to not make another SAVE_EXPR since
+     it will allow better simplification and GCSE will be able to merge the
+     computations if they actually occur.  */
+  inner = expr;
+  while (1)
+    {
+      if (TREE_CODE_CLASS (TREE_CODE (inner)) == '1')
+       inner = TREE_OPERAND (inner, 0);
+      else if (TREE_CODE_CLASS (TREE_CODE (inner)) == '2')
+       {
+         if (TREE_CONSTANT (TREE_OPERAND (inner, 1)))
+           inner = TREE_OPERAND (inner, 0);
+         else if (TREE_CONSTANT (TREE_OPERAND (inner, 0)))
+           inner = TREE_OPERAND (inner, 1);
+         else
+           break;
+       }
+      else
+       break;
+    }
+
+  return inner;
+}
+
+/* Return TRUE if EXPR is a SAVE_EXPR or wraps simple arithmetic around a
+   SAVE_EXPR.  Return FALSE otherwise.  */
+
+bool
+saved_expr_p (expr)
+     tree expr;
+{
+  return TREE_CODE (skip_simple_arithmetic (expr)) == SAVE_EXPR;
+}
+
 /* Arrange for an expression to be expanded multiple independent
    times.  This is useful for cleanup actions, as the backend can
    expand them multiple times in different places.  */
index 95f2ad4ac03b8806c85f20fa5e2af04a5b00e8be..44ccd45178458c039ed8915cb7f7f7d00b0ae9db 100644 (file)
@@ -2681,6 +2681,16 @@ extern int lvalue_or_else                PARAMS ((tree, const char *));
 
 extern tree save_expr                  PARAMS ((tree));
 
+/* Look inside EXPR and into any simple arithmetic operations.  Return
+   the innermost non-arithmetic node.  */
+
+extern tree skip_simple_arithmetic     PARAMS ((tree));
+
+/* Return TRUE if EXPR is a SAVE_EXPR or wraps simple arithmetic around a
+   SAVE_EXPR.  Return FALSE otherwise.  */
+
+extern bool saved_expr_p                PARAMS ((tree));
+
 /* Returns the index of the first non-tree operand for CODE, or the number
    of operands if all are trees.  */