Commit 7101fb18 by Jan Hubicka Committed by Jan Hubicka

cselib.c (cselib_invalidate_mem_1): Move too ...

	* cselib.c (cselib_invalidate_mem_1): Move too ...
	(cselib_invalidate_mem): ... here; use new list
	(dummy_val, first_containing_mem): New static variables.
	(clear_table): Initialize first_containing_mem.
	(discard_useless_values):  Compact the containing_mem list.
	(add_mem_for_addr): Add to the list.
	* cselib.h (cselib_val): Add next_containing_mem.

From-SVN: r64191
parent e24c3d71
Tue Mar 11 22:48:03 CET 2003 Jan Hubicka <jh@suse.cz>
* cselib.c (cselib_invalidate_mem_1): Move too ...
(cselib_invalidate_mem): ... here; use new list
(dummy_val, first_containing_mem): New static variables.
(clear_table): Initialize first_containing_mem.
(discard_useless_values): Compact the containing_mem list.
(add_mem_for_addr): Add to the list.
* cselib.h (cselib_val): Add next_containing_mem.
2003-03-11 Aldy Hernandez <aldyh@redhat.com> 2003-03-11 Aldy Hernandez <aldyh@redhat.com>
* config/rs6000/rs6000.c (rs6000_override_options): Disable string * config/rs6000/rs6000.c (rs6000_override_options): Disable string
......
...@@ -63,7 +63,6 @@ static cselib_val *cselib_lookup_mem PARAMS ((rtx, int)); ...@@ -63,7 +63,6 @@ static cselib_val *cselib_lookup_mem PARAMS ((rtx, int));
static void cselib_invalidate_regno PARAMS ((unsigned int, static void cselib_invalidate_regno PARAMS ((unsigned int,
enum machine_mode)); enum machine_mode));
static int cselib_mem_conflict_p PARAMS ((rtx, rtx)); static int cselib_mem_conflict_p PARAMS ((rtx, rtx));
static int cselib_invalidate_mem_1 PARAMS ((void **, void *));
static void cselib_invalidate_mem PARAMS ((rtx)); static void cselib_invalidate_mem PARAMS ((rtx));
static void cselib_invalidate_rtx PARAMS ((rtx, rtx, void *)); static void cselib_invalidate_rtx PARAMS ((rtx, rtx, void *));
static void cselib_record_set PARAMS ((rtx, cselib_val *, static void cselib_record_set PARAMS ((rtx, cselib_val *,
...@@ -128,6 +127,15 @@ static GTY((deletable (""))) struct elt_loc_list *empty_elt_loc_lists; ...@@ -128,6 +127,15 @@ static GTY((deletable (""))) struct elt_loc_list *empty_elt_loc_lists;
/* Set by discard_useless_locs if it deleted the last location of any /* Set by discard_useless_locs if it deleted the last location of any
value. */ value. */
static int values_became_useless; static int values_became_useless;
/* Used as stop element of the containing_mem list so we can check
presence in the list by checking the next pointer. */
static cselib_val dummy_val;
/* Used to list all values that contain memory reference.
May or may not contain the useless values - the list is compacted
each time memory is invalidated. */
static cselib_val *first_containing_mem = &dummy_val;
/* Allocate a struct elt_list and fill in its two elements with the /* Allocate a struct elt_list and fill in its two elements with the
...@@ -237,6 +245,8 @@ clear_table (clear_all) ...@@ -237,6 +245,8 @@ clear_table (clear_all)
n_useless_values = 0; n_useless_values = 0;
next_unknown_value = 0; next_unknown_value = 0;
first_containing_mem = &dummy_val;
} }
/* The equality test for our hash table. The first argument ENTRY is a table /* The equality test for our hash table. The first argument ENTRY is a table
...@@ -371,6 +381,7 @@ discard_useless_values (x, info) ...@@ -371,6 +381,7 @@ discard_useless_values (x, info)
static void static void
remove_useless_values () remove_useless_values ()
{ {
cselib_val **p, *v;
/* First pass: eliminate locations that reference the value. That in /* First pass: eliminate locations that reference the value. That in
turn can make more values useless. */ turn can make more values useless. */
do do
...@@ -383,6 +394,15 @@ remove_useless_values () ...@@ -383,6 +394,15 @@ remove_useless_values ()
/* Second pass: actually remove the values. */ /* Second pass: actually remove the values. */
htab_traverse (hash_table, discard_useless_values, 0); htab_traverse (hash_table, discard_useless_values, 0);
p = &first_containing_mem;
for (v = *p; v != &dummy_val; v = v->next_containing_mem)
if (v->locs)
{
*p = v;
p = &(*p)->next_containing_mem;
}
*p = &dummy_val;
if (n_useless_values != 0) if (n_useless_values != 0)
abort (); abort ();
} }
...@@ -706,6 +726,7 @@ new_cselib_val (value, mode) ...@@ -706,6 +726,7 @@ new_cselib_val (value, mode)
CSELIB_VAL_PTR (e->u.val_rtx) = e; CSELIB_VAL_PTR (e->u.val_rtx) = e;
e->addr_list = 0; e->addr_list = 0;
e->locs = 0; e->locs = 0;
e->next_containing_mem = 0;
return e; return e;
} }
...@@ -730,6 +751,11 @@ add_mem_for_addr (addr_elt, mem_elt, x) ...@@ -730,6 +751,11 @@ add_mem_for_addr (addr_elt, mem_elt, x)
mem_elt->locs mem_elt->locs
= new_elt_loc_list (mem_elt->locs, = new_elt_loc_list (mem_elt->locs,
replace_equiv_address_nv (x, addr_elt->u.val_rtx)); replace_equiv_address_nv (x, addr_elt->u.val_rtx));
if (mem_elt->next_containing_mem == NULL)
{
mem_elt->next_containing_mem = first_containing_mem;
first_containing_mem = mem_elt;
}
} }
/* Subroutine of cselib_lookup. Return a value for X, which is a MEM rtx. /* Subroutine of cselib_lookup. Return a value for X, which is a MEM rtx.
...@@ -1078,68 +1104,75 @@ cselib_mem_conflict_p (mem_base, val) ...@@ -1078,68 +1104,75 @@ cselib_mem_conflict_p (mem_base, val)
return 0; return 0;
} }
/* For the value found in SLOT, walk its locations to determine if any overlap /* Invalidate any locations in the table which are changed because of a
INFO (which is a MEM rtx). */ store to MEM_RTX. If this is called because of a non-const call
instruction, MEM_RTX is (mem:BLK const0_rtx). */
static int static void
cselib_invalidate_mem_1 (slot, info) cselib_invalidate_mem (mem_rtx)
void **slot; rtx mem_rtx;
void *info;
{ {
cselib_val *v = (cselib_val *) *slot; cselib_val **vp, *v, *next;
rtx mem_rtx = (rtx) info;
struct elt_loc_list **p = &v->locs;
int had_locs = v->locs != 0;
while (*p) vp = &first_containing_mem;
for (v = *vp; v != &dummy_val; v = next)
{ {
rtx x = (*p)->loc; bool has_mem = false;
cselib_val *addr; struct elt_loc_list **p = &v->locs;
struct elt_list **mem_chain; int had_locs = v->locs != 0;
/* MEMs may occur in locations only at the top level; below
that every MEM or REG is substituted by its VALUE. */
if (GET_CODE (x) != MEM
|| ! cselib_mem_conflict_p (mem_rtx, x))
{
p = &(*p)->next;
continue;
}
/* This one overlaps. */ while (*p)
/* We must have a mapping from this MEM's address to the
value (E). Remove that, too. */
addr = cselib_lookup (XEXP (x, 0), VOIDmode, 0);
mem_chain = &addr->addr_list;
for (;;)
{ {
if ((*mem_chain)->elt == v) rtx x = (*p)->loc;
cselib_val *addr;
struct elt_list **mem_chain;
/* MEMs may occur in locations only at the top level; below
that every MEM or REG is substituted by its VALUE. */
if (GET_CODE (x) != MEM)
{ {
unchain_one_elt_list (mem_chain); p = &(*p)->next;
break; continue;
}
if (! cselib_mem_conflict_p (mem_rtx, x))
{
has_mem = true;
p = &(*p)->next;
continue;
} }
mem_chain = &(*mem_chain)->next; /* This one overlaps. */
} /* We must have a mapping from this MEM's address to the
value (E). Remove that, too. */
unchain_one_elt_loc_list (p); addr = cselib_lookup (XEXP (x, 0), VOIDmode, 0);
} mem_chain = &addr->addr_list;
for (;;)
{
if ((*mem_chain)->elt == v)
{
unchain_one_elt_list (mem_chain);
break;
}
if (had_locs && v->locs == 0) mem_chain = &(*mem_chain)->next;
n_useless_values++; }
return 1; unchain_one_elt_loc_list (p);
} }
/* Invalidate any locations in the table which are changed because of a if (had_locs && v->locs == 0)
store to MEM_RTX. If this is called because of a non-const call n_useless_values++;
instruction, MEM_RTX is (mem:BLK const0_rtx). */
static void next = v->next_containing_mem;
cselib_invalidate_mem (mem_rtx) if (has_mem)
rtx mem_rtx; {
{ *vp = v;
htab_traverse (hash_table, cselib_invalidate_mem_1, mem_rtx); vp = &(*vp)->next_containing_mem;
}
else
v->next_containing_mem = NULL;
}
*vp = &dummy_val;
} }
/* Invalidate DEST, which is being assigned to or clobbered. The second and /* Invalidate DEST, which is being assigned to or clobbered. The second and
......
...@@ -38,6 +38,8 @@ typedef struct cselib_val_struct GTY(()) ...@@ -38,6 +38,8 @@ typedef struct cselib_val_struct GTY(())
/* If this value is used as an address, points to a list of values that /* If this value is used as an address, points to a list of values that
use it as an address in a MEM. */ use it as an address in a MEM. */
struct elt_list *addr_list; struct elt_list *addr_list;
struct cselib_val_struct *next_containing_mem;
} cselib_val; } cselib_val;
/* A list of rtl expressions that hold the same value. */ /* A list of rtl expressions that hold the same value. */
......
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