On Tue, 6 Oct 2015, Jan Hubicka wrote: > Hi, > While looking for uses of useless_type_conversion on non-gimple register types > I run across few that seem to be completely unnecesary and I would like to get > rid of them in hope to get rid of code comparing functions/method type and > possibly more. > > usless_type_conversion is about operations on the types in gimple expressions, > not about memory accesses nor about function calls. > > First on is in fold-const.c that may be used on MEM_REF of aggregate type. > As discussed earlier, the type compare is unnecesary when we only care about > address that seems to be the most comon case we get into this path. > > I also disabled type matching done by operand_equal_p and cleaned up the > conditional of MEM_REF into multiple ones - for example it was passing > OEP_ADDRESS_OF when comparing TYPE_SIZE which is quite a nonsense. > > I wonder what to do about OPE_CONSTANT_ADDRESS_OF. This flag does not seem > to be used at all in current tree nor documented somehow.
Eric added that. It's set when seeing ADDR_EXPRs and has an extra special handling when TREE_SIDE_EFFECTS are tested. It matters for Ada I guess. > I also made operand_equal_p to skip AA compare when -fno-strict-aliasing > is used. > > Bootstrapped/regtested x86_64-linux, OK? See comments below - otherwise it looks good. Richard. > Honza > > * fold-const.c (operand_equal_p): When in OEP_ADDRESS_OF > do not require types to match; also relax checking of MEM_REF. > Index: fold-const.c > =================================================================== > --- fold-const.c (revision 228131) > +++ fold-const.c (working copy) > @@ -2712,26 +2712,31 @@ operand_equal_p (const_tree arg0, const_ > if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST) > return tree_int_cst_equal (arg0, arg1); > > - /* If both types don't have the same signedness, then we can't consider > - them equal. We must check this before the STRIP_NOPS calls > - because they may change the signedness of the arguments. As pointers > - strictly don't have a signedness, require either two pointers or > - two non-pointers as well. */ > - if (TYPE_UNSIGNED (TREE_TYPE (arg0)) != TYPE_UNSIGNED (TREE_TYPE (arg1)) > - || POINTER_TYPE_P (TREE_TYPE (arg0)) != POINTER_TYPE_P (TREE_TYPE > (arg1))) > - return 0; > + if (!(flags & OEP_ADDRESS_OF)) > + { > + /* If both types don't have the same signedness, then we can't consider > + them equal. We must check this before the STRIP_NOPS calls > + because they may change the signedness of the arguments. As pointers > + strictly don't have a signedness, require either two pointers or > + two non-pointers as well. */ > + if (TYPE_UNSIGNED (TREE_TYPE (arg0)) != TYPE_UNSIGNED (TREE_TYPE > (arg1)) > + || POINTER_TYPE_P (TREE_TYPE (arg0)) > + != POINTER_TYPE_P (TREE_TYPE (arg1))) > + return 0; > > - /* We cannot consider pointers to different address space equal. */ > - if (POINTER_TYPE_P (TREE_TYPE (arg0)) && POINTER_TYPE_P (TREE_TYPE (arg1)) > - && (TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (arg0))) > - != TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (arg1))))) > - return 0; > + /* We cannot consider pointers to different address space equal. */ > + if (POINTER_TYPE_P (TREE_TYPE (arg0)) > + && POINTER_TYPE_P (TREE_TYPE (arg1)) > + && (TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (arg0))) > + != TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (arg1))))) > + return 0; > > - /* If both types don't have the same precision, then it is not safe > - to strip NOPs. */ > - if (element_precision (TREE_TYPE (arg0)) > - != element_precision (TREE_TYPE (arg1))) > - return 0; > + /* If both types don't have the same precision, then it is not safe > + to strip NOPs. */ > + if (element_precision (TREE_TYPE (arg0)) > + != element_precision (TREE_TYPE (arg1))) > + return 0; It's odd that you move this under the !OEP_ADDRESS_OF case but not the STRIP_NOPS itself. > + } > > STRIP_NOPS (arg0); > STRIP_NOPS (arg1); > @@ -2935,27 +2940,34 @@ operand_equal_p (const_tree arg0, const_ > > case TARGET_MEM_REF: > case MEM_REF: > - /* Require equal access sizes, and similar pointer types. > - We can have incomplete types for array references of > - variable-sized arrays from the Fortran frontend > - though. Also verify the types are compatible. */ > - if (!((TYPE_SIZE (TREE_TYPE (arg0)) == TYPE_SIZE (TREE_TYPE (arg1)) > - || (TYPE_SIZE (TREE_TYPE (arg0)) > - && TYPE_SIZE (TREE_TYPE (arg1)) > - && operand_equal_p (TYPE_SIZE (TREE_TYPE (arg0)), > - TYPE_SIZE (TREE_TYPE (arg1)), > flags))) > - && types_compatible_p (TREE_TYPE (arg0), TREE_TYPE (arg1)) > - && ((flags & OEP_ADDRESS_OF) > - || (alias_ptr_types_compatible_p > - (TREE_TYPE (TREE_OPERAND (arg0, 1)), > - TREE_TYPE (TREE_OPERAND (arg1, 1))) > - && (MR_DEPENDENCE_CLIQUE (arg0) > - == MR_DEPENDENCE_CLIQUE (arg1)) > - && (MR_DEPENDENCE_BASE (arg0) > - == MR_DEPENDENCE_BASE (arg1)) > - && (TYPE_ALIGN (TREE_TYPE (arg0)) > - == TYPE_ALIGN (TREE_TYPE (arg1))))))) > - return 0; > + if (!(flags & OEP_ADDRESS_OF)) > + { > + /* Require equal access sizes */ > + if (TYPE_SIZE (TREE_TYPE (arg0)) != TYPE_SIZE (TREE_TYPE (arg1)) > + && (!TYPE_SIZE (TREE_TYPE (arg0)) > + || !TYPE_SIZE (TREE_TYPE (arg1)) > + || !operand_equal_p (TYPE_SIZE (TREE_TYPE (arg0)), > + TYPE_SIZE (TREE_TYPE (arg1)), > + flags & ~OEP_CONSTANT_ADDRESS_OF))) so you still pass OEP_ADDRESS_OF ... > + return 0; > + /* Verify that access happens in similar types. */ > + if (!types_compatible_p (TREE_TYPE (arg0), TREE_TYPE (arg1))) > + return 0; > + /* Verify that accesses are TBAA compatible. */ > + if ((flag_strict_aliasing > + && !alias_ptr_types_compatible_p > + (TREE_TYPE (TREE_OPERAND (arg0, 1)), > + TREE_TYPE (TREE_OPERAND (arg1, 1)))) > + || MR_DEPENDENCE_CLIQUE (arg0) > + != MR_DEPENDENCE_CLIQUE (arg1) > + || MR_DEPENDENCE_BASE (arg0) > + != MR_DEPENDENCE_BASE (arg1)) > + return 0; > + } > + /* Verify that alignment is compatible. */ > + if (TYPE_ALIGN (TREE_TYPE (arg0)) > + != TYPE_ALIGN (TREE_TYPE (arg1))) > + return 0; why's compatible alignment required for OEP_ADDRESS_OF? We only look at type alignment on memory references (see get_pointer_alignment vs. get_object_alignment). > flags &= ~(OEP_CONSTANT_ADDRESS_OF|OEP_ADDRESS_OF); > return (OP_SAME (0) && OP_SAME (1) > /* TARGET_MEM_REF require equal extra operands. */ > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)