+2015-11-24 Jan Hubicka <hubicka@ucw.cz>
+
+ * lto-streamer-in.c (lto_read_body_or_constructor): Set TYPE_CANONICAL
+ only for types where LTO sets them.
+ * tree.c (build_array_type_1): Do ont set TYPE_CANONICAL for LTO.
+ (make_vector_type): Likewise.
+ (gimple_canonical_types_compatible_p): Use canonical_type_used_p.
+ * tree.h (canonical_type_used_p): New inline.
+ * alias.c (get_alias_set): Handle structural equality for all
+ types that pass canonical_type_used_p.
+ (record_component_aliases): Look through all types with
+ record_component_aliases for possible pointers; sanity check that
+ the alias sets match.
+
2015-11-24 Michael Meissner <meissner@linux.vnet.ibm.com>
* config/rs6000/rs6000.md (lround<mode>di2): Remove constraints.
set = lang_hooks.get_alias_set (t);
if (set != -1)
return set;
- /* Handle structure type equality for pointer types. This is easy
- to do, because the code bellow ignore canonical types on these anyway.
- This is important for LTO, where TYPE_CANONICAL for pointers can not
- be meaningfuly computed by the frotnend. */
- if (!POINTER_TYPE_P (t))
+ /* Handle structure type equality for pointer types, arrays and vectors.
+ This is easy to do, because the code bellow ignore canonical types on
+ these anyway. This is important for LTO, where TYPE_CANONICAL for
+ pointers can not be meaningfuly computed by the frotnend. */
+ if (canonical_type_used_p (t))
{
/* In LTO we set canonical types for all types where it makes
sense to do so. Double check we did not miss some type. */
integer(kind=4)[4] the same alias set or not.
Just be pragmatic here and make sure the array and its element
type get the same alias set assigned. */
- else if (TREE_CODE (t) == ARRAY_TYPE && !TYPE_NONALIASED_COMPONENT (t))
+ else if (TREE_CODE (t) == ARRAY_TYPE
+ && (!TYPE_NONALIASED_COMPONENT (t)
+ || TYPE_STRUCTURAL_EQUALITY_P (t)))
set = get_alias_set (TREE_TYPE (t));
/* From the former common C and C++ langhook implementation:
We also want to make pointer to array/vector equivalent to pointer to
its element (see the reasoning above). Skip all those types, too. */
for (p = t; POINTER_TYPE_P (p)
- || (TREE_CODE (p) == ARRAY_TYPE && !TYPE_NONALIASED_COMPONENT (p))
+ || (TREE_CODE (p) == ARRAY_TYPE
+ && (!TYPE_NONALIASED_COMPONENT (p)
+ || !COMPLETE_TYPE_P (p)
+ || TYPE_STRUCTURAL_EQUALITY_P (p)))
|| TREE_CODE (p) == VECTOR_TYPE;
p = TREE_TYPE (p))
{
/* VECTOR_TYPE and ARRAY_TYPE share the alias set with their
element type and that type has to be normalized to void *,
too, in the case it is a pointer. */
- while ((TREE_CODE (t) == ARRAY_TYPE
- && (!COMPLETE_TYPE_P (t)
- || TYPE_NONALIASED_COMPONENT (t)))
- || TREE_CODE (t) == VECTOR_TYPE)
- t = TREE_TYPE (t);
+ while (!canonical_type_used_p (t) && !POINTER_TYPE_P (t))
+ {
+ gcc_checking_assert (TYPE_STRUCTURAL_EQUALITY_P (t));
+ t = TREE_TYPE (t);
+ }
if (POINTER_TYPE_P (t))
t = ptr_type_node;
+ else if (flag_checking)
+ gcc_checking_assert (get_alias_set (t)
+ == get_alias_set (TREE_TYPE (field)));
}
-
+
record_alias_subset (superset, get_alias_set (t));
}
break;
if (TYPE_P (t))
{
gcc_assert (TYPE_CANONICAL (t) == NULL_TREE);
- TYPE_CANONICAL (t) = TYPE_MAIN_VARIANT (t);
+ if (type_with_alias_set_p (t)
+ && canonical_type_used_p (t))
+ TYPE_CANONICAL (t) = TYPE_MAIN_VARIANT (t);
if (TYPE_MAIN_VARIANT (t) != t)
{
gcc_assert (TYPE_NEXT_VARIANT (t) == NULL_TREE);
+2015-11-24 Jan Hubicka <hubicka@ucw.cz>
+
+ * lto.c (iterative_hash_canonical_type): Recruse for all types
+ which pass !canonical_type_used_p.
+ (gimple_register_canonical_type_1): Sanity check we do not compute
+ canonical type of anything with !canonical_type_used_p.
+ (gimple_register_canonical_type): Skip all types that are
+ !canonical_type_used_p
+
2015-11-24 Jan Hubicka <hubicka@ucw.cz>
* lto.c (unify_scc): Use free_node.
/* All type variants have same TYPE_CANONICAL. */
type = TYPE_MAIN_VARIANT (type);
- /* We do not compute TYPE_CANONICAl of POINTER_TYPE because the aliasing
- code never use it anyway. */
- if (POINTER_TYPE_P (type))
+ if (!canonical_type_used_p (type))
v = hash_canonical_type (type);
/* An already processed type. */
else if (TYPE_CANONICAL (type))
gcc_checking_assert (TYPE_P (t) && !TYPE_CANONICAL (t)
&& type_with_alias_set_p (t)
- && !POINTER_TYPE_P (t));
+ && canonical_type_used_p (t));
slot = htab_find_slot_with_hash (gimple_canonical_types, t, hash, INSERT);
if (*slot)
static void
gimple_register_canonical_type (tree t)
{
- if (TYPE_CANONICAL (t) || !type_with_alias_set_p (t) || POINTER_TYPE_P (t))
+ if (TYPE_CANONICAL (t) || !type_with_alias_set_p (t)
+ || !canonical_type_used_p (t))
return;
/* Canonical types are same among all complete variants. */
if (TYPE_CANONICAL (t) == t)
{
if (TYPE_STRUCTURAL_EQUALITY_P (elt_type)
- || (index_type && TYPE_STRUCTURAL_EQUALITY_P (index_type)))
+ || (index_type && TYPE_STRUCTURAL_EQUALITY_P (index_type))
+ || in_lto_p)
SET_TYPE_STRUCTURAL_EQUALITY (t);
else if (TYPE_CANONICAL (elt_type) != elt_type
|| (index_type && TYPE_CANONICAL (index_type) != index_type))
SET_TYPE_VECTOR_SUBPARTS (t, nunits);
SET_TYPE_MODE (t, mode);
- if (TYPE_STRUCTURAL_EQUALITY_P (innertype))
+ if (TYPE_STRUCTURAL_EQUALITY_P (innertype) || in_lto_p)
SET_TYPE_STRUCTURAL_EQUALITY (t);
else if ((TYPE_CANONICAL (innertype) != innertype
|| mode != VOIDmode)
TYPE_CANONICAL is more fine grained than the equivalnce we test (where
all pointers are considered equal. Be sure to not return false
negatives. */
- gcc_checking_assert (!POINTER_TYPE_P (t1) && !POINTER_TYPE_P (t2));
+ gcc_checking_assert (canonical_type_used_p (t1)
+ && canonical_type_used_p (t2));
return TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2);
}
extern bool gimple_canonical_types_compatible_p (const_tree, const_tree,
bool trust_type_canonical = true);
extern bool type_with_interoperable_signedness (const_tree);
-/* Return simplified tree code of type that is used for canonical type merging. */
+
+/* Return simplified tree code of type that is used for canonical type
+ merging. */
inline enum tree_code
tree_code_for_canonical_type_merging (enum tree_code code)
{
return code;
}
+/* Return ture if get_alias_set care about TYPE_CANONICAL of given type.
+ We don't define the types for pointers, arrays and vectors. The reason is
+ that pointers are handled specially: ptr_type_node accesses conflict with
+ accesses to all other pointers. This is done by alias.c.
+ Because alias sets of arrays and vectors are the same as types of their
+ elements, we can't compute canonical type either. Otherwise we could go
+ form void *[10] to int *[10] (because they are equivalent for canonical type
+ machinery) and get wrong TBAA. */
+
+inline bool
+canonical_type_used_p (const_tree t)
+{
+ return !(POINTER_TYPE_P (t)
+ || TREE_CODE (t) == ARRAY_TYPE
+ || TREE_CODE (t) == VECTOR_TYPE);
+}
+
#define tree_map_eq tree_map_base_eq
extern unsigned int tree_map_hash (const void *);
#define tree_map_marked_p tree_map_base_marked_p