mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-09 05:06:48 +08:00
langhooks.h: New file.
* langhooks.h: New file. * Makefile.in (OBJS): Added langhooks.o. (c-lang.o): Depend on langhooks.h. (c-common.o): Don't depend on tree-inline.h. (tree-inline.o): Depend on toplev.h. (langhooks.o): New rule. * c-common.c: Don't include tree-inline.h. (c_mark_lang_decl): Mark argument c as unused. (c_common_lang_init): Don't initialize hooks here. * c-lang.c: Include langhooks.h, then override some macros. (lang_hooks): Initialize with macros in langhooks.h. (c_init): Don't initialize hooks here. * toplev.c (struct lang_hooks_for_tree_inlining): New struct. (struct lang_hooks): Add tree_inlining. Refer to langhooks.h. * tree-inline.c: Include toplev.h. Don't define hook variables. * tree-inline.h: Don't define hook types nor declare hook variables. Move macros to... * langhooks.c: ... new file, as functions. Adjust all callers. From-SVN: r46096
This commit is contained in:
parent
19551f2985
commit
69dcadffba
@ -1,3 +1,24 @@
|
||||
2001-10-08 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
* langhooks.h: New file.
|
||||
* Makefile.in (OBJS): Added langhooks.o.
|
||||
(c-lang.o): Depend on langhooks.h.
|
||||
(c-common.o): Don't depend on tree-inline.h.
|
||||
(tree-inline.o): Depend on toplev.h.
|
||||
(langhooks.o): New rule.
|
||||
* c-common.c: Don't include tree-inline.h.
|
||||
(c_mark_lang_decl): Mark argument c as unused.
|
||||
(c_common_lang_init): Don't initialize hooks here.
|
||||
* c-lang.c: Include langhooks.h, then override some macros.
|
||||
(lang_hooks): Initialize with macros in langhooks.h.
|
||||
(c_init): Don't initialize hooks here.
|
||||
* toplev.c (struct lang_hooks_for_tree_inlining): New struct.
|
||||
(struct lang_hooks): Add tree_inlining. Refer to langhooks.h.
|
||||
* tree-inline.c: Include toplev.h. Don't define hook variables.
|
||||
* tree-inline.h: Don't define hook types nor declare hook
|
||||
variables. Move macros to...
|
||||
* langhooks.c: ... new file, as functions. Adjust all callers.
|
||||
|
||||
2001-10-08 Jeffrey A Law <law@cygnus.com>
|
||||
|
||||
* sibcall.c (optimize_sibling_and_tail_recursive_calls): Call
|
||||
|
@ -748,7 +748,7 @@ OBJS = \
|
||||
sdbout.o sibcall.o simplify-rtx.o splay-tree.o ssa.o ssa-ccp.o \
|
||||
ssa-dce.o stmt.o stor-layout.o stringpool.o timevar.o toplev.o tree.o \
|
||||
unroll.o varasm.o varray.o version.o xcoffout.o cfg.o cfganal.o \
|
||||
cfgbuild.o cfgcleanup.o cfgloop.o cfgrtl.o tree-inline.o \
|
||||
cfgbuild.o cfgcleanup.o cfgloop.o cfgrtl.o tree-inline.o langhooks.o \
|
||||
$(GGC) $(out_object_file) $(EXTRA_OBJS)
|
||||
|
||||
BACKEND = main.o libbackend.a
|
||||
@ -1173,7 +1173,7 @@ c-typeck.o : c-typeck.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
|
||||
$(TARGET_H) flags.h intl.h output.h $(EXPR_H) $(RTL_H) toplev.h $(TM_P_H)
|
||||
c-lang.o : c-lang.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
|
||||
$(GGC_H) c-lex.h toplev.h diagnostic.h output.h function.h \
|
||||
$(RTL_H) $(EXPR_H) tree-inline.h insn-config.h integrate.h
|
||||
$(RTL_H) $(EXPR_H) tree-inline.h insn-config.h integrate.h langhooks.h
|
||||
c-lex.o : c-lex.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) c-lex.h \
|
||||
debug.h $(C_TREE_H) \
|
||||
c-pragma.h input.h intl.h flags.h toplev.h output.h \
|
||||
@ -1249,8 +1249,7 @@ s-under: $(GCC_PASSES)
|
||||
|
||||
c-common.o : c-common.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(OBSTACK_H) \
|
||||
$(C_COMMON_H) flags.h toplev.h output.h c-pragma.h $(RTL_H) $(GGC_H) \
|
||||
$(EXPR_H) $(TM_P_H) builtin-types.def builtin-attrs.def $(TARGET_H) \
|
||||
tree-inline.h
|
||||
$(EXPR_H) $(TM_P_H) builtin-types.def builtin-attrs.def $(TARGET_H)
|
||||
|
||||
# A file used by all variants of C and some other languages.
|
||||
|
||||
@ -1349,11 +1348,13 @@ prefix.o: prefix.c $(CONFIG_H) $(SYSTEM_H) Makefile prefix.h
|
||||
|
||||
convert.o: convert.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h convert.h toplev.h
|
||||
|
||||
langhooks.o : langhooks.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) toplev.h \
|
||||
tree-inline.h
|
||||
tree.o : tree.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h function.h toplev.h \
|
||||
$(GGC_H) $(HASHTAB_H) $(TARGET_H) output.h $(TM_P_H)
|
||||
tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) \
|
||||
expr.h flags.h params.h input.h insn-config.h $(INTEGRATE_H) \
|
||||
$(VARRAY_H) $(HASHTAB_H) $(SPLAY_TREE_H) \
|
||||
$(VARRAY_H) $(HASHTAB_H) $(SPLAY_TREE_H) toplev.h \
|
||||
$(C_COMMON_H) tree-inline.h
|
||||
print-tree.o : print-tree.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(GGC_H)
|
||||
stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h \
|
||||
|
@ -22,7 +22,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "tree.h"
|
||||
#include "tree-inline.h"
|
||||
#include "flags.h"
|
||||
#include "toplev.h"
|
||||
#include "output.h"
|
||||
@ -3330,7 +3329,7 @@ mark_stmt_tree (p)
|
||||
|
||||
void
|
||||
c_mark_lang_decl (c)
|
||||
struct c_lang_decl *c;
|
||||
struct c_lang_decl *c ATTRIBUTE_UNUSED;
|
||||
{
|
||||
}
|
||||
|
||||
@ -3831,8 +3830,6 @@ c_common_lang_init ()
|
||||
if (flag_bounds_check < 0)
|
||||
flag_bounds_check = flag_bounded_pointers;
|
||||
|
||||
lang_anon_aggr_type_p = anon_aggr_type_p;
|
||||
|
||||
/* Special format checking options don't work without -Wformat; warn if
|
||||
they are used. */
|
||||
if (warn_format_y2k && !warn_format)
|
||||
|
27
gcc/c-lang.c
27
gcc/c-lang.c
@ -38,6 +38,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "cpplib.h"
|
||||
#include "insn-config.h"
|
||||
#include "integrate.h"
|
||||
#include "langhooks.h"
|
||||
|
||||
static int c_tree_printer PARAMS ((output_buffer *));
|
||||
static int c_missing_noreturn_ok_p PARAMS ((tree));
|
||||
@ -47,12 +48,26 @@ static void c_post_options PARAMS ((void));
|
||||
static int c_disregard_inline_limits PARAMS ((tree));
|
||||
static int c_cannot_inline_tree_fn PARAMS ((tree *));
|
||||
|
||||
#undef LANG_HOOKS_INIT
|
||||
#define LANG_HOOKS_INIT c_init
|
||||
#undef LANG_HOOKS_INIT_OPTIONS
|
||||
#define LANG_HOOKS_INIT_OPTIONS c_init_options
|
||||
#undef LANG_HOOKS_DECODE_OPTION
|
||||
#define LANG_HOOKS_DECODE_OPTION c_decode_option
|
||||
#undef LANG_HOOKS_POST_OPTIONS
|
||||
#define LANG_HOOKS_POST_OPTIONS c_post_options
|
||||
#undef LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN
|
||||
#define LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN \
|
||||
c_cannot_inline_tree_fn
|
||||
#undef LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS
|
||||
#define LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS \
|
||||
c_disregard_inline_limits
|
||||
#undef LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P
|
||||
#define LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P \
|
||||
anon_aggr_type_p
|
||||
|
||||
/* Each front end provides its own. */
|
||||
struct lang_hooks lang_hooks = {c_init,
|
||||
NULL, /* c_finish */
|
||||
c_init_options,
|
||||
c_decode_option,
|
||||
c_post_options};
|
||||
struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
|
||||
|
||||
/* Post-switch processing. */
|
||||
static void
|
||||
@ -112,8 +127,6 @@ c_init ()
|
||||
diagnostic_format_decoder (global_dc) = &c_tree_printer;
|
||||
lang_expand_decl_stmt = &c_expand_decl_stmt;
|
||||
lang_missing_noreturn_ok_p = &c_missing_noreturn_ok_p;
|
||||
lang_disregard_inline_limits = &c_disregard_inline_limits;
|
||||
lang_cannot_inline_tree_fn = &c_cannot_inline_tree_fn;
|
||||
|
||||
c_parse_init ();
|
||||
}
|
||||
|
142
gcc/langhooks.c
Normal file
142
gcc/langhooks.c
Normal file
@ -0,0 +1,142 @@
|
||||
/* Default language-specific hooks.
|
||||
Copyright 2001 Free Software Foundation, Inc.
|
||||
Contributed by Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "toplev.h"
|
||||
#include "tree.h"
|
||||
#include "tree-inline.h"
|
||||
|
||||
/* lang_hooks.tree_inlining.walk_subtrees is called by walk_tree()
|
||||
after handling common cases, but before walking code-specific
|
||||
sub-trees. If this hook is overridden for a language, it should
|
||||
handle language-specific tree codes, as well as language-specific
|
||||
information associated to common tree codes. If a tree node is
|
||||
completely handled within this function, it should set *SUBTREES to
|
||||
0, so that generic handling isn't attempted. For language-specific
|
||||
tree codes, generic handling would abort(), so make sure it is set
|
||||
properly. Both SUBTREES and *SUBTREES is guaranteed to be non-zero
|
||||
when the function is called. */
|
||||
|
||||
tree
|
||||
tree_inlining_default_hook_walk_subtrees (tp,subtrees,func,data,htab)
|
||||
tree *tp ATTRIBUTE_UNUSED;
|
||||
int *subtrees ATTRIBUTE_UNUSED;
|
||||
walk_tree_fn func ATTRIBUTE_UNUSED;
|
||||
void *data ATTRIBUTE_UNUSED;
|
||||
void *htab ATTRIBUTE_UNUSED;
|
||||
{
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* lang_hooks.tree_inlining.cannot_inline_tree_fn is called to
|
||||
determine whether there are language-specific reasons for not
|
||||
inlining a given function. */
|
||||
|
||||
int
|
||||
tree_inlining_default_hook_cannot_inline_tree_fn (fnp)
|
||||
tree *fnp ATTRIBUTE_UNUSED;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* lang_hooks.tree_inlining.disregard_inline_limits is called to
|
||||
determine whether a function should be considered for inlining even
|
||||
if it would exceed inlining limits. */
|
||||
|
||||
int
|
||||
tree_inlining_default_hook_disregard_inline_limits (fn)
|
||||
tree fn ATTRIBUTE_UNUSED;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* lang_hooks.tree_inlining.add_pending_fn_decls is called before
|
||||
starting to inline a function, to push any language-specific
|
||||
functions that should not be inlined into the current function,
|
||||
into VAFNP. PFN is the top of varray, and should be returned if no
|
||||
functions are pushed into VAFNP. The top of the varray should be
|
||||
returned. */
|
||||
|
||||
tree
|
||||
tree_inlining_default_hook_add_pending_fn_decls (vafnp, pfn)
|
||||
void *vafnp ATTRIBUTE_UNUSED;
|
||||
tree pfn;
|
||||
{
|
||||
return pfn;
|
||||
}
|
||||
|
||||
/* lang_hooks.tree_inlining.tree_chain_matters_p indicates whether the
|
||||
TREE_CHAIN of a language-specific tree node is relevant, i.e.,
|
||||
whether it should be walked, copied and preserved across copies. */
|
||||
|
||||
int
|
||||
tree_inlining_default_hook_tree_chain_matters_p (t)
|
||||
tree t ATTRIBUTE_UNUSED;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* lang_hooks.tree_inlining.auto_var_in_fn_p is called to determine
|
||||
whether VT is an automatic variable defined in function FT. */
|
||||
|
||||
int
|
||||
tree_inlining_default_hook_auto_var_in_fn_p (var, fn)
|
||||
tree var, fn;
|
||||
{
|
||||
return (DECL_P (var) && DECL_CONTEXT (var) == fn
|
||||
&& (((TREE_CODE (var) == VAR_DECL || TREE_CODE (var) == PARM_DECL)
|
||||
&& ! TREE_STATIC (var))
|
||||
|| TREE_CODE (var) == LABEL_DECL
|
||||
|| TREE_CODE (var) == RESULT_DECL));
|
||||
}
|
||||
|
||||
/* lang_hooks.tree_inlining.copy_res_decl_for_inlining should return a
|
||||
declaration for the result RES of function FN to be inlined into
|
||||
CALLER. NDP points to an integer that should be set in case a new
|
||||
declaration wasn't created (presumably because RES was of aggregate
|
||||
type, such that a TARGET_EXPR is used for the result). TEXPS is a
|
||||
pointer to a varray with the stack of TARGET_EXPRs seen while
|
||||
inlining functions into caller; the top of TEXPS is supposed to
|
||||
match RES. */
|
||||
|
||||
tree
|
||||
tree_inlining_default_hook_copy_res_decl_for_inlining (res, fn, caller,
|
||||
dm, ndp, texps)
|
||||
tree res, fn, caller;
|
||||
void *dm ATTRIBUTE_UNUSED;
|
||||
int *ndp ATTRIBUTE_UNUSED;
|
||||
void *texps ATTRIBUTE_UNUSED;
|
||||
{
|
||||
return copy_decl_for_inlining (res, fn, caller);
|
||||
}
|
||||
|
||||
/* lang_hooks.tree_inlining.anon_aggr_type_p determines whether T is a
|
||||
type node representing an anonymous aggregate (union, struct, etc),
|
||||
i.e., one whose members are in the same scope as the union itself. */
|
||||
|
||||
int
|
||||
tree_inlining_default_hook_anon_aggr_type_p (t)
|
||||
tree t ATTRIBUTE_UNUSED;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
114
gcc/langhooks.h
Normal file
114
gcc/langhooks.h
Normal file
@ -0,0 +1,114 @@
|
||||
/* Macros to initialize the lang_hooks data structure.
|
||||
Copyright 2001 Free Software Foundation, Inc.
|
||||
Contributed by Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef GCC_LANG_HOOKS_H
|
||||
#define GCC_LANG_HOOKS_H
|
||||
|
||||
/* Older hooks, that don't go in sub-structures for backward
|
||||
compatibility. */
|
||||
#ifndef LANG_HOOKS_INIT
|
||||
#define LANG_HOOKS_INIT NULL
|
||||
#endif
|
||||
#ifndef LANG_HOOKS_FINISH
|
||||
#define LANG_HOOKS_FINISH NULL
|
||||
#endif
|
||||
#ifndef LANG_HOOKS_INIT_OPTIONS
|
||||
#define LANG_HOOKS_INIT_OPTIONS NULL
|
||||
#endif
|
||||
#ifndef LANG_HOOKS_DECODE_OPTION
|
||||
#define LANG_HOOKS_DECODE_OPTION NULL
|
||||
#endif
|
||||
#ifndef LANG_HOOKS_POST_OPTIONS
|
||||
#define LANG_HOOKS_POST_OPTIONS NULL
|
||||
#endif
|
||||
|
||||
/* Declarations of default tree inlining hooks. */
|
||||
tree tree_inlining_default_hook_walk_subtrees PARAMS ((tree*, int *,
|
||||
walk_tree_fn,
|
||||
void *, void *));
|
||||
int tree_inlining_default_hook_cannot_inline_tree_fn PARAMS ((tree*));
|
||||
int tree_inlining_default_hook_disregard_inline_limits PARAMS ((tree));
|
||||
tree tree_inlining_default_hook_add_pending_fn_decls PARAMS ((void*, tree));
|
||||
int tree_inlining_default_hook_tree_chain_matters_p PARAMS ((tree));
|
||||
int tree_inlining_default_hook_auto_var_in_fn_p PARAMS ((tree, tree));
|
||||
tree tree_inlining_default_hook_copy_res_decl_for_inlining PARAMS ((tree, tree,
|
||||
tree,
|
||||
void *,
|
||||
int *,
|
||||
void *));
|
||||
int tree_inlining_default_hook_anon_aggr_type_p PARAMS ((tree));
|
||||
|
||||
/* Tree inlining hooks. */
|
||||
#ifndef LANG_HOOKS_TREE_INLINING_WALK_SUBTREES
|
||||
#define LANG_HOOKS_TREE_INLINING_WALK_SUBTREES \
|
||||
tree_inlining_default_hook_walk_subtrees
|
||||
#endif
|
||||
#ifndef LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN
|
||||
#define LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN \
|
||||
tree_inlining_default_hook_cannot_inline_tree_fn
|
||||
#endif
|
||||
#ifndef LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS
|
||||
#define LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS \
|
||||
tree_inlining_default_hook_disregard_inline_limits
|
||||
#endif
|
||||
#ifndef LANG_HOOKS_TREE_INLINING_ADD_PENDING_FN_DECLS
|
||||
#define LANG_HOOKS_TREE_INLINING_ADD_PENDING_FN_DECLS \
|
||||
tree_inlining_default_hook_add_pending_fn_decls
|
||||
#endif
|
||||
#ifndef LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P
|
||||
#define LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P \
|
||||
tree_inlining_default_hook_tree_chain_matters_p
|
||||
#endif
|
||||
#ifndef LANG_HOOKS_TREE_INLINING_AUTO_VAR_IN_FN_P
|
||||
#define LANG_HOOKS_TREE_INLINING_AUTO_VAR_IN_FN_P \
|
||||
tree_inlining_default_hook_auto_var_in_fn_p
|
||||
#endif
|
||||
#ifndef LANG_HOOKS_TREE_INLINING_COPY_RES_DECL_FOR_INLINING
|
||||
#define LANG_HOOKS_TREE_INLINING_COPY_RES_DECL_FOR_INLINING \
|
||||
tree_inlining_default_hook_copy_res_decl_for_inlining
|
||||
#endif
|
||||
#ifndef LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P
|
||||
#define LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P \
|
||||
tree_inlining_default_hook_anon_aggr_type_p
|
||||
#endif
|
||||
|
||||
#define LANG_HOOKS_TREE_INLINING_INITIALIZER { \
|
||||
LANG_HOOKS_TREE_INLINING_WALK_SUBTREES, \
|
||||
LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN, \
|
||||
LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS, \
|
||||
LANG_HOOKS_TREE_INLINING_ADD_PENDING_FN_DECLS, \
|
||||
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 \
|
||||
} \
|
||||
|
||||
/* The whole thing. The structure is defined in toplev.h. */
|
||||
#define LANG_HOOKS_INITIALIZER { \
|
||||
LANG_HOOKS_INIT, \
|
||||
LANG_HOOKS_FINISH, \
|
||||
LANG_HOOKS_INIT_OPTIONS, \
|
||||
LANG_HOOKS_DECODE_OPTION, \
|
||||
LANG_HOOKS_POST_OPTIONS, \
|
||||
LANG_HOOKS_TREE_INLINING_INITIALIZER \
|
||||
}
|
||||
|
||||
#endif /* GCC_LANG_HOOKS_H */
|
29
gcc/toplev.h
29
gcc/toplev.h
@ -115,7 +115,31 @@ extern void check_global_declarations PARAMS ((union tree_node **, int));
|
||||
extern const char *progname;
|
||||
extern const char *dump_base_name;
|
||||
|
||||
/* The following hooks are documented in langhooks.c. Must not be
|
||||
NULL. */
|
||||
|
||||
struct lang_hooks_for_tree_inlining
|
||||
{
|
||||
union tree_node *(*walk_subtrees) PARAMS ((union tree_node **, int *,
|
||||
union tree_node *(*)
|
||||
(union tree_node **,
|
||||
int *, void *),
|
||||
void *, void *));
|
||||
int (*cannot_inline_tree_fn) PARAMS ((union tree_node **));
|
||||
int (*disregard_inline_limits) PARAMS ((union tree_node *));
|
||||
union tree_node *(*add_pending_fn_decls) PARAMS ((void*, union tree_node *));
|
||||
int (*tree_chain_matters_p) PARAMS ((union tree_node *));
|
||||
int (*auto_var_in_fn_p) PARAMS ((union tree_node *, union tree_node *));
|
||||
union tree_node *(*copy_res_decl_for_inlining) PARAMS ((union tree_node *,
|
||||
union tree_node *,
|
||||
union tree_node *,
|
||||
void *, int *,
|
||||
void *));
|
||||
int (*anon_aggr_type_p) PARAMS ((union tree_node *));
|
||||
};
|
||||
|
||||
/* Language-specific hooks. Can be NULL unless otherwise specified. */
|
||||
|
||||
struct lang_hooks
|
||||
{
|
||||
/* Called first, to initialize the front end. */
|
||||
@ -141,6 +165,11 @@ struct lang_hooks
|
||||
|
||||
/* Called when all command line options have been processed. */
|
||||
void (*post_options) PARAMS ((void));
|
||||
|
||||
struct lang_hooks_for_tree_inlining tree_inlining;
|
||||
|
||||
/* Whenever you add entries here, make sure you adjust langhooks.h
|
||||
and langhooks.c accordingly. */
|
||||
};
|
||||
|
||||
/* Each front end provides its own. */
|
||||
|
@ -21,6 +21,7 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "toplev.h"
|
||||
#include "tree.h"
|
||||
#include "tree-inline.h"
|
||||
#include "rtl.h"
|
||||
@ -38,17 +39,6 @@ Boston, MA 02111-1307, USA. */
|
||||
this would require a shared function-as-trees infrastructure. */
|
||||
#include "c-common.h"
|
||||
|
||||
/* Definitions of language hooks. */
|
||||
|
||||
treeopt_walk_subtrees_type *lang_walk_subtrees;
|
||||
treeopt_cannot_inline_tree_fn_type *lang_cannot_inline_tree_fn;
|
||||
treeopt_disregard_inline_limits_type *lang_disregard_inline_limits;
|
||||
treeopt_add_pending_fn_decls_type *lang_add_pending_fn_decls;
|
||||
treeopt_tree_chain_matters_p_type *lang_tree_chain_matters_p;
|
||||
treeopt_auto_var_in_fn_p_type *lang_auto_var_in_fn_p;
|
||||
treeopt_copy_res_decl_for_inlining_type *lang_copy_res_decl_for_inlining;
|
||||
treeopt_anon_aggr_type_p *lang_anon_aggr_type_p;
|
||||
|
||||
/* 0 if we should not perform inlining.
|
||||
1 if we should expand functions calls inline at the tree level.
|
||||
2 if we should consider *all* functions to be inline
|
||||
@ -139,7 +129,7 @@ remap_decl (decl, id)
|
||||
|
||||
/* We only remap local variables in the current function. */
|
||||
fn = VARRAY_TOP_TREE (id->fns);
|
||||
if (! LANG_AUTO_VAR_IN_FN_P (decl, fn))
|
||||
if (! (*lang_hooks.tree_inlining.auto_var_in_fn_p) (decl, fn))
|
||||
return NULL_TREE;
|
||||
|
||||
/* See if we have remapped this declaration. */
|
||||
@ -170,7 +160,7 @@ remap_decl (decl, id)
|
||||
}
|
||||
|
||||
if (! DECL_NAME (t) && TREE_TYPE (t)
|
||||
&& LANG_ANON_AGGR_TYPE_P (TREE_TYPE (t)))
|
||||
&& (*lang_hooks.tree_inlining.anon_aggr_type_p) (TREE_TYPE (t)))
|
||||
{
|
||||
/* For a VAR_DECL of anonymous type, we must also copy the
|
||||
member VAR_DECLS here and rechain the
|
||||
@ -381,7 +371,7 @@ copy_body_r (tp, walk_subtrees, data)
|
||||
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. */
|
||||
else if (LANG_AUTO_VAR_IN_FN_P (*tp, fn))
|
||||
else if ((*lang_hooks.tree_inlining.auto_var_in_fn_p) (*tp, fn))
|
||||
{
|
||||
tree new_decl;
|
||||
|
||||
@ -423,7 +413,8 @@ copy_body_r (tp, walk_subtrees, data)
|
||||
}
|
||||
else if (TREE_CODE (*tp) == MODIFY_EXPR
|
||||
&& TREE_OPERAND (*tp, 0) == TREE_OPERAND (*tp, 1)
|
||||
&& LANG_AUTO_VAR_IN_FN_P (TREE_OPERAND (*tp, 0), fn))
|
||||
&& ((*lang_hooks.tree_inlining.auto_var_in_fn_p)
|
||||
(TREE_OPERAND (*tp, 0), fn)))
|
||||
{
|
||||
/* Some assignments VAR = VAR; don't generate any rtl code
|
||||
and thus don't count as variable modification. Avoid
|
||||
@ -614,9 +605,9 @@ declare_return_variable (id, use_stmt)
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
var = LANG_COPY_RES_DECL_FOR_INLINING (result, fn, VARRAY_TREE (id->fns, 0),
|
||||
id->decl_map, &need_return_decl,
|
||||
&id->target_exprs);
|
||||
var = ((*lang_hooks.tree_inlining.copy_res_decl_for_inlining)
|
||||
(result, fn, VARRAY_TREE (id->fns, 0), id->decl_map,
|
||||
&need_return_decl, &id->target_exprs));
|
||||
|
||||
/* Register the VAR_DECL as the equivalent for the RESULT_DECL; that
|
||||
way, when the RESULT_DECL is encountered, it will be
|
||||
@ -682,7 +673,7 @@ inlinable_function_p (fn, id)
|
||||
/* We can't inline functions that are too big. Only allow a single
|
||||
function to eat up half of our budget. Make special allowance
|
||||
for extern inline functions, though. */
|
||||
else if (! LANG_DISREGARD_INLINE_LIMITS (fn)
|
||||
else if (! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn)
|
||||
&& DECL_NUM_STMTS (fn) * INSNS_PER_STMT > MAX_INLINE_INSNS / 2)
|
||||
;
|
||||
/* All is well. We can inline this function. Traditionally, GCC
|
||||
@ -699,13 +690,13 @@ inlinable_function_p (fn, id)
|
||||
be that we've done so much inlining already that we don't want to
|
||||
risk too much inlining any more and thus halve the acceptable
|
||||
size. */
|
||||
if (! LANG_DISREGARD_INLINE_LIMITS (fn)
|
||||
if (! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn)
|
||||
&& ((DECL_NUM_STMTS (fn) + (id ? id->inlined_stmts : 0)) * INSNS_PER_STMT
|
||||
> MAX_INLINE_INSNS)
|
||||
&& DECL_NUM_STMTS (fn) * INSNS_PER_STMT > MAX_INLINE_INSNS / 4)
|
||||
inlinable = 0;
|
||||
|
||||
if (inlinable && LANG_CANNOT_INLINE_TREE_FN (&fn))
|
||||
if (inlinable && (*lang_hooks.tree_inlining.cannot_inline_tree_fn) (&fn))
|
||||
inlinable = 0;
|
||||
|
||||
/* If we don't have the function body available, we can't inline
|
||||
@ -999,7 +990,8 @@ optimize_inline_calls (fn)
|
||||
prev_fn = current_function_decl;
|
||||
}
|
||||
|
||||
prev_fn = LANG_ADD_PENDING_FN_DECLS (&id.fns, prev_fn);
|
||||
prev_fn = ((*lang_hooks.tree_inlining.add_pending_fn_decls)
|
||||
(&id.fns, prev_fn));
|
||||
|
||||
/* Create the stack of TARGET_EXPRs. */
|
||||
VARRAY_TREE_INIT (id.target_exprs, 32, "target_exprs");
|
||||
@ -1124,7 +1116,7 @@ walk_tree (tp, func, data, htab_)
|
||||
if (!walk_subtrees)
|
||||
{
|
||||
if (statement_code_p (code) || code == TREE_LIST
|
||||
|| LANG_TREE_CHAIN_MATTERS_P (*tp))
|
||||
|| (*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);
|
||||
else
|
||||
@ -1188,7 +1180,8 @@ walk_tree (tp, func, data, htab_)
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
result = LANG_WALK_SUBTREES (tp, &walk_subtrees, func, data, htab);
|
||||
result = (*lang_hooks.tree_inlining.walk_subtrees) (tp, &walk_subtrees, func,
|
||||
data, htab);
|
||||
if (result || ! walk_subtrees)
|
||||
return result;
|
||||
|
||||
@ -1316,7 +1309,7 @@ copy_tree_r (tp, walk_subtrees, data)
|
||||
|| TREE_CODE_CLASS (code) == 's'
|
||||
|| code == TREE_LIST
|
||||
|| code == TREE_VEC
|
||||
|| LANG_TREE_CHAIN_MATTERS_P (*tp))
|
||||
|| (*lang_hooks.tree_inlining.tree_chain_matters_p) (*tp))
|
||||
{
|
||||
/* Because the chain gets clobbered when we make a copy, we save it
|
||||
here. */
|
||||
@ -1328,7 +1321,7 @@ copy_tree_r (tp, walk_subtrees, data)
|
||||
/* Now, restore the chain, if appropriate. That will cause
|
||||
walk_tree to walk into the chain as well. */
|
||||
if (code == PARM_DECL || code == TREE_LIST
|
||||
|| LANG_TREE_CHAIN_MATTERS_P (*tp)
|
||||
|| (*lang_hooks.tree_inlining.tree_chain_matters_p) (*tp)
|
||||
|| statement_code_p (code))
|
||||
TREE_CHAIN (*tp) = chain;
|
||||
|
||||
|
@ -32,104 +32,6 @@ tree copy_tree_r PARAMS ((tree*, int*, void*));
|
||||
void clone_body PARAMS ((tree, tree, void*));
|
||||
void remap_save_expr PARAMS ((tree*, void*, tree, int*));
|
||||
|
||||
/* LANG_WALK_SUBTREES is called by walk_tree() after handling common
|
||||
cases, but before walking code-specific sub-trees. If
|
||||
lang_walk_subtrees is defined for a language, it should handle
|
||||
language-specific tree codes, as well as language-specific
|
||||
information associated to common tree codes. If a tree node is
|
||||
completely handled within this function, it should set *SUBTREES to
|
||||
0, so that generic handling isn't attempted. For language-specific
|
||||
tree codes, generic handling would abort(), so make sure it is set
|
||||
properly. Both SUBTREES and *SUBTREES is guaranteed to be non-zero
|
||||
when the function is called. */
|
||||
|
||||
#define LANG_WALK_SUBTREES(TP,SUBTREES,FUNC,DATA,HTAB) \
|
||||
(lang_walk_subtrees \
|
||||
? (*lang_walk_subtrees)((TP),(SUBTREES),(FUNC),(DATA),(HTAB)) \
|
||||
: 0)
|
||||
typedef tree treeopt_walk_subtrees_type PARAMS ((tree*, int*, walk_tree_fn,
|
||||
void*, void*));
|
||||
extern treeopt_walk_subtrees_type *lang_walk_subtrees;
|
||||
|
||||
/* LANG_CANNOT_INLINE_TREE_FN is called to determine whether there are
|
||||
language-specific reasons for not inlining a given function. */
|
||||
|
||||
#define LANG_CANNOT_INLINE_TREE_FN(FNP) \
|
||||
(lang_cannot_inline_tree_fn ? (*lang_cannot_inline_tree_fn)(FNP) : 0)
|
||||
typedef int treeopt_cannot_inline_tree_fn_type PARAMS ((tree*));
|
||||
extern treeopt_cannot_inline_tree_fn_type *lang_cannot_inline_tree_fn;
|
||||
|
||||
/* LANG_DISREGARD_INLINE_LIMITS is called to determine whether a
|
||||
function should be inlined even if it would exceed inlining limits. */
|
||||
|
||||
#define LANG_DISREGARD_INLINE_LIMITS(FN) \
|
||||
(lang_disregard_inline_limits ? (*lang_disregard_inline_limits)(FN) : 0)
|
||||
typedef int treeopt_disregard_inline_limits_type PARAMS ((tree));
|
||||
extern treeopt_disregard_inline_limits_type *lang_disregard_inline_limits;
|
||||
|
||||
/* LANG_ADD_PENDING_FN_DECLS is called before starting to inline a
|
||||
function, to push any language-specific functions that should not
|
||||
be inlined into the current function, into VAFNP. PFN is the top
|
||||
of varray, and should be returned if no functions are pushed into
|
||||
VAFNP. The top of the varray should be returned. */
|
||||
|
||||
#define LANG_ADD_PENDING_FN_DECLS(VAFNP,PFN) \
|
||||
(lang_add_pending_fn_decls \
|
||||
? (*lang_add_pending_fn_decls)((VAFNP),(PFN)) \
|
||||
: (PFN))
|
||||
typedef tree treeopt_add_pending_fn_decls_type PARAMS ((void*,tree));
|
||||
extern treeopt_add_pending_fn_decls_type *lang_add_pending_fn_decls;
|
||||
|
||||
/* LANG_TREE_CHAIN_MATTERS_P indicates whether the TREE_CHAIN of a
|
||||
language-specific tree node is relevant, i.e., whether it should be
|
||||
walked, copied and preserved across copies. */
|
||||
|
||||
#define LANG_TREE_CHAIN_MATTERS_P(T) \
|
||||
(lang_tree_chain_matters_p ? (*lang_tree_chain_matters_p)(T) : 0)
|
||||
typedef int treeopt_tree_chain_matters_p_type PARAMS ((tree));
|
||||
extern treeopt_tree_chain_matters_p_type *lang_tree_chain_matters_p;
|
||||
|
||||
/* LANG_AUTO_VAR_IN_FN_P is called to determine whether VT is an
|
||||
automatic variable defined in function FT. */
|
||||
|
||||
#define LANG_AUTO_VAR_IN_FN_P(VT,FT) \
|
||||
(lang_auto_var_in_fn_p ? (*lang_auto_var_in_fn_p)((VT),(FT)) \
|
||||
: (DECL_P (VT) && DECL_CONTEXT (VT) == (FT) \
|
||||
&& (((TREE_CODE (VT) == VAR_DECL || TREE_CODE (VT) == PARM_DECL) \
|
||||
&& ! TREE_STATIC (VT)) \
|
||||
|| TREE_CODE (VT) == LABEL_DECL \
|
||||
|| TREE_CODE (VT) == RESULT_DECL)))
|
||||
typedef int treeopt_auto_var_in_fn_p_type PARAMS ((tree,tree));
|
||||
extern treeopt_auto_var_in_fn_p_type *lang_auto_var_in_fn_p;
|
||||
|
||||
/* LANG_COPY_RES_DECL_FOR_INLINING should return a declaration for the
|
||||
result RES of function FN to be inlined into CALLER. NDP points to
|
||||
an integer that should be set in case a new declaration wasn't
|
||||
created (presumably because RES was of aggregate type, such that a
|
||||
TARGET_EXPR is used for the result). TEXPS is a pointer to a
|
||||
varray with the stack of TARGET_EXPRs seen while inlining functions
|
||||
into caller; the top of TEXPS is supposed to match RES. */
|
||||
|
||||
#define LANG_COPY_RES_DECL_FOR_INLINING(RES,FN,CALLER,DM,NDP,TEXPS) \
|
||||
(lang_copy_res_decl_for_inlining \
|
||||
? (*lang_copy_res_decl_for_inlining)((RES),(FN),(CALLER),\
|
||||
(DM),(NDP),(TEXPS)) \
|
||||
: copy_decl_for_inlining ((RES), (FN), (CALLER)))
|
||||
typedef tree treeopt_copy_res_decl_for_inlining_type PARAMS ((tree, tree,
|
||||
tree, void*,
|
||||
int*, void*));
|
||||
extern treeopt_copy_res_decl_for_inlining_type
|
||||
*lang_copy_res_decl_for_inlining;
|
||||
|
||||
/* LANG_ANON_AGGR_TYPE_P determines whether T is a type node
|
||||
representing an anonymous aggregate (union, struct, etc), i.e., one
|
||||
whose members are in the same scope as the union itself. */
|
||||
|
||||
#define LANG_ANON_AGGR_TYPE_P(T) \
|
||||
(lang_anon_aggr_type_p ? (*lang_anon_aggr_type_p)(T) : 0)
|
||||
typedef int treeopt_anon_aggr_type_p PARAMS ((tree));
|
||||
extern treeopt_anon_aggr_type_p *lang_anon_aggr_type_p;
|
||||
|
||||
/* 0 if we should not perform inlining.
|
||||
1 if we should expand functions calls inline at the tree level.
|
||||
2 if we should consider *all* functions to be inline
|
||||
|
Loading…
Reference in New Issue
Block a user