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:
Richard Kenner 2001-11-27 14:31:29 +00:00 committed by Richard Kenner
parent 188235dff1
commit ac79cd5ab9
20 changed files with 205 additions and 154 deletions

View File

@ -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

View File

@ -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 \

View File

@ -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));

View File

@ -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;

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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 ();

View File

@ -135,7 +135,6 @@ void
init_cplus_expand ()
{
lang_expand_expr = cplus_expand_expr;
lang_expand_constant = cplus_expand_constant;
}
int

View File

@ -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

View File

@ -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));

View File

@ -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, \

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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. */

View File

@ -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;

View File

@ -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. */

View File

@ -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

View File

@ -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);