mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-11 09:19:44 +08:00
tree.c (walk_tree): Expose tail recursion.
* tree.c (walk_tree): Expose tail recursion. (walk_stmt_tree): New function. * cp-tree.h: Prototype walk_stmt_tree. * semantics.c (prune_unused_decls): Operate on SCOPE_STMTs not the BLOCKs directly. If a BLOCK has no variables after pruning, discard it. (finish_stmt_tree): Use walk_stmt_tree. No need to save and restore the line number. From-SVN: r36178
This commit is contained in:
parent
3392dafcfd
commit
11f53b6a08
@ -1,3 +1,14 @@
|
||||
2000-09-05 Zack Weinberg <zack@wolery.cumb.org>
|
||||
|
||||
* tree.c (walk_tree): Expose tail recursion.
|
||||
(walk_stmt_tree): New function.
|
||||
* cp-tree.h: Prototype walk_stmt_tree.
|
||||
* semantics.c (prune_unused_decls): Operate on SCOPE_STMTs not
|
||||
the BLOCKs directly. If a BLOCK has no variables after
|
||||
pruning, discard it.
|
||||
(finish_stmt_tree): Use walk_stmt_tree. No need to save and
|
||||
restore the line number.
|
||||
|
||||
2000-09-05 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* Makefile.in (CXX_TREE_H): Add dependency on HTAB_H.
|
||||
|
@ -4543,6 +4543,9 @@ extern tree walk_tree PARAMS ((tree *,
|
||||
extern tree walk_tree_without_duplicates PARAMS ((tree *,
|
||||
walk_tree_fn,
|
||||
void *));
|
||||
extern tree walk_stmt_tree PARAMS ((tree *,
|
||||
walk_tree_fn,
|
||||
void *));
|
||||
extern tree copy_tree_r PARAMS ((tree *, int *, void *));
|
||||
extern int cp_valid_lang_attribute PARAMS ((tree, tree, tree, tree));
|
||||
extern tree make_ptrmem_cst PARAMS ((tree, tree));
|
||||
|
@ -2274,21 +2274,28 @@ prune_unused_decls (tp, walk_subtrees, data)
|
||||
return prune_unused_decls (tp, walk_subtrees, data);
|
||||
}
|
||||
}
|
||||
else if (TREE_CODE (t) == BLOCK)
|
||||
else if (TREE_CODE (t) == SCOPE_STMT)
|
||||
{
|
||||
/* walk_tree doesn't inspect BLOCK_VARS, so we must do it by hand. */
|
||||
tree *vp;
|
||||
/* Remove all unused decls from the BLOCK of this SCOPE_STMT. */
|
||||
tree block = SCOPE_STMT_BLOCK (t);
|
||||
|
||||
for (vp = &BLOCK_VARS (t); *vp; )
|
||||
if (block)
|
||||
{
|
||||
tree v = *vp;
|
||||
if (! TREE_USED (v) && DECL_NAME (v) && DECL_SOURCE_LINE (v) == 0)
|
||||
*vp = TREE_CHAIN (v); /* drop */
|
||||
else
|
||||
vp = &TREE_CHAIN (v); /* advance */
|
||||
tree *vp;
|
||||
|
||||
for (vp = &BLOCK_VARS (block); *vp; )
|
||||
{
|
||||
tree v = *vp;
|
||||
if (! TREE_USED (v) && DECL_NAME (v) && DECL_SOURCE_LINE (v) == 0)
|
||||
*vp = TREE_CHAIN (v); /* drop */
|
||||
else
|
||||
vp = &TREE_CHAIN (v); /* advance */
|
||||
}
|
||||
/* If there are now no variables, the entire BLOCK can be dropped.
|
||||
(This causes SCOPE_NULLIFIED_P (t) to be true.) */
|
||||
if (BLOCK_VARS (block) == NULL_TREE)
|
||||
SCOPE_STMT_BLOCK (t) = NULL_TREE;
|
||||
}
|
||||
if (BLOCK_VARS (t) == NULL_TREE)
|
||||
TREE_USED (t) = 0;
|
||||
}
|
||||
return NULL_TREE;
|
||||
}
|
||||
@ -2314,18 +2321,14 @@ finish_stmt_tree (t)
|
||||
tree *t;
|
||||
{
|
||||
tree stmt;
|
||||
int old_lineno;
|
||||
|
||||
/* Remove the fake extra statement added in begin_stmt_tree. */
|
||||
stmt = TREE_CHAIN (*t);
|
||||
*t = stmt;
|
||||
SET_LAST_STMT (NULL_TREE);
|
||||
|
||||
/* Remove unused decls from the stmt tree. walk_tree messes with
|
||||
the line number, so save/restore it. */
|
||||
old_lineno = lineno;
|
||||
walk_tree_without_duplicates (t, prune_unused_decls, NULL);
|
||||
lineno = old_lineno;
|
||||
/* Remove unused decls from the stmt tree. */
|
||||
walk_stmt_tree (t, prune_unused_decls, NULL);
|
||||
|
||||
if (cfun)
|
||||
{
|
||||
|
@ -1319,7 +1319,8 @@ walk_tree (tp, func, data, htab)
|
||||
WALK_SUBTREE (DECL_SIZE_UNIT (DECL_STMT_DECL (*tp)));
|
||||
}
|
||||
|
||||
WALK_SUBTREE (TREE_CHAIN (*tp));
|
||||
/* This can be tail-recursion optimized if we write it this way. */
|
||||
return walk_tree (&TREE_CHAIN (*tp), func, data, htab);
|
||||
}
|
||||
|
||||
/* We didn't find what we were looking for. */
|
||||
@ -1454,6 +1455,73 @@ walk_tree_without_duplicates (tp, func, data)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Like walk_tree, but only examines statement nodes. We don't need a
|
||||
without_duplicates variant of this one because the statement tree is
|
||||
a tree, not a graph. */
|
||||
|
||||
tree
|
||||
walk_stmt_tree (tp, func, data)
|
||||
tree *tp;
|
||||
walk_tree_fn func;
|
||||
void *data;
|
||||
{
|
||||
enum tree_code code;
|
||||
int walk_subtrees;
|
||||
tree result;
|
||||
int i, len;
|
||||
|
||||
#define WALK_SUBTREE(NODE) \
|
||||
do \
|
||||
{ \
|
||||
result = walk_stmt_tree (&(NODE), func, data); \
|
||||
if (result) \
|
||||
return result; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Skip empty subtrees. */
|
||||
if (!*tp)
|
||||
return NULL_TREE;
|
||||
|
||||
/* Skip subtrees below non-statement nodes. */
|
||||
if (!statement_code_p (TREE_CODE (*tp)))
|
||||
return NULL_TREE;
|
||||
|
||||
/* Call the function. */
|
||||
walk_subtrees = 1;
|
||||
result = (*func) (tp, &walk_subtrees, data);
|
||||
|
||||
/* If we found something, return it. */
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
/* Even if we didn't, FUNC may have decided that there was nothing
|
||||
interesting below this point in the tree. */
|
||||
if (!walk_subtrees)
|
||||
return NULL_TREE;
|
||||
|
||||
/* FUNC may have modified the tree, recheck that we're looking at a
|
||||
statement node. */
|
||||
code = TREE_CODE (*tp);
|
||||
if (!statement_code_p (code))
|
||||
return NULL_TREE;
|
||||
|
||||
/* Walk over all the sub-trees of this operand. Statement nodes never
|
||||
contain RTL, and we needn't worry about TARGET_EXPRs. */
|
||||
len = TREE_CODE_LENGTH (code);
|
||||
|
||||
/* Go through the subtrees. We need to do this in forward order so
|
||||
that the scope of a FOR_EXPR is handled properly. */
|
||||
for (i = 0; i < len; ++i)
|
||||
WALK_SUBTREE (TREE_OPERAND (*tp, i));
|
||||
|
||||
/* Finally visit the chain. This can be tail-recursion optimized if
|
||||
we write it this way. */
|
||||
return walk_stmt_tree (&TREE_CHAIN (*tp), func, data);
|
||||
|
||||
#undef WALK_SUBTREE
|
||||
}
|
||||
|
||||
/* Called from count_trees via walk_tree. */
|
||||
|
||||
static tree
|
||||
|
Loading…
Reference in New Issue
Block a user