* tree.c (skip_simple_arithmetics_at, saved_expr_p): New functions.
authorkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 16 Apr 2003 21:33:19 +0000 (21:33 +0000)
committerkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 16 Apr 2003 21:33:19 +0000 (21:33 +0000)
        (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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@65702 138bc75d-0d04-0410-961f-82ee72b054a4

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

index bb692cf..19fdf5a 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 065a4fc..fa64fd2 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 7ebdda8..66067d6 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 09c239e..ce5e219 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 95f2ad4..44ccd45 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.  */