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
This commit is contained in:
Alex Samuel 1999-12-01 08:13:54 +00:00 committed by Alex Samuel
parent 777ad4c21f
commit 52a921766e
3 changed files with 100 additions and 71 deletions

View 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

View 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

View File

@ -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) \