rtl.h (STRING_POOL_ADDRESS_P): Rename to DEFERRED_CONSTANT_P.

* rtl.h (STRING_POOL_ADDRESS_P): Rename to DEFERRED_CONSTANT_P.
	* varasm.c (struct varasm_status): Add deferred_constants field.
	(n_deferred_strings): Delete variable.
	(n_deferred_constants): New #define.
	(struct constant_descriptor_tree): Kill next and label fields.
	(const_hash_table, MAX_HASH_TABLE): Delete.
	(const_desc_htab): New static variable.
	(const_hash): Rename const_desc_hash, and make it fit the
	hashtab.h interface.
	(const_desc_eq): New.
	(const_hash_1, compare_constant): Const-ify arguments.
	(build_constant_desc): Set DEFERRED_CONSTANT_P on all new
	SYMBOL_REFs.  Clarify comments.  Don't set desc->label.
	(output_constant_def): Do the lookup/insert using the
	hashtab.h interface.  Don't muck with n_deferred_constants or
	DEFERRED_CONSTANT_P here.
	Always call maybe_output_constant_def_contents.
	(maybe_output_constant_def_contents): Take a pointer to the
	descriptor, not the EXP and RTL separately.  Return
	immediately if this constant is not deferred.  Defer output of
	everything, except writable string constants.  Update
	n_deferred_constants here.
	(output_constant_def_contents): Now takes just one argument,
	an rtx.  Clear DEFERRED_CONSTANT_P here.
	(mark_constant_pool): Update for rename of n_deferred_strings.
	(mark_constant): Don't clear DEFERRED_CONSTANT_P here.

	(init_varasm_status): Clear p->deferred_constants.
	(init_varasm_once): Call htab_create_ggc for const_desc_htab.

	* gcc.dg/const-elim-1.c, gcc.dg/const-elim-2.c: New testcases.

From-SVN: r66505
This commit is contained in:
Zack Weinberg 2003-05-05 21:57:54 +00:00
parent 68ef8841db
commit 10b6a27401
6 changed files with 208 additions and 99 deletions

View File

@ -1,3 +1,35 @@
2003-05-05 Zack Weinberg <zack@codesourcery.com>
* rtl.h (STRING_POOL_ADDRESS_P): Rename to DEFERRED_CONSTANT_P.
* varasm.c (struct varasm_status): Add deferred_constants field.
(n_deferred_strings): Delete variable.
(n_deferred_constants): New #define.
(struct constant_descriptor_tree): Kill next and label fields.
(const_hash_table, MAX_HASH_TABLE): Delete.
(const_desc_htab): New static variable.
(const_hash): Rename const_desc_hash, and make it fit the
hashtab.h interface.
(const_desc_eq): New.
(const_hash_1, compare_constant): Const-ify arguments.
(build_constant_desc): Set DEFERRED_CONSTANT_P on all new
SYMBOL_REFs. Clarify comments. Don't set desc->label.
(output_constant_def): Do the lookup/insert using the
hashtab.h interface. Don't muck with n_deferred_constants or
DEFERRED_CONSTANT_P here.
Always call maybe_output_constant_def_contents.
(maybe_output_constant_def_contents): Take a pointer to the
descriptor, not the EXP and RTL separately. Return
immediately if this constant is not deferred. Defer output of
everything, except writable string constants. Update
n_deferred_constants here.
(output_constant_def_contents): Now takes just one argument,
an rtx. Clear DEFERRED_CONSTANT_P here.
(mark_constant_pool): Update for rename of n_deferred_strings.
(mark_constant): Don't clear DEFERRED_CONSTANT_P here.
(init_varasm_status): Clear p->deferred_constants.
(init_varasm_once): Call htab_create_ggc for const_desc_htab.
2003-05-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* builtins.c (expand_builtin_stpcpy): Only expand when the length
@ -5,9 +37,9 @@
2003-05-05 Aldy Hernandez <aldyh@redhat.com>
* testsuite/gcc.c-torture/compile/simd-6.c: New.
* testsuite/gcc.c-torture/compile/simd-6.c: New.
* c-typeck.c (digest_init): Handle arrays of vector constants.
* c-typeck.c (digest_init): Handle arrays of vector constants.
2003-05-05 Jakub Jelinek <jakub@redhat.com>
@ -19,17 +51,17 @@
2003-05-05 Aldy Hernandez <aldyh@redhat.com>
* testsuite/gcc.dg/20030505.c: New.
* testsuite/gcc.dg/20030505.c: New.
* c-typeck.c (convert_for_assignment): Opaque pointers can
interconvert.
* c-typeck.c (convert_for_assignment): Opaque pointers can
interconvert.
* config/rs6000/rs6000.c: New global opaque_p_V2SI_type_node.
(rs6000_init_builtins): Initialize opaque_p_V2SI_type_node.
(spe_init_builtins): Rename all pv2si_type_node to
opaque_p_V2SI_type_node.
Remove declaration of pv2si_type_node.
(is_ev64_opaque_type): Accept opaque pointers.
* config/rs6000/rs6000.c: New global opaque_p_V2SI_type_node.
(rs6000_init_builtins): Initialize opaque_p_V2SI_type_node.
(spe_init_builtins): Rename all pv2si_type_node to
opaque_p_V2SI_type_node.
Remove declaration of pv2si_type_node.
(is_ev64_opaque_type): Accept opaque pointers.
2003-05-05 Geoffrey Keating <geoffk@apple.com>
@ -40,27 +72,27 @@
(rs6000_generate_compare): Use flag_finite_math_only.
(rs6000_emit_cmove): Handle UNLE. Support UNEQ under -ffast-math.
Use HONOR_* rather than flag_unsafe_math_optimizations. Correct
UNGE and GT cases. Handle UNEQ and LTGT when ! HONOR_NANS.
UNGE and GT cases. Handle UNEQ and LTGT when ! HONOR_NANS.
* toplev.c (check_global_declarations): Suppress not-used warning
for volatile variables.
2003-05-05 Olivier Hainque <hainque@act-europe.fr>
* expr.c (expand_expr, case BIT_FIELD_REF): Refine the test forcing
usage of bitfield instructions for mode1 != BLKmode, only ignoring
SLOW_UNALIGNED_ACCESS if the field is not byte aligned.
(store_field): Likewise.
* expr.c (expand_expr, case BIT_FIELD_REF): Refine the test forcing
usage of bitfield instructions for mode1 != BLKmode, only ignoring
SLOW_UNALIGNED_ACCESS if the field is not byte aligned.
(store_field): Likewise.
2003-05-05 Aldy Hernandez <aldyh@redhat.com>
* config/rs6000/rs6000.c (rs6000_expand_binop_builtin): Add
evsubifw to builtins accepting 5-bit unsigned constants.
(easy_vector_constant): Return if V1DImode. Fix typo.
* config/rs6000/rs6000.c (rs6000_expand_binop_builtin): Add
evsubifw to builtins accepting 5-bit unsigned constants.
(easy_vector_constant): Return if V1DImode. Fix typo.
2003-05-05 Aldy Hernandez <aldyh@redhat.com>
* config/rs6000/spe.h: Revert licensing change from last patch.
* config/rs6000/spe.h: Revert licensing change from last patch.
2003-05-05 DJ Delorie <dj@redhat.com>
@ -77,7 +109,7 @@
2003-05-05 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
* libgcov.c (__gcov_merge_add): Do not use gcov_type when inhibit_libc
is defined.
is defined.
2003-05-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>

View File

@ -1234,10 +1234,11 @@ do { \
#define CONSTANT_POOL_ADDRESS_P(RTX) \
(RTL_FLAG_CHECK1("CONSTANT_POOL_ADDRESS_P", (RTX), SYMBOL_REF)->unchanging)
/* 1 if RTX is a symbol_ref that addresses this function's string constant
pool */
#define STRING_POOL_ADDRESS_P(RTX) \
(RTL_FLAG_CHECK1("STRING_POOL_ADDRESS_P", (RTX), SYMBOL_REF)->frame_related)
/* 1 if RTX is a symbol_ref that addresses a value in the file's constant
pool which has not yet been output. This information is private to
varasm.c. */
#define DEFERRED_CONSTANT_P(RTX) \
(RTL_FLAG_CHECK1("DEFERRED_CONSTANT_P", (RTX), SYMBOL_REF)->frame_related)
/* Used if RTX is a symbol_ref, for machine-specific purposes. */
#define SYMBOL_REF_FLAG(RTX) \

View File

@ -1,3 +1,7 @@
2003-05-05 Zack Weinberg <zack@codesourcery.com>
* gcc.dg/const-elim-1.c, gcc.dg/const-elim-2.c: New testcases.
2003-05-05 Jakub Jelinek <jakub@redhat.com>
* gcc.c-torture/execute/string-opt-18.c (main): Add 3 new tests.

View File

@ -0,0 +1,48 @@
/* Verify that constants in memory, referenced only by dead code,
are not emitted to the object file.
FIXME: Not presently possible to apply -pedantic to code with
complex constants in it. The __extension__ should shut up the
warning but doesn't. (Hard to fix -- the lexer is not aware of
the parser's state.) */
/* { dg-do compile } */
/* { dg-options "-O2 -std=c99" } */
/* { dg-final { scan-assembler-not "LC" } } */
#define I (__extension__ 1.0iF)
struct S { int a; double b[2]; void *c; };
extern void use_str(const char *);
extern void use_S(const struct S *);
extern void use_cplx(__complex__ double);
static inline int
returns_23(void) { return 23; }
void
test1(void)
{
if (returns_23() == 23)
return;
use_str("waltz, nymph, for quick jigs vex bud");
use_S(&(const struct S){12, {3.1415, 2.1828}, 0 });
use_cplx(3.1415 + 2.1828*I);
}
void
test2(void)
{
const char *str = "pack my box with five dozen liquor jugs";
const struct S S = { 23, { 1.414, 1.618 }, 0 };
const __complex__ double cplx = 1.414 + 1.618*I;
if (returns_23() == 23)
return;
use_str(str);
use_S(&S);
use_cplx(cplx);
}

View File

@ -0,0 +1,10 @@
/* The string constant in this test case should be emitted exactly once. */
/* { dg-do compile } */
/* { dg-options "-O2" } */
/* { dg-final { scan-assembler-times "hi there" 1 } } */
static inline int returns_23() { return 23; }
const char *test1(void) { if (returns_23()) return 0; return "hi there"; }
const char *test2(void) { return "hi there"; }
const char *test3(void) { return "hi there"; }

View File

@ -96,6 +96,10 @@ struct varasm_status GTY(())
/* Current offset in constant pool (does not include any machine-specific
header). */
HOST_WIDE_INT x_pool_offset;
/* Number of tree-constants deferred during the expansion of this
function. */
unsigned int deferred_constants;
};
#define const_rtx_hash_table (cfun->varasm->x_const_rtx_hash_table)
@ -103,6 +107,7 @@ struct varasm_status GTY(())
#define first_pool (cfun->varasm->x_first_pool)
#define last_pool (cfun->varasm->x_last_pool)
#define pool_offset (cfun->varasm->x_pool_offset)
#define n_deferred_constants (cfun->varasm->deferred_constants)
/* Number for making the label on the next
constant that is stored in memory. */
@ -138,12 +143,12 @@ static HOST_WIDE_INT const_alias_set;
static const char *strip_reg_name PARAMS ((const char *));
static int contains_pointers_p PARAMS ((tree));
static void decode_addr_const PARAMS ((tree, struct addr_const *));
static unsigned int const_hash PARAMS ((tree));
static unsigned int const_hash_1 PARAMS ((tree));
static int compare_constant PARAMS ((tree, tree));
static hashval_t const_desc_hash PARAMS ((const void *));
static int const_desc_eq PARAMS ((const void *, const void *));
static hashval_t const_hash_1 PARAMS ((const tree));
static int compare_constant PARAMS ((const tree, const tree));
static tree copy_constant PARAMS ((tree));
static void maybe_output_constant_def_contents PARAMS ((tree, rtx, int));
static void output_constant_def_contents PARAMS ((tree, const char *));
static void output_constant_def_contents PARAMS ((rtx));
static void decode_rtx_const PARAMS ((enum machine_mode, rtx,
struct rtx_const *));
static unsigned int const_hash_rtx PARAMS ((enum machine_mode, rtx));
@ -2143,12 +2148,6 @@ struct rtx_const GTY(())
struct constant_descriptor_tree GTY(())
{
/* More constant_descriptors with the same hash code. */
struct constant_descriptor_tree *next;
/* The label of the constant. */
const char *label;
/* A MEM for the constant. */
rtx rtl;
@ -2156,28 +2155,28 @@ struct constant_descriptor_tree GTY(())
tree value;
};
#define MAX_HASH_TABLE 1009
static GTY(()) struct constant_descriptor_tree *
const_hash_table[MAX_HASH_TABLE];
static GTY((param_is (struct constant_descriptor_tree)))
htab_t const_desc_htab;
static struct constant_descriptor_tree * build_constant_desc PARAMS ((tree));
static unsigned int n_deferred_strings = 0;
static void maybe_output_constant_def_contents
PARAMS ((struct constant_descriptor_tree *, int));
/* Compute a hash code for a constant expression. */
static unsigned int
const_hash (exp)
tree exp;
static hashval_t
const_desc_hash (ptr)
const void *ptr;
{
return const_hash_1 (exp) % MAX_HASH_TABLE;
return const_hash_1 (((struct constant_descriptor_tree *)ptr)->value);
}
static unsigned int
static hashval_t
const_hash_1 (exp)
tree exp;
const tree exp;
{
const char *p;
unsigned int hi;
hashval_t hi;
int len, i;
enum tree_code code = TREE_CODE (exp);
@ -2198,7 +2197,6 @@ const_hash_1 (exp)
p = TREE_STRING_POINTER (exp);
len = TREE_STRING_LENGTH (exp);
break;
case COMPLEX_CST:
return (const_hash_1 (TREE_REALPART (exp)) * 5
+ const_hash_1 (TREE_IMAGPART (exp)));
@ -2272,13 +2270,23 @@ const_hash_1 (exp)
return hi;
}
/* Wrapper of compare_constant, for the htab interface. */
static int
const_desc_eq (p1, p2)
const void *p1;
const void *p2;
{
return compare_constant (((struct constant_descriptor_tree *)p1)->value,
((struct constant_descriptor_tree *)p2)->value);
}
/* Compare t1 and t2, and return 1 only if they are known to result in
the same bit pattern on output. */
static int
compare_constant (t1, t2)
tree t1;
tree t2;
const tree t1;
const tree t2;
{
enum tree_code typecode;
@ -2531,11 +2539,18 @@ build_constant_desc (exp)
/* Set flags or add text to the name to record information, such as
that it is a local symbol. If the name is changed, the macro
ASM_OUTPUT_LABELREF will have to know how to strip this
information. */
information. This call might invalidate our local variable
SYMBOL; we can't use it afterward. */
(*targetm.encode_section_info) (exp, rtl, true);
/* Descriptors start out deferred; this simplifies the logic in
maybe_output_constant_def_contents. However, we do not bump
n_deferred_constants here, because we don't know if we're inside
a function and have an n_deferred_constants to bump. */
DEFERRED_CONSTANT_P (XEXP (rtl, 0)) = 1;
desc->rtl = rtl;
desc->label = XSTR (XEXP (desc->rtl, 0), 0);
return desc;
}
@ -2548,8 +2563,8 @@ build_constant_desc (exp)
Otherwise, output such a constant in memory
and generate an rtx for it.
If DEFER is nonzero, the output of string constants can be deferred
and output only if referenced in the function after all optimizations.
If DEFER is nonzero, this constant can be deferred and output only
if referenced in the function after all optimizations.
The const_hash_table records which constants already have label strings. */
@ -2558,70 +2573,64 @@ output_constant_def (exp, defer)
tree exp;
int defer;
{
int hash;
struct constant_descriptor_tree *desc;
struct constant_descriptor_tree key;
void **loc;
/* Compute hash code of EXP. Search the descriptors for that hash code
to see if any of them describes EXP. If yes, the descriptor records
the label number already assigned. */
hash = const_hash (exp);
for (desc = const_hash_table[hash]; desc; desc = desc->next)
if (compare_constant (exp, desc->value))
break;
/* Look up EXP in the table of constant descriptors. If we didn't find
it, create a new one. */
key.value = exp;
loc = htab_find_slot (const_desc_htab, &key, INSERT);
desc = *loc;
if (desc == 0)
{
desc = build_constant_desc (exp);
desc->next = const_hash_table[hash];
const_hash_table[hash] = desc;
maybe_output_constant_def_contents (exp, desc->rtl, defer);
}
else if (!defer && STRING_POOL_ADDRESS_P (XEXP (desc->rtl, 0)))
{
/* This string is currently deferred but we need to output it
now; mark it no longer deferred. */
STRING_POOL_ADDRESS_P (XEXP (desc->rtl, 0)) = 0;
n_deferred_strings--;
maybe_output_constant_def_contents (exp, desc->rtl, 0);
*loc = desc;
}
maybe_output_constant_def_contents (desc, defer);
return desc->rtl;
}
/* Subroutine of output_constant_def:
Decide whether or not to defer the output of EXP, which can be
accesed through rtl RTL, and either do the output or record EXP in
the table of deferred strings. */
/* Subroutine of output_constant_def: Decide whether or not we need to
output the constant DESC now, and if so, do it. */
static void
maybe_output_constant_def_contents (exp, rtl, defer)
tree exp;
rtx rtl;
maybe_output_constant_def_contents (desc, defer)
struct constant_descriptor_tree *desc;
int defer;
{
rtx symbol = XEXP (desc->rtl, 0);
if (flag_syntax_only)
return;
/* Is this a string constant that can be deferred? */
if (defer && TREE_CODE (exp) == STRING_CST && !flag_writable_strings)
if (!DEFERRED_CONSTANT_P (symbol))
/* Already output; don't do it again. */
return;
/* The only constants that cannot safely be deferred, assuming the
context allows it, are strings under flag_writable_strings. */
if (defer && (TREE_CODE (desc->value) != STRING_CST
|| !flag_writable_strings))
{
STRING_POOL_ADDRESS_P (XEXP (rtl, 0)) = 1;
n_deferred_strings++;
if (cfun)
n_deferred_constants++;
return;
}
output_constant_def_contents (exp, XSTR (XEXP (rtl, 0), 0));
output_constant_def_contents (symbol);
}
/* Now output assembler code to define the label for EXP,
and follow it with the data of EXP. */
/* We must output the constant data referred to by SYMBOL; do so. */
static void
output_constant_def_contents (exp, label)
tree exp;
const char *label;
output_constant_def_contents (symbol)
rtx symbol;
{
tree exp = SYMBOL_REF_DECL (symbol);
const char *label = XSTR (symbol, 0);
/* Make sure any other constants whose addresses appear in EXP
are assigned label numbers. */
int reloc = output_addressed_constants (exp);
@ -2632,6 +2641,9 @@ output_constant_def_contents (exp, label)
align = CONSTANT_ALIGNMENT (exp, align);
#endif
/* We are no longer deferring this constant. */
DEFERRED_CONSTANT_P (symbol) = 0;
if (IN_NAMED_SECTION (exp))
named_section (exp, NULL, reloc);
else
@ -2715,6 +2727,7 @@ init_varasm_status (f)
p->x_first_pool = p->x_last_pool = 0;
p->x_pool_offset = 0;
p->deferred_constants = 0;
}
@ -3329,8 +3342,8 @@ output_constant_pool (fnname, fndecl)
}
/* Look through the instructions for this function, and mark all the
entries in the constant pool which are actually being used.
Emit used deferred strings. */
entries in the constant pool which are actually being used. Emit
deferred constants which have indeed been used. */
static void
mark_constant_pool ()
@ -3339,7 +3352,7 @@ mark_constant_pool ()
rtx link;
struct pool_constant *pool;
if (first_pool == 0 && n_deferred_strings == 0)
if (first_pool == 0 && n_deferred_constants == 0)
return;
for (pool = first_pool; pool; pool = pool->next)
@ -3453,11 +3466,10 @@ mark_constant (current_rtx, data)
else
return -1;
}
else if (STRING_POOL_ADDRESS_P (x))
else if (DEFERRED_CONSTANT_P (x))
{
STRING_POOL_ADDRESS_P (x) = 0;
n_deferred_strings--;
output_constant_def_contents (SYMBOL_REF_DECL (x), XSTR (x, 0));
n_deferred_constants--;
output_constant_def_contents (x);
}
}
return 0;
@ -4544,6 +4556,8 @@ init_varasm_once ()
{
in_named_htab = htab_create_ggc (31, in_named_entry_hash,
in_named_entry_eq, NULL);
const_desc_htab = htab_create_ggc (1009, const_desc_hash,
const_desc_eq, NULL);
const_alias_set = new_alias_set ();
}