summaryrefslogtreecommitdiff
path: root/gcc/varasm.c
diff options
context:
space:
mode:
authorkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>2001-11-03 16:28:33 +0000
committerkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>2001-11-03 16:28:33 +0000
commitebde4c17a4d1275843066100b6616ed64b00baa3 (patch)
treee4c4eeed512573bd6eb976e608911eb4c0cfb6f1 /gcc/varasm.c
parent606a59ec0bef92bc475b34c2d782cdbb3edc4cb8 (diff)
downloadgcc-ebde4c17a4d1275843066100b6616ed64b00baa3.tar.gz
* cselib.c (cselib_subst_to_values, case CONST_DOUBLE): Remove
reference to CONST_DOUBLE_MEM in comment. * emit-rtl.c (gen_rtx_CONST_DOUBLE): Remove one operand. (gen_rtx, case CONST_DOUBLE): Call it with one less operand. (init_emit_once): Don't clear CONST_DOUBLE_MEM. * function.c (pop_function_context_from): Don't call restore_varasm_status. * function.h (restore_varasm_status): Delete declaration. * gengenrtl.c (CONST_DOUBLE_FORMAT): Delete CONST_DOUBLE_MEM slot. * rtl.c: Likewise. * rtl.def (CONST_DOUBLE): Update comment. * rtl.h (CONST_DOUBLE_HIGH, CONST_DOUBLE_LOW): Update operand number. (CONST_DOUBLE_CHAIN): Likewise. (CONST_DOUBLE_MEM): Delete. (gen_rtx_CONST_DOUBLE): Update parameters. * varasm.c (struct varasm_status): x_pool_offset now HOST_WIDE_INT. Remove reference to CONST_DOUBLE_MEM. (const_alias_set): New variable. (immed_double_const): Change call to gen_rtx_CONST_DOUBLE. (immed_real_const_1): Adjust tests for 0, 1, and 2. Don't set CONST_DOUBLE_MEM. (clear_const_double_mem): Don't do anything with const_tiny_rtx. (output_constant_def): Don't look at TREE_CST_RTL if INTEGER_CST. Put constant in const_alias_set. (struct pool_constant): ALIGN now unsigned. OFFSET now HOST_WIDE_INT. Delete LABEL. (restore_varasm_status): Deleted. (mark_pool_constant): Mark desc->rtl. (force_const_mem): Rework to store rtl in hash table, not CONST_DOUBLE_MEM. Put constant in const_alias_set. (find_pool_constant): Check desc->rtl. (mark_constants, mark_constant): Don't special-case CONST_DOUBLE. (init_varasm_once): Initialize const_alias_set. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@46736 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/varasm.c')
-rw-r--r--gcc/varasm.c273
1 files changed, 105 insertions, 168 deletions
diff --git a/gcc/varasm.c b/gcc/varasm.c
index c42ad384032..ebdac3bced3 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -96,13 +96,10 @@ struct varasm_status
/* Current offset in constant pool (does not include any machine-specific
header). */
- int x_pool_offset;
+ HOST_WIDE_INT x_pool_offset;
/* Chain of all CONST_DOUBLE rtx's constructed for the current function.
- They are chained through the CONST_DOUBLE_CHAIN.
- A CONST_DOUBLE rtx has CONST_DOUBLE_MEM != cc0_rtx iff it is on this chain.
- In that case, CONST_DOUBLE_MEM is either a MEM,
- or const0_rtx if no MEM has been made for this CONST_DOUBLE yet. */
+ They are chained through the CONST_DOUBLE_CHAIN. */
rtx x_const_double_chain;
};
@@ -135,6 +132,15 @@ int size_directive_output;
tree last_assemble_variable_decl;
+/* RTX_UNCHANGING_P in a MEM can mean it is stored into, for initialization.
+ So giving constant the alias set for the type will allow such
+ initializations to appear to conflict with the load of the constant. We
+ avoid this by giving all constants an alias set for just constants.
+ Since there will be no stores to that a alias set, nothing will ever
+ conflict with them. */
+
+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 assemble_real_1 PARAMS ((PTR));
@@ -2249,7 +2255,7 @@ immed_double_const (i0, i1, mode)
return r;
/* No; make a new one and add it to the chain. */
- r = gen_rtx_CONST_DOUBLE (mode, const0_rtx, i0, i1);
+ r = gen_rtx_CONST_DOUBLE (mode, i0, i1);
/* Don't touch const_double_chain if not inside any function. */
if (current_function_decl != 0)
@@ -2277,16 +2283,16 @@ immed_real_const_1 (d, mode)
u.d = d;
- /* Detect special cases. */
- if (REAL_VALUES_IDENTICAL (dconst0, d))
+ /* Detect special cases. Check for NaN first, because some ports
+ (specifically the i386) do not emit correct ieee-fp code by default, and
+ thus will generate a core dump here if we pass a NaN to REAL_VALUES_EQUAL
+ and if REAL_VALUES_EQUAL does a floating point comparison. */
+ if (! REAL_VALUE_ISNAN (d) && REAL_VALUES_IDENTICAL (dconst0, d))
return CONST0_RTX (mode);
-
- /* Check for NaN first, because some ports (specifically the i386) do not
- emit correct ieee-fp code by default, and thus will generate a core
- dump here if we pass a NaN to REAL_VALUES_EQUAL and if REAL_VALUES_EQUAL
- does a floating point comparison. */
else if (! REAL_VALUE_ISNAN (d) && REAL_VALUES_EQUAL (dconst1, d))
return CONST1_RTX (mode);
+ else if (! REAL_VALUE_ISNAN (d) && REAL_VALUES_EQUAL (dconst2, d))
+ return CONST2_RTX (mode);
if (sizeof u == sizeof (HOST_WIDE_INT))
return immed_double_const (u.i[0], 0, mode);
@@ -2325,12 +2331,6 @@ immed_real_const_1 (d, mode)
else
CONST_DOUBLE_CHAIN (r) = NULL_RTX;
- /* Store const0_rtx in CONST_DOUBLE_MEM since this CONST_DOUBLE is on the
- chain, but has not been allocated memory. Actual use of CONST_DOUBLE_MEM
- is only through force_const_mem. */
-
- CONST_DOUBLE_MEM (r) = const0_rtx;
-
return r;
}
@@ -2352,25 +2352,13 @@ void
clear_const_double_mem ()
{
rtx r, next;
- enum machine_mode mode;
- int i;
for (r = const_double_chain; r; r = next)
{
next = CONST_DOUBLE_CHAIN (r);
CONST_DOUBLE_CHAIN (r) = 0;
- CONST_DOUBLE_MEM (r) = cc0_rtx;
}
const_double_chain = 0;
-
- for (i = 0; i <= 2; i++)
- for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
- mode = GET_MODE_WIDER_MODE (mode))
- {
- r = const_tiny_rtx[i][(int) mode];
- CONST_DOUBLE_CHAIN (r) = 0;
- CONST_DOUBLE_MEM (r) = cc0_rtx;
- }
}
/* Given an expression EXP with a constant value,
@@ -3292,8 +3280,9 @@ output_constant_def (exp, defer)
int found = 1;
int after_function = 0;
int labelno = -1;
+ rtx rtl;
- if (TREE_CST_RTL (exp))
+ if (TREE_CODE (exp) != INTEGER_CST && TREE_CST_RTL (exp))
return TREE_CST_RTL (exp);
/* Make sure any other constants whose addresses appear in EXP
@@ -3328,16 +3317,21 @@ output_constant_def (exp, defer)
const_hash_table[hash] = desc;
/* We have a symbol name; construct the SYMBOL_REF and the MEM. */
- desc->rtl
+ rtl = desc->rtl
= gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)),
gen_rtx_SYMBOL_REF (Pmode, desc->label));
- set_mem_attributes (desc->rtl, exp, 1);
+ set_mem_attributes (rtl, exp, 1);
+ set_mem_alias_set (rtl, 0);
+ set_mem_alias_set (rtl, const_alias_set);
found = 0;
}
+ else
+ rtl = desc->rtl;
- TREE_CST_RTL (exp) = desc->rtl;
+ if (TREE_CODE (exp) != INTEGER_CST)
+ TREE_CST_RTL (exp) = rtl;
/* Optionally set flags or add text to the name to record information
such as that it is a function name. If the name is changed, the macro
@@ -3348,7 +3342,7 @@ output_constant_def (exp, defer)
if (! found)
{
ENCODE_SECTION_INFO (exp);
- desc->rtl = TREE_CST_RTL (exp);
+ desc->rtl = rtl;
desc->label = XSTR (XEXP (desc->rtl, 0), 0);
}
#endif
@@ -3360,7 +3354,7 @@ output_constant_def (exp, defer)
#endif
if (found
- && STRING_POOL_ADDRESS_P (XEXP (desc->rtl, 0))
+ && STRING_POOL_ADDRESS_P (XEXP (rtl, 0))
&& (!defer || defer_addressed_constants_flag || after_function))
{
defstr = (struct deferred_string **)
@@ -3372,7 +3366,7 @@ output_constant_def (exp, defer)
remove it from deferred string hash table. */
found = 0;
labelno = (*defstr)->labelno;
- STRING_POOL_ADDRESS_P (XEXP (desc->rtl, 0)) = 0;
+ STRING_POOL_ADDRESS_P (XEXP (rtl, 0)) = 0;
htab_clear_slot (const_str_htab, (void **) defstr);
}
}
@@ -3383,8 +3377,9 @@ output_constant_def (exp, defer)
{
if (defer_addressed_constants_flag || after_function)
{
- struct deferred_constant *p;
- p = (struct deferred_constant *) xmalloc (sizeof (struct deferred_constant));
+ struct deferred_constant *p
+ = (struct deferred_constant *)
+ xmalloc (sizeof (struct deferred_constant));
p->exp = copy_constant (exp);
p->reloc = reloc;
@@ -3425,13 +3420,13 @@ output_constant_def (exp, defer)
p->label = desc->label;
p->labelno = labelno;
*defstr = p;
- STRING_POOL_ADDRESS_P (XEXP (desc->rtl, 0)) = 1;
+ STRING_POOL_ADDRESS_P (XEXP (rtl, 0)) = 1;
}
}
}
}
- return TREE_CST_RTL (exp);
+ return rtl;
}
/* Now output assembler code to define the label for EXP,
@@ -3494,12 +3489,11 @@ struct pool_constant
{
struct constant_descriptor *desc;
struct pool_constant *next, *next_sym;
- const char *label;
rtx constant;
enum machine_mode mode;
int labelno;
- int align;
- int offset;
+ unsigned int align;
+ HOST_WIDE_INT offset;
int mark;
};
@@ -3530,23 +3524,6 @@ init_varasm_status (f)
p->x_const_double_chain = 0;
}
-/* Nested functions diddle with our const_double_chain via
- clear_const_double_mem and const_tiny_rtx. Remove these
- entries from our const_double_chain. */
-
-void
-restore_varasm_status (f)
- struct function *f;
-{
- rtx *p = &f->varasm->x_const_double_chain;
-
- while (*p)
- if (CONST_DOUBLE_MEM (*p) == cc0_rtx)
- *p = CONST_DOUBLE_CHAIN (*p);
- else
- p = &CONST_DOUBLE_CHAIN (*p);
-}
-
/* Mark PC for GC. */
static void
@@ -3557,6 +3534,7 @@ mark_pool_constant (pc)
{
ggc_mark (pc);
ggc_mark_rtx (pc->constant);
+ ggc_mark_rtx (pc->desc->rtl);
pc = pc->next;
}
}
@@ -3590,19 +3568,22 @@ free_varasm_status (f)
/* Clear out the hash tables. */
for (i = 0; i < MAX_RTX_HASH_TABLE; ++i)
{
- struct constant_descriptor* cd;
+ struct constant_descriptor *cd;
cd = p->x_const_rtx_hash_table[i];
- while (cd) {
- struct constant_descriptor* next = cd->next;
- free (cd);
- cd = next;
- }
+ while (cd)
+ {
+ struct constant_descriptor *next = cd->next;
+
+ free (cd);
+ cd = next;
+ }
}
free (p->x_const_rtx_hash_table);
free (p->x_const_rtx_sym_hash_table);
free (p);
+
f->varasm = NULL;
}
@@ -3786,116 +3767,77 @@ force_const_mem (mode, x)
int hash;
struct constant_descriptor *desc;
char label[256];
- const char *found = 0;
rtx def;
-
- /* If we want this CONST_DOUBLE in the same mode as it is in memory
- (this will always be true for floating CONST_DOUBLEs that have been
- placed in memory, but not for VOIDmode (integer) CONST_DOUBLEs),
- use the previous copy. Otherwise, make a new one. Note that in
- the unlikely event that this same CONST_DOUBLE is used in two different
- modes in an alternating fashion, we will allocate a lot of different
- memory locations, but this should be extremely rare. */
-
- if (GET_CODE (x) == CONST_DOUBLE
- && GET_CODE (CONST_DOUBLE_MEM (x)) == MEM
- && GET_MODE (CONST_DOUBLE_MEM (x)) == mode)
- return CONST_DOUBLE_MEM (x);
+ struct pool_constant *pool;
+ unsigned int align;
/* Compute hash code of X. Search the descriptors for that hash code
- to see if any of them describes X. If yes, the descriptor records
- the label number already assigned. */
-
+ to see if any of them describes X. If yes, we have an rtx to use. */
hash = const_hash_rtx (mode, x);
-
for (desc = const_rtx_hash_table[hash]; desc; desc = desc->next)
if (compare_constant_rtx (mode, x, desc))
- {
- found = desc->label;
- break;
- }
-
- if (found == 0)
- {
- struct pool_constant *pool;
- int align;
-
- /* No constant equal to X is known to have been output.
- Make a constant descriptor to enter X in the hash table.
- Assign the label number and record it in the descriptor for
- future calls to this function to find. */
-
- desc = record_constant_rtx (mode, x);
- desc->next = const_rtx_hash_table[hash];
- const_rtx_hash_table[hash] = desc;
-
- /* Align the location counter as required by EXP's data type. */
- align = GET_MODE_ALIGNMENT (mode == VOIDmode ? word_mode : mode);
+ return desc->rtl;
+
+ /* No constant equal to X is known to have been output.
+ Make a constant descriptor to enter X in the hash table
+ and make a MEM for it. */
+ desc = record_constant_rtx (mode, x);
+ desc->next = const_rtx_hash_table[hash];
+ const_rtx_hash_table[hash] = desc;
+
+ /* Align the location counter as required by EXP's data type. */
+ align = GET_MODE_ALIGNMENT (mode == VOIDmode ? word_mode : mode);
#ifdef CONSTANT_ALIGNMENT
- align = CONSTANT_ALIGNMENT (make_tree (type_for_mode (mode, 0), x),
- align);
+ align = CONSTANT_ALIGNMENT (make_tree (type_for_mode (mode, 0), x), align);
#endif
- pool_offset += (align / BITS_PER_UNIT) - 1;
- pool_offset &= ~ ((align / BITS_PER_UNIT) - 1);
-
- if (GET_CODE (x) == LABEL_REF)
- LABEL_PRESERVE_P (XEXP (x, 0)) = 1;
-
- /* Allocate a pool constant descriptor, fill it in, and chain it in. */
-
- pool = (struct pool_constant *) ggc_alloc (sizeof (struct pool_constant));
- pool->desc = desc;
- pool->constant = x;
- pool->mode = mode;
- pool->labelno = const_labelno;
- pool->align = align;
- pool->offset = pool_offset;
- pool->mark = 1;
- pool->next = 0;
-
- if (last_pool == 0)
- first_pool = pool;
- else
- last_pool->next = pool;
-
- last_pool = pool;
- pool_offset += GET_MODE_SIZE (mode);
-
- /* Create a string containing the label name, in LABEL. */
- ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
-
- ++const_labelno;
+ pool_offset += (align / BITS_PER_UNIT) - 1;
+ pool_offset &= ~ ((align / BITS_PER_UNIT) - 1);
+
+ if (GET_CODE (x) == LABEL_REF)
+ LABEL_PRESERVE_P (XEXP (x, 0)) = 1;
+
+ /* Allocate a pool constant descriptor, fill it in, and chain it in. */
+ pool = (struct pool_constant *) ggc_alloc (sizeof (struct pool_constant));
+ pool->desc = desc;
+ pool->constant = x;
+ pool->mode = mode;
+ pool->labelno = const_labelno;
+ pool->align = align;
+ pool->offset = pool_offset;
+ pool->mark = 1;
+ pool->next = 0;
+
+ if (last_pool == 0)
+ first_pool = pool;
+ else
+ last_pool->next = pool;
+
+ last_pool = pool;
+ pool_offset += GET_MODE_SIZE (mode);
- desc->label = found = ggc_strdup (label);
+ /* Create a string containing the label name, in LABEL. */
+ ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
- /* Add label to symbol hash table. */
- hash = SYMHASH (found);
- pool->label = found;
- pool->next_sym = const_rtx_sym_hash_table[hash];
- const_rtx_sym_hash_table[hash] = pool;
- }
+ ++const_labelno;
- /* We have a symbol name; construct the SYMBOL_REF and the MEM. */
+ /* Construct the SYMBOL_REF and the MEM. */
- def = gen_rtx_MEM (mode, gen_rtx_SYMBOL_REF (Pmode, found));
+ pool->desc->rtl = def
+ = gen_rtx_MEM (mode, gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (label)));
+ set_mem_alias_set (def, const_alias_set);
set_mem_attributes (def, type_for_mode (mode, 0), 1);
RTX_UNCHANGING_P (def) = 1;
+ /* Add label to symbol hash table. */
+ hash = SYMHASH (XSTR (XEXP (def, 0), 0));
+ pool->next_sym = const_rtx_sym_hash_table[hash];
+ const_rtx_sym_hash_table[hash] = pool;
+
/* Mark the symbol_ref as belonging to this constants pool. */
CONSTANT_POOL_ADDRESS_P (XEXP (def, 0)) = 1;
current_function_uses_const_pool = 1;
- if (GET_CODE (x) == CONST_DOUBLE)
- {
- if (CONST_DOUBLE_MEM (x) == cc0_rtx)
- {
- CONST_DOUBLE_CHAIN (x) = const_double_chain;
- const_double_chain = x;
- }
- CONST_DOUBLE_MEM (x) = def;
- }
-
return def;
}
@@ -3912,7 +3854,7 @@ find_pool_constant (f, addr)
for (pool = f->varasm->x_const_rtx_sym_hash_table[SYMHASH (label)]; pool;
pool = pool->next_sym)
- if (pool->label == label)
+ if (XSTR (XEXP (pool->desc->rtl, 0), 0) == label)
return pool;
abort ();
@@ -4131,10 +4073,6 @@ mark_constants (x)
mark_constant (&x, NULL);
return;
}
- /* Never search inside a CONST_DOUBLE, because CONST_DOUBLE_MEM may be
- a MEM, but does not constitute a use of that MEM. */
- else if (GET_CODE (x) == CONST_DOUBLE)
- return;
/* Insns may appear inside a SEQUENCE. Only check the patterns of
insns, not any notes that may be attached. We don't want to mark
@@ -4182,7 +4120,7 @@ mark_constants (x)
/* Given a SYMBOL_REF CURRENT_RTX, mark it and all constants it refers
to as used. Emit referenced deferred strings. This function can
- be used with for_each_rtx () to mark all SYMBOL_REFs in an rtx. */
+ be used with for_each_rtx to mark all SYMBOL_REFs in an rtx. */
static int
mark_constant (current_rtx, data)
@@ -4193,10 +4131,7 @@ mark_constant (current_rtx, data)
if (x == NULL_RTX)
return 0;
- else if (GET_CODE(x) == CONST_DOUBLE)
- /* Never search inside a CONST_DOUBLE because CONST_DOUBLE_MEM may
- be a MEM but does not constitute a use of that MEM. */
- return -1;
+
else if (GET_CODE (x) == SYMBOL_REF)
{
if (CONSTANT_POOL_ADDRESS_P (x))
@@ -5185,6 +5120,8 @@ init_varasm_once ()
mark_const_hash_entry);
ggc_add_root (&const_str_htab, 1, sizeof const_str_htab,
mark_const_str_htab);
+
+ const_alias_set = new_alias_set ();
}
/* Select a set of attributes for section NAME based on the properties