tree.h (DECL_SEEN_IN_BIND_EXPR_P): New macro.
* tree.h (DECL_SEEN_IN_BIND_EXPR_P): New macro. * gimplify.c (gimple_add_tmp_var, gimplify_bind_expr): Use it. (gimplify_target_expr, gimplify_expr): Likewise. (copy_if_shared_r): No longer need special case for BIND_EXPR. (unshare_body, unvisit_body): Only look at nested if BODY_P is whole function. (gimplify_compound_lval): See if we can strip any useless conversion. (gimplify_modify_expr, gimplify_modify_expr_to_memcpy): Take size from RHS, not LHS. (gimplify_modify_expr_to_memset): Likewise. (gimplify_expr, case CONSTRUCTOR): Handle use as statement. * tree-inline.c (setup_one_parameter): Use DECL_SEEN_IN_BIND_EXPR_P. (declare_inline_vars): Likewise. (walk_type_fields): New function. (walk_tree): Use it. * tree-nested.c (create_tmp_var_for): Show seen in BIND_EXPR. From-SVN: r84121
This commit is contained in:
parent
402a3dec96
commit
48eb4e53cd
@ -5,6 +5,23 @@
|
||||
|
||||
2004-07-05 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
||||
|
||||
* tree.h (DECL_SEEN_IN_BIND_EXPR_P): New macro.
|
||||
* gimplify.c (gimple_add_tmp_var, gimplify_bind_expr): Use it.
|
||||
(gimplify_target_expr, gimplify_expr): Likewise.
|
||||
(copy_if_shared_r): No longer need special case for BIND_EXPR.
|
||||
(unshare_body, unvisit_body): Only look at nested if BODY_P is
|
||||
whole function.
|
||||
(gimplify_compound_lval): See if we can strip any useless conversion.
|
||||
(gimplify_modify_expr, gimplify_modify_expr_to_memcpy): Take size
|
||||
from RHS, not LHS.
|
||||
(gimplify_modify_expr_to_memset): Likewise.
|
||||
(gimplify_expr, case CONSTRUCTOR): Handle use as statement.
|
||||
* tree-inline.c (setup_one_parameter): Use DECL_SEEN_IN_BIND_EXPR_P.
|
||||
(declare_inline_vars): Likewise.
|
||||
(walk_type_fields): New function.
|
||||
(walk_tree): Use it.
|
||||
* tree-nested.c (create_tmp_var_for): Show seen in BIND_EXPR.
|
||||
|
||||
* tree-sra.c (struct sra_walk_fns): Init function now returns bool.
|
||||
(sra_walk_modify_expr): Allow init function to fail.
|
||||
(scan_init): Now returns bool.
|
||||
|
@ -509,20 +509,17 @@ declare_tmp_vars (tree vars, tree scope)
|
||||
temps = nreverse (last);
|
||||
TREE_CHAIN (last) = BIND_EXPR_VARS (scope);
|
||||
BIND_EXPR_VARS (scope) = temps;
|
||||
|
||||
/* We don't add the temps to the block for this BIND_EXPR, as we're
|
||||
not interested in debugging info for them. */
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gimple_add_tmp_var (tree tmp)
|
||||
{
|
||||
if (TREE_CHAIN (tmp) || tmp->decl.seen_in_bind_expr)
|
||||
if (TREE_CHAIN (tmp) || DECL_SEEN_IN_BIND_EXPR_P (tmp))
|
||||
abort ();
|
||||
|
||||
DECL_CONTEXT (tmp) = current_function_decl;
|
||||
tmp->decl.seen_in_bind_expr = 1;
|
||||
DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
|
||||
|
||||
if (gimplify_ctxp)
|
||||
{
|
||||
@ -657,19 +654,6 @@ copy_if_shared_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
|
||||
TREE_VISITED (t) = 1;
|
||||
}
|
||||
|
||||
/* Special-case BIND_EXPR. We should never be copying these, therefore
|
||||
we can omit examining BIND_EXPR_VARS. Which also avoids problems with
|
||||
double processing of the DECL_INITIAL, which could be seen via both
|
||||
the BIND_EXPR_VARS and a DECL_EXPR. */
|
||||
else if (code == BIND_EXPR)
|
||||
{
|
||||
if (TREE_VISITED (t))
|
||||
abort ();
|
||||
TREE_VISITED (t) = 1;
|
||||
*walk_subtrees = 0;
|
||||
walk_tree (&BIND_EXPR_BODY (t), copy_if_shared_r, NULL, NULL);
|
||||
}
|
||||
|
||||
/* If this node has been visited already, unshare it and don't look
|
||||
any deeper. */
|
||||
else if (TREE_VISITED (t))
|
||||
@ -713,8 +697,9 @@ unmark_visited_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Unshare all the trees in BODY_P, a pointer to the body of FNDECL, and the
|
||||
bodies of any nested functions. */
|
||||
/* Unshare all the trees in BODY_P, a pointer into the body of FNDECL, and the
|
||||
bodies of any nested functions if we are unsharing the entire body of
|
||||
FNDECL. */
|
||||
|
||||
static void
|
||||
unshare_body (tree *body_p, tree fndecl)
|
||||
@ -722,8 +707,9 @@ unshare_body (tree *body_p, tree fndecl)
|
||||
struct cgraph_node *cgn = cgraph_node (fndecl);
|
||||
|
||||
walk_tree (body_p, copy_if_shared_r, NULL, NULL);
|
||||
for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
|
||||
unshare_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl);
|
||||
if (body_p == &DECL_SAVED_TREE (fndecl))
|
||||
for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
|
||||
unshare_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl);
|
||||
}
|
||||
|
||||
/* Likewise, but mark all trees as not visited. */
|
||||
@ -734,8 +720,9 @@ unvisit_body (tree *body_p, tree fndecl)
|
||||
struct cgraph_node *cgn = cgraph_node (fndecl);
|
||||
|
||||
walk_tree (body_p, unmark_visited_r, NULL, NULL);
|
||||
for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
|
||||
unvisit_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl);
|
||||
if (body_p == &DECL_SAVED_TREE (fndecl))
|
||||
for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
|
||||
unvisit_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl);
|
||||
}
|
||||
|
||||
/* Unshare T and all the trees reached from T via TREE_CHAIN. */
|
||||
@ -890,7 +877,7 @@ gimplify_bind_expr (tree *expr_p, tree temp, tree *pre_p)
|
||||
|
||||
/* Mark variables seen in this bind expr. */
|
||||
for (t = BIND_EXPR_VARS (bind_expr); t ; t = TREE_CHAIN (t))
|
||||
t->decl.seen_in_bind_expr = 1;
|
||||
DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
|
||||
|
||||
gimple_push_bind_expr (bind_expr);
|
||||
gimplify_ctxp->save_stack = false;
|
||||
@ -1668,7 +1655,8 @@ gimplify_compound_lval (tree *expr_p, tree *pre_p,
|
||||
tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval, fallback);
|
||||
ret = MIN (ret, tret);
|
||||
|
||||
/* And finally, the indices and operands to BIT_FIELD_REF. */
|
||||
/* And finally, the indices and operands to BIT_FIELD_REF. During this
|
||||
loop we also remove any useless conversions. */
|
||||
for (; VARRAY_ACTIVE_SIZE (stack) > 0; )
|
||||
{
|
||||
tree t = VARRAY_TOP_TREE (stack);
|
||||
@ -1700,7 +1688,9 @@ gimplify_compound_lval (tree *expr_p, tree *pre_p,
|
||||
is_gimple_val, fb_rvalue);
|
||||
ret = MIN (ret, tret);
|
||||
}
|
||||
|
||||
|
||||
STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
|
||||
|
||||
/* The innermost expression P may have originally had TREE_SIDE_EFFECTS
|
||||
set which would have caused all the outer expressions in EXPR_P
|
||||
leading to P to also have had TREE_SIDE_EFFECTS set. */
|
||||
@ -2321,7 +2311,7 @@ gimplify_modify_expr_to_memcpy (tree *expr_p, bool want_value)
|
||||
to = TREE_OPERAND (*expr_p, 0);
|
||||
from = TREE_OPERAND (*expr_p, 1);
|
||||
|
||||
t = TYPE_SIZE_UNIT (TREE_TYPE (to));
|
||||
t = TYPE_SIZE_UNIT (TREE_TYPE (from));
|
||||
t = unshare_expr (t);
|
||||
t = SUBSTITUTE_PLACEHOLDER_IN_EXPR (t, to);
|
||||
t = SUBSTITUTE_PLACEHOLDER_IN_EXPR (t, from);
|
||||
@ -2356,7 +2346,7 @@ gimplify_modify_expr_to_memset (tree *expr_p, bool want_value)
|
||||
|
||||
to = TREE_OPERAND (*expr_p, 0);
|
||||
|
||||
t = TYPE_SIZE_UNIT (TREE_TYPE (to));
|
||||
t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_OPERAND (*expr_p, 1)));
|
||||
t = unshare_expr (t);
|
||||
t = SUBSTITUTE_PLACEHOLDER_IN_EXPR (t, to);
|
||||
args = tree_cons (NULL, t, NULL);
|
||||
@ -2772,8 +2762,15 @@ gimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value)
|
||||
/* If the value being copied is of variable width, expose the length
|
||||
if the copy by converting the whole thing to a memcpy/memset.
|
||||
Note that we need to do this before gimplifying any of the operands
|
||||
so that we can resolve any PLACEHOLDER_EXPRs in the size. */
|
||||
if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p))) != INTEGER_CST)
|
||||
so that we can resolve any PLACEHOLDER_EXPRs in the size.
|
||||
Also note that the RTL expander uses the size of the expression to
|
||||
be copied, not of the destination, so that is what we must here.
|
||||
The types on both sides of the MODIFY_EXPR should be the same,
|
||||
but they aren't always and there are problems with class-wide types
|
||||
in Ada where it's hard to make it "correct". */
|
||||
if (TREE_CODE (TREE_TYPE (*from_p)) != ERROR_MARK
|
||||
&& TYPE_SIZE_UNIT (TREE_TYPE (*from_p))
|
||||
&& TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*from_p))) != INTEGER_CST)
|
||||
{
|
||||
if (TREE_CODE (*from_p) == CONSTRUCTOR)
|
||||
return gimplify_modify_expr_to_memset (expr_p, want_value);
|
||||
@ -3361,7 +3358,7 @@ gimplify_target_expr (tree *expr_p, tree *pre_p, tree *post_p)
|
||||
TREE_OPERAND (targ, 3) = init;
|
||||
TARGET_EXPR_INITIAL (targ) = NULL_TREE;
|
||||
}
|
||||
else if (!temp->decl.seen_in_bind_expr)
|
||||
else if (!DECL_SEEN_IN_BIND_EXPR_P (temp))
|
||||
/* We should have expanded this before. */
|
||||
abort ();
|
||||
|
||||
@ -3699,8 +3696,20 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
|
||||
break;
|
||||
|
||||
case CONSTRUCTOR:
|
||||
/* Don't reduce this in place; let gimplify_init_constructor work
|
||||
its magic. */
|
||||
/* Don't reduce this in place; let gimplify_init_constructor work its
|
||||
magic. Buf if we're just elaborating this for side effects, just
|
||||
gimplify any element that has side-effects. */
|
||||
if (fallback == fb_none)
|
||||
{
|
||||
for (tmp = CONSTRUCTOR_ELTS (*expr_p); tmp;
|
||||
tmp = TREE_CHAIN (tmp))
|
||||
if (TREE_SIDE_EFFECTS (TREE_VALUE (tmp)))
|
||||
gimplify_expr (&TREE_VALUE (tmp), pre_p, post_p,
|
||||
gimple_test_f, fallback);
|
||||
|
||||
*expr_p = NULL_TREE;
|
||||
}
|
||||
|
||||
ret = GS_ALL_DONE;
|
||||
break;
|
||||
|
||||
@ -3801,7 +3810,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
|
||||
tmp = *expr_p;
|
||||
if (!TREE_STATIC (tmp) && !DECL_EXTERNAL (tmp)
|
||||
&& decl_function_context (tmp) == current_function_decl
|
||||
&& !tmp->decl.seen_in_bind_expr)
|
||||
&& !DECL_SEEN_IN_BIND_EXPR_P (tmp))
|
||||
{
|
||||
#ifdef ENABLE_CHECKING
|
||||
if (!errorcount && !sorrycount)
|
||||
|
@ -766,7 +766,7 @@ setup_one_parameter (inline_data *id, tree p, tree value, tree fn,
|
||||
*vars = var;
|
||||
|
||||
/* Make gimplifier happy about this variable. */
|
||||
var->decl.seen_in_bind_expr = lang_hooks.gimple_before_inlining;
|
||||
DECL_SEEN_IN_BIND_EXPR_P (var) = lang_hooks.gimple_before_inlining;
|
||||
|
||||
/* Even if P was TREE_READONLY, the new VAR should not be.
|
||||
In the original code, we would have constructed a
|
||||
@ -1951,6 +1951,100 @@ save_body (tree fn, tree *arg_copy)
|
||||
return body;
|
||||
}
|
||||
|
||||
#define WALK_SUBTREE(NODE) \
|
||||
do \
|
||||
{ \
|
||||
result = walk_tree (&(NODE), func, data, htab); \
|
||||
if (result) \
|
||||
return result; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* This is a subroutine of walk_tree that walks field of TYPE that are to
|
||||
be walked whenever a type is seen in the tree. Rest of operands and return
|
||||
value are as for walk_tree. */
|
||||
|
||||
static tree
|
||||
walk_type_fields (tree type, walk_tree_fn func, void *data, void *htab)
|
||||
{
|
||||
tree result = NULL_TREE;
|
||||
|
||||
switch (TREE_CODE (type))
|
||||
{
|
||||
case POINTER_TYPE:
|
||||
case REFERENCE_TYPE:
|
||||
/* We have to worry about mutually recursive pointers. These can't
|
||||
be written in C. They can in Ada. It's pathlogical, but
|
||||
there's an ACATS test (c38102a) that checks it. Deal with this
|
||||
by checking if we're pointing to another pointer, that one
|
||||
points to another pointer, that one does too, and we have no htab.
|
||||
If so, get a hash table. We check three levels deep to avoid
|
||||
the cost of the hash table if we don't need one. */
|
||||
if (POINTER_TYPE_P (TREE_TYPE (type))
|
||||
&& POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (type)))
|
||||
&& POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (TREE_TYPE (type))))
|
||||
&& !htab)
|
||||
{
|
||||
result = walk_tree_without_duplicates (&TREE_TYPE (type),
|
||||
func, data);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* ... fall through ... */
|
||||
|
||||
case COMPLEX_TYPE:
|
||||
WALK_SUBTREE (TREE_TYPE (type));
|
||||
break;
|
||||
|
||||
case METHOD_TYPE:
|
||||
WALK_SUBTREE (TYPE_METHOD_BASETYPE (type));
|
||||
|
||||
/* Fall through. */
|
||||
|
||||
case FUNCTION_TYPE:
|
||||
WALK_SUBTREE (TREE_TYPE (type));
|
||||
{
|
||||
tree arg;
|
||||
|
||||
/* We never want to walk into default arguments. */
|
||||
for (arg = TYPE_ARG_TYPES (type); arg; arg = TREE_CHAIN (arg))
|
||||
WALK_SUBTREE (TREE_VALUE (arg));
|
||||
}
|
||||
break;
|
||||
|
||||
case ARRAY_TYPE:
|
||||
/* Don't follow this nodes's type if a pointer for fear that we'll
|
||||
have infinite recursion. Those types are uninteresting anyway. */
|
||||
if (!POINTER_TYPE_P (TREE_TYPE (type))
|
||||
&& TREE_CODE (TREE_TYPE (type)) != OFFSET_TYPE)
|
||||
WALK_SUBTREE (TREE_TYPE (type));
|
||||
WALK_SUBTREE (TYPE_DOMAIN (type));
|
||||
break;
|
||||
|
||||
case BOOLEAN_TYPE:
|
||||
case ENUMERAL_TYPE:
|
||||
case INTEGER_TYPE:
|
||||
case CHAR_TYPE:
|
||||
case REAL_TYPE:
|
||||
WALK_SUBTREE (TYPE_MIN_VALUE (type));
|
||||
WALK_SUBTREE (TYPE_MAX_VALUE (type));
|
||||
break;
|
||||
|
||||
case OFFSET_TYPE:
|
||||
WALK_SUBTREE (TREE_TYPE (type));
|
||||
WALK_SUBTREE (TYPE_OFFSET_BASETYPE (type));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Apply FUNC to all the sub-trees of TP in a pre-order traversal. FUNC is
|
||||
called with the DATA and the address of each sub-tree. If FUNC returns a
|
||||
non-NULL value, the traversal is aborted, and the value returned by FUNC
|
||||
@ -1965,15 +2059,6 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
|
||||
int walk_subtrees;
|
||||
tree result;
|
||||
|
||||
#define WALK_SUBTREE(NODE) \
|
||||
do \
|
||||
{ \
|
||||
result = walk_tree (&(NODE), func, data, htab); \
|
||||
if (result) \
|
||||
return result; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define WALK_SUBTREE_TAIL(NODE) \
|
||||
do \
|
||||
{ \
|
||||
@ -2025,43 +2110,42 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
|
||||
if (result || ! walk_subtrees)
|
||||
return result;
|
||||
|
||||
/* If this is a DECL_EXPR, walk into various fields of the type or variable
|
||||
that it's defining. We only want to walk into these fields of a decl
|
||||
or type in this case.
|
||||
/* If this is a DECL_EXPR, walk into various fields of the type that it's
|
||||
defining. We only want to walk into these fields of a type in this
|
||||
case. Note that decls get walked as part of the processing of a
|
||||
BIND_EXPR.
|
||||
|
||||
??? Precisely which fields of types that we are supposed to walk in
|
||||
this case vs. the normal case aren't well defined. */
|
||||
if (code == DECL_EXPR
|
||||
&& TREE_CODE (DECL_EXPR_DECL (*tp)) != ERROR_MARK
|
||||
&& TREE_CODE (DECL_EXPR_DECL (*tp)) == TYPE_DECL
|
||||
&& TREE_CODE (TREE_TYPE (DECL_EXPR_DECL (*tp))) != ERROR_MARK)
|
||||
{
|
||||
tree decl = DECL_EXPR_DECL (*tp);
|
||||
tree type = TREE_TYPE (decl);
|
||||
tree *type_p = &TREE_TYPE (DECL_EXPR_DECL (*tp));
|
||||
|
||||
/* Walk into fields of the DECL if it's not a type. */
|
||||
if (TREE_CODE (decl) != TYPE_DECL)
|
||||
{
|
||||
if (TREE_CODE (decl) != FIELD_DECL && TREE_CODE (decl) != PARM_DECL)
|
||||
WALK_SUBTREE (DECL_INITIAL (decl));
|
||||
/* Call the function for the type. See if it returns anything or
|
||||
doesn't want us to continue. If we are to continue, walk both
|
||||
the normal fields and those for the declaration case. */
|
||||
result = (*func) (type_p, &walk_subtrees, data);
|
||||
if (result || !walk_subtrees)
|
||||
return NULL_TREE;
|
||||
|
||||
WALK_SUBTREE (DECL_SIZE (decl));
|
||||
WALK_SUBTREE_TAIL (DECL_SIZE_UNIT (decl));
|
||||
}
|
||||
result = walk_type_fields (*type_p, func, data, htab_);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
/* Otherwise, we are declaring a type. First do the common fields via
|
||||
recursion, then the fields we only do when we are declaring the type
|
||||
or object. */
|
||||
WALK_SUBTREE (type);
|
||||
WALK_SUBTREE (TYPE_SIZE (type));
|
||||
WALK_SUBTREE (TYPE_SIZE_UNIT (type));
|
||||
WALK_SUBTREE (TYPE_SIZE (*type_p));
|
||||
WALK_SUBTREE (TYPE_SIZE_UNIT (*type_p));
|
||||
|
||||
/* If this is a record type, also walk the fields. */
|
||||
if (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE
|
||||
|| TREE_CODE (type) == QUAL_UNION_TYPE)
|
||||
if (TREE_CODE (*type_p) == RECORD_TYPE
|
||||
|| TREE_CODE (*type_p) == UNION_TYPE
|
||||
|| TREE_CODE (*type_p) == QUAL_UNION_TYPE)
|
||||
{
|
||||
tree field;
|
||||
|
||||
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
|
||||
for (field = TYPE_FIELDS (*type_p); field;
|
||||
field = TREE_CHAIN (field))
|
||||
{
|
||||
/* We'd like to look at the type of the field, but we can easily
|
||||
get infinite recursion. So assume it's pointed to elsewhere
|
||||
@ -2072,7 +2156,7 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
|
||||
WALK_SUBTREE (DECL_FIELD_OFFSET (field));
|
||||
WALK_SUBTREE (DECL_SIZE (field));
|
||||
WALK_SUBTREE (DECL_SIZE_UNIT (field));
|
||||
if (TREE_CODE (type) == QUAL_UNION_TYPE)
|
||||
if (TREE_CODE (*type_p) == QUAL_UNION_TYPE)
|
||||
WALK_SUBTREE (DECL_QUALIFIER (field));
|
||||
}
|
||||
}
|
||||
@ -2114,6 +2198,13 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* If this is a type, walk the needed fields in the type. */
|
||||
else if (TYPE_P (*tp))
|
||||
{
|
||||
result = walk_type_fields (*tp, func, data, htab_);
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Not one of the easy cases. We must explicitly go through the
|
||||
@ -2126,8 +2217,6 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
|
||||
case REAL_CST:
|
||||
case VECTOR_CST:
|
||||
case STRING_CST:
|
||||
case VECTOR_TYPE:
|
||||
case VOID_TYPE:
|
||||
case BLOCK:
|
||||
case PLACEHOLDER_EXPR:
|
||||
case SSA_NAME:
|
||||
@ -2183,7 +2272,6 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
|
||||
WALK_SUBTREE (DECL_INITIAL (decl));
|
||||
WALK_SUBTREE (DECL_SIZE (decl));
|
||||
WALK_SUBTREE (DECL_SIZE_UNIT (decl));
|
||||
WALK_SUBTREE (TREE_TYPE (decl));
|
||||
}
|
||||
WALK_SUBTREE_TAIL (BIND_EXPR_BODY (*tp));
|
||||
}
|
||||
@ -2196,70 +2284,6 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
|
||||
}
|
||||
break;
|
||||
|
||||
case POINTER_TYPE:
|
||||
case REFERENCE_TYPE:
|
||||
/* We have to worry about mutually recursive pointers. These can't
|
||||
be written in C. They can in Ada. It's pathlogical, but
|
||||
there's an ACATS test (c38102a) that checks it. Deal with this
|
||||
by checking if we're pointing to another pointer, that one
|
||||
points to another pointer, that one does too, and we have no htab.
|
||||
If so, get a hash table. We check three levels deep to avoid
|
||||
the cost of the hash table if we don't need one. */
|
||||
if (POINTER_TYPE_P (TREE_TYPE (*tp))
|
||||
&& POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*tp)))
|
||||
&& POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (TREE_TYPE (*tp))))
|
||||
&& !htab)
|
||||
{
|
||||
result = walk_tree_without_duplicates (&TREE_TYPE (*tp),
|
||||
func, data);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* ... fall through ... */
|
||||
|
||||
case COMPLEX_TYPE:
|
||||
WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
|
||||
break;
|
||||
|
||||
case METHOD_TYPE:
|
||||
WALK_SUBTREE (TYPE_METHOD_BASETYPE (*tp));
|
||||
|
||||
/* Fall through. */
|
||||
|
||||
case FUNCTION_TYPE:
|
||||
WALK_SUBTREE (TREE_TYPE (*tp));
|
||||
{
|
||||
tree arg;
|
||||
|
||||
/* We never want to walk into default arguments. */
|
||||
for (arg = TYPE_ARG_TYPES (*tp); arg; arg = TREE_CHAIN (arg))
|
||||
WALK_SUBTREE (TREE_VALUE (arg));
|
||||
}
|
||||
break;
|
||||
|
||||
case ARRAY_TYPE:
|
||||
/* Don't follow this nodes's type if a pointer for fear that we'll
|
||||
have infinite recursion. Those types are uninteresting anyway. */
|
||||
if (!POINTER_TYPE_P (TREE_TYPE (*tp))
|
||||
&& TREE_CODE (TREE_TYPE (*tp)) != OFFSET_TYPE)
|
||||
WALK_SUBTREE (TREE_TYPE (*tp));
|
||||
WALK_SUBTREE_TAIL (TYPE_DOMAIN (*tp));
|
||||
|
||||
case BOOLEAN_TYPE:
|
||||
case ENUMERAL_TYPE:
|
||||
case INTEGER_TYPE:
|
||||
case CHAR_TYPE:
|
||||
case REAL_TYPE:
|
||||
WALK_SUBTREE (TYPE_MIN_VALUE (*tp));
|
||||
WALK_SUBTREE_TAIL (TYPE_MAX_VALUE (*tp));
|
||||
|
||||
case OFFSET_TYPE:
|
||||
WALK_SUBTREE (TREE_TYPE (*tp));
|
||||
WALK_SUBTREE_TAIL (TYPE_OFFSET_BASETYPE (*tp));
|
||||
|
||||
default:
|
||||
/* ??? This could be a language-defined node. We really should make
|
||||
a hook for it, but right now just ignore it. */
|
||||
@ -2498,7 +2522,7 @@ declare_inline_vars (tree bind_expr, tree vars)
|
||||
tree t;
|
||||
|
||||
for (t = vars; t; t = TREE_CHAIN (t))
|
||||
vars->decl.seen_in_bind_expr = 1;
|
||||
DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
|
||||
}
|
||||
|
||||
add_var_to_bind_expr (bind_expr, vars);
|
||||
|
@ -145,6 +145,7 @@ create_tmp_var_for (struct nesting_info *info, tree type, const char *prefix)
|
||||
tmp_var = create_tmp_var_raw (type, prefix);
|
||||
DECL_CONTEXT (tmp_var) = info->context;
|
||||
TREE_CHAIN (tmp_var) = info->new_local_var_chain;
|
||||
DECL_SEEN_IN_BIND_EXPR_P (tmp_var) = 1;
|
||||
info->new_local_var_chain = tmp_var;
|
||||
|
||||
return tmp_var;
|
||||
|
@ -1985,6 +1985,11 @@ extern GTY (()) unsigned binfo_lang_slots;
|
||||
#define DECL_DECLARED_INLINE_P(NODE) \
|
||||
(FUNCTION_DECL_CHECK (NODE)->decl.declared_inline_flag)
|
||||
|
||||
/* Nonzero in a decl means that the gimplifier has seen (or placed)
|
||||
this variable in a BIND_EXPR. */
|
||||
#define DECL_SEEN_IN_BIND_EXPR_P(NODE) \
|
||||
(DECL_CHECK (NODE)->decl.seen_in_bind_expr)
|
||||
|
||||
/* In a VAR_DECL, nonzero if the decl is a register variable with
|
||||
an explicit asm specification. */
|
||||
#define DECL_HARD_REGISTER(NODE) (DECL_CHECK (NODE)->decl.inline_flag)
|
||||
|
Loading…
Reference in New Issue
Block a user