summaryrefslogtreecommitdiff
path: root/gcc/ggc-common.c
diff options
context:
space:
mode:
authorsamuel <samuel@138bc75d-0d04-0410-961f-82ee72b054a4>1999-12-01 08:13:54 +0000
committersamuel <samuel@138bc75d-0d04-0410-961f-82ee72b054a4>1999-12-01 08:13:54 +0000
commitf7cb0e3920463e689701f00ecc35b366e7d429ec (patch)
treec96dbba718d499e1c801803080a2d22950da4a59 /gcc/ggc-common.c
parent14b40abb6ae68019b5e020f193fd5965701d4b97 (diff)
downloadgcc-f7cb0e3920463e689701f00ecc35b366e7d429ec.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@30734 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ggc-common.c')
-rw-r--r--gcc/ggc-common.c128
1 files changed, 72 insertions, 56 deletions
diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c
index bacbcddbd5d..4fd9810e633 100644
--- a/gcc/ggc-common.c
+++ b/gcc/ggc-common.c
@@ -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