]> gcc.gnu.org Git - gcc.git/commitdiff
tree.c (first_rtl_op): New fn.
authorJason Merrill <jason@yorick.cygnus.com>
Mon, 16 Feb 1998 04:52:31 +0000 (04:52 +0000)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 16 Feb 1998 04:52:31 +0000 (23:52 -0500)
* tree.c (first_rtl_op): New fn.
(unsave_expr_now): Use it.
* print-tree.c (print_node): Likewise.
* tree.c (has_cleanups): New fn.
* fold-const.c (fold, case CLEANUP_POINT_EXPR): Use it.  Be more
conservative about pushing the cleanup point down.
* tree.h: Declare them.

From-SVN: r18023

gcc/ChangeLog
gcc/fold-const.c
gcc/print-tree.c
gcc/tree.c
gcc/tree.h

index 472a5b34175bb367993a3f0796b3ce0dc52cda7c..ce452cb14a921b27b13bc74ff1abaf059b36a031 100644 (file)
@@ -1,3 +1,13 @@
+1998-02-16  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * tree.c (first_rtl_op): New fn.
+       (unsave_expr_now): Use it.
+       * print-tree.c (print_node): Likewise.
+       * tree.c (has_cleanups): New fn.
+       * fold-const.c (fold, case CLEANUP_POINT_EXPR): Use it.  Be more
+       conservative about pushing the cleanup point down.
+       * tree.h: Declare them.
+
 Sun Feb 15 23:28:44 1998  Jeffrey A Law  (law@cygnus.com)
 
        * toplev.c (flag_schedule_reverse_before_reload): Delete variable.
index 4d021dbfebcb1be2beb9a27df2521905b72fa748..35d8bebe9164a991cccc5be58e7c8601d1de9398 100644 (file)
@@ -5920,7 +5920,7 @@ fold (expr)
       /* Pull arithmetic ops out of the CLEANUP_POINT_EXPR where
          appropriate.  */
     case CLEANUP_POINT_EXPR:
-      if (! TREE_SIDE_EFFECTS (arg0))
+      if (! has_cleanups (arg0))
        return TREE_OPERAND (t, 0);
 
       {
@@ -5941,12 +5941,14 @@ fold (expr)
          {
            arg01 = TREE_OPERAND (arg0, 1);
 
-           if (! TREE_SIDE_EFFECTS (arg00))
+           if (TREE_CONSTANT (arg00)
+               || ((code0 == TRUTH_ANDIF_EXPR || code0 == TRUTH_ORIF_EXPR)
+                   && ! has_cleanups (arg00)))
              return fold (build (code0, type, arg00,
                                  fold (build1 (CLEANUP_POINT_EXPR,
                                                TREE_TYPE (arg01), arg01))));
 
-           if (! TREE_SIDE_EFFECTS (arg01))
+           if (TREE_CONSTANT (arg01))
              return fold (build (code0, type,
                                  fold (build1 (CLEANUP_POINT_EXPR,
                                                TREE_TYPE (arg00), arg00)),
index f075f0b3834634dbe462d1d597a08ea2fb5846fa..5b81bc5dd9f83511781b4dbe0e7425c61728e8d6 100644 (file)
@@ -547,29 +547,10 @@ print_node (file, prefix, node, indent)
          return;
        }
 
-      first_rtl = len = tree_code_length[(int) TREE_CODE (node)];
-      /* These kinds of nodes contain rtx's, not trees,
+      len = tree_code_length[(int) TREE_CODE (node)];
+      /* Some nodes contain rtx's, not trees,
         after a certain point.  Print the rtx's as rtx's.  */
-      switch (TREE_CODE (node))
-       {
-       case SAVE_EXPR:
-         first_rtl = 2;
-         break;
-       case CALL_EXPR:
-         first_rtl = 2;
-         break;
-       case METHOD_CALL_EXPR:
-         first_rtl = 3;
-         break;
-       case WITH_CLEANUP_EXPR:
-         /* Should be defined to be 2.  */
-         first_rtl = 1;
-         break;
-       case RTL_EXPR:
-         first_rtl = 0;
-       default:
-         break;
-       }
+      first_rtl = first_rtl_op (TREE_CODE (node));
       for (i = 0; i < len; i++)
        {
          if (i >= first_rtl)
index 9659cd0ff811d47d9797fc8afd74d787e01d7352..1f135328717e33d579fdc90548df859a9d76335b 100644 (file)
@@ -2387,6 +2387,31 @@ unsave_expr (expr)
   return t;
 }
 
+/* Returns the index of the first non-tree operand for CODE, or the number
+   of operands if all are trees.  */
+
+int
+first_rtl_op (code)
+     enum tree_code code;
+{
+  switch (code)
+    {
+    case SAVE_EXPR:
+      return 2;
+    case RTL_EXPR:
+      return 0;
+    case CALL_EXPR:
+      return 2;
+    case WITH_CLEANUP_EXPR:
+      /* Should be defined to be 2.  */
+      return 1;
+    case METHOD_CALL_EXPR:
+      return 3;
+    default:
+      return tree_code_length [(int) code];
+    }
+}
+
 /* Modify a tree in place so that all the evaluate only once things
    are cleared out.  Return the EXPR given.  */
 
@@ -2402,12 +2427,11 @@ unsave_expr_now (expr)
     return expr;
 
   code = TREE_CODE (expr);
-  first_rtl = tree_code_length [(int) code];
+  first_rtl = first_rtl_op (code);
   switch (code)
     {
     case SAVE_EXPR:
       SAVE_EXPR_RTL (expr) = 0;
-      first_rtl = 2;
       break;
 
     case TARGET_EXPR:
@@ -2419,7 +2443,6 @@ unsave_expr_now (expr)
       /* I don't yet know how to emit a sequence multiple times.  */
       if (RTL_EXPR_SEQUENCE (expr) != 0)
        abort ();
-      first_rtl = 0;
       break;
 
     case CALL_EXPR:
@@ -2434,16 +2457,6 @@ unsave_expr_now (expr)
              exp = TREE_CHAIN (exp);
            }
        }
-      first_rtl = 2;
-      break;
-
-    case WITH_CLEANUP_EXPR:
-      /* Should be defined to be 2.  */
-      first_rtl = 1;
-      break;
-
-    case METHOD_CALL_EXPR:
-      first_rtl = 3;
       break;
 
     default:
@@ -2561,6 +2574,64 @@ contains_placeholder_p (exp)
       return 0;
     }
 }
+
+/* Return 1 if EXP contains any expressions that produce cleanups for an
+   outer scope to deal with.  Used by fold.  */
+
+int
+has_cleanups (exp)
+     tree exp;
+{
+  int i, nops, cmp;
+
+  if (! TREE_SIDE_EFFECTS (exp))
+    return 0;
+
+  switch (TREE_CODE (exp))
+    {
+    case TARGET_EXPR:
+    case WITH_CLEANUP_EXPR:
+      return 1;
+
+    case CLEANUP_POINT_EXPR:
+      return 0;
+
+    case CALL_EXPR:
+      for (exp = TREE_OPERAND (exp, 1); exp; exp = TREE_CHAIN (exp))
+       {
+         cmp = has_cleanups (TREE_VALUE (exp));
+         if (cmp)
+           return cmp;
+       }
+      return 0;
+
+    default:
+      break;
+    }
+
+  /* This general rule works for most tree codes.  All exceptions should be
+     handled above.  If this is a language-specific tree code, we can't
+     trust what might be in the operand, so say we don't know
+     the situation.  */
+  if ((int) TREE_CODE (exp) >= (int) LAST_AND_UNUSED_TREE_CODE)
+    return -1;
+
+  nops = first_rtl_op (TREE_CODE (exp));
+  for (i = 0; i < nops; i++)
+    if (TREE_OPERAND (exp, i) != 0)
+      {
+       int type = TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, i)));
+       if (type == 'e' || type == '<' || type == '1' || type == '2'
+           || type == 'r' || type == 's')
+         {
+           cmp = has_cleanups (TREE_OPERAND (exp, i));
+           if (cmp)
+             return cmp;
+         }
+      }
+
+  return 0;
+}
 \f
 /* Given a tree EXP, a FIELD_DECL F, and a replacement value R,
    return a tree with all occurrences of references to F in a
index 093304ab04e1a638cc8d417589315163872ce7a2..39ec3033055679ce03cc7cca23fe345d92978779 100644 (file)
@@ -1490,6 +1490,11 @@ extern int lvalue_or_else                PROTO((tree, char *));
 
 extern tree save_expr                  PROTO((tree));
 
+/* Returns the index of the first non-tree operand for CODE, or the number
+   of operands if all are trees.  */
+
+extern int first_rtl_op                        PROTO((enum tree_code));
+
 /* unsave_expr (EXP) returns an expression equivalent to EXP but it
    can be used multiple times and will evaluate EXP, in it's entirety
    each time.  */
@@ -1509,6 +1514,11 @@ extern tree unsave_expr_now              PROTO((tree));
 
 extern int contains_placeholder_p      PROTO((tree));
 
+/* Return 1 if EXP contains any expressions that produce cleanups for an
+   outer scope to deal with.  Used by fold.  */
+
+extern int has_cleanups                        PROTO((tree));
+
 /* Given a tree EXP, a FIELD_DECL F, and a replacement value R,
    return a tree with all occurrences of references to F in a
    PLACEHOLDER_EXPR replaced by R.   Note that we assume here that EXP
This page took 0.087609 seconds and 5 git commands to generate.