Commit a4c6502a by Mark Mitchell Committed by Mark Mitchell

cse.c (dump_class): New function.

	* cse.c (dump_class): New function.
	(invalidate_memory): Fix typo in comment.
	* function.c (temp_slot): Add an alias set field.
	(assign_stack_temp): Only reuse slots if they will have the
	same alias set as before.
	(combine_temp_slots): Don't combine if -fstrict-aliasing;
	that's unsafe.
	* rtl.c (copy_rtx): Copy all the flags (in particular,
	MEM_SCALAR_P).

From-SVN: r25372
parent 44768aae
Mon Feb 22 13:33:47 1999 Mark Mitchell <mark@markmitchell.com>
* cse.c (dump_class): New function.
(invalidate_memory): Fix typo in comment.
* function.c (temp_slot): Add an alias set field.
(assign_stack_temp): Only reuse slots if they will have the
same alias set as before.
(combine_temp_slots): Don't combine if -fstrict-aliasing;
that's unsafe.
* rtl.c (copy_rtx): Copy all the flags (in particular,
MEM_SCALAR_P).
Mon Feb 22 14:13:23 1999 Vladimir N. Makarov <vmakarov@cygnus.com> Mon Feb 22 14:13:23 1999 Vladimir N. Makarov <vmakarov@cygnus.com>
* configure.in (i[34567]86-*-linux-gnu*, * configure.in (i[34567]86-*-linux-gnu*,
......
...@@ -663,9 +663,29 @@ static void cse_check_loop_start PROTO((rtx, rtx)); ...@@ -663,9 +663,29 @@ static void cse_check_loop_start PROTO((rtx, rtx));
static void cse_set_around_loop PROTO((rtx, rtx, rtx)); static void cse_set_around_loop PROTO((rtx, rtx, rtx));
static rtx cse_basic_block PROTO((rtx, rtx, struct branch_path *, int)); static rtx cse_basic_block PROTO((rtx, rtx, struct branch_path *, int));
static void count_reg_usage PROTO((rtx, int *, rtx, int)); static void count_reg_usage PROTO((rtx, int *, rtx, int));
static void dump_class PROTO((struct table_elt*));
extern int rtx_equal_function_value_matters; extern int rtx_equal_function_value_matters;
/* Dump the expressions in the equivalence class indicated by CLASSP.
This function is used only for debugging. */
void
dump_class (classp)
struct table_elt *classp;
{
struct table_elt *elt;
fprintf (stderr, "Equivalence chain for ");
print_rtl (stderr, classp->exp);
fprintf (stderr, ": \n");
for (elt = classp->first_same_value; elt; elt = elt->next_same_value)
{
print_rtl (stderr, elt->exp);
fprintf (stderr, "\n");
}
}
/* Return an estimate of the cost of computing rtx X. /* Return an estimate of the cost of computing rtx X.
One use is in cse, to decide which expression to keep in the hash table. One use is in cse, to decide which expression to keep in the hash table.
Another is in rtl generation, to pick the cheapest way to multiply. Another is in rtl generation, to pick the cheapest way to multiply.
...@@ -7821,7 +7841,7 @@ cse_insn (insn, libcall_insn) ...@@ -7821,7 +7841,7 @@ cse_insn (insn, libcall_insn)
prev_insn = insn; prev_insn = insn;
} }
/* Remove from the ahsh table all expressions that reference memory. */ /* Remove from the hash table all expressions that reference memory. */
static void static void
invalidate_memory () invalidate_memory ()
{ {
......
...@@ -394,6 +394,17 @@ struct temp_slot ...@@ -394,6 +394,17 @@ struct temp_slot
int align; int align;
/* The size, in units, of the slot. */ /* The size, in units, of the slot. */
HOST_WIDE_INT size; HOST_WIDE_INT size;
/* The alias set for the slot. If the alias set is zero, we don't
know anything about the alias set of the slot. We must only
reuse a slot if it is assigned an object of the same alias set.
Otherwise, the rest of the compiler may assume that the new use
of the slot cannot alias the old use of the slot, which is
false. If the slot has alias set zero, then we can't reuse the
slot at all, since we have no idea what alias set may have been
imposed on the memory. For example, if the stack slot is the
call frame for an inline functioned, we have no idea what alias
sets will be assigned to various pieces of the call frame. */
int alias_set;
/* The value of `sequence_rtl_expr' when this temporary is allocated. */ /* The value of `sequence_rtl_expr' when this temporary is allocated. */
tree rtl_expr; tree rtl_expr;
/* Non-zero if this temporary is currently in use. */ /* Non-zero if this temporary is currently in use. */
...@@ -875,7 +886,9 @@ assign_outer_stack_local (mode, size, align, function) ...@@ -875,7 +886,9 @@ assign_outer_stack_local (mode, size, align, function)
with this flag. KEEP is 2 if we allocate a longer term temporary, with this flag. KEEP is 2 if we allocate a longer term temporary,
whose lifetime is controlled by CLEANUP_POINT_EXPRs. KEEP is 3 whose lifetime is controlled by CLEANUP_POINT_EXPRs. KEEP is 3
if we are to allocate something at an inner level to be treated as if we are to allocate something at an inner level to be treated as
a variable in the block (e.g., a SAVE_EXPR). */ a variable in the block (e.g., a SAVE_EXPR).
TYPE is the type that will be used for the stack slot. */
static rtx static rtx
assign_stack_temp_for_type (mode, size, keep, type) assign_stack_temp_for_type (mode, size, keep, type)
...@@ -885,6 +898,7 @@ assign_stack_temp_for_type (mode, size, keep, type) ...@@ -885,6 +898,7 @@ assign_stack_temp_for_type (mode, size, keep, type)
tree type; tree type;
{ {
int align; int align;
int alias_set;
struct temp_slot *p, *best_p = 0; struct temp_slot *p, *best_p = 0;
/* If SIZE is -1 it means that somebody tried to allocate a temporary /* If SIZE is -1 it means that somebody tried to allocate a temporary
...@@ -892,6 +906,14 @@ assign_stack_temp_for_type (mode, size, keep, type) ...@@ -892,6 +906,14 @@ assign_stack_temp_for_type (mode, size, keep, type)
if (size == -1) if (size == -1)
abort (); abort ();
/* If we know the alias set for the memory that will be used, use
it. If there's no TYPE, then we don't know anything about the
alias set for the memory. */
if (type)
alias_set = get_alias_set (type);
else
alias_set = 0;
align = GET_MODE_ALIGNMENT (mode); align = GET_MODE_ALIGNMENT (mode);
if (mode == BLKmode) if (mode == BLKmode)
align = BIGGEST_ALIGNMENT; align = BIGGEST_ALIGNMENT;
...@@ -907,6 +929,8 @@ assign_stack_temp_for_type (mode, size, keep, type) ...@@ -907,6 +929,8 @@ assign_stack_temp_for_type (mode, size, keep, type)
for (p = temp_slots; p; p = p->next) for (p = temp_slots; p; p = p->next)
if (p->align >= align && p->size >= size && GET_MODE (p->slot) == mode if (p->align >= align && p->size >= size && GET_MODE (p->slot) == mode
&& ! p->in_use && ! p->in_use
&& (!flag_strict_aliasing
|| (alias_set && p->alias_set == alias_set))
&& (best_p == 0 || best_p->size > p->size && (best_p == 0 || best_p->size > p->size
|| (best_p->size == p->size && best_p->align > p->align))) || (best_p->size == p->size && best_p->align > p->align)))
{ {
...@@ -924,7 +948,11 @@ assign_stack_temp_for_type (mode, size, keep, type) ...@@ -924,7 +948,11 @@ assign_stack_temp_for_type (mode, size, keep, type)
/* If there are enough aligned bytes left over, make them into a new /* If there are enough aligned bytes left over, make them into a new
temp_slot so that the extra bytes don't get wasted. Do this only temp_slot so that the extra bytes don't get wasted. Do this only
for BLKmode slots, so that we can be sure of the alignment. */ for BLKmode slots, so that we can be sure of the alignment. */
if (GET_MODE (best_p->slot) == BLKmode) if (GET_MODE (best_p->slot) == BLKmode
/* We can't split slots if -fstrict-aliasing because the
information about the alias set for the new slot will be
lost. */
&& !flag_strict_aliasing)
{ {
int alignment = best_p->align / BITS_PER_UNIT; int alignment = best_p->align / BITS_PER_UNIT;
HOST_WIDE_INT rounded_size = CEIL_ROUND (size, alignment); HOST_WIDE_INT rounded_size = CEIL_ROUND (size, alignment);
...@@ -978,6 +1006,7 @@ assign_stack_temp_for_type (mode, size, keep, type) ...@@ -978,6 +1006,7 @@ assign_stack_temp_for_type (mode, size, keep, type)
p->slot = assign_stack_local (mode, size, align); p->slot = assign_stack_local (mode, size, align);
p->align = align; p->align = align;
p->alias_set = alias_set;
/* The following slot size computation is necessary because we don't /* The following slot size computation is necessary because we don't
know the actual size of the temporary slot until assign_stack_local know the actual size of the temporary slot until assign_stack_local
...@@ -1103,6 +1132,11 @@ combine_temp_slots () ...@@ -1103,6 +1132,11 @@ combine_temp_slots ()
struct temp_slot *prev_p, *prev_q; struct temp_slot *prev_p, *prev_q;
int num_slots; int num_slots;
/* We can't combine slots, because the information about which slot
is in which alias set will be lost. */
if (flag_strict_aliasing)
return;
/* If there are a lot of temp slots, don't do anything unless /* If there are a lot of temp slots, don't do anything unless
high levels of optimizaton. */ high levels of optimizaton. */
if (! flag_expensive_optimizations) if (! flag_expensive_optimizations)
......
...@@ -319,11 +319,24 @@ copy_rtx (orig) ...@@ -319,11 +319,24 @@ copy_rtx (orig)
} }
copy = rtx_alloc (code); copy = rtx_alloc (code);
PUT_MODE (copy, GET_MODE (orig));
copy->in_struct = orig->in_struct; /* Copy the various flags, and other information. We assume that
copy->volatil = orig->volatil; all fields need copying, and then clear the fields that should
copy->unchanging = orig->unchanging; not be copied. That is the sensible default behavior, and forces
copy->integrated = orig->integrated; us to explicitly document why we are *not* copying a flag. */
bcopy (orig, copy, sizeof (struct rtx_def) - sizeof (rtunion));
/* We do not copy the USED flag, which is used as a mark bit during
walks over the RTL. */
copy->used = 0;
/* We do not copy JUMP, CALL, or FRAME_RELATED for INSNs. */
if (GET_RTX_CLASS (code) == 'i')
{
copy->jump = 0;
copy->call = 0;
copy->frame_related = 0;
}
format_ptr = GET_RTX_FORMAT (GET_CODE (copy)); format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment