diff options
author | aoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-01-07 21:37:15 +0000 |
---|---|---|
committer | aoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-01-07 21:37:15 +0000 |
commit | c98120f01786b08bb96bc85bf9c4884fc6a3f2c2 (patch) | |
tree | ec96ad4cd466791636722eef9137d3e821672768 /gcc/cselib.c | |
parent | 5cf85759b6c16a7c7d1171ca958f3a4e2e07363c (diff) | |
download | gcc-c98120f01786b08bb96bc85bf9c4884fc6a3f2c2.tar.gz |
PR bootstrap/51725
* cselib.c (new_elt_loc_list): Promote addr_list to canonical node.
Add canonical node to containing_mem chain after the non-canonical
one, even if there weren't any locs to propagate.
(remove_useless_values): Keep only canonical values.
(add_mem_for_addr, cselib_lookup_mem): Canonicalize addr.
(cselib_invalidate_mem): Likewise. Ensure v is canonical, and
canonicalize mem_chain elements that are not discarded.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182982 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cselib.c')
-rw-r--r-- | gcc/cselib.c | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/gcc/cselib.c b/gcc/cselib.c index 7db24ae729a..ab9c458fe82 100644 --- a/gcc/cselib.c +++ b/gcc/cselib.c @@ -277,12 +277,27 @@ new_elt_loc_list (cselib_val *val, rtx loc) } el->next = val->locs; next = val->locs = CSELIB_VAL_PTR (loc)->locs; - if (CSELIB_VAL_PTR (loc)->next_containing_mem != NULL - && val->next_containing_mem == NULL) - { - val->next_containing_mem = first_containing_mem; - first_containing_mem = val; - } + } + + if (CSELIB_VAL_PTR (loc)->addr_list) + { + /* Bring in addr_list into canonical node. */ + struct elt_list *last = CSELIB_VAL_PTR (loc)->addr_list; + while (last->next) + last = last->next; + last->next = val->addr_list; + val->addr_list = CSELIB_VAL_PTR (loc)->addr_list; + CSELIB_VAL_PTR (loc)->addr_list = NULL; + } + + if (CSELIB_VAL_PTR (loc)->next_containing_mem != NULL + && val->next_containing_mem == NULL) + { + /* Add VAL to the containing_mem list after LOC. LOC will + be removed when we notice it doesn't contain any + MEMs. */ + val->next_containing_mem = CSELIB_VAL_PTR (loc)->next_containing_mem; + CSELIB_VAL_PTR (loc)->next_containing_mem = val; } /* Chain LOC back to VAL. */ @@ -641,7 +656,7 @@ remove_useless_values (void) p = &first_containing_mem; for (v = *p; v != &dummy_val; v = v->next_containing_mem) - if (v->locs) + if (v->locs && v == canonical_cselib_val (v)) { *p = v; p = &(*p)->next_containing_mem; @@ -1274,6 +1289,7 @@ add_mem_for_addr (cselib_val *addr_elt, cselib_val *mem_elt, rtx x) { struct elt_loc_list *l; + addr_elt = canonical_cselib_val (addr_elt); mem_elt = canonical_cselib_val (mem_elt); /* Avoid duplicates. */ @@ -1322,6 +1338,7 @@ cselib_lookup_mem (rtx x, int create) if (! addr) return 0; + addr = canonical_cselib_val (addr); /* Find a value that describes a value of our mode at that address. */ for (l = addr->addr_list; l; l = l->next) if (GET_MODE (l->elt->val_rtx) == mode) @@ -2218,15 +2235,22 @@ cselib_invalidate_mem (rtx mem_rtx) /* 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, GET_MODE (x)); + addr = canonical_cselib_val (addr); + gcc_checking_assert (v == canonical_cselib_val (v)); mem_chain = &addr->addr_list; for (;;) { - if (canonical_cselib_val ((*mem_chain)->elt) == v) + cselib_val *canon = canonical_cselib_val ((*mem_chain)->elt); + + if (canon == v) { unchain_one_elt_list (mem_chain); break; } + /* Record canonicalized elt. */ + (*mem_chain)->elt = canon; + mem_chain = &(*mem_chain)->next; } |