Commit 46e8c075 by Mark Mitchell Committed by Mark Mitchell

Make-lang.in (CXX_SRCS): Add optimize.c.

1999-11-25  Mark Mitchell  <mark@codesourcery.com>

	* Make-lang.in (CXX_SRCS): Add optimize.c.
	* Makefile.in (CXX_OBJS): Add optimize.o.
	(CXX_TREE_H): Add splay-tree.h, system.h, and $(CONFIG_H).
	(spew.o, lex.o, decl.o, decl2.o, typeck2.o, typeck.o): Adjust.
	(class.o, call.o, friend.o, init.o, method.o, cvt.o): Likewise.
	(search.o, tree.o, ptree.o, rtti.o, except.o, expr.o): Likewise.
	(xref.o, pt.o, error.o, errfn.o, repo.o, semantics.o): Likewise.
	(dump.o): Likewise.
	(optimize.o): New target.
	* class.c: Don't include splay-tree.h.
	* cp-tree.def (CTOR_COMPLETE): Rename to CTOR_STMT.
	* cp-tree.h: Include splay-tree.h.
	(DECL_UNINLINABLE): New macro.
	(CTOR_BEGIN_P, CTOR_END_P): New macros.
	(flag_inline_trees): New variable.
	(local_variable_p): New function.
	(nonstatic_local_decl_p): Likewise.
	(optimize_function): Likewise.
	(cplus_unsave_expr_now): Remove.
	(copy_tree_r): Declare.
	(remap_save_expr): Likewise.
	* decl.c (local_variable_p): Don't
	make it static.
	(local_variable_p_walkfn): New function.
	(make_rtl_for_local_static): Remove code to try to avoid writing
	out static constants.
	(emit_local_var): Fix indentation.
	(nonstatic_local_decl_p): New function.
	(check_default_argument): Use local_variable_p_walkfn, not
	local_variable_p, when walking the tree.
	(start_function): Set the DECL_CONTEXT for automatically generated
	labels.
	(finish_constructor_body): Use CTOR_STMT to mark the end of a
	constructor.
	* decl2.c: Don't include splay-tree.h.
	(flag_inline_trees): Define.
	* dump.c: Don't include
	splay-tree.h.
	* except.c (expand_end_catch_block): Fix comment formatting.
	(expand_end_eh_spec): Set DECL_CONTEXT on temporary variables.
	(expand_throw): Tidy comment.
	* init.c (build_vec_delete_1): Use create_temporary_var.
	* lex.c (cplus_tree_code_type): Make it static.
	(cplus_tree_code_length): Likewise.
	(cplus_tree_code_name): Likewise.
	* optimize.c: New file.
	* semantics.c (finish_goto_stmt): Set DECL_UNLINABLE for functions
	with computed gotos.
	(setup_vtbl_ptr): Mark the beginnings of constructors with
	CTOR_STMT.
	(expand_stmt): Handle CTOR_STMT, not CTOR_COMPLETE.
	(expand_body): Call optimize_function.  Save bodies if we're doing
	inlining on trees.
	* tree.c: Don't include splay-tree.h.  Include insn-config.h and
	integrate.h.
	(copy_tree_r): Make it public.
	(statement_code_p): New function.
	(mark_local_for_remap_r): Likewise.
	(cp_usave_r): Likewise.
	(cp_unsave): Likewise.
	(build_cplus_new): Set DECL_CONTEXT for temporary variables.
	(walk_tree): Walk into `s' class nodes.  Walk statement chains.
	(copy_tree_r): Handle 's' class nodes.  Restore chains for
	statements.  Nullify scopes.  Don't copy types.
	(init_tree): Set lang_unsave to cp_unsave.
	(remap_save_expr): Define.
	* ir.texi: Document CTOR_STMT.

From-SVN: r30669
parent 82d26ad0
1999-11-25 Mark Mitchell <mark@codesourcery.com>
* Make-lang.in (CXX_SRCS): Add optimize.c.
* Makefile.in (CXX_OBJS): Add optimize.o.
(CXX_TREE_H): Add splay-tree.h, system.h, and $(CONFIG_H).
(spew.o, lex.o, decl.o, decl2.o, typeck2.o, typeck.o): Adjust.
(class.o, call.o, friend.o, init.o, method.o, cvt.o): Likewise.
(search.o, tree.o, ptree.o, rtti.o, except.o, expr.o): Likewise.
(xref.o, pt.o, error.o, errfn.o, repo.o, semantics.o): Likewise.
(dump.o): Likewise.
(optimize.o): New target.
* class.c: Don't include splay-tree.h.
* cp-tree.def (CTOR_COMPLETE): Rename to CTOR_STMT.
* cp-tree.h: Include splay-tree.h.
(DECL_UNINLINABLE): New macro.
(CTOR_BEGIN_P, CTOR_END_P): New macros.
(flag_inline_trees): New variable.
(local_variable_p): New function.
(nonstatic_local_decl_p): Likewise.
(optimize_function): Likewise.
(cplus_unsave_expr_now): Remove.
(copy_tree_r): Declare.
(remap_save_expr): Likewise.
* decl.c (local_variable_p): Don't
make it static.
(local_variable_p_walkfn): New function.
(make_rtl_for_local_static): Remove code to try to avoid writing
out static constants.
(emit_local_var): Fix indentation.
(nonstatic_local_decl_p): New function.
(check_default_argument): Use local_variable_p_walkfn, not
local_variable_p, when walking the tree.
(start_function): Set the DECL_CONTEXT for automatically generated
labels.
(finish_constructor_body): Use CTOR_STMT to mark the end of a
constructor.
* decl2.c: Don't include splay-tree.h.
(flag_inline_trees): Define.
* dump.c: Don't include
splay-tree.h.
* except.c (expand_end_catch_block): Fix comment formatting.
(expand_end_eh_spec): Set DECL_CONTEXT on temporary variables.
(expand_throw): Tidy comment.
* init.c (build_vec_delete_1): Use create_temporary_var.
* lex.c (cplus_tree_code_type): Make it static.
(cplus_tree_code_length): Likewise.
(cplus_tree_code_name): Likewise.
* optimize.c: New file.
* semantics.c (finish_goto_stmt): Set DECL_UNLINABLE for functions
with computed gotos.
(setup_vtbl_ptr): Mark the beginnings of constructors with
CTOR_STMT.
(expand_stmt): Handle CTOR_STMT, not CTOR_COMPLETE.
(expand_body): Call optimize_function. Save bodies if we're doing
inlining on trees.
* tree.c: Don't include splay-tree.h. Include insn-config.h and
integrate.h.
(copy_tree_r): Make it public.
(statement_code_p): New function.
(mark_local_for_remap_r): Likewise.
(cp_usave_r): Likewise.
(cp_unsave): Likewise.
(build_cplus_new): Set DECL_CONTEXT for temporary variables.
(walk_tree): Walk into `s' class nodes. Walk statement chains.
(copy_tree_r): Handle 's' class nodes. Restore chains for
statements. Nullify scopes. Don't copy types.
(init_tree): Set lang_unsave to cp_unsave.
(remap_save_expr): Define.
* ir.texi: Document CTOR_STMT.
1999-11-24 Jason Merrill <jason@casey.cygnus.com>
* search.c (note_debug_info_needed): Do perform this optimization
......
......@@ -118,7 +118,7 @@ CXX_SRCS = $(srcdir)/cp/call.c $(srcdir)/cp/decl2.c \
$(srcdir)/cp/error.c $(srcdir)/cp/friend.c $(srcdir)/cp/init.c \
$(srcdir)/cp/parse.y $(srcdir)/cp/typeck2.c \
$(srcdir)/cp/repo.c $(srcdir)/cp/semantics.c \
$(srcdir)/cp/dump.c
$(srcdir)/cp/dump.c $(srcdir)/cp/optimize.c
cc1plus$(exeext): $(P) $(CXX_SRCS) $(LIBDEPS) stamp-objlist c-common.o \
c-pragma.o $(srcdir)/cp/cp-tree.h $(srcdir)/cp/cp-tree.def \
......
......@@ -175,7 +175,7 @@ INCLUDES = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config -I$(srcdir)
CXX_OBJS = call.o decl.o errfn.o expr.o pt.o typeck2.o \
class.o decl2.o error.o lex.o parse.o ptree.o rtti.o spew.o typeck.o cvt.o \
except.o friend.o init.o method.o search.o semantics.o tree.o xref.o \
repo.o dump.o @extra_cxx_objs@
repo.o dump.o optimize.o @extra_cxx_objs@
# Language-independent object files.
OBJS = `cat ../stamp-objlist` ../c-common.o ../c-pragma.o
......@@ -202,12 +202,14 @@ RTL_H = $(srcdir)/../rtl.h $(srcdir)/../rtl.def \
TREE_H = $(srcdir)/../tree.h $(srcdir)/../real.h $(srcdir)/../tree.def \
$(srcdir)/../machmode.h $(srcdir)/../machmode.def
CXX_TREE_H = $(TREE_H) cp-tree.h $(srcdir)/../c-common.h cp-tree.def \
$(srcdir)/../function.h $(srcdir)/../varray.h
$(srcdir)/../function.h $(srcdir)/../varray.h \
$(srcdir)/../../include/splay-tree.h \
$(srcdir)/../system.h $(CONFIG_H)
PARSE_H = $(srcdir)/parse.h
PARSE_C = $(srcdir)/parse.c
EXPR_H = $(srcdir)/../expr.h ../insn-codes.h
parse.o : $(PARSE_C) $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h lex.h \
parse.o : $(PARSE_C) $(CXX_TREE_H) $(srcdir)/../flags.h lex.h \
$(srcdir)/../except.h $(srcdir)/../output.h $(srcdir)/../system.h \
$(srcdir)/../toplev.h $(srcdir)/../ggc.h
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(BIG_SWITCHFLAG) \
......@@ -239,64 +241,66 @@ $(srcdir)/hash.h: $(srcdir)/gxx.gperf
echo " ftp://sourceware.cygnus.com/pub/egcs/infrastructure/gperf*" >&2 ; \
exit 1 )
spew.o : spew.c $(CONFIG_H) $(CXX_TREE_H) $(PARSE_H) $(srcdir)/../flags.h \
lex.h $(srcdir)/../system.h $(srcdir)/../toplev.h
lex.o : lex.c $(CONFIG_H) $(CXX_TREE_H) \
spew.o : spew.c $(CXX_TREE_H) $(PARSE_H) $(srcdir)/../flags.h \
lex.h $(srcdir)/../toplev.h
lex.o : lex.c $(CXX_TREE_H) \
$(PARSE_H) input.c $(srcdir)/../flags.h hash.h lex.h \
$(srcdir)/../c-pragma.h $(srcdir)/../system.h $(srcdir)/../toplev.h \
$(srcdir)/../c-pragma.h $(srcdir)/../toplev.h \
$(srcdir)/../output.h $(srcdir)/../mbchar.h $(srcdir)/../ggc.h
decl.o : decl.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
decl.o : decl.c $(CXX_TREE_H) $(srcdir)/../flags.h \
lex.h decl.h $(srcdir)/../stack.h $(srcdir)/../output.h \
$(srcdir)/../except.h $(srcdir)/../system.h $(srcdir)/../toplev.h \
$(srcdir)/../except.h $(srcdir)/../toplev.h \
$(srcdir)/../hash.h $(srcdir)/../ggc.h $(RTL_H)
decl2.o : decl2.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
lex.h decl.h $(EXPR_H) $(srcdir)/../except.h \
$(srcdir)/../output.h $(srcdir)/../except.h $(srcdir)/../system.h \
decl2.o : decl2.c $(CXX_TREE_H) $(srcdir)/../flags.h \
lex.h decl.h $(EXPR_H) $(srcdir)/../output.h $(srcdir)/../except.h \
$(srcdir)/../toplev.h $(srcdir)/../dwarf2out.h $(srcdir)/../dwarfout.h \
$(srcdir)/../../include/splay-tree.h $(srcdir)/../ggc.h $(RTL_H)
typeck2.o : typeck2.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
$(srcdir)/../system.h $(srcdir)/../toplev.h $(srcdir)/../output.h
typeck.o : typeck.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \
$(EXPR_H) $(srcdir)/../system.h $(srcdir)/../toplev.h
class.o : class.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
$(srcdir)/../system.h $(srcdir)/../toplev.h \
$(srcdir)/../../include/splay-tree.h $(RTL_H)
call.o : call.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
$(srcdir)/../system.h $(srcdir)/../toplev.h $(RTL_H)
friend.o : friend.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \
$(srcdir)/../system.h $(srcdir)/../toplev.h
init.o : init.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \
$(EXPR_H) $(srcdir)/../system.h $(srcdir)/../toplev.h $(srcdir)/../ggc.h
method.o : method.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h \
$(srcdir)/../ggc.h $(RTL_H)
typeck2.o : typeck2.c $(CXX_TREE_H) $(srcdir)/../flags.h \
$(srcdir)/../toplev.h $(srcdir)/../output.h
typeck.o : typeck.c $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \
$(EXPR_H) $(srcdir)/../toplev.h
class.o : class.c $(CXX_TREE_H) $(srcdir)/../flags.h \
$(srcdir)/../toplev.h $(RTL_H)
call.o : call.c $(CXX_TREE_H) $(srcdir)/../flags.h \
$(srcdir)/../toplev.h $(RTL_H)
friend.o : friend.c $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \
$(srcdir)/../toplev.h
init.o : init.c $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \
$(EXPR_H) $(srcdir)/../toplev.h $(srcdir)/../ggc.h \
$(srcdir)/../except.h
method.o : method.c $(CXX_TREE_H) \
$(srcdir)/../toplev.h $(srcdir)/../ggc.h $(RTL_H)
cvt.o : cvt.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h decl.h \
cvt.o : cvt.c $(CXX_TREE_H) decl.h \
$(srcdir)/../flags.h $(srcdir)/../toplev.h $(srcdir)/../convert.h
search.o : search.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../stack.h \
$(srcdir)/../flags.h $(srcdir)/../system.h $(srcdir)/../toplev.h $(RTL_H)
tree.o : tree.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
$(srcdir)/../system.h $(srcdir)/../toplev.h $(srcdir)/../ggc.h $(RTL_H) \
$(srcdir)/../../include/splay-tree.h
ptree.o : ptree.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h
rtti.o : rtti.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
$(srcdir)/../system.h $(srcdir)/../toplev.h
except.o : except.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \
$(srcdir)/../except.h $(srcdir)/../system.h $(srcdir)/../toplev.h
expr.o : expr.c $(CONFIG_H) $(CXX_TREE_H) $(RTL_H) $(srcdir)/../flags.h \
$(EXPR_H) $(srcdir)/../system.h $(srcdir)/../toplev.h $(srcdir)/../except.h
xref.o : xref.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../input.h \
$(srcdir)/../system.h $(srcdir)/../toplev.h
pt.o : pt.c $(CONFIG_H) $(CXX_TREE_H) decl.h $(PARSE_H) lex.h \
$(srcdir)/../system.h $(srcdir)/../toplev.h $(srcdir)/../ggc.h $(RTL_H)
error.o : error.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h \
search.o : search.c $(CXX_TREE_H) $(srcdir)/../stack.h \
$(srcdir)/../flags.h $(srcdir)/../toplev.h $(RTL_H)
tree.o : tree.c $(CXX_TREE_H) $(srcdir)/../flags.h \
$(srcdir)/../toplev.h $(srcdir)/../ggc.h $(RTL_H) \
../insn-config.h $(srcdir)/../integrate.h
ptree.o : ptree.c $(CXX_TREE_H) $(srcdir)/../system.h
rtti.o : rtti.c $(CXX_TREE_H) $(srcdir)/../flags.h \
$(srcdir)/../toplev.h
except.o : except.c $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \
$(srcdir)/../except.h $(srcdir)/../toplev.h
expr.o : expr.c $(CXX_TREE_H) $(RTL_H) $(srcdir)/../flags.h \
$(EXPR_H) $(srcdir)/../toplev.h $(srcdir)/../except.h
xref.o : xref.c $(CXX_TREE_H) $(srcdir)/../input.h \
$(srcdir)/../toplev.h
pt.o : pt.c $(CXX_TREE_H) decl.h $(PARSE_H) lex.h \
$(srcdir)/../toplev.h $(srcdir)/../ggc.h $(RTL_H) \
$(srcdir)/../except.h
error.o : error.c $(CXX_TREE_H) \
$(srcdir)/../toplev.h
errfn.o : errfn.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h \
errfn.o : errfn.c $(CXX_TREE_H) \
$(srcdir)/../toplev.h
repo.o : repo.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h \
repo.o : repo.c $(CXX_TREE_H) \
$(srcdir)/../toplev.h $(srcdir)/../ggc.h
semantics.o: semantics.c $(CONFIG_H) $(CXX_TREE_H) lex.h \
$(srcdir)/../except.h $(srcdir)/../system.h $(srcdir)/../toplev.h \
semantics.o: semantics.c $(CXX_TREE_H) lex.h \
$(srcdir)/../except.h $(srcdir)/../toplev.h \
$(srcdir)/../flags.h $(srcdir)/../ggc.h
dump.o: dump.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h
dump.o: dump.c $(CXX_TREE_H)
optimize.o: optimize.c $(CXX_TREE_H) \
$(srcdir)/../rtl.h $(srcdir)/../integrate.h ../insn-config.h
#
# These exist for maintenance purposes.
......
......@@ -30,7 +30,6 @@ Boston, MA 02111-1307, USA. */
#include "rtl.h"
#include "output.h"
#include "toplev.h"
#include "splay-tree.h"
#include "ggc.h"
#include "lex.h"
......
......@@ -237,9 +237,11 @@ DEFTREECODE (ASM_STMT, "asm_stmt", 'e', 5)
run if an exception is thrown before the end of the enclosing
function. */
DEFTREECODE (SUBOBJECT, "subobject", 'e', 1)
/* A CTOR_COMPLETE statements marks the end of the main body of the
constructor, not including any function try blocks. */
DEFTREECODE (CTOR_COMPLETE, "ctor_complete", 'e', 0)
/* An CTOR_STMT marks the beginning (if CTOR_BEGIN_P holds) or end of
a contstructor (if CTOR_END_P) holds. At the end of a constructor,
the cleanups associated with any SUBOBJECT_CLEANUPS need no longer
be run. */
DEFTREECODE (CTOR_STMT, "ctor_stmt", 'e', 0)
/* A CLEANUP_STMT marks the point at which a declaration is fully
constructed. If, after this point, the CLEANUP_DECL goes out of
scope, the CLEANUP_EXPR must be run. */
......
......@@ -21,6 +21,7 @@ Boston, MA 02111-1307, USA. */
#include "c-common.h"
#include "function.h"
#include "splay-tree.h"
#include "varray.h"
#ifndef _CP_TREE_H
......@@ -40,6 +41,7 @@ Boston, MA 02111-1307, USA. */
CLEANUP_P (in TRY_BLOCK)
AGGR_INIT_VIA_CTOR_P (in AGGR_INIT_EXPR)
SCOPE_BEGIN_P (in SCOPE_STMT)
CTOR_BEGIN_P (in CTOR_STMT)
1: IDENTIFIER_VIRTUAL_P.
TI_PENDING_TEMPLATE_FLAG.
TEMPLATE_PARMS_FOR_INLINE.
......@@ -2121,6 +2123,10 @@ extern int flag_new_for_scope;
#define SET_DECL_C_BIT_FIELD(NODE) \
(DECL_LANG_SPECIFIC (FIELD_DECL_CHECK (NODE))->decl_flags.bitfield = 1)
/* In a FUNCTION_DECL, nonzero if the function cannot be inlined. */
#define DECL_UNINLINABLE(NODE) \
(DECL_LANG_SPECIFIC (NODE)->decl_flags.bitfield)
#define INTEGRAL_CODE_P(CODE) \
(CODE == INTEGER_TYPE || CODE == ENUMERAL_TYPE || CODE == BOOLEAN_TYPE)
......@@ -2691,6 +2697,14 @@ extern int flag_new_for_scope;
#define SCOPE_END_P(NODE) \
(!SCOPE_BEGIN_P (SCOPE_STMT_CHECK (NODE)))
/* Nonzero if this CTOR_STMT is for the beginning of a constructor. */
#define CTOR_BEGIN_P(NODE) \
(TREE_LANG_FLAG_0 (CTOR_STMT_CHECK (NODE)))
/* Nonzero if this CTOR_STMT is for the end of a constructor. */
#define CTOR_END_P(NODE) \
(!CTOR_BEGIN_P (NODE))
/* Nonzero for a SCOPE_STMT if there were no variables in this scope. */
#define SCOPE_NULLIFIED_P(NODE) \
(TREE_LANG_FLAG_3 (SCOPE_STMT_CHECK (NODE)))
......@@ -3107,6 +3121,11 @@ extern int flag_new_abi;
extern int flag_honor_std;
/* Nonzero if we should expand functions calls inline at the tree
level, rather than at the RTL level. */
extern int flag_inline_trees;
/* Nonzero if we're done parsing and into end-of-file activities. */
extern int at_eof;
......@@ -3532,6 +3551,8 @@ extern tree maybe_push_decl PROTO((tree));
extern void emit_local_var PROTO((tree));
extern tree build_target_expr_with_type PROTO((tree, tree));
extern void make_rtl_for_local_static PROTO((tree));
extern int local_variable_p PROTO((tree));
extern int nonstatic_local_decl_p PROTO((tree));
/* in decl2.c */
extern void init_decl2 PROTO((void));
......@@ -3744,6 +3765,9 @@ extern void emit_thunk PROTO((tree));
extern void synthesize_method PROTO((tree));
extern tree get_id_2 PROTO((const char *, tree));
/* In optimize.c */
extern void optimize_function PROTO((tree));
/* in pt.c */
extern void init_pt PROTO ((void));
extern void check_template_shadow PROTO ((tree));
......@@ -3960,7 +3984,6 @@ extern tree arbitrate_lookup PROTO((tree, tree, tree));
/* in tree.c */
extern void init_tree PROTO((void));
extern void cplus_unsave_expr_now PROTO((tree));
extern int pod_type_p PROTO((tree));
extern void unshare_base_binfos PROTO((tree));
extern int member_p PROTO((tree));
......@@ -4028,9 +4051,11 @@ extern tree maybe_dummy_object PROTO((tree, tree *));
extern int is_dummy_object PROTO((tree));
typedef tree (*walk_tree_fn) PROTO((tree *, int *, void *));
extern tree walk_tree PROTO((tree *, walk_tree_fn, void *));
extern tree copy_tree_r PROTO((tree *, int *, void *));
extern int cp_valid_lang_attribute PROTO((tree, tree, tree, tree));
extern tree make_ptrmem_cst PROTO((tree, tree));
extern tree cp_build_qualified_type_real PROTO((tree, int, int));
extern void remap_save_expr PROTO((tree *, splay_tree, tree));
#define cp_build_qualified_type(TYPE, QUALS) \
cp_build_qualified_type_real ((TYPE), (QUALS), /*complain=*/1)
......
......@@ -141,7 +141,7 @@ static boolean typename_compare PROTO((hash_table_key, hash_table_key));
static void push_binding PROTO((tree, tree, struct binding_level*));
static int add_binding PROTO((tree, tree));
static void pop_binding PROTO((tree, tree));
static tree local_variable_p PROTO((tree *, int *, void *));
static tree local_variable_p_walkfn PROTO((tree *, int *, void *));
static tree find_binding PROTO((tree, tree));
static tree select_decl PROTO((tree, int));
static int lookup_flags PROTO((int, int));
......@@ -7362,26 +7362,10 @@ make_rtl_for_local_static (decl)
tree type = TREE_TYPE (decl);
const char *asmspec = NULL;
if (TREE_READONLY (decl)
&& DECL_INITIAL (decl) != NULL_TREE
&& DECL_INITIAL (decl) != error_mark_node
&& ! EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl))
&& ! TREE_SIDE_EFFECTS (decl)
&& ! TREE_PUBLIC (decl)
&& ! DECL_EXTERNAL (decl)
&& ! TYPE_NEEDS_DESTRUCTOR (type)
&& ! TREE_ADDRESSABLE (decl)
&& DECL_MODE (decl) != BLKmode)
{
/* As an optimization, we try to put register-sized static
constants in a register, rather than writing them out. If we
take the address of the constant later, we'll make RTL for it
at that point. */
DECL_RTL (decl) = gen_reg_rtx (DECL_MODE (decl));
store_expr (DECL_INITIAL (decl), DECL_RTL (decl), 0);
TREE_ASM_WRITTEN (decl) = 1;
return;
}
/* If we inlined this variable, we could see it's declaration
again. */
if (DECL_RTL (decl))
return;
if (DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl))
{
......@@ -7543,9 +7527,8 @@ emit_local_var (decl)
{
/* Create RTL for this variable. */
if (DECL_RTL (decl))
/* Only a RESULT_DECL should have non-NULL RTL when
arriving here. All other local variables are
assigned RTL in this function. */
/* Only a RESULT_DECL should have non-NULL RTL when arriving here.
All other local variables are assigned RTL in this function. */
my_friendly_assert (TREE_CODE (decl) == RESULT_DECL,
19990828);
else
......@@ -11141,27 +11124,48 @@ require_complete_types_for_parms (parms)
}
}
/* Returns *TP if *TP is a local variable (or parameter). Returns
NULL_TREE otherwise. */
/* Returns non-zero if T is a local variable. */
static tree
local_variable_p (tp, walk_subtrees, data)
tree *tp;
int *walk_subtrees ATTRIBUTE_UNUSED;
void *data ATTRIBUTE_UNUSED;
int
local_variable_p (t)
tree t;
{
tree t = *tp;
if ((TREE_CODE (t) == VAR_DECL
/* A VAR_DECL with a context that is a _TYPE is a static data
member. */
&& !TYPE_P (CP_DECL_CONTEXT (t))
/* Any other non-local variable must be at namespace scope. */
&& TREE_CODE (CP_DECL_CONTEXT (t)) != NAMESPACE_DECL)
&& !DECL_NAMESPACE_SCOPE_P (t))
|| (TREE_CODE (t) == PARM_DECL))
return t;
return 1;
return NULL_TREE;
return 0;
}
/* Returns non-zero if T is an automatic local variable or a label.
(These are the declarations that need to be remapped when the code
containing them is duplicated.) */
int
nonstatic_local_decl_p (t)
tree t;
{
return ((local_variable_p (t) && !TREE_STATIC (t))
|| TREE_CODE (t) == LABEL_DECL
|| TREE_CODE (t) == RESULT_DECL);
}
/* Like local_variable_p, but suitable for use as a tree-walking
function. */
static tree
local_variable_p_walkfn (tp, walk_subtrees, data)
tree *tp;
int *walk_subtrees ATTRIBUTE_UNUSED;
void *data ATTRIBUTE_UNUSED;
{
return ((local_variable_p (*tp) && !DECL_ARTIFICIAL (*tp))
? *tp : NULL_TREE);
}
/* Check that ARG, which is a default-argument expression for a
......@@ -11230,7 +11234,7 @@ check_default_argument (decl, arg)
The keyword `this' shall not be used in a default argument of a
member function. */
var = walk_tree (&arg, local_variable_p, NULL);
var = walk_tree (&arg, local_variable_p_walkfn, NULL);
if (var)
{
cp_error ("default argument `%E' uses local variable `%D'",
......@@ -13067,9 +13071,15 @@ start_function (declspecs, declarator, attrs, flags)
if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl1))
&& DECL_LANGUAGE (decl1) == lang_cplusplus)
dtor_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
{
dtor_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
DECL_CONTEXT (dtor_label) = current_function_decl;
}
else if (DECL_CONSTRUCTOR_P (decl1))
ctor_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
{
ctor_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
DECL_CONTEXT (ctor_label) = current_function_decl;
}
return 1;
}
......@@ -13295,10 +13305,8 @@ finish_constructor_body ()
/* In check_return_expr we translate an empty return from a
constructor to a return of `this'. */
finish_return_stmt (NULL_TREE);
/* Mark the end of the main constructor body. */
if (DECL_CONSTRUCTOR_P (current_function_decl))
add_tree (build_min_nt (CTOR_COMPLETE));
/* Mark the end of the constructor. */
add_tree (build_min_nt (CTOR_STMT));
}
/* At the end of every destructor we generate code to restore virtual
......
......@@ -42,7 +42,6 @@ Boston, MA 02111-1307, USA. */
#include "toplev.h"
#include "dwarf2out.h"
#include "dwarfout.h"
#include "splay-tree.h"
#include "ggc.h"
#if USE_CPPLIB
......@@ -444,6 +443,11 @@ int flag_new_abi;
int flag_honor_std;
/* Nonzero if we should expand functions calls inline at the tree
level, rather than at the RTL level. */
int flag_inline_trees = 0;
/* Maximum template instantiation depth. Must be at least 17 for ANSI
compliance. */
......
......@@ -23,7 +23,6 @@ Boston, MA 02111-1307, USA. */
#include "system.h"
#include "tree.h"
#include "cp-tree.h"
#include "splay-tree.h"
/* Flags used with queue functions. */
#define DUMP_NONE 0
......
......@@ -564,7 +564,7 @@ expand_end_catch_block (blocks)
/* Cleanup the EH parameter. */
finish_compound_stmt (/*has_no_scope=*/0, compound_stmt_2);
/* Cleanup the EH object. */
/* Cleanup the EH object. */
finish_compound_stmt (/*has_no_scope=*/0, compound_stmt_1);
}
......@@ -615,6 +615,7 @@ expand_end_eh_spec (raises, try_block)
decl = build_decl (VAR_DECL, NULL_TREE, tmp);
DECL_ARTIFICIAL (decl) = 1;
DECL_INITIAL (decl) = types;
DECL_CONTEXT (decl) = current_function_decl;
cp_finish_decl (decl, types, NULL_TREE, 0);
decl = decay_conversion (decl);
......@@ -804,12 +805,10 @@ expand_throw (exp)
tree object, ptr;
/* OK, this is kind of wacky. The WP says that we call
terminate
when the exception handling mechanism, after completing
evaluation of the expression to be thrown but before the
exception is caught (_except.throw_), calls a user function
that exits via an uncaught exception.
terminate when the exception handling mechanism, after
completing evaluation of the expression to be thrown but
before the exception is caught (_except.throw_), calls a
user function that exits via an uncaught exception.
So we have to protect the actual initialization of the
exception object with terminate(), but evaluate the expression
......
......@@ -2470,7 +2470,7 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, use_global_delete)
/* The below is short by BI_header_size */
virtual_size = fold (size_binop (MULT_EXPR, size_exp, maxindex));
tbase = build_decl (VAR_DECL, NULL_TREE, ptype);
tbase = create_temporary_var (ptype);
tbase_init = build_modify_expr (tbase, NOP_EXPR,
fold (build (PLUS_EXPR, ptype,
base,
......
......@@ -1274,9 +1274,11 @@ following the @code{TREE_CHAIN} link from one substatement to the next.
Used to represent a @code{continue} statement. There are no additional
fields.
@item CTOR_COMPLETE
@item CTOR_STMT
Used to mark the end of the main body of a constructor.
Used to mark the beginning (if @code{CTOR_BEGIN_P} holds) or end (if
@code{CTOR_END_P} holds of the main body of a constructor. See also
@code{SUBOBJECT} for more information on how to use these nodes.
@item DECL_STMT
......@@ -1387,9 +1389,9 @@ equalit) to @code{CATCH_ALL_TYPE} if this handler is for all types.
In a constructor, these nodes are used to mark the point at which a
subobject of @code{this} is fully constructed. If, after this point, an
exception is thrown before a CTOR_COMPLETE statement is encountered, the
@code{SUBOBJECT_CLEANUP} must be executed. The cleanups must be
executed in the reverse order in which they appear.
exception is thrown before a @code{CTOR_STMT} with @code{CTOR_END_P} set
is encountered, the @code{SUBOBJECT_CLEANUP} must be executed. The
cleanups must be executed in the reverse order in which they appear.
@item SWITCH_STMT
......
......@@ -405,7 +405,7 @@ my_get_run_time ()
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
char cplus_tree_code_type[] = {
static char cplus_tree_code_type[] = {
'x',
#include "cp-tree.def"
};
......@@ -417,7 +417,7 @@ char cplus_tree_code_type[] = {
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
int cplus_tree_code_length[] = {
static int cplus_tree_code_length[] = {
0,
#include "cp-tree.def"
};
......@@ -427,7 +427,7 @@ int cplus_tree_code_length[] = {
Used for printing out the tree and error messages. */
#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
const char *cplus_tree_code_name[] = {
static const char *cplus_tree_code_name[] = {
"@@dummy",
#include "cp-tree.def"
};
......
......@@ -658,7 +658,16 @@ finish_goto_stmt (destination)
TREE_USED (destination) = 1;
if (building_stmt_tree ())
add_tree (build_min_nt (GOTO_STMT, destination));
{
if (TREE_CODE (destination) != LABEL_DECL)
/* We don't inline calls to functions with computed gotos.
Those functions are typically up to some funny business,
and may be depending on the labels being at particular
addresses, or some such. */
DECL_UNINLINABLE (current_function_decl) = 1;
add_tree (build_min_nt (GOTO_STMT, destination));
}
else
{
emit_line_note (input_filename, lineno);
......@@ -1183,7 +1192,17 @@ setup_vtbl_ptr ()
(CTOR_INITIALIZER,
current_member_init_list, current_base_init_list));
else
finish_expr_stmt (emit_base_init (current_class_type));
{
tree ctor_stmt;
/* Mark the beginning of the constructor. */
ctor_stmt = build_min_nt (CTOR_STMT);
CTOR_BEGIN_P (ctor_stmt) = 1;
add_tree (ctor_stmt);
/* And actually initialize the base-classes and members. */
finish_expr_stmt (emit_base_init (current_class_type));
}
}
else if (DECL_DESTRUCTOR_P (current_function_decl)
&& !processing_template_decl)
......@@ -1592,6 +1611,9 @@ finish_label_address_expr (label)
TREE_USED (label) = 1;
result = build1 (ADDR_EXPR, ptr_type_node, label);
TREE_CONSTANT (result) = 1;
/* This function cannot be inlined. All jumps to the addressed
label should wind up at the same point. */
DECL_UNINLINABLE (current_function_decl) = 1;
}
return result;
......@@ -2268,11 +2290,6 @@ expand_stmt (t)
finish_expr_stmt (EXPR_STMT_EXPR (t));
break;
case CTOR_COMPLETE:
/* All subobjects have been fully constructed at this point. */
end_protect_partials ();
break;
case DECL_STMT:
{
tree decl;
......@@ -2309,6 +2326,16 @@ expand_stmt (t)
begin_catch_block (TREE_TYPE (t));
break;
case CTOR_STMT:
if (CTOR_BEGIN_P (t))
begin_protect_partials ();
else
/* After this point, any exceptions will cause the
destructor to be executed, so we no longer need to worry
about destroying the various subobjects ourselves. */
end_protect_partials ();
break;
case FOR_STMT:
{
tree tmp;
......@@ -2508,6 +2535,9 @@ expand_body (fn)
if (flag_syntax_only)
return;
/* Optimize the body of the function before expanding it. */
optimize_function (fn);
/* Save the current file name and line number. When we expand the
body of the function, we'll set LINENO and INPUT_FILENAME so that
error-mesages come out in the right places. */
......@@ -2538,9 +2568,17 @@ expand_body (fn)
/* Generate code for the function. */
finish_function (lineno, 0);
/* We don't need the body any more. Allow it to be garbage
collected. We can't do this if we're going to dump everything. */
if (!flag_dump_translation_unit)
/* If possible, obliterate the body of the function so that it can
be garbage collected. */
if (flag_dump_translation_unit)
/* Keep the body; we're going to dump it. */
;
else if (DECL_INLINE (fn) && flag_inline_trees)
/* We might need the body of this function so that we can expand
it inline somewhere else. */
;
else
/* We don't need the body; blow it away. */
DECL_SAVED_TREE (fn) = NULL_TREE;
/* And restore the current source position. */
......
......@@ -28,7 +28,8 @@ Boston, MA 02111-1307, USA. */
#include "rtl.h"
#include "toplev.h"
#include "ggc.h"
#include "splay-tree.h"
#include "insn-config.h"
#include "integrate.h"
static tree bot_manip PROTO((tree *, int *, void *));
static tree bot_replace PROTO((tree *, int *, void *));
......@@ -42,7 +43,10 @@ static cp_lvalue_kind lvalue_p_1 PROTO((tree, int));
static tree no_linkage_helper PROTO((tree *, int *, void *));
static tree build_srcloc PROTO((char *, int));
static void mark_list_hash PROTO ((void *));
static tree copy_tree_r PROTO ((tree *, int *, void *));
static int statement_code_p PROTO((enum tree_code));
static tree mark_local_for_remap_r PROTO((tree *, int *, void *));
static tree cp_unsave_r PROTO ((tree *, int *, void *));
static void cp_unsave PROTO((tree *));
static tree build_target_expr PROTO((tree, tree));
#define CEIL(x,y) (((x) + (y) - 1) / (y))
......@@ -259,6 +263,7 @@ build_cplus_new (type, init)
slot = build (VAR_DECL, type);
DECL_ARTIFICIAL (slot) = 1;
DECL_CONTEXT (slot) = current_function_decl;
layout_decl (slot, 0);
/* We split the CALL_EXPR into its function and its arguments here.
......@@ -1456,6 +1461,45 @@ is_aggr_type_2 (t1, t2)
return 0;
return IS_AGGR_TYPE (t1) && IS_AGGR_TYPE (t2);
}
/* Returns non-zero if CODE is the code for a statement. */
static int
statement_code_p (code)
enum tree_code code;
{
switch (code)
{
case EXPR_STMT:
case COMPOUND_STMT:
case DECL_STMT:
case IF_STMT:
case FOR_STMT:
case WHILE_STMT:
case DO_STMT:
case RETURN_STMT:
case BREAK_STMT:
case CONTINUE_STMT:
case SWITCH_STMT:
case GOTO_STMT:
case LABEL_STMT:
case ASM_STMT:
case SUBOBJECT:
case CLEANUP_STMT:
case START_CATCH_STMT:
case CTOR_STMT:
case SCOPE_STMT:
case CTOR_INITIALIZER:
case CASE_LABEL:
case RETURN_INIT:
case TRY_BLOCK:
case HANDLER:
return 1;
default:
return 0;
}
}
#define PRINT_RING_SIZE 4
......@@ -1594,7 +1638,8 @@ walk_tree (tp, func, data)
/* Handle commmon cases up front. */
if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
|| TREE_CODE_CLASS (code) == 'r')
|| TREE_CODE_CLASS (code) == 'r'
|| TREE_CODE_CLASS (code) == 's')
{
int i;
......@@ -1602,6 +1647,11 @@ walk_tree (tp, func, data)
for (i = first_rtl_op (code) - 1; i >= 0; --i)
WALK_SUBTREE (TREE_OPERAND (*tp, i));
/* For statements, we also walk the chain so that we cover the
entire statement tree. */
if (statement_code_p (code))
WALK_SUBTREE (TREE_CHAIN (*tp));
/* We didn't find what we were looking for. */
return NULL_TREE;
}
......@@ -1706,7 +1756,7 @@ walk_tree (tp, func, data)
if (TYPE_PTRMEMFUNC_P (*tp))
WALK_SUBTREE (TYPE_PTRMEMFUNC_FN_TYPE (*tp));
break;
default:
my_friendly_abort (19990803);
}
......@@ -1755,10 +1805,10 @@ no_linkage_check (t)
/* Passed to walk_tree. Copies the node pointed to, if appropriate. */
static tree
tree
copy_tree_r (tp, walk_subtrees, data)
tree *tp;
int *walk_subtrees ATTRIBUTE_UNUSED;
int *walk_subtrees;
void *data ATTRIBUTE_UNUSED;
{
enum tree_code code = TREE_CODE (*tp);
......@@ -1767,6 +1817,7 @@ copy_tree_r (tp, walk_subtrees, data)
if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
|| TREE_CODE_CLASS (code) == 'r'
|| TREE_CODE_CLASS (code) == 'c'
|| TREE_CODE_CLASS (code) == 's'
|| code == PARM_DECL
|| code == TREE_LIST
|| code == TREE_VEC
......@@ -1781,12 +1832,21 @@ 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 || code == OVERLOAD)
if (code == PARM_DECL || code == TREE_LIST || code == OVERLOAD
|| statement_code_p (code))
TREE_CHAIN (*tp) = chain;
/* For now, we don't update BLOCKs when we make copies. So, we
have to nullify all scope-statements. */
if (TREE_CODE (*tp) == SCOPE_STMT)
SCOPE_NULLIFIED_P (*tp) = 1;
}
else if (code == TEMPLATE_TEMPLATE_PARM)
/* These must be copied specially. */
*tp = copy_template_template_parm (*tp);
else if (TREE_CODE_CLASS (code) == 't')
/* There's no need to copy types, or anything beneath them. */
*walk_subtrees = 0;
return NULL_TREE;
}
......@@ -2605,41 +2665,143 @@ void
init_tree ()
{
make_lang_type_fn = cp_make_lang_type;
lang_unsave_expr_now = cplus_unsave_expr_now;
lang_unsave = cp_unsave;
ggc_add_root (list_hash_table,
sizeof (list_hash_table) / sizeof (struct list_hash *),
sizeof (struct list_hash *),
mark_list_hash);
}
/* The C++ version of unsave_expr_now.
See gcc/tree.c:unsave_expr_now for comments. */
/* The SAVE_EXPR pointed to by TP is being copied. If ST contains
information indicating to what new SAVE_EXPR this one should be
mapped, use that one. Otherwise, create a new node and enter it in
ST. FN is the function into which the copy will be placed. */
void
cplus_unsave_expr_now (expr)
tree expr;
remap_save_expr (tp, st, fn)
tree *tp;
splay_tree st;
tree fn;
{
if (expr == NULL)
return;
splay_tree_node n;
else if (TREE_CODE (expr) == AGGR_INIT_EXPR)
/* See if we already encountered this SAVE_EXPR. */
n = splay_tree_lookup (st, (splay_tree_key) *tp);
/* If we didn't already remap this SAVE_EXPR, do so now. */
if (!n)
{
unsave_expr_now (TREE_OPERAND (expr,0));
if (TREE_OPERAND (expr, 1)
&& TREE_CODE (TREE_OPERAND (expr, 1)) == TREE_LIST)
{
tree exp = TREE_OPERAND (expr, 1);
while (exp)
{
unsave_expr_now (TREE_VALUE (exp));
exp = TREE_CHAIN (exp);
}
}
unsave_expr_now (TREE_OPERAND (expr,2));
return;
tree t = copy_node (*tp);
/* The SAVE_EXPR is now part of the function into which we
are inlining this body. */
SAVE_EXPR_CONTEXT (t) = fn;
/* And we haven't evaluated it yet. */
SAVE_EXPR_RTL (t) = NULL_RTX;
/* Remember this SAVE_EXPR. */
n = splay_tree_insert (st,
(splay_tree_key) *tp,
(splay_tree_value) t);
}
/* Replace this SAVE_EXPR with the copy. */
*tp = (tree) n->value;
}
/* Called via walk_tree. If *TP points to a DECL_STMT for a local
declaration, copies the declaration and enters it in the splay_tree
pointed to by DATA (which is really a `splay_tree *'). */
static tree
mark_local_for_remap_r (tp, walk_subtrees, data)
tree *tp;
int *walk_subtrees ATTRIBUTE_UNUSED;
void *data;
{
tree t = *tp;
splay_tree st = (splay_tree) data;
if ((TREE_CODE (t) == DECL_STMT
&& nonstatic_local_decl_p (DECL_STMT_DECL (t)))
|| TREE_CODE (t) == LABEL_STMT)
{
tree decl;
tree copy;
/* Figure out what's being declared. */
decl = (TREE_CODE (t) == DECL_STMT
? DECL_STMT_DECL (t) : LABEL_STMT_LABEL (t));
/* Make a copy. */
copy = copy_decl_for_inlining (decl,
DECL_CONTEXT (decl),
DECL_CONTEXT (decl));
/* Remember the copy. */
splay_tree_insert (st,
(splay_tree_key) decl,
(splay_tree_value) copy);
}
return NULL_TREE;
}
/* Called via walk_tree when an expression is unsaved. Using the
splay_tree pointed to by ST (which is really a `splay_tree *'),
remaps all local declarations to appropriate replacements. */
static tree
cp_unsave_r (tp, walk_subtrees, data)
tree *tp;
int *walk_subtrees;
void *data;
{
splay_tree st = (splay_tree) data;
splay_tree_node n;
/* Only a local declaration (variable or label). */
if (nonstatic_local_decl_p (*tp))
{
/* Lookup the declaration. */
n = splay_tree_lookup (st, (splay_tree_key) *tp);
/* If it's there, remap it. */
if (n)
*tp = (tree) n->value;
}
else if (TREE_CODE (*tp) == SAVE_EXPR)
remap_save_expr (tp, st, current_function_decl);
else
return;
{
copy_tree_r (tp, walk_subtrees, NULL);
/* Do whatever unsaving is required. */
unsave_expr_1 (*tp);
}
/* Keep iterating. */
return NULL_TREE;
}
/* Called by unsave_expr_now whenever an expression (*TP) needs to be
unsaved. */
static void
cp_unsave (tp)
tree *tp;
{
splay_tree st;
/* Create a splay-tree to map old local variable declarations to new
ones. */
st = splay_tree_new (splay_tree_compare_pointers, NULL, NULL);
/* Walk the tree once figuring out what needs to be remapped. */
walk_tree (tp, mark_local_for_remap_r, st);
/* Walk the tree again, copying, remapping, and unsaving. */
walk_tree (tp, cp_unsave_r, st);
/* Clean up. */
splay_tree_delete (st);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment