diff options
author | Alexandre Oliva <aoliva@redhat.com> | 2001-10-26 18:27:13 +0000 |
---|---|---|
committer | Alexandre Oliva <aoliva@gcc.gnu.org> | 2001-10-26 18:27:13 +0000 |
commit | 6c624f7f882ea3fdd121c9ab5f8d604c00ac3e10 (patch) | |
tree | 3e38f5a0ee686bbb4dece960208ac211172b1f69 /gcc/tree-inline.c | |
parent | 45c23566b6caa9010dda42a4df20b4e7f17d238a (diff) | |
download | gcc-6c624f7f882ea3fdd121c9ab5f8d604c00ac3e10.zip gcc-6c624f7f882ea3fdd121c9ab5f8d604c00ac3e10.tar.gz gcc-6c624f7f882ea3fdd121c9ab5f8d604c00ac3e10.tar.bz2 |
tree-inline.c (WALK_SUBTREE_TAIL): New macro.
* tree-inline.c (WALK_SUBTREE_TAIL): New macro.
(walk_tree): Use it for tail calls where appropriate.
From-SVN: r46556
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r-- | gcc/tree-inline.c | 48 |
1 files changed, 28 insertions, 20 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 25d0964..865ec234 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1086,6 +1086,15 @@ walk_tree (tp, func, data, htab_) } \ while (0) +#define WALK_SUBTREE_TAIL(NODE) \ + do \ + { \ + tp = & (NODE); \ + goto tail_recurse; \ + } \ + while (0) + + tail_recurse: /* Skip empty subtrees. */ if (!*tp) return NULL_TREE; @@ -1120,7 +1129,7 @@ walk_tree (tp, func, data, htab_) if (statement_code_p (code) || code == TREE_LIST || (*lang_hooks.tree_inlining.tree_chain_matters_p) (*tp)) /* But we still need to check our siblings. */ - return walk_tree (&TREE_CHAIN (*tp), func, data, htab); + WALK_SUBTREE_TAIL (TREE_CHAIN (*tp)); else return NULL_TREE; } @@ -1168,7 +1177,7 @@ walk_tree (tp, func, data, htab_) } /* This can be tail-recursion optimized if we write it this way. */ - return walk_tree (&TREE_CHAIN (*tp), func, data, htab); + WALK_SUBTREE_TAIL (TREE_CHAIN (*tp)); } /* We didn't find what we were looking for. */ @@ -1176,10 +1185,7 @@ walk_tree (tp, func, data, htab_) } else if (TREE_CODE_CLASS (code) == 'd') { - WALK_SUBTREE (TREE_TYPE (*tp)); - - /* We didn't find what we were looking for. */ - return NULL_TREE; + WALK_SUBTREE_TAIL (TREE_TYPE (*tp)); } result = (*lang_hooks.tree_inlining.walk_subtrees) (tp, &walk_subtrees, func, @@ -1211,30 +1217,35 @@ walk_tree (tp, func, data, htab_) case POINTER_TYPE: case REFERENCE_TYPE: - WALK_SUBTREE (TREE_TYPE (*tp)); + WALK_SUBTREE_TAIL (TREE_TYPE (*tp)); break; case TREE_LIST: WALK_SUBTREE (TREE_VALUE (*tp)); - WALK_SUBTREE (TREE_CHAIN (*tp)); + WALK_SUBTREE_TAIL (TREE_CHAIN (*tp)); break; case TREE_VEC: { int len = TREE_VEC_LENGTH (*tp); - while (len--) + + if (len == 0) + break; + + /* Walk all elements but the first. */ + while (--len) WALK_SUBTREE (TREE_VEC_ELT (*tp, len)); + + /* Now walk the first one as a tail call. */ + WALK_SUBTREE_TAIL (TREE_VEC_ELT (*tp, 0)); } - break; case COMPLEX_CST: WALK_SUBTREE (TREE_REALPART (*tp)); - WALK_SUBTREE (TREE_IMAGPART (*tp)); - break; + WALK_SUBTREE_TAIL (TREE_IMAGPART (*tp)); case CONSTRUCTOR: - WALK_SUBTREE (CONSTRUCTOR_ELTS (*tp)); - break; + WALK_SUBTREE_TAIL (CONSTRUCTOR_ELTS (*tp)); case METHOD_TYPE: WALK_SUBTREE (TYPE_METHOD_BASETYPE (*tp)); @@ -1253,18 +1264,15 @@ walk_tree (tp, func, data, htab_) case ARRAY_TYPE: WALK_SUBTREE (TREE_TYPE (*tp)); - WALK_SUBTREE (TYPE_DOMAIN (*tp)); - break; + WALK_SUBTREE_TAIL (TYPE_DOMAIN (*tp)); case INTEGER_TYPE: WALK_SUBTREE (TYPE_MIN_VALUE (*tp)); - WALK_SUBTREE (TYPE_MAX_VALUE (*tp)); - break; + WALK_SUBTREE_TAIL (TYPE_MAX_VALUE (*tp)); case OFFSET_TYPE: WALK_SUBTREE (TREE_TYPE (*tp)); - WALK_SUBTREE (TYPE_OFFSET_BASETYPE (*tp)); - break; + WALK_SUBTREE_TAIL (TYPE_OFFSET_BASETYPE (*tp)); default: abort (); |