diff options
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/ggc-common.c | 128 | ||||
-rw-r--r-- | gcc/ggc.h | 35 |
3 files changed, 100 insertions, 71 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2fdac346e38..6f153d10e0f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 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 diff --git a/gcc/ggc.h b/gcc/ggc.h index 3f55a21736b..809edeca1a3 100644 --- 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) \ |