Commit 52a92176 by Alex Samuel Committed by Alex Samuel

ggc.h (ggc_test_and_set_mark): New macro.

	* 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.

From-SVN: r30734
parent 777ad4c2
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> 1999-11-30 Jason Merrill <jason@casey.cygnus.com>
* dwarf2out.c (scope_die_for): Only handle types. Only search for * dwarf2out.c (scope_die_for): Only handle types. Only search for
......
...@@ -234,76 +234,92 @@ ggc_mark_rtx_children (r) ...@@ -234,76 +234,92 @@ ggc_mark_rtx_children (r)
{ {
const char *fmt; const char *fmt;
int i; int i;
enum rtx_code code = GET_CODE (r); rtx next_rtx;
/* Collect statistics, if appropriate. */ do
if (ggc_stats)
{ {
++ggc_stats->num_rtxs[(int) code]; enum rtx_code code = GET_CODE (r);
ggc_stats->size_rtxs[(int) code] += ggc_get_size (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 /* Collect statistics, if appropriate. */
any right poking our noses in? */ if (ggc_stats)
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: ++ggc_stats->num_rtxs[(int) code];
case NOTE_INSN_RANGE_END: ggc_stats->size_rtxs[(int) code] += ggc_get_size (r);
case NOTE_INSN_LIVE: }
ggc_mark_rtx (NOTE_RANGE_INFO (r));
break;
case NOTE_INSN_BLOCK_BEG: /* ??? If (some of) these are really pass-dependant info, do we
case NOTE_INSN_BLOCK_END: have any right poking our noses in? */
ggc_mark_tree (NOTE_BLOCK (r)); 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; break;
default: default:
if (NOTE_LINE_NUMBER (r) >= 0)
ggc_mark_string (NOTE_SOURCE_FILE (r));
break; break;
} }
break;
default: for (fmt = GET_RTX_FORMAT (GET_CODE (r)), i = 0; *fmt ; ++fmt, ++i)
break;
}
for (fmt = GET_RTX_FORMAT (GET_CODE (r)), i = 0; *fmt ; ++fmt, ++i)
{
switch (*fmt)
{ {
case 'e': case 'u': rtx exp;
ggc_mark_rtx (XEXP (r, i)); switch (*fmt)
break; {
case 'V': case 'E': case 'e': case 'u':
ggc_mark_rtvec (XVEC (r, i)); exp = XEXP (r, i);
break; if (ggc_test_and_set_mark (exp))
case 'S': case 's': {
ggc_mark_if_gcable (XSTR (r, i)); if (next_rtx == NULL)
break; 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 /* V had not been previously marked, but has now been marked via
......
...@@ -64,25 +64,30 @@ extern void ggc_mark_rtx_children PROTO ((struct rtx_def *)); ...@@ -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_rtvec_children PROTO ((struct rtvec_def *));
extern void ggc_mark_tree_children PROTO ((union tree_node *)); extern void ggc_mark_tree_children PROTO ((union tree_node *));
#define ggc_mark_rtx(EXPR) \ /* If EXPR is not NULL and previously unmarked, mark it and evaluate
do { \ to true. Otherwise evaluate to false. */
rtx r__ = (EXPR); \ #define ggc_test_and_set_mark(EXPR) \
if (r__ != NULL && ! ggc_set_mark (r__)) \ ((EXPR) != NULL && ! ggc_set_mark (EXPR))
ggc_mark_rtx_children (r__); \
#define ggc_mark_rtx(EXPR) \
do { \
rtx r__ = (EXPR); \
if (ggc_test_and_set_mark (r__)) \
ggc_mark_rtx_children (r__); \
} while (0) } while (0)
#define ggc_mark_tree(EXPR) \ #define ggc_mark_tree(EXPR) \
do { \ do { \
tree t__ = (EXPR); \ tree t__ = (EXPR); \
if (t__ != NULL && ! ggc_set_mark (t__)) \ if (ggc_test_and_set_mark (t__)) \
ggc_mark_tree_children (t__); \ ggc_mark_tree_children (t__); \
} while (0) } while (0)
#define ggc_mark_rtvec(EXPR) \ #define ggc_mark_rtvec(EXPR) \
do { \ do { \
rtvec v__ = (EXPR); \ rtvec v__ = (EXPR); \
if (v__ != NULL && ! ggc_set_mark (v__)) \ if (ggc_test_and_set_mark (v__)) \
ggc_mark_rtvec_children (v__); \ ggc_mark_rtvec_children (v__); \
} while (0) } while (0)
#define ggc_mark_string(EXPR) \ #define ggc_mark_string(EXPR) \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment