avoid early asm output

This avoids early assembler output via the gimplifier creating
new static CTORs.  The output machinery seems to be prepared to
output constants recursively and it's just a matter of
appropriately defering or not defering output.

This also has the advantage of not outputting .string for
optimized away local aggregate initializers containing string
references.

2020-06-18  Richard Biener  <rguenther@suse.de>

	* varasm.c (assemble_variable): Make sure to not
	defer output when outputting addressed constants.
	(output_constant_def_contents): Likewise.
	(add_constant_to_table): Take and pass on whether to
	defer output.
	(output_addressed_constants): Likewise.
	(output_constant_def): Pass on whether to defer output
	to add_constant_to_table.
	(tree_output_constant_def): Defer output of constants.
This commit is contained in:
Richard Biener 2020-06-18 11:02:26 +02:00
parent da2b7c7f0a
commit 5553433d7b
1 changed files with 13 additions and 13 deletions

View File

@ -110,7 +110,7 @@ static void decode_addr_const (tree, class addr_const *);
static hashval_t const_hash_1 (const tree); static hashval_t const_hash_1 (const tree);
static int compare_constant (const tree, const tree); static int compare_constant (const tree, const tree);
static void output_constant_def_contents (rtx); static void output_constant_def_contents (rtx);
static void output_addressed_constants (tree); static void output_addressed_constants (tree, int);
static unsigned HOST_WIDE_INT output_constant (tree, unsigned HOST_WIDE_INT, static unsigned HOST_WIDE_INT output_constant (tree, unsigned HOST_WIDE_INT,
unsigned int, bool, bool); unsigned int, bool, bool);
static void globalize_decl (tree); static void globalize_decl (tree);
@ -2272,7 +2272,7 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
/* Output any data that we will need to use the address of. */ /* Output any data that we will need to use the address of. */
if (DECL_INITIAL (decl) && DECL_INITIAL (decl) != error_mark_node) if (DECL_INITIAL (decl) && DECL_INITIAL (decl) != error_mark_node)
output_addressed_constants (DECL_INITIAL (decl)); output_addressed_constants (DECL_INITIAL (decl), 0);
/* dbxout.c needs to know this. */ /* dbxout.c needs to know this. */
if (sect && (sect->common.flags & SECTION_CODE) != 0) if (sect && (sect->common.flags & SECTION_CODE) != 0)
@ -3426,11 +3426,11 @@ build_constant_desc (tree exp)
already have labels. */ already have labels. */
static constant_descriptor_tree * static constant_descriptor_tree *
add_constant_to_table (tree exp) add_constant_to_table (tree exp, int defer)
{ {
/* The hash table methods may call output_constant_def for addressed /* The hash table methods may call output_constant_def for addressed
constants, so handle them first. */ constants, so handle them first. */
output_addressed_constants (exp); output_addressed_constants (exp, defer);
/* Sanity check to catch recursive insertion. */ /* Sanity check to catch recursive insertion. */
static bool inserting; static bool inserting;
@ -3474,7 +3474,7 @@ add_constant_to_table (tree exp)
rtx rtx
output_constant_def (tree exp, int defer) output_constant_def (tree exp, int defer)
{ {
struct constant_descriptor_tree *desc = add_constant_to_table (exp); struct constant_descriptor_tree *desc = add_constant_to_table (exp, defer);
maybe_output_constant_def_contents (desc, defer); maybe_output_constant_def_contents (desc, defer);
return desc->rtl; return desc->rtl;
} }
@ -3544,7 +3544,7 @@ output_constant_def_contents (rtx symbol)
/* Make sure any other constants whose addresses appear in EXP /* Make sure any other constants whose addresses appear in EXP
are assigned label numbers. */ are assigned label numbers. */
output_addressed_constants (exp); output_addressed_constants (exp, 0);
/* We are no longer deferring this constant. */ /* We are no longer deferring this constant. */
TREE_ASM_WRITTEN (decl) = TREE_ASM_WRITTEN (exp) = 1; TREE_ASM_WRITTEN (decl) = TREE_ASM_WRITTEN (exp) = 1;
@ -3608,7 +3608,7 @@ lookup_constant_def (tree exp)
tree tree
tree_output_constant_def (tree exp) tree_output_constant_def (tree exp)
{ {
struct constant_descriptor_tree *desc = add_constant_to_table (exp); struct constant_descriptor_tree *desc = add_constant_to_table (exp, 1);
tree decl = SYMBOL_REF_DECL (XEXP (desc->rtl, 0)); tree decl = SYMBOL_REF_DECL (XEXP (desc->rtl, 0));
varpool_node::finalize_decl (decl); varpool_node::finalize_decl (decl);
return decl; return decl;
@ -4327,7 +4327,7 @@ compute_reloc_for_constant (tree exp)
Indicate whether an ADDR_EXPR has been encountered. */ Indicate whether an ADDR_EXPR has been encountered. */
static void static void
output_addressed_constants (tree exp) output_addressed_constants (tree exp, int defer)
{ {
tree tem; tree tem;
@ -4347,21 +4347,21 @@ output_addressed_constants (tree exp)
tem = DECL_INITIAL (tem); tem = DECL_INITIAL (tem);
if (CONSTANT_CLASS_P (tem) || TREE_CODE (tem) == CONSTRUCTOR) if (CONSTANT_CLASS_P (tem) || TREE_CODE (tem) == CONSTRUCTOR)
output_constant_def (tem, 0); output_constant_def (tem, defer);
if (TREE_CODE (tem) == MEM_REF) if (TREE_CODE (tem) == MEM_REF)
output_addressed_constants (TREE_OPERAND (tem, 0)); output_addressed_constants (TREE_OPERAND (tem, 0), defer);
break; break;
case PLUS_EXPR: case PLUS_EXPR:
case POINTER_PLUS_EXPR: case POINTER_PLUS_EXPR:
case MINUS_EXPR: case MINUS_EXPR:
output_addressed_constants (TREE_OPERAND (exp, 1)); output_addressed_constants (TREE_OPERAND (exp, 1), defer);
gcc_fallthrough (); gcc_fallthrough ();
CASE_CONVERT: CASE_CONVERT:
case VIEW_CONVERT_EXPR: case VIEW_CONVERT_EXPR:
output_addressed_constants (TREE_OPERAND (exp, 0)); output_addressed_constants (TREE_OPERAND (exp, 0), defer);
break; break;
case CONSTRUCTOR: case CONSTRUCTOR:
@ -4369,7 +4369,7 @@ output_addressed_constants (tree exp)
unsigned HOST_WIDE_INT idx; unsigned HOST_WIDE_INT idx;
FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, tem) FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, tem)
if (tem != 0) if (tem != 0)
output_addressed_constants (tem); output_addressed_constants (tem, defer);
} }
break; break;