> > - /* For aggregates we rely on TYPE_CANONICAL exclusively and require > > - explicit conversions for types involving to be structurally > > - compared types. */ > > + /* For aggregates compare only the size and mode. Accesses to fields do > > have > > + a type information by themselves and thus we only care if we can i.e. > > + use the types in move operations. */ > > else if (AGGREGATE_TYPE_P (inner_type) > > && TREE_CODE (inner_type) == TREE_CODE (outer_type)) > > - return false; > > + return (!TYPE_SIZE (outer_type) > > + || (TYPE_SIZE (inner_type) > > + && operand_equal_p (TYPE_SIZE (inner_type), > > + TYPE_SIZE (outer_type), 0))) > > + && TYPE_MODE (outer_type) == TYPE_MODE (inner_type); > > If we require the TYPE_MODE check then just remove the !AGGREGATE_TYPE_P > check on the mode equality check at the beginning of the function. > There must be a reason why I allowed modes to differ there btw ;)
I will test the variant moving TYPE_MODE check early. I don't know if aggregates are special. Only I know that move from agreggate with one mode to aggregate with another does not work even if they have same sizes. I dunno if we can actually move non-aggregates this way for fun and profit. In general I would like to see less uses of TYPE_MODE than more and sort of seeing it go away from gimple types, because it is RTL thingy. > > The size compare might be too conservative for > > X = WITH_SIZE_EXPR <Y, size>; > > where we take the size to copy from the WITH_SIZE_EXPR. Of course > you can't tell this from the types. Well. Do we actually need > the !TYPE_SIZE (aka !COMPLETE_TYPE_P) case? Or does this happen > exactly when WITH_SIZE_EXPR is used? It does happen for "bogus" uses of type_compatible_p. For exmaple ipa-icf calls the predicate on almost everything and gets to incomplete types here, so we can't segfault. I have patches for this, but would like to handle this incrementally. > > vertical space missing > > > + else if (TREE_CODE (inner_type) == OFFSET_TYPE > > + && TREE_CODE (inner_type) == TREE_CODE (outer_type)) > > + return useless_type_conversion_p (TREE_TYPE (outer_type), > > + TREE_TYPE (inner_type)) > > + && useless_type_conversion_p > > + (TYPE_OFFSET_BASETYPE (outer_type), > > + TYPE_OFFSET_BASETYPE (inner_type)); > > I believe OFFSET_TYPEs in GIMPLE are a red herring - the only cases > I saw them are on INTEGER_CSTs. Nothing in the middle-end looks at their > type or TYPE_OFFSET_BASETYPE. IMHO the C++ frontend should > GIMPLIFY those away. I don't remember trying that btw. so I believe > it might be quite easy (and OFFSET_TYPE should become a C++ frontend > tree code). Agreed. I also do not see reason to have them and their existence always surprise me. I can try to look into this incrementally (keeping the compare as it is right now) Jason, do you have any suggestions how this can be done? I guess we can pull those out of onstant initializers when folding, so we may need to do some canonicalization here. Honza > > > > > return false; > > } > > > > > > -- > Richard Biener <rguent...@suse.de> > SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB > 21284 (AG Nuernberg)