/* Interprocedural Identical Code Folding pass
- Copyright (C) 2014-2018 Free Software Foundation, Inc.
+ Copyright (C) 2014-2019 Free Software Foundation, Inc.
Contributed by Jan Hubicka <hubicka@ucw.cz> and Martin Liska <mliska@suse.cz>
m_hash_set = true;
}
+hash_map<const_tree, hashval_t> sem_item::m_type_hash_cache;
+
/* Semantic function constructor that uses STACK as bitmap memory stack. */
sem_function::sem_function (bitmap_obstack *stack)
return m_hash;
}
-/* Return ture if A1 and A2 represent equivalent function attribute lists.
- Based on comp_type_attributes. */
-
-bool
-sem_item::compare_attributes (const_tree a1, const_tree a2)
-{
- const_tree a;
- if (a1 == a2)
- return true;
- for (a = a1; a != NULL_TREE; a = TREE_CHAIN (a))
- {
- const struct attribute_spec *as;
- const_tree attr;
-
- as = lookup_attribute_spec (get_attribute_name (a));
- /* TODO: We can introduce as->affects_decl_identity
- and as->affects_decl_reference_identity if attribute mismatch
- gets a common reason to give up on merging. It may not be worth
- the effort.
- For example returns_nonnull affects only references, while
- optimize attribute can be ignored because it is already lowered
- into flags representation and compared separately. */
- if (!as)
- continue;
-
- attr = lookup_attribute (as->name, CONST_CAST_TREE (a2));
- if (!attr || !attribute_value_equal (a, attr))
- break;
- }
- if (!a)
- {
- for (a = a2; a != NULL_TREE; a = TREE_CHAIN (a))
- {
- const struct attribute_spec *as;
-
- as = lookup_attribute_spec (get_attribute_name (a));
- if (!as)
- continue;
-
- if (!lookup_attribute (as->name, CONST_CAST_TREE (a1)))
- break;
- /* We don't need to compare trees again, as we did this
- already in first loop. */
- }
- if (!a)
- return true;
- }
- /* TODO: As in comp_type_attributes we may want to introduce target hook. */
- return false;
-}
-
/* Compare properties of symbols N1 and N2 that does not affect semantics of
symbol itself but affects semantics of its references from USED_BY (which
may be NULL if it is unknown). If comparsion is false, symbols
variables just compare attributes for references - the codegen
for constructors is affected only by those attributes that we lower
to explicit representation (such as DECL_ALIGN or DECL_SECTION). */
- if (!compare_attributes (DECL_ATTRIBUTES (n1->decl),
- DECL_ATTRIBUTES (n2->decl)))
+ if (!attribute_list_equal (DECL_ATTRIBUTES (n1->decl),
+ DECL_ATTRIBUTES (n2->decl)))
return return_false_with_msg ("different var decl attributes");
if (comp_type_attributes (TREE_TYPE (n1->decl),
TREE_TYPE (n2->decl)) != 1)
return return_false_with_msg ("thunk fixed_offset mismatch");
if (cnode->thunk.virtual_value != cnode2->thunk.virtual_value)
return return_false_with_msg ("thunk virtual_value mismatch");
+ if (cnode->thunk.indirect_offset != cnode2->thunk.indirect_offset)
+ return return_false_with_msg ("thunk indirect_offset mismatch");
if (cnode->thunk.this_adjusting != cnode2->thunk.this_adjusting)
return return_false_with_msg ("thunk this_adjusting mismatch");
if (cnode->thunk.virtual_offset_p != cnode2->thunk.virtual_offset_p)
cl_optimization *opt1 = opts_for_fn (decl);
cl_optimization *opt2 = opts_for_fn (item->decl);
- if (opt1 != opt2 && memcmp (opt1, opt2, sizeof(cl_optimization)))
+ if (opt1 != opt2 && !cl_optimization_option_eq (opt1, opt2))
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
if (comp_type_attributes (TREE_TYPE (decl),
TREE_TYPE (item->decl)) != 1)
return return_false_with_msg ("different type attributes");
- if (!compare_attributes (DECL_ATTRIBUTES (decl),
- DECL_ATTRIBUTES (item->decl)))
+ if (!attribute_list_equal (DECL_ATTRIBUTES (decl),
+ DECL_ATTRIBUTES (item->decl)))
return return_false_with_msg ("different decl attributes");
/* The type of THIS pointer type memory location for
"can not create wrapper of stdarg function.\n");
}
else if (ipa_fn_summaries
- && ipa_fn_summaries->get_create (alias)->self_size <= 2)
+ && ipa_fn_summaries->get (alias) != NULL
+ && ipa_fn_summaries->get (alias)->self_size <= 2)
{
if (dump_file)
fprintf (dump_file, "Wrapper creation is not "
return;
}
- hashval_t *val = optimizer->m_type_hash_cache.get (type);
+ hashval_t *val = m_type_hash_cache.get (type);
if (!val)
{
hstate2.add_int (nf);
hash = hstate2.end ();
hstate.add_hwi (hash);
- optimizer->m_type_hash_cache.put (type, hash);
+ m_type_hash_cache.put (type, hash);
}
else
hstate.add_hwi (*val);
return true;
}
+/* Compare function for sorting pairs in do_congruence_step_f. */
+
+int
+sem_item_optimizer::sort_congruence_split (const void *a_, const void *b_)
+{
+ const std::pair<congruence_class *, bitmap> *a
+ = (const std::pair<congruence_class *, bitmap> *)a_;
+ const std::pair<congruence_class *, bitmap> *b
+ = (const std::pair<congruence_class *, bitmap> *)b_;
+ if (a->first->id < b->first->id)
+ return -1;
+ else if (a->first->id > b->first->id)
+ return 1;
+ return 0;
+}
+
/* Tests if a class CLS used as INDEXth splits any congruence classes.
Bitmap stack BMSTACK is used for bitmap allocation. */
}
}
+ auto_vec<std::pair<congruence_class *, bitmap> > to_split;
+ to_split.reserve_exact (split_map.elements ());
+ for (hash_map <congruence_class *, bitmap>::iterator i = split_map.begin ();
+ i != split_map.end (); ++i)
+ to_split.safe_push (*i);
+ to_split.qsort (sort_congruence_split);
+
traverse_split_pair pair;
pair.optimizer = this;
pair.cls = cls;
splitter_class_removed = false;
- split_map.traverse <traverse_split_pair *,
- sem_item_optimizer::traverse_congruence_split> (&pair);
+ for (unsigned i = 0; i < to_split.length (); ++i)
+ traverse_congruence_split (to_split[i].first, to_split[i].second, &pair);
/* Bitmap clean-up. */
split_map.traverse <traverse_split_pair *,