aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog38
-rw-r--r--gcc/Makefile.in6
-rw-r--r--gcc/c-common.h10
-rw-r--r--gcc/c-lang.c4
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/Make-lang.in3
-rw-r--r--gcc/cp/cp-lang.c5
-rw-r--r--gcc/cp/decl.c1
-rw-r--r--gcc/cp/expr.c1
-rw-r--r--gcc/expr.c17
-rw-r--r--gcc/expr.h17
-rw-r--r--gcc/langhooks-def.h6
-rw-r--r--gcc/langhooks.c19
-rw-r--r--gcc/langhooks.h14
-rw-r--r--gcc/output.h3
-rw-r--r--gcc/stmt.c19
-rw-r--r--gcc/stor-layout.c6
-rw-r--r--gcc/toplev.c2
-rw-r--r--gcc/tree.c19
-rw-r--r--gcc/varasm.c161
20 files changed, 205 insertions, 154 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ab35538..e8a377c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,41 @@
+Tue Nov 27 08:21:47 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * 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 <rth@redhat.com>
* ifcvt.c (noce_try_store_flag_constants): Test for overflow
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 1cb1599..80b7f10 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 84e4bb9..1d87cf4 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 a5c8662..0578cb2 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 110f7c4..ea6353b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+Tue Nov 27 09:03:47 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * 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 <neil@daikokuya.demon.co.uk>
* decl2.c (c_language): Move to c-common.c.
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 3a1f149..f9700ba 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 dbca8af..598c3fc 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 6fdb1c4..9f4d82d 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 f2fe6eb..57099dc 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 32e6d2d..240fb8b 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 764e081..4275b81 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 bb38e01..1ee631b 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 8465bd3..3054ee7 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 befdb0f..0519d21 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 7937988..6d67032 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 7c185e7..2615df0 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 22dd86b..e16045f 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 caefaff..e0e8a96 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 1b6dc79..b86a339 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 c241745..b7bd9c3 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);