diff options
author | Richard Biener <rguenther@suse.de> | 2013-09-20 17:49:45 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2013-09-20 17:49:45 +0000 |
commit | a3cc13ccc8f4fce1b3990fa7c722924d42d19d85 (patch) | |
tree | c54ad3c3f957c8c89ffe6012a594fc159e3e1196 /gcc/tree-scalar-evolution.c | |
parent | 925f3871dba29771277bd1c5f8371d28f4156e6d (diff) | |
download | gcc-a3cc13ccc8f4fce1b3990fa7c722924d42d19d85.zip gcc-a3cc13ccc8f4fce1b3990fa7c722924d42d19d85.tar.gz gcc-a3cc13ccc8f4fce1b3990fa7c722924d42d19d85.tar.bz2 |
re PR middle-end/58484 (ICE in chrec_fold_plus_1, at tree-chrec.c:272 building 416.gamess)
2013-09-20 Richard Biener <rguenther@suse.de>
PR middle-end/58484
* tree-scalar-evolution.c (struct scev_info_str): Shrink by
remembering SSA name version and block index.
(new_scev_info_str): Adjust.
(hash_scev_info): Likewise. Also hash the block index.
(eq_scev_info): Adjust.
(find_var_scev_info): Likewise.
(struct instantiate_cache_entry): Remove.
(struct instantiate_cache_type): Use a htab to map name, block
to chrec.
(instantiate_cache_type::~instantiate_cache_type): Adjust.
(get_instantiated_value_entry): Likewise.
(hash_idx_scev_info, eq_idx_scev_info): New functions.
(instantiate_scev_name): Adjust.
* gfortran.dg/pr58484.f: New testcase.
From-SVN: r202790
Diffstat (limited to 'gcc/tree-scalar-evolution.c')
-rw-r--r-- | gcc/tree-scalar-evolution.c | 86 |
1 files changed, 51 insertions, 35 deletions
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c index f15f91c..bda45a6 100644 --- a/gcc/tree-scalar-evolution.c +++ b/gcc/tree-scalar-evolution.c @@ -269,13 +269,13 @@ static tree analyze_scalar_evolution_1 (struct loop *, tree, tree); static tree analyze_scalar_evolution_for_address_of (struct loop *loop, tree var); -/* The cached information about an SSA name VAR, claiming that below - basic block INSTANTIATED_BELOW, the value of VAR can be expressed - as CHREC. */ +/* The cached information about an SSA name with version NAME_VERSION, + claiming that below basic block with index INSTANTIATED_BELOW, the + value of the SSA name can be expressed as CHREC. */ struct GTY(()) scev_info_str { - basic_block instantiated_below; - tree var; + unsigned int name_version; + int instantiated_below; tree chrec; }; @@ -309,9 +309,9 @@ new_scev_info_str (basic_block instantiated_below, tree var) struct scev_info_str *res; res = ggc_alloc_scev_info_str (); - res->var = var; + res->name_version = SSA_NAME_VERSION (var); res->chrec = chrec_not_analyzed_yet; - res->instantiated_below = instantiated_below; + res->instantiated_below = instantiated_below->index; return res; } @@ -319,9 +319,10 @@ new_scev_info_str (basic_block instantiated_below, tree var) /* Computes a hash function for database element ELT. */ static inline hashval_t -hash_scev_info (const void *elt) +hash_scev_info (const void *elt_) { - return SSA_NAME_VERSION (((const struct scev_info_str *) elt)->var); + const struct scev_info_str *elt = (const struct scev_info_str *) elt_; + return elt->name_version ^ elt->instantiated_below; } /* Compares database elements E1 and E2. */ @@ -332,7 +333,7 @@ eq_scev_info (const void *e1, const void *e2) const struct scev_info_str *elt1 = (const struct scev_info_str *) e1; const struct scev_info_str *elt2 = (const struct scev_info_str *) e2; - return (elt1->var == elt2->var + return (elt1->name_version == elt2->name_version && elt1->instantiated_below == elt2->instantiated_below); } @@ -355,8 +356,8 @@ find_var_scev_info (basic_block instantiated_below, tree var) struct scev_info_str tmp; PTR *slot; - tmp.var = var; - tmp.instantiated_below = instantiated_below; + tmp.name_version = SSA_NAME_VERSION (var); + tmp.instantiated_below = instantiated_below->index; slot = htab_find_slot (scalar_evolution_info, &tmp, INSERT); if (!*slot) @@ -2065,16 +2066,10 @@ analyze_scalar_evolution_in_loop (struct loop *wrto_loop, struct loop *use_loop, instantiating a CHREC or resolving mixers. For this use instantiated_below is always the same. */ -struct instantiate_cache_entry -{ - tree name; - tree chrec; -}; - struct instantiate_cache_type { - pointer_map<unsigned> *map; - vec<instantiate_cache_entry> entries; + htab_t map; + vec<scev_info_str> entries; instantiate_cache_type () : map (NULL), entries(vNULL) {} ~instantiate_cache_type (); @@ -2086,40 +2081,60 @@ instantiate_cache_type::~instantiate_cache_type () { if (map != NULL) { - delete map; + htab_delete (map); entries.release (); } } +/* Cache to avoid infinite recursion when instantiating an SSA name. + Live during the outermost instantiate_scev or resolve_mixers call. */ +static instantiate_cache_type *global_cache; + +/* Computes a hash function for database element ELT. */ + +static inline hashval_t +hash_idx_scev_info (const void *elt_) +{ + unsigned idx = ((size_t) elt_) - 2; + return hash_scev_info (&global_cache->entries[idx]); +} + +/* Compares database elements E1 and E2. */ + +static inline int +eq_idx_scev_info (const void *e1, const void *e2) +{ + unsigned idx1 = ((size_t) e1) - 2; + return eq_scev_info (&global_cache->entries[idx1], e2); +} + /* Returns from CACHE the slot number of the cached chrec for NAME. */ static unsigned -get_instantiated_value_entry (instantiate_cache_type &cache, tree name) +get_instantiated_value_entry (instantiate_cache_type &cache, + tree name, basic_block instantiate_below) { if (!cache.map) { - cache.map = new pointer_map<unsigned>; + cache.map = htab_create (10, hash_idx_scev_info, eq_idx_scev_info, NULL); cache.entries.create (10); } - bool existed_p; - unsigned *slot = cache.map->insert (name, &existed_p); - if (!existed_p) + scev_info_str e; + e.name_version = SSA_NAME_VERSION (name); + e.instantiated_below = instantiate_below->index; + void **slot = htab_find_slot_with_hash (cache.map, &e, + hash_scev_info (&e), INSERT); + if (!*slot) { - struct instantiate_cache_entry e; - e.name = name; e.chrec = chrec_not_analyzed_yet; - *slot = cache.entries.length (); + *slot = (void *)(size_t)(cache.entries.length () + 2); cache.entries.safe_push (e); } - return *slot; + return ((size_t)*slot) - 2; } -/* Cache to avoid infinite recursion when instantiating an SSA name. - Live during the outermost instantiate_scev or resolve_mixers call. */ -static instantiate_cache_type *global_cache; - /* Return the closed_loop_phi node for VAR. If there is none, return NULL_TREE. */ @@ -2195,7 +2210,8 @@ instantiate_scev_name (basic_block instantiate_below, | a_2 -> {0, +, 1, +, a_2}_1 */ - unsigned si = get_instantiated_value_entry (*global_cache, chrec); + unsigned si = get_instantiated_value_entry (*global_cache, + chrec, instantiate_below); if (global_cache->get (si) != chrec_not_analyzed_yet) return global_cache->get (si); |