diff options
author | samuel <samuel@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-12-01 08:13:54 +0000 |
---|---|---|
committer | samuel <samuel@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-12-01 08:13:54 +0000 |
commit | f7cb0e3920463e689701f00ecc35b366e7d429ec (patch) | |
tree | c96dbba718d499e1c801803080a2d22950da4a59 /gcc/ggc-common.c | |
parent | 14b40abb6ae68019b5e020f193fd5965701d4b97 (diff) | |
download | gcc-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.c | 128 |
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 |