From b3187c7c505e8cf33bbc544e5841787a08ecb7a5 Mon Sep 17 00:00:00 2001 From: kenner Date: Tue, 27 Nov 2001 14:31:29 +0000 Subject: * Makefile.in (c-lang.o): Depends on langhooks-def.h. (expr.o, varasm.o): Depends on langhooks.h. * c-common.c (c_safe_from_p): Always declare. (c_expand_expr): Refine when declared. * c-lang.c (c-common.h): Now include. (LANG_HOOKS_SAFE_FROM_P): Define new hook. (c_init): Don't set lang_safe_from_expr. * expr.c (langhooks.h): Now include. (lang_safe_from_p): No longer define. (safe_from_p): Use lang hook. (expand_expr): Set IGNORE if VOID_TYPE result of VIEW_CONVERT_EXPR too. (expand_expr, case VIEW_CONVERT_EXPR): Pass ro_modifier down. * expr.h (lang_expand_constant, lang_safe_from_p): Delete. * langhooks-def.h (lhd_return_tree, lhd_safe_from_p): New decls. (LANG_HOOKS_EXPAND_CONSTANT, LANG_HOOKS_SAFE_FROM_P): New hooks. * langhooks.c (lhd_return_tree, lhd_safe_from_p): New functions. * langhooks.h (struct lang_hooks): New fields expand_constant and safe_from_p. * output.h (output_constant): Size arg is HOST_WIDE_INT. * stmt.c (expand_decl_init): No longer need to expand constant for CONST_DECL. * stor-layout.c (put_pending_size): Don't check for SAVE_EXPR. * toplev.c (lang_expand_constant): Delete var. * tree.c (save_expr): Don't put another SAVE_EXPR around simple operations on SAVE_EXPR. * varasm.c (langhooks.h): Now include. (compare_constant_1): Use lang_hooks, not lang_expand_constant. (record_constant_1, output_addressed_constants): Likewise. (initializer_constant_valid_p, output_constant): Likewise. (output_constant_def): Process no-defer of string constant. (output_addressed_constants, case ADDR_EXPR): Use handled_component_p. (output_constant): Strip more conversions. Track our size and pad for the rest. (array_size_for_constructor): Remove code for non-byte STRING_CST. (output_constructor): SIZE now HOST_WIDE_INT. * cp/Make-lang.in (cp-lang.o): Depends on c-common.h. * cp/cp-lang.c (c-common.h): Include. (LANG_HOOKS_EXPAND_CONSTANT, LANG_HOOKS_SAFE_FROM_P): New hooks. * cp/decl.c (cxx_init_decl_processing): Don't set lang_safe_from_p. * cp/expr.c (init_cplus_expand): Don't set lang_expand_constant. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@47376 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 38 +++++++++++++ gcc/Makefile.in | 6 +- gcc/c-common.h | 10 ++-- gcc/c-lang.c | 4 +- gcc/cp/ChangeLog | 8 +++ gcc/cp/Make-lang.in | 3 +- gcc/cp/cp-lang.c | 5 ++ gcc/cp/decl.c | 1 - gcc/cp/expr.c | 1 - gcc/expr.c | 17 ++---- gcc/expr.h | 17 ------ gcc/langhooks-def.h | 6 ++ gcc/langhooks.c | 19 +++++++ gcc/langhooks.h | 14 +++++ gcc/output.h | 3 +- gcc/stmt.c | 19 ++----- gcc/stor-layout.c | 6 +- gcc/toplev.c | 2 - gcc/tree.c | 19 ++++++- gcc/varasm.c | 161 ++++++++++++++++++++++++---------------------------- 20 files changed, 205 insertions(+), 154 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ab355387288..e8a377c3108 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,41 @@ +Tue Nov 27 08:21:47 2001 Richard Kenner + + * Makefile.in (c-lang.o): Depends on langhooks-def.h. + (expr.o, varasm.o): Depends on langhooks.h. + * c-common.c (c_safe_from_p): Always declare. + (c_expand_expr): Refine when declared. + * c-lang.c (c-common.h): Now include. + (LANG_HOOKS_SAFE_FROM_P): Define new hook. + (c_init): Don't set lang_safe_from_expr. + * expr.c (langhooks.h): Now include. + (lang_safe_from_p): No longer define. + (safe_from_p): Use lang hook. + (expand_expr): Set IGNORE if VOID_TYPE result of VIEW_CONVERT_EXPR too. + (expand_expr, case VIEW_CONVERT_EXPR): Pass ro_modifier down. + * expr.h (lang_expand_constant, lang_safe_from_p): Delete. + * langhooks-def.h (lhd_return_tree, lhd_safe_from_p): New decls. + (LANG_HOOKS_EXPAND_CONSTANT, LANG_HOOKS_SAFE_FROM_P): New hooks. + * langhooks.c (lhd_return_tree, lhd_safe_from_p): New functions. + * langhooks.h (struct lang_hooks): New fields expand_constant + and safe_from_p. + * output.h (output_constant): Size arg is HOST_WIDE_INT. + * stmt.c (expand_decl_init): No longer need to expand constant + for CONST_DECL. + * stor-layout.c (put_pending_size): Don't check for SAVE_EXPR. + * toplev.c (lang_expand_constant): Delete var. + * tree.c (save_expr): Don't put another SAVE_EXPR around simple + operations on SAVE_EXPR. + * varasm.c (langhooks.h): Now include. + (compare_constant_1): Use lang_hooks, not lang_expand_constant. + (record_constant_1, output_addressed_constants): Likewise. + (initializer_constant_valid_p, output_constant): Likewise. + (output_constant_def): Process no-defer of string constant. + (output_addressed_constants, case ADDR_EXPR): Use handled_component_p. + (output_constant): Strip more conversions. + Track our size and pad for the rest. + (array_size_for_constructor): Remove code for non-byte STRING_CST. + (output_constructor): SIZE now HOST_WIDE_INT. + 2001-11-27 Richard Henderson * ifcvt.c (noce_try_store_flag_constants): Test for overflow diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 1cb15998f73..80b7f108b0b 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1173,7 +1173,7 @@ c-typeck.o : c-typeck.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_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 $(VARRAY_H) \ $(RTL_H) $(EXPR_H) tree-inline.h insn-config.h integrate.h langhooks.h \ - langhooks-def.h + langhooks-def.h c-common.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 \ @@ -1394,7 +1394,7 @@ errors.o : errors.c $(GCONFIG_H) $(SYSTEM_H) errors.h varasm.o : varasm.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) flags.h \ function.h $(EXPR_H) hard-reg-set.h $(REGS_H) $(OBSTACK_H) \ output.h c-pragma.h toplev.h xcoffout.h debug.h $(GGC_H) $(TM_P_H) \ - $(HASHTAB_H) $(TARGET_H) + $(HASHTAB_H) $(TARGET_H) langhooks.h function.o : function.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \ function.h $(EXPR_H) libfuncs.h $(REGS_H) hard-reg-set.h \ insn-config.h $(RECOG_H) output.h toplev.h except.h hash.h $(GGC_H) $(TM_P_H) @@ -1408,7 +1408,7 @@ except.o : except.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \ expr.o : expr.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h function.h \ $(REGS_H) $(EXPR_H) $(OPTABS_H) libfuncs.h insn-attr.h insn-config.h \ $(RECOG_H) output.h typeclass.h hard-reg-set.h toplev.h hard-reg-set.h \ - except.h reload.h $(GGC_H) intl.h $(TM_P_H) + except.h reload.h $(GGC_H) langhooks.h intl.h $(TM_P_H) builtins.o : builtins.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \ $(TARGET_H) function.h $(REGS_H) $(EXPR_H) $(OPTABS_H) insn-config.h \ $(RECOG_H) output.h typeclass.h hard-reg-set.h toplev.h hard-reg-set.h \ diff --git a/gcc/c-common.h b/gcc/c-common.h index 84e4bb95824..1d87cf45cbb 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -802,14 +802,14 @@ extern tree lookup_label PARAMS ((tree)); in C. */ extern void (*back_end_hook) PARAMS ((tree)); -#ifdef RTX_CODE +/* enum expand_modified is in expr.h, as is the macro below. */ -extern struct rtx_def *c_expand_expr PARAMS ((tree, rtx, - enum machine_mode, - enum expand_modifier)); +#ifdef QUEUED_VAR +extern rtx c_expand_expr PARAMS ((tree, rtx, enum machine_mode, + enum expand_modifier)); +#endif extern int c_safe_from_p PARAMS ((rtx, tree)); -#endif extern int c_unsafe_for_reeval PARAMS ((tree)); diff --git a/gcc/c-lang.c b/gcc/c-lang.c index a5c86625b30..0578cb24ef7 100644 --- a/gcc/c-lang.c +++ b/gcc/c-lang.c @@ -34,6 +34,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "rtl.h" #include "expr.h" #include "c-tree.h" +#include "c-common.h" #include "c-lex.h" #include "cpplib.h" #include "insn-config.h" @@ -64,6 +65,8 @@ static int c_cannot_inline_tree_fn PARAMS ((tree *)); #define LANG_HOOKS_POST_OPTIONS c_post_options #undef LANG_HOOKS_GET_ALIAS_SET #define LANG_HOOKS_GET_ALIAS_SET c_common_get_alias_set +#undef LANG_HOOKS_SAFE_FROM_P +#define LANG_HOOKS_SAFE_FROM_P c_safe_from_p #undef LANG_HOOKS_PRINT_IDENTIFIER #define LANG_HOOKS_PRINT_IDENTIFIER c_print_identifier #undef LANG_HOOKS_SET_YYDEBUG @@ -121,7 +124,6 @@ c_init (filename) restore_lang_status = &pop_c_function_context; mark_lang_status = &mark_c_function_context; lang_expand_expr = &c_expand_expr; - lang_safe_from_p = &c_safe_from_p; 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; diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 110f7c40e8e..ea6353bea87 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +Tue Nov 27 09:03:47 2001 Richard Kenner + + * Make-lang.in (cp-lang.o): Depends on c-common.h. + * cp-lang.c (c-common.h): Include. + (LANG_HOOKS_EXPAND_CONSTANT, LANG_HOOKS_SAFE_FROM_P): New hooks. + * decl.c (cxx_init_decl_processing): Don't set lang_safe_from_p. + * expr.c (init_cplus_expand): Don't set lang_expand_constant. + 2001-11-26 Neil Booth * decl2.c (c_language): Move to c-common.c. diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index 3a1f1497fd0..f9700ba8d52 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -243,7 +243,8 @@ cp/spew.o: cp/spew.c $(CXX_TREE_H) cp/parse.h flags.h cp/lex.h toplev.h cp/lex.o: cp/lex.c $(CXX_TREE_H) cp/parse.h flags.h cp/lex.h c-pragma.h \ toplev.h output.h mbchar.h $(GGC_H) input.h diagnostic.h cp/operators.def \ $(TM_P_H) -cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) toplev.h langhooks.h langhooks-def.h +cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) toplev.h langhooks.h langhooks-def.h \ + c-common.h cp/decl.o: cp/decl.c $(CXX_TREE_H) flags.h cp/lex.h cp/decl.h stack.h \ output.h $(EXPR_H) except.h toplev.h hash.h $(GGC_H) $(RTL_H) \ cp/operators.def $(TM_P_H) tree-inline.h diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c index dbca8af24de..598c3fc5c74 100644 --- a/gcc/cp/cp-lang.c +++ b/gcc/cp/cp-lang.c @@ -23,6 +23,7 @@ Boston, MA 02111-1307, USA. */ #include "system.h" #include "tree.h" #include "cp-tree.h" +#include "c-common.h" #include "toplev.h" #include "langhooks.h" #include "langhooks-def.h" @@ -45,6 +46,10 @@ static HOST_WIDE_INT cxx_get_alias_set PARAMS ((tree)); #define LANG_HOOKS_POST_OPTIONS cxx_post_options #undef LANG_HOOKS_GET_ALIAS_SET #define LANG_HOOKS_GET_ALIAS_SET cxx_get_alias_set +#undef LANG_HOOKS_EXPAND_CONSTANT +#define LANG_HOOKS_EXPAND_CONSTANT cplus_expand_constant +#undef LANG_HOOKS_SAFE_FROM_P +#define LANG_HOOKS_SAFE_FROM_P c_safe_from_p #undef LANG_HOOKS_PRINT_STATISTICS #define LANG_HOOKS_PRINT_STATISTICS cxx_print_statistics #undef LANG_HOOKS_PRINT_XNODE diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 6fdb1c48d65..9f4d82d8bd6 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -6407,7 +6407,6 @@ cxx_init_decl_processing () init_lang_status = &push_cp_function_context; free_lang_status = &pop_cp_function_context; mark_lang_status = &mark_cp_function_context; - lang_safe_from_p = &c_safe_from_p; lang_missing_noreturn_ok_p = &cp_missing_noreturn_ok_p; cp_parse_init (); diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c index f2fe6ebf476..57099dcde3f 100644 --- a/gcc/cp/expr.c +++ b/gcc/cp/expr.c @@ -135,7 +135,6 @@ void init_cplus_expand () { lang_expand_expr = cplus_expand_expr; - lang_expand_constant = cplus_expand_constant; } int diff --git a/gcc/expr.c b/gcc/expr.c index 32e6d2db991..240fb8b6032 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -42,6 +42,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "typeclass.h" #include "toplev.h" #include "ggc.h" +#include "langhooks.h" #include "intl.h" #include "tm_p.h" @@ -72,15 +73,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #define CASE_VECTOR_PC_RELATIVE 0 #endif -/* Hook called by safe_from_p for language-specific tree codes. It is - up to the language front-end to install a hook if it has any such - codes that safe_from_p needs to know about. Since same_from_p will - recursively explore the TREE_OPERANDs of an expression, this hook - should not reexamine those pieces. This routine may recursively - call safe_from_p; it should always pass `0' as the TOP_P - parameter. */ -int (*lang_safe_from_p) PARAMS ((rtx, tree)); - /* If this is nonzero, we do not bother generating VOLATILE around volatile memory references, and we are willing to output indirect addresses. If cse is to follow, we reject @@ -5854,8 +5846,7 @@ safe_from_p (x, exp, top_p) special handling. */ if ((unsigned int) TREE_CODE (exp) >= (unsigned int) LAST_AND_UNUSED_TREE_CODE - && lang_safe_from_p - && !(*lang_safe_from_p) (x, exp)) + && !(*lang_hooks.safe_from_p) (x, exp)) return 0; } @@ -6148,7 +6139,7 @@ expand_expr (exp, target, tmode, modifier) ignore = (target == const0_rtx || ((code == NON_LVALUE_EXPR || code == NOP_EXPR || code == CONVERT_EXPR || code == REFERENCE_EXPR - || code == COND_EXPR) + || code == COND_EXPR || code == VIEW_CONVERT_EXPR) && TREE_CODE (type) == VOID_TYPE)); /* Make a read-only version of the modifier. */ @@ -7536,7 +7527,7 @@ expand_expr (exp, target, tmode, modifier) return target; case VIEW_CONVERT_EXPR: - op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, mode, 0); + op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, mode, ro_modifier); /* If the input and output modes are both the same, we are done. Otherwise, if neither mode is BLKmode and both are within a word, we diff --git a/gcc/expr.h b/gcc/expr.h index 764e0818a8a..4275b812953 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -775,25 +775,8 @@ extern rtx (*lang_expand_expr) PARAMS ((union tree_node *, rtx, enum machine_mode, enum expand_modifier modifier)); -#ifdef TREE_CODE -/* Hook called by output_constant for language-specific tree codes. - It is up to the language front-end to install a hook if it has any - such codes that output_constant needs to know about. Returns a - language-independent constant equivalent to its input. */ -extern tree (*lang_expand_constant) PARAMS ((tree)); - extern int safe_from_p PARAMS ((rtx, tree, int)); -/* Hook called by safe_from_p for language-specific tree codes. It is - up to the language front-end to install a hook if it has any such - codes that safe_from_p needs to know about. Since same_from_p will - recursively explore the TREE_OPERANDs of an expression, this hook - should not reexamine those pieces. This routine may recursively - call safe_from_p; it should always pass `0' as the TOP_P - parameter. */ -extern int (*lang_safe_from_p) PARAMS ((rtx, tree)); -#endif - /* Call this once to initialize the contents of the optabs appropriately for the current target machine. */ extern void init_optabs PARAMS ((void)); diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h index bb38e01cc71..1ee631b1e75 100644 --- a/gcc/langhooks-def.h +++ b/gcc/langhooks-def.h @@ -40,6 +40,8 @@ extern HOST_WIDE_INT hook_get_alias_set_0 PARAMS ((tree)); extern void lhd_do_nothing PARAMS ((void)); extern int lhd_decode_option PARAMS ((int, char **)); extern HOST_WIDE_INT lhd_get_alias_set PARAMS ((tree)); +extern tree lhd_return_tree PARAMS ((tree)); +extern int lhd_safe_from_p PARAMS ((rtx, tree)); extern void lhd_clear_binding_stack PARAMS ((void)); extern void lhd_print_tree_nothing PARAMS ((FILE *, tree, int)); extern void lhd_set_yydebug PARAMS ((int)); @@ -67,6 +69,8 @@ int lhd_tree_inlining_anon_aggr_type_p PARAMS ((tree)); #define LANG_HOOKS_DECODE_OPTION lhd_decode_option #define LANG_HOOKS_POST_OPTIONS lhd_do_nothing #define LANG_HOOKS_GET_ALIAS_SET lhd_get_alias_set +#define LANG_HOOKS_EXPAND_CONSTANT lhd_return_tree +#define LANG_HOOKS_SAFE_FROM_P lhd_safe_from_p #define LANG_HOOKS_HONOR_READONLY false #define LANG_HOOKS_PRINT_STATISTICS lhd_do_nothing #define LANG_HOOKS_PRINT_XNODE lhd_print_tree_nothing @@ -126,6 +130,8 @@ int lhd_tree_dump_type_quals PARAMS ((tree)); LANG_HOOKS_FINISH, \ LANG_HOOKS_CLEAR_BINDING_STACK, \ LANG_HOOKS_GET_ALIAS_SET, \ + LANG_HOOKS_EXPAND_CONSTANT, \ + LANG_HOOKS_SAFE_FROM_P, \ LANG_HOOKS_HONOR_READONLY, \ LANG_HOOKS_PRINT_STATISTICS, \ LANG_HOOKS_PRINT_XNODE, \ diff --git a/gcc/langhooks.c b/gcc/langhooks.c index 8465bd32e50..3054ee7130c 100644 --- a/gcc/langhooks.c +++ b/gcc/langhooks.c @@ -38,6 +38,15 @@ lhd_do_nothing () { } +/* Do nothing (return the tree node passed). */ + +tree +lhd_return_tree (t) + tree t; +{ + return t; +} + /* Do nothing; the default hook to decode an option. */ int @@ -58,6 +67,16 @@ lhd_print_tree_nothing (file, node, indent) { } +/* Called from safe_from_p. */ + +int +lhd_safe_from_p (x, exp) + rtx x; + tree exp; +{ + return 1; +} + /* Called when -dy is given on the command line. */ void diff --git a/gcc/langhooks.h b/gcc/langhooks.h index befdb0f6838..0519d21bbfe 100644 --- a/gcc/langhooks.h +++ b/gcc/langhooks.h @@ -109,6 +109,20 @@ struct lang_hooks Returns -1 if the language does nothing special for it. */ HOST_WIDE_INT (*get_alias_set) PARAMS ((tree)); + /* Called with an expression that is to be processed as a constant. + Returns either the same expression or a language-independent + constant equivalent to its input. */ + tree (*expand_constant) PARAMS ((tree)); + + /* Hook called by safe_from_p for language-specific tree codes. It is + up to the language front-end to install a hook if it has any such + codes that safe_from_p needs to know about. Since same_from_p will + recursively explore the TREE_OPERANDs of an expression, this hook + should not reexamine those pieces. This routine may recursively + call safe_from_p; it should always pass `0' as the TOP_P + parameter. */ + int (*safe_from_p) PARAMS ((rtx, tree)); + /* Nonzero if TYPE_READONLY and TREE_READONLY should always be honored. */ bool honor_readonly; diff --git a/gcc/output.h b/gcc/output.h index 793798809ca..6d67032d51f 100644 --- a/gcc/output.h +++ b/gcc/output.h @@ -368,7 +368,8 @@ extern tree initializer_constant_valid_p PARAMS ((tree, tree)); with zeros if necessary. SIZE must always be specified. ALIGN is the alignment in bits that may be assumed for the data. */ -extern void output_constant PARAMS ((tree, int, unsigned)); +extern void output_constant PARAMS ((tree, HOST_WIDE_INT, + unsigned int)); #endif #ifdef RTX_CODE diff --git a/gcc/stmt.c b/gcc/stmt.c index 7c185e700b5..2615df09a24 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -4108,21 +4108,10 @@ expand_decl_init (decl) { int was_used = TREE_USED (decl); - /* If this is a CONST_DECL, we don't have to generate any code, but - if DECL_INITIAL is a constant, call expand_expr to force TREE_CST_RTL - to be set while in the obstack containing the constant. If we don't - do this, we can lose if we have functions nested three deep and the middle - function makes a CONST_DECL whose DECL_INITIAL is a STRING_CST while - the innermost function is the first to expand that STRING_CST. */ - if (TREE_CODE (decl) == CONST_DECL) - { - if (DECL_INITIAL (decl) && TREE_CONSTANT (DECL_INITIAL (decl))) - expand_expr (DECL_INITIAL (decl), NULL_RTX, VOIDmode, - EXPAND_INITIALIZER); - return; - } - - if (TREE_STATIC (decl)) + /* If this is a CONST_DECL, we don't have to generate any code. Likewise + for static decls. */ + if (TREE_CODE (decl) == CONST_DECL + || TREE_STATIC (decl)) return; /* Compute and store the initial value now. */ diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 22dd86b709e..e16045f1f5a 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -114,8 +114,7 @@ void put_pending_size (expr) tree expr; { - if (TREE_CODE (expr) == SAVE_EXPR) - pending_sizes = tree_cons (NULL_TREE, expr, pending_sizes); + pending_sizes = tree_cons (NULL_TREE, expr, pending_sizes); } /* Put a chain of objects into the pending sizes list, which must be @@ -140,7 +139,8 @@ variable_size (size) { /* If the language-processor is to take responsibility for variable-sized items (e.g., languages which have elaboration procedures like Ada), - just return SIZE unchanged. Likewise for self-referential sizes. */ + just return SIZE unchanged. Likewise for self-referential sizes and + constant sizes. */ if (TREE_CONSTANT (size) || global_bindings_p () < 0 || contains_placeholder_p (size)) return size; diff --git a/gcc/toplev.c b/gcc/toplev.c index caefaff81f8..e0e8a963144 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -395,8 +395,6 @@ typedef rtx (*lang_expand_expr_t) lang_expand_expr_t lang_expand_expr = 0; -tree (*lang_expand_constant) PARAMS ((tree)) = 0; - /* Pointer to function to finish handling an incomplete decl at the end of compilation. */ diff --git a/gcc/tree.c b/gcc/tree.c index 1b6dc79e857..b86a339fe5c 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -1549,20 +1549,33 @@ save_expr (expr) tree expr; { tree t = fold (expr); + tree inner; /* We don't care about whether this can be used as an lvalue in this context. */ while (TREE_CODE (t) == NON_LVALUE_EXPR) t = TREE_OPERAND (t, 0); + + /* If we have simple operations applied to a SAVE_EXPR or to a SAVE_EXPR and + a constant, it will be more efficient to not make another SAVE_EXPR since + it will allow better simplification and GCSE will be able to merge the + computations if they actualy occur. */ + for (inner = t; + (TREE_CODE_CLASS (TREE_CODE (inner)) == '1' + || (TREE_CODE_CLASS (TREE_CODE (inner)) == '2' + && TREE_CONSTANT (TREE_OPERAND (inner, 1)))); + inner = TREE_OPERAND (inner, 0)) + ; + /* If the tree evaluates to a constant, then we don't want to hide that fact (i.e. this allows further folding, and direct checks for constants). However, a read-only object that has side effects cannot be bypassed. Since it is no problem to reevaluate literals, we just return the literal node. */ - - if (TREE_CONSTANT (t) || (TREE_READONLY (t) && ! TREE_SIDE_EFFECTS (t)) - || TREE_CODE (t) == SAVE_EXPR || TREE_CODE (t) == ERROR_MARK) + if (TREE_CONSTANT (inner) + || (TREE_READONLY (inner) && ! TREE_SIDE_EFFECTS (inner)) + || TREE_CODE (inner) == SAVE_EXPR || TREE_CODE (inner) == ERROR_MARK) return t; /* If T contains a PLACEHOLDER_EXPR, we must evaluate it each time, since diff --git a/gcc/varasm.c b/gcc/varasm.c index c241745054b..b7bd9c320e0 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -43,6 +43,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "hashtab.h" #include "c-pragma.h" #include "ggc.h" +#include "langhooks.h" #include "tm_p.h" #include "debug.h" #include "target.h" @@ -168,7 +169,8 @@ static int output_addressed_constants PARAMS ((tree)); static void output_after_function_constants PARAMS ((void)); static unsigned HOST_WIDE_INT array_size_for_constructor PARAMS ((tree)); static unsigned min_align PARAMS ((unsigned, unsigned)); -static void output_constructor PARAMS ((tree, int, unsigned)); +static void output_constructor PARAMS ((tree, HOST_WIDE_INT, + unsigned int)); #ifdef ASM_WEAKEN_LABEL static void remove_from_pending_weak_list PARAMS ((const char *)); #endif @@ -2477,6 +2479,11 @@ struct constant_descriptor #define MAX_HASH_TABLE 1009 static struct constant_descriptor *const_hash_table[MAX_HASH_TABLE]; +/* We maintain a hash table of STRING_CST values. Unless we are asked to force + out a string constant, we defer output of the constants until we know + they are actually used. This will be if something takes its address or if + there is a usage of the string in the RTL of a function. */ + #define STRHASH(x) ((hashval_t)((long)(x) >> 3)) struct deferred_string @@ -2739,7 +2746,7 @@ compare_constant_1 (exp, p) strp = (const unsigned char *)TREE_STRING_POINTER (exp); len = TREE_STRING_LENGTH (exp); if (memcmp ((char *) &TREE_STRING_LENGTH (exp), p, - sizeof TREE_STRING_LENGTH (exp))) + sizeof TREE_STRING_LENGTH (exp))) return 0; p += sizeof TREE_STRING_LENGTH (exp); @@ -2899,12 +2906,14 @@ compare_constant_1 (exp, p) return compare_constant_1 (TREE_OPERAND (exp, 0), p); default: - if (lang_expand_constant) - { - exp = (*lang_expand_constant) (exp); - return compare_constant_1 (exp, p); - } - return 0; + { + tree new = (*lang_hooks.expand_constant) (exp); + + if (new != exp) + return compare_constant_1 (new, p); + else + return 0; + } } /* Compare constant contents. */ @@ -3111,12 +3120,13 @@ record_constant_1 (exp) return; default: - if (lang_expand_constant) - { - exp = (*lang_expand_constant) (exp); + { + tree new = (*lang_hooks.expand_constant) (exp); + + if (new != exp) record_constant_1 (exp); - } - return; + return; + } } /* Record constant contents. */ @@ -3283,7 +3293,10 @@ output_constant_def (exp, defer) int labelno = -1; rtx rtl; - if (TREE_CODE (exp) != INTEGER_CST && TREE_CST_RTL (exp)) + /* We can't just use the saved RTL if this is a defererred string constant + and we are not to defer anymode. */ + if (TREE_CODE (exp) != INTEGER_CST && TREE_CST_RTL (exp) + && (defer || !STRING_POOL_ADDRESS_P (XEXP (TREE_CST_RTL (exp), 0)))) return TREE_CST_RTL (exp); /* Make sure any other constants whose addresses appear in EXP @@ -4192,29 +4205,26 @@ output_addressed_constants (exp) tree exp; { int reloc = 0; + tree tem; /* Give the front-end a chance to convert VALUE to something that looks more like a constant to the back-end. */ - if (lang_expand_constant) - exp = (*lang_expand_constant) (exp); + exp = (*lang_hooks.expand_constant) (exp); switch (TREE_CODE (exp)) { case ADDR_EXPR: - { - tree constant = TREE_OPERAND (exp, 0); + /* Go inside any operations that get_inner_reference can handle and see + if what's inside is a constant: no need to do anything here for + addresses of variables or functions. */ + for (tem = TREE_OPERAND (exp, 0); handled_component_p (tem); + tem = TREE_OPERAND (tem, 0)) + ; - while (TREE_CODE (constant) == COMPONENT_REF) - { - constant = TREE_OPERAND (constant, 0); - } + if (TREE_CODE_CLASS (TREE_CODE (tem)) == 'c' + || TREE_CODE (tem) == CONSTRUCTOR) + output_constant_def (tem, 0); - if (TREE_CODE_CLASS (TREE_CODE (constant)) == 'c' - || TREE_CODE (constant) == CONSTRUCTOR) - /* No need to do anything here - for addresses of variables or functions. */ - output_constant_def (constant, 0); - } reloc = 1; break; @@ -4231,12 +4241,10 @@ output_addressed_constants (exp) break; case CONSTRUCTOR: - { - tree link; - for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link)) - if (TREE_VALUE (link) != 0) - reloc |= output_addressed_constants (TREE_VALUE (link)); - } + for (tem = CONSTRUCTOR_ELTS (exp); tem; tem = TREE_CHAIN (tem)) + if (TREE_VALUE (tem) != 0) + reloc |= output_addressed_constants (TREE_VALUE (tem)); + break; default: @@ -4262,8 +4270,7 @@ initializer_constant_valid_p (value, endtype) { /* Give the front-end a chance to convert VALUE to something that looks more like a constant to the back-end. */ - if (lang_expand_constant) - value = (*lang_expand_constant) (value); + value = (*lang_hooks.expand_constant) (value); switch (TREE_CODE (value)) { @@ -4438,37 +4445,29 @@ initializer_constant_valid_p (value, endtype) void output_constant (exp, size, align) tree exp; - int size; + HOST_WIDE_INT size; unsigned int align; { - enum tree_code code = TREE_CODE (TREE_TYPE (exp)); + enum tree_code code; + HOST_WIDE_INT thissize; /* Some front-ends use constants other than the standard language-indepdent varieties, but which may still be output directly. Give the front-end a chance to convert EXP to a language-independent representation. */ - if (lang_expand_constant) - { - exp = (*lang_expand_constant) (exp); - code = TREE_CODE (TREE_TYPE (exp)); - } + exp = (*lang_hooks.expand_constant) (exp); if (size == 0 || flag_syntax_only) return; - /* Eliminate the NON_LVALUE_EXPR_EXPR that makes a cast not be an lvalue. - That way we get the constant (we hope) inside it. Also, strip off any - NOP_EXPR that converts between two record, union, array, or set types - or a CONVERT_EXPR that converts to a union TYPE. */ - while ((TREE_CODE (exp) == NOP_EXPR - && (TREE_TYPE (exp) == TREE_TYPE (TREE_OPERAND (exp, 0)) - || AGGREGATE_TYPE_P (TREE_TYPE (exp)))) - || (TREE_CODE (exp) == CONVERT_EXPR && code == UNION_TYPE) + /* Eliminate any conversions since we'll be outputting the underlying + constant. */ + while (TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR || TREE_CODE (exp) == NON_LVALUE_EXPR || TREE_CODE (exp) == VIEW_CONVERT_EXPR) - { - exp = TREE_OPERAND (exp, 0); - code = TREE_CODE (TREE_TYPE (exp)); - } + exp = TREE_OPERAND (exp, 0); + + code = TREE_CODE (TREE_TYPE (exp)); + thissize = int_size_in_bytes (TREE_TYPE (exp)); /* Allow a constructor with no elements for any data type. This means to fill the space with zeros. */ @@ -4490,6 +4489,8 @@ output_constant (exp, size, align) return; } + /* Now output the underlying data. If we've handling the padding, return. + Otherwise, break and ensure THISSIZE is the size written. */ switch (code) { case CHAR_TYPE: @@ -4498,16 +4499,10 @@ output_constant (exp, size, align) case ENUMERAL_TYPE: case POINTER_TYPE: case REFERENCE_TYPE: - /* ??? What about (int)((float)(int)&foo + 4) */ - while (TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR - || TREE_CODE (exp) == NON_LVALUE_EXPR) - exp = TREE_OPERAND (exp, 0); - if (! assemble_integer (expand_expr (exp, NULL_RTX, VOIDmode, EXPAND_INITIALIZER), size, align, 0)) error ("initializer for integer value is too complicated"); - size = 0; break; case REAL_TYPE: @@ -4517,14 +4512,12 @@ output_constant (exp, size, align) assemble_real (TREE_REAL_CST (exp), mode_for_size (size * BITS_PER_UNIT, MODE_FLOAT, 0), align); - size = 0; break; case COMPLEX_TYPE: - output_constant (TREE_REALPART (exp), size / 2, align); - output_constant (TREE_IMAGPART (exp), size / 2, - min_align (align, BITS_PER_UNIT * (size / 2))); - size -= (size / 2) * 2; + output_constant (TREE_REALPART (exp), thissize / 2, align); + output_constant (TREE_IMAGPART (exp), thissize / 2, + min_align (align, BITS_PER_UNIT * (thissize / 2))); break; case ARRAY_TYPE: @@ -4535,16 +4528,8 @@ output_constant (exp, size, align) } else if (TREE_CODE (exp) == STRING_CST) { - int excess = 0; - - if (size > TREE_STRING_LENGTH (exp)) - { - excess = size - TREE_STRING_LENGTH (exp); - size = TREE_STRING_LENGTH (exp); - } - - assemble_string (TREE_STRING_POINTER (exp), size); - size = excess; + thissize = MIN (TREE_STRING_LENGTH (exp), size); + assemble_string (TREE_STRING_POINTER (exp), thissize); } else abort (); @@ -4562,22 +4547,23 @@ output_constant (exp, size, align) if (TREE_CODE (exp) == INTEGER_CST) assemble_integer (expand_expr (exp, NULL_RTX, VOIDmode, EXPAND_INITIALIZER), - size, align, 1); + thissize, align, 1); else if (TREE_CODE (exp) == CONSTRUCTOR) { - unsigned char *buffer = (unsigned char *) alloca (size); - if (get_set_constructor_bytes (exp, buffer, size)) + unsigned char *buffer = (unsigned char *) alloca (thissize); + if (get_set_constructor_bytes (exp, buffer, thissize)) abort (); - assemble_string ((char *) buffer, size); + assemble_string ((char *) buffer, thissize); } else error ("unknown set constructor type"); return; default: - break; /* ??? */ + abort (); } + size -= thissize; if (size > 0) assemble_zeros (size); } @@ -4593,13 +4579,12 @@ array_size_for_constructor (val) { tree max_index, i; + /* This code used to attempt to handle string constants that are not + arrays of single-bytes, but nothing else does, so there's no point in + doing it here. */ if (TREE_CODE (val) == STRING_CST) - { - HOST_WIDE_INT len = TREE_STRING_LENGTH(val); - HOST_WIDE_INT esz = int_size_in_bytes (TREE_TYPE (TREE_TYPE (val))); - HOST_WIDE_INT tsz = len * esz; - return tsz; - } + return TREE_STRING_LENGTH (val); + max_index = NULL_TREE; for (i = CONSTRUCTOR_ELTS (val); i ; i = TREE_CHAIN (i)) { @@ -4632,7 +4617,7 @@ array_size_for_constructor (val) static void output_constructor (exp, size, align) tree exp; - int size; + HOST_WIDE_INT size; unsigned int align; { tree type = TREE_TYPE (exp); -- cgit v1.2.1