OSDN Git Service

* ggc.h (ggc_test_and_set_mark): New macro.
authorsamuel <samuel@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 1 Dec 1999 08:13:54 +0000 (08:13 +0000)
committersamuel <samuel@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 1 Dec 1999 08:13:54 +0000 (08:13 +0000)
(ggc_mark_rtx): Use ggc_test_and_set_mark.
(ggc_mark_tree): Likewise.
(ggc_mark_rtvec): Likewise.
* ggc-common.c (ggc_mark_rtx_children): Reduce recursion.

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

gcc/ChangeLog
gcc/ggc-common.c
gcc/ggc.h

index 2fdac34..6f153d1 100644 (file)
@@ -1,3 +1,11 @@
+1999-11-30  Alex Samuel  <samuel@codesourcery.com>
+
+       * ggc.h (ggc_test_and_set_mark): New macro.
+       (ggc_mark_rtx): Use ggc_test_and_set_mark.
+       (ggc_mark_tree): Likewise.
+       (ggc_mark_rtvec): Likewise.
+       * ggc-common.c (ggc_mark_rtx_children): Reduce recursion. 
+
 1999-11-30  Jason Merrill  <jason@casey.cygnus.com>
 
        * dwarf2out.c (scope_die_for): Only handle types.  Only search for
index bacbcdd..4fd9810 100644 (file)
@@ -234,76 +234,92 @@ ggc_mark_rtx_children (r)
 {
   const char *fmt;
   int i;
-  enum rtx_code code = GET_CODE (r);
+  rtx next_rtx;
 
-  /* Collect statistics, if appropriate.  */
-  if (ggc_stats)
+  do 
     {
-      ++ggc_stats->num_rtxs[(int) code];
-      ggc_stats->size_rtxs[(int) code] += ggc_get_size (r);
-    }
+      enum rtx_code code = GET_CODE (r);
+      /* This gets set to a child rtx to eliminate tail recursion.  */
+      next_rtx = NULL;
 
-  /* ??? If (some of) these are really pass-dependant info, do we have
-     any right poking our noses in?  */
-  switch (code)
-    {
-    case JUMP_INSN:
-      ggc_mark_rtx (JUMP_LABEL (r));
-      break;
-    case CODE_LABEL:
-      ggc_mark_rtx (LABEL_REFS (r));
-      ggc_mark_string (LABEL_ALTERNATE_NAME (r));
-      break;
-    case LABEL_REF:
-      ggc_mark_rtx (LABEL_NEXTREF (r));
-      ggc_mark_rtx (CONTAINING_INSN (r));
-      break;
-    case ADDRESSOF:
-      ggc_mark_tree (ADDRESSOF_DECL (r));
-      break;
-    case CONST_DOUBLE:
-      ggc_mark_rtx (CONST_DOUBLE_CHAIN (r));
-      break;
-    case NOTE:
-      switch (NOTE_LINE_NUMBER (r))
+      /* Collect statistics, if appropriate.  */
+      if (ggc_stats)
        {
-       case NOTE_INSN_RANGE_START:
-       case NOTE_INSN_RANGE_END:
-       case NOTE_INSN_LIVE:
-         ggc_mark_rtx (NOTE_RANGE_INFO (r));
-         break;
+         ++ggc_stats->num_rtxs[(int) code];
+         ggc_stats->size_rtxs[(int) code] += ggc_get_size (r);
+       }
 
-       case NOTE_INSN_BLOCK_BEG:
-       case NOTE_INSN_BLOCK_END:
-         ggc_mark_tree (NOTE_BLOCK (r));
+      /* ??? If (some of) these are really pass-dependant info, do we
+        have any right poking our noses in?  */
+      switch (code)
+       {
+       case JUMP_INSN:
+         ggc_mark_rtx (JUMP_LABEL (r));
+         break;
+       case CODE_LABEL:
+         ggc_mark_rtx (LABEL_REFS (r));
+         ggc_mark_string (LABEL_ALTERNATE_NAME (r));
+         break;
+       case LABEL_REF:
+         ggc_mark_rtx (LABEL_NEXTREF (r));
+         ggc_mark_rtx (CONTAINING_INSN (r));
+         break;
+       case ADDRESSOF:
+         ggc_mark_tree (ADDRESSOF_DECL (r));
+         break;
+       case CONST_DOUBLE:
+         ggc_mark_rtx (CONST_DOUBLE_CHAIN (r));
+         break;
+       case NOTE:
+         switch (NOTE_LINE_NUMBER (r))
+           {
+           case NOTE_INSN_RANGE_START:
+           case NOTE_INSN_RANGE_END:
+           case NOTE_INSN_LIVE:
+             ggc_mark_rtx (NOTE_RANGE_INFO (r));
+             break;
+
+           case NOTE_INSN_BLOCK_BEG:
+           case NOTE_INSN_BLOCK_END:
+             ggc_mark_tree (NOTE_BLOCK (r));
+             break;
+
+           default:
+             if (NOTE_LINE_NUMBER (r) >= 0)
+               ggc_mark_string (NOTE_SOURCE_FILE (r));
+             break;
+           }
          break;
 
        default:
-         if (NOTE_LINE_NUMBER (r) >= 0)
-           ggc_mark_string (NOTE_SOURCE_FILE (r));
          break;
        }
-      break;
 
-    default:
-      break;
-    }
-
-  for (fmt = GET_RTX_FORMAT (GET_CODE (r)), i = 0; *fmt ; ++fmt, ++i)
-    {
-      switch (*fmt)
+      for (fmt = GET_RTX_FORMAT (GET_CODE (r)), i = 0; *fmt ; ++fmt, ++i)
        {
-       case 'e': case 'u':
-         ggc_mark_rtx (XEXP (r, i));
-         break;
-       case 'V': case 'E':
-         ggc_mark_rtvec (XVEC (r, i));
-         break;
-       case 'S': case 's':
-         ggc_mark_if_gcable (XSTR (r, i));
-         break;
+         rtx exp;
+         switch (*fmt)
+           {
+           case 'e': case 'u':
+             exp = XEXP (r, i);
+             if (ggc_test_and_set_mark (exp))
+               { 
+                 if (next_rtx == NULL) 
+                   next_rtx = exp; 
+                 else 
+                   ggc_mark_rtx_children (exp);
+               } 
+             break;
+           case 'V': case 'E':
+             ggc_mark_rtvec (XVEC (r, i));
+             break;
+           case 'S': case 's':
+             ggc_mark_if_gcable (XSTR (r, i));
+             break;
+           }
        }
     }
+  while ((r = next_rtx) != NULL);
 }
 
 /* V had not been previously marked, but has now been marked via
index 3f55a21..809edec 100644 (file)
--- a/gcc/ggc.h
+++ b/gcc/ggc.h
@@ -64,25 +64,30 @@ extern void ggc_mark_rtx_children PROTO ((struct rtx_def *));
 extern void ggc_mark_rtvec_children PROTO ((struct rtvec_def *));
 extern void ggc_mark_tree_children PROTO ((union tree_node *));
 
-#define ggc_mark_rtx(EXPR)                     \
-  do {                                         \
-    rtx r__ = (EXPR);                          \
-    if (r__ != NULL && ! ggc_set_mark (r__))   \
-      ggc_mark_rtx_children (r__);             \
+/* If EXPR is not NULL and previously unmarked, mark it and evaluate
+   to true.  Otherwise evaluate to false.  */
+#define ggc_test_and_set_mark(EXPR) \
+  ((EXPR) != NULL && ! ggc_set_mark (EXPR))
+
+#define ggc_mark_rtx(EXPR)                      \
+  do {                                          \
+    rtx r__ = (EXPR);                           \
+    if (ggc_test_and_set_mark (r__))            \
+      ggc_mark_rtx_children (r__);              \
   } while (0)
 
-#define ggc_mark_tree(EXPR)                    \
-  do {                                         \
-    tree t__ = (EXPR);                         \
-    if (t__ != NULL && ! ggc_set_mark (t__))   \
-      ggc_mark_tree_children (t__);            \
+#define ggc_mark_tree(EXPR)                     \
+  do {                                          \
+    tree t__ = (EXPR);                          \
+    if (ggc_test_and_set_mark (t__))            \
+      ggc_mark_tree_children (t__);             \
   } while (0)
 
-#define ggc_mark_rtvec(EXPR)                   \
-  do {                                         \
-    rtvec v__ = (EXPR);                                \
-    if (v__ != NULL && ! ggc_set_mark (v__))   \
-      ggc_mark_rtvec_children (v__);           \
+#define ggc_mark_rtvec(EXPR)                    \
+  do {                                          \
+    rtvec v__ = (EXPR);                         \
+    if (ggc_test_and_set_mark (v__))            \
+      ggc_mark_rtvec_children (v__);            \
   } while (0)
 
 #define ggc_mark_string(EXPR)                  \