diff options
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cselib.c | 133 | ||||
-rw-r--r-- | gcc/cselib.h | 2 |
3 files changed, 95 insertions, 50 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c05eeb63634..a3ec4c6cb59 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +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> * config/rs6000/rs6000.c (rs6000_override_options): Disable string diff --git a/gcc/cselib.c b/gcc/cselib.c index 63fab2233a9..564afbaaacb 100644 --- a/gcc/cselib.c +++ b/gcc/cselib.c @@ -63,7 +63,6 @@ static cselib_val *cselib_lookup_mem PARAMS ((rtx, int)); static void cselib_invalidate_regno PARAMS ((unsigned int, enum machine_mode)); 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_rtx PARAMS ((rtx, rtx, void *)); static void cselib_record_set PARAMS ((rtx, cselib_val *, @@ -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 value. */ 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 @@ -237,6 +245,8 @@ clear_table (clear_all) n_useless_values = 0; next_unknown_value = 0; + + first_containing_mem = &dummy_val; } /* The equality test for our hash table. The first argument ENTRY is a table @@ -371,6 +381,7 @@ discard_useless_values (x, info) static void remove_useless_values () { + cselib_val **p, *v; /* First pass: eliminate locations that reference the value. That in turn can make more values useless. */ do @@ -383,6 +394,15 @@ remove_useless_values () /* Second pass: actually remove the values. */ 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) abort (); } @@ -706,6 +726,7 @@ new_cselib_val (value, mode) CSELIB_VAL_PTR (e->u.val_rtx) = e; e->addr_list = 0; e->locs = 0; + e->next_containing_mem = 0; return e; } @@ -730,6 +751,11 @@ add_mem_for_addr (addr_elt, mem_elt, x) mem_elt->locs = new_elt_loc_list (mem_elt->locs, 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. @@ -1078,68 +1104,75 @@ cselib_mem_conflict_p (mem_base, val) return 0; } -/* For the value found in SLOT, walk its locations to determine if any overlap - INFO (which is a MEM rtx). */ +/* Invalidate any locations in the table which are changed because of a + store to MEM_RTX. If this is called because of a non-const call + instruction, MEM_RTX is (mem:BLK const0_rtx). */ -static int -cselib_invalidate_mem_1 (slot, info) - void **slot; - void *info; +static void +cselib_invalidate_mem (mem_rtx) + rtx mem_rtx; { - cselib_val *v = (cselib_val *) *slot; - rtx mem_rtx = (rtx) info; - struct elt_loc_list **p = &v->locs; - int had_locs = v->locs != 0; + cselib_val **vp, *v, *next; - while (*p) + vp = &first_containing_mem; + for (v = *vp; v != &dummy_val; v = next) { - 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 - || ! cselib_mem_conflict_p (mem_rtx, x)) - { - p = &(*p)->next; - continue; - } + bool has_mem = false; + struct elt_loc_list **p = &v->locs; + int had_locs = v->locs != 0; - /* This one overlaps. */ - /* 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 (;;) + while (*p) { - 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); - break; + p = &(*p)->next; + continue; + } + if (! cselib_mem_conflict_p (mem_rtx, x)) + { + has_mem = true; + p = &(*p)->next; + continue; } - mem_chain = &(*mem_chain)->next; - } - - unchain_one_elt_loc_list (p); - } + /* This one overlaps. */ + /* 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) + { + unchain_one_elt_list (mem_chain); + break; + } - if (had_locs && v->locs == 0) - n_useless_values++; + mem_chain = &(*mem_chain)->next; + } - return 1; -} + unchain_one_elt_loc_list (p); + } -/* Invalidate any locations in the table which are changed because of a - store to MEM_RTX. If this is called because of a non-const call - instruction, MEM_RTX is (mem:BLK const0_rtx). */ + if (had_locs && v->locs == 0) + n_useless_values++; -static void -cselib_invalidate_mem (mem_rtx) - rtx mem_rtx; -{ - htab_traverse (hash_table, cselib_invalidate_mem_1, mem_rtx); + next = v->next_containing_mem; + if (has_mem) + { + *vp = v; + 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 diff --git a/gcc/cselib.h b/gcc/cselib.h index f29ee8de04e..9cceddbfcbc 100644 --- a/gcc/cselib.h +++ b/gcc/cselib.h @@ -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 use it as an address in a MEM. */ struct elt_list *addr_list; + + struct cselib_val_struct *next_containing_mem; } cselib_val; /* A list of rtl expressions that hold the same value. */ |