Makefile.in (c-lang.o): Depends on langhooks-def.h.
* 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. From-SVN: r47376
This commit is contained in:
parent
188235dff1
commit
ac79cd5ab9
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -135,7 +135,6 @@ void
|
|||
init_cplus_expand ()
|
||||
{
|
||||
lang_expand_expr = cplus_expand_expr;
|
||||
lang_expand_constant = cplus_expand_constant;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
17
gcc/expr.c
17
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
|
||||
|
|
17
gcc/expr.h
17
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));
|
||||
|
|
|
@ -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, \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
19
gcc/stmt.c
19
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. */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
19
gcc/tree.c
19
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
|
||||
|
|
161
gcc/varasm.c
161
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);
|
||||
|
|
Loading…
Reference in New Issue