aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-inline.c
diff options
context:
space:
mode:
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>2004-07-06 02:20:16 +0000
committerRichard Kenner <kenner@gcc.gnu.org>2004-07-05 22:20:16 -0400
commit5377d5ba398d4949af937fc025c1b01203aa3315 (patch)
treee36b5564359495ed12dc4107ed22bf65a3afddcc /gcc/tree-inline.c
parentaac1d259ac0a17ccce902d1f151422554ee5f2d8 (diff)
downloadgcc-5377d5ba398d4949af937fc025c1b01203aa3315.zip
gcc-5377d5ba398d4949af937fc025c1b01203aa3315.tar.gz
gcc-5377d5ba398d4949af937fc025c1b01203aa3315.tar.bz2
langhooks-def.h (LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P): Extra arg.
* langhooks-def.h (LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P): Extra arg. * langhooks.h (var_mod_type_p): Likewise. * c-decl.c (finish_decl): Add extra arg to variably_modified_type_p. * expr.c (count_type_elements): Properly handle return from array_type_nelts and properly test for overflow. * gimplify.c (gimplify_init_constructor): Properly handle return from array_type_nelts. (gimplify_addr_expr): Remove redundant clear of TREE_SIDE_EFFECTS. * integrate.c (copy_decl_for_inlining): Correct comments. * tree-inline.c (remap_decl): Update comments, remove dead code, and copy DECL_FIELD_OFFSET and DECL_QUALIFIER, if they exist. (remap_type): Only remap if variably modified by vars in function being inlined. (copy_body_r): Use compatible_type langhooks to see when can fold. (setup_one_parameter): Don't remap type. (inline_forbidden_p_1): Add arg to variably_modified_type_p. * tree.c (recompute_tree_invarant_for_addr_expr): Properly compute TREE_INVARIANT for decl case. (find_var_from_fn): New function. (variably_modified_type_p): Add arg and call new function. * tree.h (variably_modified_type_p): Add extra arg. * cp/cp-lang.c (cp_var_mod_type_p): Add extra arg. * cp/decl.c (grokdeclarator): Extra arg to variably_modified_type_p. * cp/pt.c (check_instantiated_args, unify): Likewise. From-SVN: r84144
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r--gcc/tree-inline.c76
1 files changed, 35 insertions, 41 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 34a158c..fcda4ad 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -155,35 +155,21 @@ insert_decl_map (inline_data *id, tree key, tree value)
(splay_tree_value) value);
}
-/* Remap DECL during the copying of the BLOCK tree for the function. */
+/* Remap DECL during the copying of the BLOCK tree for the function.
+ We are only called to remap local variables in the current function. */
static tree
remap_decl (tree decl, inline_data *id)
{
- splay_tree_node n;
- tree fn;
-
- /* We only remap local variables in the current function. */
- fn = VARRAY_TOP_TREE (id->fns);
-#if 0
- /* We need to remap statics, too, so that they get expanded even if the
- inline function is never emitted out of line. We might as well also
- remap extern decls so that they show up in the debug info. */
- if (! lang_hooks.tree_inlining.auto_var_in_fn_p (decl, fn))
- return NULL_TREE;
-#endif
-
- /* See if we have remapped this declaration. */
- n = splay_tree_lookup (id->decl_map, (splay_tree_key) decl);
+ splay_tree_node n = splay_tree_lookup (id->decl_map, (splay_tree_key) decl);
+ tree fn = VARRAY_TOP_TREE (id->fns);
- /* If we didn't already have an equivalent for this declaration,
- create one now. */
+ /* See if we have remapped this declaration. If we didn't already have an
+ equivalent for this declaration, create one now. */
if (!n)
{
- tree t;
-
/* Make a copy of the variable or label. */
- t = copy_decl_for_inlining (decl, fn, VARRAY_TREE (id->fns, 0));
+ tree t = copy_decl_for_inlining (decl, fn, VARRAY_TREE (id->fns, 0));
/* Remap types, if necessary. */
TREE_TYPE (t) = remap_type (TREE_TYPE (t), id);
@@ -197,6 +183,14 @@ remap_decl (tree decl, inline_data *id)
walk_tree (&DECL_SIZE (t), copy_body_r, id, NULL);
walk_tree (&DECL_SIZE_UNIT (t), copy_body_r, id, NULL);
+ /* If fields, do likewise for offset and qualifier. */
+ if (TREE_CODE (t) == FIELD_DECL)
+ {
+ walk_tree (&DECL_FIELD_OFFSET (t), copy_body_r, id, NULL);
+ if (TREE_CODE (DECL_CONTEXT (t)) == QUAL_UNION_TYPE)
+ walk_tree (&DECL_QUALIFIER (t), copy_body_r, id, NULL);
+ }
+
#if 0
/* FIXME handle anon aggrs. */
if (! DECL_NAME (t) && TREE_TYPE (t)
@@ -243,8 +237,9 @@ remap_type (tree type, inline_data *id)
if (node)
return (tree) node->value;
- /* The type only needs remapping if it's variably modified. */
- if (! variably_modified_type_p (type))
+ /* The type only needs remapping if it's variably modified by a variable
+ in the function we are inlining. */
+ if (! variably_modified_type_p (type, VARRAY_TOP_TREE (id->fns)))
{
insert_decl_map (id, type, type);
return type;
@@ -458,12 +453,8 @@ copy_bind_expr (tree *tp, int *walk_subtrees, inline_data *id)
static tree
copy_body_r (tree *tp, int *walk_subtrees, void *data)
{
- inline_data* id;
- tree fn;
-
- /* Set up. */
- id = (inline_data *) data;
- fn = VARRAY_TOP_TREE (id->fns);
+ inline_data *id = (inline_data *) data;
+ tree fn = VARRAY_TOP_TREE (id->fns);
#if 0
/* All automatic variables should have a DECL_CONTEXT indicating
@@ -507,7 +498,7 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data)
/* Local variables and labels need to be replaced by equivalent
variables. We don't want to copy static variables; there's only
one of those, no matter how many times we inline the containing
- function. */
+ function. Similarly for globals from an outer function. */
else if (lang_hooks.tree_inlining.auto_var_in_fn_p (*tp, fn))
{
tree new_decl;
@@ -603,13 +594,13 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data)
value = (tree) n->value;
if (TREE_CODE (value) == INDIRECT_REF)
{
- /* Assume that the argument types properly match the
- parameter types. We can't compare them well enough
- without a comptypes langhook, and we don't want to
- call convert and introduce a NOP_EXPR to convert
- between two equivalent types (i.e. that only differ
- in use of typedef names). */
- *tp = TREE_OPERAND (value, 0);
+ if (!lang_hooks.types_compatible_p
+ (TREE_TYPE (*tp), TREE_TYPE (TREE_OPERAND (value, 0))))
+ *tp = fold_convert (TREE_TYPE (*tp),
+ TREE_OPERAND (value, 0));
+ else
+ *tp = TREE_OPERAND (value, 0);
+
return copy_body_r (tp, walk_subtrees, data);
}
}
@@ -626,7 +617,9 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data)
{
value = (tree) n->value;
STRIP_NOPS (value);
- if (TREE_CODE (value) == ADDR_EXPR)
+ if (TREE_CODE (value) == ADDR_EXPR
+ && (lang_hooks.types_compatible_p
+ (TREE_TYPE (*tp), TREE_TYPE (TREE_OPERAND (value, 0)))))
{
*tp = TREE_OPERAND (value, 0);
return copy_body_r (tp, walk_subtrees, data);
@@ -739,9 +732,10 @@ setup_one_parameter (inline_data *id, tree p, tree value, tree fn,
}
}
- /* Make an equivalent VAR_DECL with the remapped type. */
+ /* Make an equivalent VAR_DECL. Note that we must NOT remap the type
+ here since the type of this decl must be visible to the calling
+ function. */
var = copy_decl_for_inlining (p, fn, VARRAY_TREE (id->fns, 0));
- TREE_TYPE (var) = remap_type (TREE_TYPE (var), id);
/* See if the frontend wants to pass this by invisible reference. If
so, our new VAR_DECL will have REFERENCE_TYPE, and we need to
@@ -1072,7 +1066,7 @@ inline_forbidden_p_1 (tree *nodep, int *walk_subtrees ATTRIBUTE_UNUSED,
then the type node for S doesn't get adjusted properly when
F is inlined, and we abort in find_function_data. */
for (t = TYPE_FIELDS (node); t; t = TREE_CHAIN (t))
- if (variably_modified_type_p (TREE_TYPE (t)))
+ if (variably_modified_type_p (TREE_TYPE (t), NULL))
{
inline_forbidden_reason
= N_("%Jfunction '%F' can never be inlined "