This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH to inlining and templates
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 05 Dec 2001 17:32:56 +0000
- Subject: C++ PATCH to inlining and templates
For a while now, the code to stop infinite recursion in template
instantiation has been broken when optimizing, because we don't actually
recursively instantiate functions anymore; rather, we instantiate one, then
when we try to inline its calls, we instantiate the next one. This patch
modifies the inliner to tell the frontend when it's starting to examine a
function, so that the C++ frontend can record the instantiation context as
appropriate. Testcase in g++.dg/template/recurse.C.
Tested i686-pc-linux-gnu, applied to trunk. I also have a version for the
gcc 3.0 branch, which is simpler because the tree inliner lives in the C++
frontend. Attached at the end. Mark, can I go ahead and apply that, too?
2001-12-04 Jason Merrill <jason@redhat.com>
* langhooks.h (struct lang_hooks_for_tree_inlining): Add
start_inlining, end_inlining.
* tree-inline.c (expand_call_inline): Call them.
* langhooks-def.h (LANG_HOOKS_TREE_INLINING_START_INLINING): Define.
(LANG_HOOKS_TREE_INLINING_END_INLINING): Define.
(LANG_HOOKS_TREE_INLINING_INITIALIZER): Add them.
* langhooks.c (lhd_tree_inlining_start_inlining): New fn.
(lhd_tree_inlining_end_inlining): New fn.
2001-12-04 Jason Merrill <jason@redhat.com>
* cp-lang.c (LANG_HOOKS_TREE_INLINING_START_INLINING): Define.
(LANG_HOOKS_TREE_INLINING_END_INLINING): Define.
* tree.c (cp_start_inlining, cp_end_inlining): New fns.
* pt.c (push_tinst_level): No longer static.
* cp-tree.h: Declare them.
*** ./gcc/cp/pt.c.~1~ Fri Nov 23 17:27:59 2001
--- ./gcc/cp/pt.c Tue Dec 4 15:50:18 2001
*************** static int try_one_overload PARAMS ((tre
*** 98,104 ****
unification_kind_t, int));
static int unify PARAMS ((tree, tree, tree, tree, int));
static void add_pending_template PARAMS ((tree));
- static int push_tinst_level PARAMS ((tree));
static void reopen_tinst_level PARAMS ((tree));
static tree classtype_mangled_name PARAMS ((tree));
static char *mangle_class_name_for_template PARAMS ((const char *, tree, tree));
--- 98,103 ----
*************** static int last_template_error_tick;
*** 4458,4464 ****
/* We're starting to instantiate D; record the template instantiation context
for diagnostics and to restore it later. */
! static int
push_tinst_level (d)
tree d;
{
--- 4457,4463 ----
/* We're starting to instantiate D; record the template instantiation context
for diagnostics and to restore it later. */
! int
push_tinst_level (d)
tree d;
{
*** ./gcc/cp/cp-tree.h.~1~ Fri Nov 30 14:05:56 2001
--- ./gcc/cp/cp-tree.h Tue Dec 4 16:12:41 2001
*************** extern void do_decl_instantiation PARAM
*** 3968,3973 ****
--- 3971,3977 ----
extern void do_type_instantiation PARAMS ((tree, tree, int));
extern tree instantiate_decl PARAMS ((tree, int));
extern tree get_bindings PARAMS ((tree, tree, tree));
+ extern int push_tinst_level PARAMS ((tree));
extern void pop_tinst_level PARAMS ((void));
extern int more_specialized_class PARAMS ((tree, tree));
extern int is_member_template PARAMS ((tree));
*************** extern int cp_is_overload_p PARAMS ((tre
*** 4240,4245 ****
--- 4244,4251 ----
extern int cp_auto_var_in_fn_p PARAMS ((tree,tree));
extern tree cp_copy_res_decl_for_inlining PARAMS ((tree, tree, tree, void*,
int*, void*));
+ extern int cp_start_inlining PARAMS ((tree));
+ extern void cp_end_inlining PARAMS ((tree));
/* in typeck.c */
extern int string_conv_p PARAMS ((tree, tree, int));
*** ./gcc/cp/tree.c.~1~ Fri Nov 30 14:06:02 2001
--- ./gcc/cp/tree.c Tue Dec 4 16:57:38 2001
*************** cp_copy_res_decl_for_inlining (result, f
*** 2230,2235 ****
--- 2230,2259 ----
return var;
}
+ /* Record that we're about to start inlining FN, and return non-zero if
+ that's OK. Used for lang_hooks.tree_inlining.start_inlining. */
+
+ int
+ cp_start_inlining (fn)
+ tree fn;
+ {
+ if (DECL_TEMPLATE_INSTANTIATION (fn))
+ return push_tinst_level (fn);
+ else
+ return 1;
+ }
+
+ /* Record that we're done inlining FN. Used for
+ lang_hooks.tree_inlining.end_inlining. */
+
+ void
+ cp_end_inlining (fn)
+ tree fn ATTRIBUTE_UNUSED;
+ {
+ if (DECL_TEMPLATE_INSTANTIATION (fn))
+ pop_tinst_level ();
+ }
+
/* Initialize tree.c. */
void
*** ./gcc/cp/cp-lang.c.~1~ Fri Nov 30 14:05:56 2001
--- ./gcc/cp/cp-lang.c Tue Dec 4 15:47:19 2001
*************** static HOST_WIDE_INT cxx_get_alias_set P
*** 83,88 ****
--- 83,92 ----
cp_copy_res_decl_for_inlining
#undef LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P
#define LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P anon_aggr_type_p
+ #undef LANG_HOOKS_TREE_INLINING_START_INLINING
+ #define LANG_HOOKS_TREE_INLINING_START_INLINING cp_start_inlining
+ #undef LANG_HOOKS_TREE_INLINING_END_INLINING
+ #define LANG_HOOKS_TREE_INLINING_END_INLINING cp_end_inlining
#undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN
#define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN cp_dump_tree
#undef LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN
*** ./gcc/langhooks.h.~1~ Fri Nov 30 14:05:38 2001
--- ./gcc/langhooks.h Tue Dec 4 15:45:04 2001
*************** struct lang_hooks_for_tree_inlining
*** 46,51 ****
--- 46,53 ----
void *, int *,
void *));
int (*anon_aggr_type_p) PARAMS ((union tree_node *));
+ int (*start_inlining) PARAMS ((union tree_node *));
+ void (*end_inlining) PARAMS ((union tree_node *));
};
/* The following hooks are used by tree-dump.c. */
*** ./gcc/langhooks.c.~1~ Fri Nov 30 14:05:38 2001
--- ./gcc/langhooks.c Tue Dec 4 16:23:40 2001
*************** lhd_tree_inlining_anon_aggr_type_p (t)
*** 231,236 ****
--- 231,257 ----
return 0;
}
+ /* lang_hooks.tree_inlining.start_inlining and end_inlining perform any
+ language-specific bookkeeping necessary for processing
+ FN. start_inlining returns non-zero if inlining should proceed, zero if
+ not.
+
+ For instance, the C++ version keeps track of template instantiations to
+ avoid infinite recursion. */
+
+ int
+ lhd_tree_inlining_start_inlining (fn)
+ tree fn ATTRIBUTE_UNUSED;
+ {
+ return 1;
+ }
+
+ void
+ lhd_tree_inlining_end_inlining (fn)
+ tree fn ATTRIBUTE_UNUSED;
+ {
+ }
+
/* lang_hooks.tree_dump.dump_tree: Dump language-specific parts of tree
nodes. Returns non-zero if it does not want the usual dumping of the
second argument. */
*** ./gcc/tree-inline.c.~1~ Fri Nov 30 14:05:42 2001
--- ./gcc/tree-inline.c Tue Dec 4 15:51:28 2001
*************** expand_call_inline (tp, walk_subtrees, d
*** 812,817 ****
--- 812,820 ----
if (!inlinable_function_p (fn, id))
return NULL_TREE;
+ if (! (*lang_hooks.tree_inlining.start_inlining) (fn))
+ return NULL_TREE;
+
/* Set the current filename and line number to the function we are
inlining so that when we create new _STMT nodes here they get
line numbers corresponding to the function we are calling. We
*************** expand_call_inline (tp, walk_subtrees, d
*** 950,955 ****
--- 953,960 ----
/* Don't walk into subtrees. We've already handled them above. */
*walk_subtrees = 0;
+ (*lang_hooks.tree_inlining.end_inlining) (fn);
+
/* Keep iterating. */
return NULL_TREE;
}
*** ./gcc/langhooks-def.h.~1~ Fri Nov 30 14:05:38 2001
--- ./gcc/langhooks-def.h Tue Dec 4 15:46:24 2001
*************** tree lhd_tree_inlining_copy_res_decl_for
*** 59,64 ****
--- 59,66 ----
tree, void *,
int *, void *));
int lhd_tree_inlining_anon_aggr_type_p PARAMS ((tree));
+ int lhd_tree_inlining_start_inlining PARAMS ((tree));
+ void lhd_tree_inlining_end_inlining PARAMS ((tree));
#define LANG_HOOKS_NAME "GNU unknown"
#define LANG_HOOKS_IDENTIFIER_SIZE sizeof (struct lang_identifier)
*************** int lhd_tree_inlining_anon_aggr_type_p
*** 95,100 ****
--- 97,106 ----
lhd_tree_inlining_copy_res_decl_for_inlining
#define LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P \
lhd_tree_inlining_anon_aggr_type_p
+ #define LANG_HOOKS_TREE_INLINING_START_INLINING \
+ lhd_tree_inlining_start_inlining
+ #define LANG_HOOKS_TREE_INLINING_END_INLINING \
+ lhd_tree_inlining_end_inlining
#define LANG_HOOKS_TREE_INLINING_INITIALIZER { \
LANG_HOOKS_TREE_INLINING_WALK_SUBTREES, \
*************** int lhd_tree_inlining_anon_aggr_type_p
*** 104,110 ****
LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P, \
LANG_HOOKS_TREE_INLINING_AUTO_VAR_IN_FN_P, \
LANG_HOOKS_TREE_INLINING_COPY_RES_DECL_FOR_INLINING, \
! LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P \
} \
/* Tree dump hooks. */
--- 110,118 ----
LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P, \
LANG_HOOKS_TREE_INLINING_AUTO_VAR_IN_FN_P, \
LANG_HOOKS_TREE_INLINING_COPY_RES_DECL_FOR_INLINING, \
! LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P, \
! LANG_HOOKS_TREE_INLINING_START_INLINING, \
! LANG_HOOKS_TREE_INLINING_END_INLINING \
} \
/* Tree dump hooks. */
2001-12-05 Jason Merrill <jason@redhat.com>
* pt.c (push_tinst_level): No longer static.
* cp-tree.h: Declare it.
* optimize.c (expand_call_inline): Record template instantiation
context.
*** cp-tree.h.~1~ Fri Nov 30 03:47:35 2001
--- cp-tree.h Tue Dec 4 17:32:06 2001
*************** extern void do_decl_instantiation PARAM
*** 4173,4178 ****
--- 4173,4179 ----
extern void do_type_instantiation PARAMS ((tree, tree, int));
extern tree instantiate_decl PARAMS ((tree, int));
extern tree get_bindings PARAMS ((tree, tree, tree));
+ extern int push_tinst_level PARAMS ((tree));
extern void pop_tinst_level PARAMS ((void));
extern int more_specialized_class PARAMS ((tree, tree));
extern int is_member_template PARAMS ((tree));
*** optimize.c.~1~ Thu Nov 29 14:33:19 2001
--- optimize.c Tue Dec 4 17:33:13 2001
*************** expand_call_inline (tp, walk_subtrees, d
*** 777,782 ****
--- 777,786 ----
if (!inlinable_function_p (fn, id))
return NULL_TREE;
+ if (DECL_TEMPLATE_INSTANTIATION (fn)
+ && ! push_tinst_level (fn))
+ return NULL_TREE;
+
/* Set the current filename and line number to the function we are
inlining so that when we create new _STMT nodes here they get
line numbers corresponding to the function we are calling. We
*************** expand_call_inline (tp, walk_subtrees, d
*** 915,920 ****
--- 919,927 ----
/* Don't walk into subtrees. We've already handled them above. */
*walk_subtrees = 0;
+ if (DECL_TEMPLATE_INSTANTIATION (fn))
+ pop_tinst_level ();
+
/* Keep iterating. */
return NULL_TREE;
}
*** pt.c.~1~ Thu Nov 29 14:33:20 2001
--- pt.c Tue Dec 4 17:32:07 2001
*************** static int try_one_overload PARAMS ((tre
*** 100,106 ****
unification_kind_t, int));
static int unify PARAMS ((tree, tree, tree, tree, int));
static void add_pending_template PARAMS ((tree));
- static int push_tinst_level PARAMS ((tree));
static void reopen_tinst_level PARAMS ((tree));
static tree classtype_mangled_name PARAMS ((tree));
static char *mangle_class_name_for_template PARAMS ((const char *, tree, tree));
--- 100,105 ----
*************** static int last_template_error_tick;
*** 4433,4439 ****
/* We're starting to instantiate D; record the template instantiation context
for diagnostics and to restore it later. */
! static int
push_tinst_level (d)
tree d;
{
--- 4432,4438 ----
/* We're starting to instantiate D; record the template instantiation context
for diagnostics and to restore it later. */
! int
push_tinst_level (d)
tree d;
{