Message ID | patch-18722-tamar@arm.com |
---|---|
State | New |
Headers | show |
Series | [1/2] middle-end: refactor type to be explicit in operand_equal_p [PR114932] | expand |
ping > -----Original Message----- > From: Tamar Christina <tamar.christina@arm.com> > Sent: Tuesday, August 20, 2024 2:06 PM > To: gcc-patches@gcc.gnu.org > Cc: nd <nd@arm.com>; rguenther@suse.de; jlaw@ventanamicro.com > Subject: [PATCH 1/2]middle-end: refactor type to be explicit in operand_equal_p > [PR114932] > > Hi All, > > This is a refactoring with no expected behavioral change. > The goal with this is to make the type of the expressions being used explicit. > > I did not change all the recursive calls to operand_equal_p () to recurse > directly to the new function but instead this goes through the top level call > which re-extracts the types. > > This was done because in most of the cases where we recurse type == arg. > The second patch makes use of this new flexibility to implement an overload > of operand_equal_p which checks for equality under two's complement. > > Bootstrapped Regtested on aarch64-none-linux-gnu, > arm-none-linux-gnueabihf, x86_64-pc-linux-gnu > -m32, -m64 and no issues. > > Ok for master? > > Thanks, > Tamar > > gcc/ChangeLog: > > PR tree-optimization/114932 > * fold-const.cc (operand_compare::operand_equal_p): Split into one that > takes explicit type parameters and use that in public one. > * fold-const.h (class operand_compare): Add operand_equal_p private > overload. > > --- > diff --git a/gcc/fold-const.h b/gcc/fold-const.h > index > b82ef137e2f2096f86c20df3c7749747e604177e..878545b1148b839e8a8e866f > 38e31161f0d116c8 100644 > --- a/gcc/fold-const.h > +++ b/gcc/fold-const.h > @@ -273,6 +273,12 @@ protected: > true is returned. Then RET is set to corresponding comparsion result. */ > bool verify_hash_value (const_tree arg0, const_tree arg1, unsigned int flags, > bool *ret); > + > +private: > + /* Return true if two operands are equal. The flags fields can be used > + to specify OEP flags described in tree-core.h. */ > + bool operand_equal_p (tree, const_tree, tree, const_tree, > + unsigned int flags); > }; > > #endif // GCC_FOLD_CONST_H > diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc > index > 8908e7381e72cbbf4a8fd96f18cbf4436aba8441..71e82b1d76d4106c7c23c54af > 8b35905a1af9f1c 100644 > --- a/gcc/fold-const.cc > +++ b/gcc/fold-const.cc > @@ -3156,6 +3156,17 @@ combine_comparisons (location_t loc, > bool > operand_compare::operand_equal_p (const_tree arg0, const_tree arg1, > unsigned int flags) > +{ > + return operand_equal_p (TREE_TYPE (arg0), arg0, TREE_TYPE (arg1), arg1, > flags); > +} > + > +/* The same as operand_equal_p however the type of ARG0 and ARG1 are > assumed to be > + the TYPE0 and TYPE1 respectively. */ > + > +bool > +operand_compare::operand_equal_p (tree type0, const_tree arg0, > + tree type1, const_tree arg1, > + unsigned int flags) > { > bool r; > if (verify_hash_value (arg0, arg1, flags, &r)) > @@ -3166,25 +3177,25 @@ operand_compare::operand_equal_p (const_tree > arg0, const_tree arg1, > > /* If either is ERROR_MARK, they aren't equal. */ > if (TREE_CODE (arg0) == ERROR_MARK || TREE_CODE (arg1) == ERROR_MARK > - || TREE_TYPE (arg0) == error_mark_node > - || TREE_TYPE (arg1) == error_mark_node) > + || type0 == error_mark_node > + || type1 == error_mark_node) > return false; > > /* Similar, if either does not have a type (like a template id), > they aren't equal. */ > - if (!TREE_TYPE (arg0) || !TREE_TYPE (arg1)) > + if (!type0 || !type1) > return false; > > /* Bitwise identity makes no sense if the values have different layouts. */ > if ((flags & OEP_BITWISE) > - && !tree_nop_conversion_p (TREE_TYPE (arg0), TREE_TYPE (arg1))) > + && !tree_nop_conversion_p (type0, type1)) > return false; > > /* 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))))) > + if (POINTER_TYPE_P (type0) > + && POINTER_TYPE_P (type1) > + && (TYPE_ADDR_SPACE (TREE_TYPE (type0)) > + != TYPE_ADDR_SPACE (TREE_TYPE (type1)))) > return false; > > /* Check equality of integer constants before bailing out due to > @@ -3211,12 +3222,15 @@ operand_compare::operand_equal_p (const_tree > arg0, const_tree arg1, > > /* 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))) > + if (element_precision (type0) > + != element_precision (type1)) > return false; > > STRIP_NOPS (arg0); > STRIP_NOPS (arg1); > + > + type0 = TREE_TYPE (arg0); > + type1 = TREE_TYPE (arg1); > } > #if 0 > /* FIXME: Fortran FE currently produce ADDR_EXPR of NOP_EXPR. Enable the > @@ -3275,9 +3289,9 @@ operand_compare::operand_equal_p (const_tree arg0, > const_tree arg1, > > /* When not checking adddresses, this is needed for conversions and for > COMPONENT_REF. Might as well play it safe and always test this. */ > - if (TREE_CODE (TREE_TYPE (arg0)) == ERROR_MARK > - || TREE_CODE (TREE_TYPE (arg1)) == ERROR_MARK > - || (TYPE_MODE (TREE_TYPE (arg0)) != TYPE_MODE (TREE_TYPE (arg1)) > + if (TREE_CODE (type0) == ERROR_MARK > + || TREE_CODE (type1) == ERROR_MARK > + || (TYPE_MODE (type0) != TYPE_MODE (type1) > && !(flags & OEP_ADDRESS_OF))) > return false; > > @@ -3364,8 +3378,8 @@ operand_compare::operand_equal_p (const_tree arg0, > const_tree arg1, > return true; > > /* See sem_variable::equals in ipa-icf for a similar approach. */ > - tree typ0 = TREE_TYPE (arg0); > - tree typ1 = TREE_TYPE (arg1); > + tree typ0 = type0; > + tree typ1 = type1; > > if (TREE_CODE (typ0) != TREE_CODE (typ1)) > return false; > @@ -3444,8 +3458,8 @@ operand_compare::operand_equal_p (const_tree arg0, > const_tree arg1, > { > CASE_CONVERT: > case FIX_TRUNC_EXPR: > - if (TYPE_UNSIGNED (TREE_TYPE (arg0)) > - != TYPE_UNSIGNED (TREE_TYPE (arg1))) > + if (TYPE_UNSIGNED (type0) > + != TYPE_UNSIGNED (type1)) > return false; > break; > default: > @@ -3481,12 +3495,12 @@ operand_compare::operand_equal_p (const_tree > arg0, const_tree arg1, > case INDIRECT_REF: > if (!(flags & OEP_ADDRESS_OF)) > { > - if (TYPE_ALIGN (TREE_TYPE (arg0)) > - != TYPE_ALIGN (TREE_TYPE (arg1))) > + if (TYPE_ALIGN (type0) > + != TYPE_ALIGN (type1)) > return false; > /* Verify that the access types are compatible. */ > - if (TYPE_MAIN_VARIANT (TREE_TYPE (arg0)) > - != TYPE_MAIN_VARIANT (TREE_TYPE (arg1))) > + if (TYPE_MAIN_VARIANT (type0) > + != TYPE_MAIN_VARIANT (type1)) > return false; > } > flags &= ~OEP_ADDRESS_OF; > @@ -3494,8 +3508,8 @@ operand_compare::operand_equal_p (const_tree arg0, > const_tree arg1, > > case IMAGPART_EXPR: > /* Require the same offset. */ > - if (!operand_equal_p (TYPE_SIZE (TREE_TYPE (arg0)), > - TYPE_SIZE (TREE_TYPE (arg1)), > + if (!operand_equal_p (TYPE_SIZE (type0), > + TYPE_SIZE (type1), > flags & ~OEP_ADDRESS_OF)) > return false; > > @@ -3509,15 +3523,15 @@ operand_compare::operand_equal_p (const_tree > arg0, const_tree arg1, > 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)), > + if (TYPE_SIZE (type0) != TYPE_SIZE (type1) > + && (!TYPE_SIZE (type0) > + || !TYPE_SIZE (type1) > + || !operand_equal_p (TYPE_SIZE (type0), > + TYPE_SIZE (type1), > flags))) > return false; > /* Verify that access happens in similar types. */ > - if (!types_compatible_p (TREE_TYPE (arg0), TREE_TYPE (arg1))) > + if (!types_compatible_p (type0, type1)) > return false; > /* Verify that accesses are TBAA compatible. */ > if (!alias_ptr_types_compatible_p > @@ -3529,8 +3543,8 @@ operand_compare::operand_equal_p (const_tree arg0, > const_tree arg1, > != MR_DEPENDENCE_BASE (arg1))) > return false; > /* Verify that alignment is compatible. */ > - if (TYPE_ALIGN (TREE_TYPE (arg0)) > - != TYPE_ALIGN (TREE_TYPE (arg1))) > + if (TYPE_ALIGN (type0) > + != TYPE_ALIGN (type1)) > return false; > } > flags &= ~OEP_ADDRESS_OF; > @@ -3802,16 +3816,16 @@ operand_compare::operand_equal_p (const_tree > arg0, const_tree arg1, > indexed in increasing order and form an initial sequence. > > We make no effort to compare nonconstant ones in GENERIC. */ > - if (!VECTOR_TYPE_P (TREE_TYPE (arg0)) > - || !VECTOR_TYPE_P (TREE_TYPE (arg1))) > + if (!VECTOR_TYPE_P (type0) > + || !VECTOR_TYPE_P (type1)) > return false; > > /* Be sure that vectors constructed have the same representation. > We only tested element precision and modes to match. > Vectors may be BLKmode and thus also check that the number of > parts match. */ > - if (maybe_ne (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)), > - TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg1)))) > + if (maybe_ne (TYPE_VECTOR_SUBPARTS (type0), > + TYPE_VECTOR_SUBPARTS (type1))) > return false; > > vec<constructor_elt, va_gc> *v0 = CONSTRUCTOR_ELTS (arg0); > > > > > --
ping > -----Original Message----- > From: Tamar Christina > Sent: Tuesday, September 10, 2024 8:57 PM > To: Tamar Christina <tamar.christina@arm.com>; gcc-patches@gcc.gnu.org > Cc: nd <nd@arm.com>; rguenther@suse.de; jlaw@ventanamicro.com > Subject: RE: [PATCH 1/2]middle-end: refactor type to be explicit in > operand_equal_p [PR114932] > > ping > > > -----Original Message----- > > From: Tamar Christina <tamar.christina@arm.com> > > Sent: Tuesday, August 20, 2024 2:06 PM > > To: gcc-patches@gcc.gnu.org > > Cc: nd <nd@arm.com>; rguenther@suse.de; jlaw@ventanamicro.com > > Subject: [PATCH 1/2]middle-end: refactor type to be explicit in operand_equal_p > > [PR114932] > > > > Hi All, > > > > This is a refactoring with no expected behavioral change. > > The goal with this is to make the type of the expressions being used explicit. > > > > I did not change all the recursive calls to operand_equal_p () to recurse > > directly to the new function but instead this goes through the top level call > > which re-extracts the types. > > > > This was done because in most of the cases where we recurse type == arg. > > The second patch makes use of this new flexibility to implement an overload > > of operand_equal_p which checks for equality under two's complement. > > > > Bootstrapped Regtested on aarch64-none-linux-gnu, > > arm-none-linux-gnueabihf, x86_64-pc-linux-gnu > > -m32, -m64 and no issues. > > > > Ok for master? > > > > Thanks, > > Tamar > > > > gcc/ChangeLog: > > > > PR tree-optimization/114932 > > * fold-const.cc (operand_compare::operand_equal_p): Split into one that > > takes explicit type parameters and use that in public one. > > * fold-const.h (class operand_compare): Add operand_equal_p private > > overload. > > > > --- > > diff --git a/gcc/fold-const.h b/gcc/fold-const.h > > index > > > b82ef137e2f2096f86c20df3c7749747e604177e..878545b1148b839e8a8e866f > > 38e31161f0d116c8 100644 > > --- a/gcc/fold-const.h > > +++ b/gcc/fold-const.h > > @@ -273,6 +273,12 @@ protected: > > true is returned. Then RET is set to corresponding comparsion result. */ > > bool verify_hash_value (const_tree arg0, const_tree arg1, unsigned int flags, > > bool *ret); > > + > > +private: > > + /* Return true if two operands are equal. The flags fields can be used > > + to specify OEP flags described in tree-core.h. */ > > + bool operand_equal_p (tree, const_tree, tree, const_tree, > > + unsigned int flags); > > }; > > > > #endif // GCC_FOLD_CONST_H > > diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc > > index > > > 8908e7381e72cbbf4a8fd96f18cbf4436aba8441..71e82b1d76d4106c7c23c54af > > 8b35905a1af9f1c 100644 > > --- a/gcc/fold-const.cc > > +++ b/gcc/fold-const.cc > > @@ -3156,6 +3156,17 @@ combine_comparisons (location_t loc, > > bool > > operand_compare::operand_equal_p (const_tree arg0, const_tree arg1, > > unsigned int flags) > > +{ > > + return operand_equal_p (TREE_TYPE (arg0), arg0, TREE_TYPE (arg1), arg1, > > flags); > > +} > > + > > +/* The same as operand_equal_p however the type of ARG0 and ARG1 are > > assumed to be > > + the TYPE0 and TYPE1 respectively. */ > > + > > +bool > > +operand_compare::operand_equal_p (tree type0, const_tree arg0, > > + tree type1, const_tree arg1, > > + unsigned int flags) > > { > > bool r; > > if (verify_hash_value (arg0, arg1, flags, &r)) > > @@ -3166,25 +3177,25 @@ operand_compare::operand_equal_p (const_tree > > arg0, const_tree arg1, > > > > /* If either is ERROR_MARK, they aren't equal. */ > > if (TREE_CODE (arg0) == ERROR_MARK || TREE_CODE (arg1) == ERROR_MARK > > - || TREE_TYPE (arg0) == error_mark_node > > - || TREE_TYPE (arg1) == error_mark_node) > > + || type0 == error_mark_node > > + || type1 == error_mark_node) > > return false; > > > > /* Similar, if either does not have a type (like a template id), > > they aren't equal. */ > > - if (!TREE_TYPE (arg0) || !TREE_TYPE (arg1)) > > + if (!type0 || !type1) > > return false; > > > > /* Bitwise identity makes no sense if the values have different layouts. */ > > if ((flags & OEP_BITWISE) > > - && !tree_nop_conversion_p (TREE_TYPE (arg0), TREE_TYPE (arg1))) > > + && !tree_nop_conversion_p (type0, type1)) > > return false; > > > > /* 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))))) > > + if (POINTER_TYPE_P (type0) > > + && POINTER_TYPE_P (type1) > > + && (TYPE_ADDR_SPACE (TREE_TYPE (type0)) > > + != TYPE_ADDR_SPACE (TREE_TYPE (type1)))) > > return false; > > > > /* Check equality of integer constants before bailing out due to > > @@ -3211,12 +3222,15 @@ operand_compare::operand_equal_p (const_tree > > arg0, const_tree arg1, > > > > /* 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))) > > + if (element_precision (type0) > > + != element_precision (type1)) > > return false; > > > > STRIP_NOPS (arg0); > > STRIP_NOPS (arg1); > > + > > + type0 = TREE_TYPE (arg0); > > + type1 = TREE_TYPE (arg1); > > } > > #if 0 > > /* FIXME: Fortran FE currently produce ADDR_EXPR of NOP_EXPR. Enable the > > @@ -3275,9 +3289,9 @@ operand_compare::operand_equal_p (const_tree > arg0, > > const_tree arg1, > > > > /* When not checking adddresses, this is needed for conversions and for > > COMPONENT_REF. Might as well play it safe and always test this. */ > > - if (TREE_CODE (TREE_TYPE (arg0)) == ERROR_MARK > > - || TREE_CODE (TREE_TYPE (arg1)) == ERROR_MARK > > - || (TYPE_MODE (TREE_TYPE (arg0)) != TYPE_MODE (TREE_TYPE (arg1)) > > + if (TREE_CODE (type0) == ERROR_MARK > > + || TREE_CODE (type1) == ERROR_MARK > > + || (TYPE_MODE (type0) != TYPE_MODE (type1) > > && !(flags & OEP_ADDRESS_OF))) > > return false; > > > > @@ -3364,8 +3378,8 @@ operand_compare::operand_equal_p (const_tree > arg0, > > const_tree arg1, > > return true; > > > > /* See sem_variable::equals in ipa-icf for a similar approach. */ > > - tree typ0 = TREE_TYPE (arg0); > > - tree typ1 = TREE_TYPE (arg1); > > + tree typ0 = type0; > > + tree typ1 = type1; > > > > if (TREE_CODE (typ0) != TREE_CODE (typ1)) > > return false; > > @@ -3444,8 +3458,8 @@ operand_compare::operand_equal_p (const_tree > arg0, > > const_tree arg1, > > { > > CASE_CONVERT: > > case FIX_TRUNC_EXPR: > > - if (TYPE_UNSIGNED (TREE_TYPE (arg0)) > > - != TYPE_UNSIGNED (TREE_TYPE (arg1))) > > + if (TYPE_UNSIGNED (type0) > > + != TYPE_UNSIGNED (type1)) > > return false; > > break; > > default: > > @@ -3481,12 +3495,12 @@ operand_compare::operand_equal_p (const_tree > > arg0, const_tree arg1, > > case INDIRECT_REF: > > if (!(flags & OEP_ADDRESS_OF)) > > { > > - if (TYPE_ALIGN (TREE_TYPE (arg0)) > > - != TYPE_ALIGN (TREE_TYPE (arg1))) > > + if (TYPE_ALIGN (type0) > > + != TYPE_ALIGN (type1)) > > return false; > > /* Verify that the access types are compatible. */ > > - if (TYPE_MAIN_VARIANT (TREE_TYPE (arg0)) > > - != TYPE_MAIN_VARIANT (TREE_TYPE (arg1))) > > + if (TYPE_MAIN_VARIANT (type0) > > + != TYPE_MAIN_VARIANT (type1)) > > return false; > > } > > flags &= ~OEP_ADDRESS_OF; > > @@ -3494,8 +3508,8 @@ operand_compare::operand_equal_p (const_tree > arg0, > > const_tree arg1, > > > > case IMAGPART_EXPR: > > /* Require the same offset. */ > > - if (!operand_equal_p (TYPE_SIZE (TREE_TYPE (arg0)), > > - TYPE_SIZE (TREE_TYPE (arg1)), > > + if (!operand_equal_p (TYPE_SIZE (type0), > > + TYPE_SIZE (type1), > > flags & ~OEP_ADDRESS_OF)) > > return false; > > > > @@ -3509,15 +3523,15 @@ operand_compare::operand_equal_p (const_tree > > arg0, const_tree arg1, > > 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)), > > + if (TYPE_SIZE (type0) != TYPE_SIZE (type1) > > + && (!TYPE_SIZE (type0) > > + || !TYPE_SIZE (type1) > > + || !operand_equal_p (TYPE_SIZE (type0), > > + TYPE_SIZE (type1), > > flags))) > > return false; > > /* Verify that access happens in similar types. */ > > - if (!types_compatible_p (TREE_TYPE (arg0), TREE_TYPE (arg1))) > > + if (!types_compatible_p (type0, type1)) > > return false; > > /* Verify that accesses are TBAA compatible. */ > > if (!alias_ptr_types_compatible_p > > @@ -3529,8 +3543,8 @@ operand_compare::operand_equal_p (const_tree > arg0, > > const_tree arg1, > > != MR_DEPENDENCE_BASE (arg1))) > > return false; > > /* Verify that alignment is compatible. */ > > - if (TYPE_ALIGN (TREE_TYPE (arg0)) > > - != TYPE_ALIGN (TREE_TYPE (arg1))) > > + if (TYPE_ALIGN (type0) > > + != TYPE_ALIGN (type1)) > > return false; > > } > > flags &= ~OEP_ADDRESS_OF; > > @@ -3802,16 +3816,16 @@ operand_compare::operand_equal_p (const_tree > > arg0, const_tree arg1, > > indexed in increasing order and form an initial sequence. > > > > We make no effort to compare nonconstant ones in GENERIC. */ > > - if (!VECTOR_TYPE_P (TREE_TYPE (arg0)) > > - || !VECTOR_TYPE_P (TREE_TYPE (arg1))) > > + if (!VECTOR_TYPE_P (type0) > > + || !VECTOR_TYPE_P (type1)) > > return false; > > > > /* Be sure that vectors constructed have the same representation. > > We only tested element precision and modes to match. > > Vectors may be BLKmode and thus also check that the number of > > parts match. */ > > - if (maybe_ne (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)), > > - TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg1)))) > > + if (maybe_ne (TYPE_VECTOR_SUBPARTS (type0), > > + TYPE_VECTOR_SUBPARTS (type1))) > > return false; > > > > vec<constructor_elt, va_gc> *v0 = CONSTRUCTOR_ELTS (arg0); > > > > > > > > > > --
ping > -----Original Message----- > From: Tamar Christina <Tamar.Christina@arm.com> > Sent: Monday, September 23, 2024 8:41 AM > To: gcc-patches@gcc.gnu.org > Cc: nd <nd@arm.com>; rguenther@suse.de; jlaw@ventanamicro.com > Subject: RE: [PATCH 1/2]middle-end: refactor type to be explicit in > operand_equal_p [PR114932] > > ping > > > -----Original Message----- > > From: Tamar Christina > > Sent: Tuesday, September 10, 2024 8:57 PM > > To: Tamar Christina <tamar.christina@arm.com>; gcc-patches@gcc.gnu.org > > Cc: nd <nd@arm.com>; rguenther@suse.de; jlaw@ventanamicro.com > > Subject: RE: [PATCH 1/2]middle-end: refactor type to be explicit in > > operand_equal_p [PR114932] > > > > ping > > > > > -----Original Message----- > > > From: Tamar Christina <tamar.christina@arm.com> > > > Sent: Tuesday, August 20, 2024 2:06 PM > > > To: gcc-patches@gcc.gnu.org > > > Cc: nd <nd@arm.com>; rguenther@suse.de; jlaw@ventanamicro.com > > > Subject: [PATCH 1/2]middle-end: refactor type to be explicit in > operand_equal_p > > > [PR114932] > > > > > > Hi All, > > > > > > This is a refactoring with no expected behavioral change. > > > The goal with this is to make the type of the expressions being used explicit. > > > > > > I did not change all the recursive calls to operand_equal_p () to recurse > > > directly to the new function but instead this goes through the top level call > > > which re-extracts the types. > > > > > > This was done because in most of the cases where we recurse type == arg. > > > The second patch makes use of this new flexibility to implement an overload > > > of operand_equal_p which checks for equality under two's complement. > > > > > > Bootstrapped Regtested on aarch64-none-linux-gnu, > > > arm-none-linux-gnueabihf, x86_64-pc-linux-gnu > > > -m32, -m64 and no issues. > > > > > > Ok for master? > > > > > > Thanks, > > > Tamar > > > > > > gcc/ChangeLog: > > > > > > PR tree-optimization/114932 > > > * fold-const.cc (operand_compare::operand_equal_p): Split into one that > > > takes explicit type parameters and use that in public one. > > > * fold-const.h (class operand_compare): Add operand_equal_p private > > > overload. > > > > > > --- > > > diff --git a/gcc/fold-const.h b/gcc/fold-const.h > > > index > > > > > > b82ef137e2f2096f86c20df3c7749747e604177e..878545b1148b839e8a8e866f > > > 38e31161f0d116c8 100644 > > > --- a/gcc/fold-const.h > > > +++ b/gcc/fold-const.h > > > @@ -273,6 +273,12 @@ protected: > > > true is returned. Then RET is set to corresponding comparsion result. */ > > > bool verify_hash_value (const_tree arg0, const_tree arg1, unsigned int flags, > > > bool *ret); > > > + > > > +private: > > > + /* Return true if two operands are equal. The flags fields can be used > > > + to specify OEP flags described in tree-core.h. */ > > > + bool operand_equal_p (tree, const_tree, tree, const_tree, > > > + unsigned int flags); > > > }; > > > > > > #endif // GCC_FOLD_CONST_H > > > diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc > > > index > > > > > > 8908e7381e72cbbf4a8fd96f18cbf4436aba8441..71e82b1d76d4106c7c23c54af > > > 8b35905a1af9f1c 100644 > > > --- a/gcc/fold-const.cc > > > +++ b/gcc/fold-const.cc > > > @@ -3156,6 +3156,17 @@ combine_comparisons (location_t loc, > > > bool > > > operand_compare::operand_equal_p (const_tree arg0, const_tree arg1, > > > unsigned int flags) > > > +{ > > > + return operand_equal_p (TREE_TYPE (arg0), arg0, TREE_TYPE (arg1), arg1, > > > flags); > > > +} > > > + > > > +/* The same as operand_equal_p however the type of ARG0 and ARG1 are > > > assumed to be > > > + the TYPE0 and TYPE1 respectively. */ > > > + > > > +bool > > > +operand_compare::operand_equal_p (tree type0, const_tree arg0, > > > + tree type1, const_tree arg1, > > > + unsigned int flags) > > > { > > > bool r; > > > if (verify_hash_value (arg0, arg1, flags, &r)) > > > @@ -3166,25 +3177,25 @@ operand_compare::operand_equal_p > (const_tree > > > arg0, const_tree arg1, > > > > > > /* If either is ERROR_MARK, they aren't equal. */ > > > if (TREE_CODE (arg0) == ERROR_MARK || TREE_CODE (arg1) == > ERROR_MARK > > > - || TREE_TYPE (arg0) == error_mark_node > > > - || TREE_TYPE (arg1) == error_mark_node) > > > + || type0 == error_mark_node > > > + || type1 == error_mark_node) > > > return false; > > > > > > /* Similar, if either does not have a type (like a template id), > > > they aren't equal. */ > > > - if (!TREE_TYPE (arg0) || !TREE_TYPE (arg1)) > > > + if (!type0 || !type1) > > > return false; > > > > > > /* Bitwise identity makes no sense if the values have different layouts. */ > > > if ((flags & OEP_BITWISE) > > > - && !tree_nop_conversion_p (TREE_TYPE (arg0), TREE_TYPE (arg1))) > > > + && !tree_nop_conversion_p (type0, type1)) > > > return false; > > > > > > /* 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))))) > > > + if (POINTER_TYPE_P (type0) > > > + && POINTER_TYPE_P (type1) > > > + && (TYPE_ADDR_SPACE (TREE_TYPE (type0)) > > > + != TYPE_ADDR_SPACE (TREE_TYPE (type1)))) > > > return false; > > > > > > /* Check equality of integer constants before bailing out due to > > > @@ -3211,12 +3222,15 @@ operand_compare::operand_equal_p > (const_tree > > > arg0, const_tree arg1, > > > > > > /* 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))) > > > + if (element_precision (type0) > > > + != element_precision (type1)) > > > return false; > > > > > > STRIP_NOPS (arg0); > > > STRIP_NOPS (arg1); > > > + > > > + type0 = TREE_TYPE (arg0); > > > + type1 = TREE_TYPE (arg1); > > > } > > > #if 0 > > > /* FIXME: Fortran FE currently produce ADDR_EXPR of NOP_EXPR. Enable the > > > @@ -3275,9 +3289,9 @@ operand_compare::operand_equal_p (const_tree > > arg0, > > > const_tree arg1, > > > > > > /* When not checking adddresses, this is needed for conversions and for > > > COMPONENT_REF. Might as well play it safe and always test this. */ > > > - if (TREE_CODE (TREE_TYPE (arg0)) == ERROR_MARK > > > - || TREE_CODE (TREE_TYPE (arg1)) == ERROR_MARK > > > - || (TYPE_MODE (TREE_TYPE (arg0)) != TYPE_MODE (TREE_TYPE (arg1)) > > > + if (TREE_CODE (type0) == ERROR_MARK > > > + || TREE_CODE (type1) == ERROR_MARK > > > + || (TYPE_MODE (type0) != TYPE_MODE (type1) > > > && !(flags & OEP_ADDRESS_OF))) > > > return false; > > > > > > @@ -3364,8 +3378,8 @@ operand_compare::operand_equal_p (const_tree > > arg0, > > > const_tree arg1, > > > return true; > > > > > > /* See sem_variable::equals in ipa-icf for a similar approach. */ > > > - tree typ0 = TREE_TYPE (arg0); > > > - tree typ1 = TREE_TYPE (arg1); > > > + tree typ0 = type0; > > > + tree typ1 = type1; > > > > > > if (TREE_CODE (typ0) != TREE_CODE (typ1)) > > > return false; > > > @@ -3444,8 +3458,8 @@ operand_compare::operand_equal_p (const_tree > > arg0, > > > const_tree arg1, > > > { > > > CASE_CONVERT: > > > case FIX_TRUNC_EXPR: > > > - if (TYPE_UNSIGNED (TREE_TYPE (arg0)) > > > - != TYPE_UNSIGNED (TREE_TYPE (arg1))) > > > + if (TYPE_UNSIGNED (type0) > > > + != TYPE_UNSIGNED (type1)) > > > return false; > > > break; > > > default: > > > @@ -3481,12 +3495,12 @@ operand_compare::operand_equal_p > (const_tree > > > arg0, const_tree arg1, > > > case INDIRECT_REF: > > > if (!(flags & OEP_ADDRESS_OF)) > > > { > > > - if (TYPE_ALIGN (TREE_TYPE (arg0)) > > > - != TYPE_ALIGN (TREE_TYPE (arg1))) > > > + if (TYPE_ALIGN (type0) > > > + != TYPE_ALIGN (type1)) > > > return false; > > > /* Verify that the access types are compatible. */ > > > - if (TYPE_MAIN_VARIANT (TREE_TYPE (arg0)) > > > - != TYPE_MAIN_VARIANT (TREE_TYPE (arg1))) > > > + if (TYPE_MAIN_VARIANT (type0) > > > + != TYPE_MAIN_VARIANT (type1)) > > > return false; > > > } > > > flags &= ~OEP_ADDRESS_OF; > > > @@ -3494,8 +3508,8 @@ operand_compare::operand_equal_p (const_tree > > arg0, > > > const_tree arg1, > > > > > > case IMAGPART_EXPR: > > > /* Require the same offset. */ > > > - if (!operand_equal_p (TYPE_SIZE (TREE_TYPE (arg0)), > > > - TYPE_SIZE (TREE_TYPE (arg1)), > > > + if (!operand_equal_p (TYPE_SIZE (type0), > > > + TYPE_SIZE (type1), > > > flags & ~OEP_ADDRESS_OF)) > > > return false; > > > > > > @@ -3509,15 +3523,15 @@ operand_compare::operand_equal_p > (const_tree > > > arg0, const_tree arg1, > > > 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)), > > > + if (TYPE_SIZE (type0) != TYPE_SIZE (type1) > > > + && (!TYPE_SIZE (type0) > > > + || !TYPE_SIZE (type1) > > > + || !operand_equal_p (TYPE_SIZE (type0), > > > + TYPE_SIZE (type1), > > > flags))) > > > return false; > > > /* Verify that access happens in similar types. */ > > > - if (!types_compatible_p (TREE_TYPE (arg0), TREE_TYPE (arg1))) > > > + if (!types_compatible_p (type0, type1)) > > > return false; > > > /* Verify that accesses are TBAA compatible. */ > > > if (!alias_ptr_types_compatible_p > > > @@ -3529,8 +3543,8 @@ operand_compare::operand_equal_p (const_tree > > arg0, > > > const_tree arg1, > > > != MR_DEPENDENCE_BASE (arg1))) > > > return false; > > > /* Verify that alignment is compatible. */ > > > - if (TYPE_ALIGN (TREE_TYPE (arg0)) > > > - != TYPE_ALIGN (TREE_TYPE (arg1))) > > > + if (TYPE_ALIGN (type0) > > > + != TYPE_ALIGN (type1)) > > > return false; > > > } > > > flags &= ~OEP_ADDRESS_OF; > > > @@ -3802,16 +3816,16 @@ operand_compare::operand_equal_p > (const_tree > > > arg0, const_tree arg1, > > > indexed in increasing order and form an initial sequence. > > > > > > We make no effort to compare nonconstant ones in GENERIC. */ > > > - if (!VECTOR_TYPE_P (TREE_TYPE (arg0)) > > > - || !VECTOR_TYPE_P (TREE_TYPE (arg1))) > > > + if (!VECTOR_TYPE_P (type0) > > > + || !VECTOR_TYPE_P (type1)) > > > return false; > > > > > > /* Be sure that vectors constructed have the same representation. > > > We only tested element precision and modes to match. > > > Vectors may be BLKmode and thus also check that the number of > > > parts match. */ > > > - if (maybe_ne (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)), > > > - TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg1)))) > > > + if (maybe_ne (TYPE_VECTOR_SUBPARTS (type0), > > > + TYPE_VECTOR_SUBPARTS (type1))) > > > return false; > > > > > > vec<constructor_elt, va_gc> *v0 = CONSTRUCTOR_ELTS (arg0); > > > > > > > > > > > > > > > --
ping > -----Original Message----- > From: Tamar Christina <Tamar.Christina@arm.com> > Sent: Monday, October 14, 2024 4:08 PM > To: Tamar Christina <Tamar.Christina@arm.com>; gcc-patches@gcc.gnu.org > Cc: nd <nd@arm.com>; rguenther@suse.de; jlaw@ventanamicro.com > Subject: RE: [PATCH 1/2]middle-end: refactor type to be explicit in > operand_equal_p [PR114932] > > ping > > > -----Original Message----- > > From: Tamar Christina <Tamar.Christina@arm.com> > > Sent: Monday, September 23, 2024 8:41 AM > > To: gcc-patches@gcc.gnu.org > > Cc: nd <nd@arm.com>; rguenther@suse.de; jlaw@ventanamicro.com > > Subject: RE: [PATCH 1/2]middle-end: refactor type to be explicit in > > operand_equal_p [PR114932] > > > > ping > > > > > -----Original Message----- > > > From: Tamar Christina > > > Sent: Tuesday, September 10, 2024 8:57 PM > > > To: Tamar Christina <tamar.christina@arm.com>; gcc-patches@gcc.gnu.org > > > Cc: nd <nd@arm.com>; rguenther@suse.de; jlaw@ventanamicro.com > > > Subject: RE: [PATCH 1/2]middle-end: refactor type to be explicit in > > > operand_equal_p [PR114932] > > > > > > ping > > > > > > > -----Original Message----- > > > > From: Tamar Christina <tamar.christina@arm.com> > > > > Sent: Tuesday, August 20, 2024 2:06 PM > > > > To: gcc-patches@gcc.gnu.org > > > > Cc: nd <nd@arm.com>; rguenther@suse.de; jlaw@ventanamicro.com > > > > Subject: [PATCH 1/2]middle-end: refactor type to be explicit in > > operand_equal_p > > > > [PR114932] > > > > > > > > Hi All, > > > > > > > > This is a refactoring with no expected behavioral change. > > > > The goal with this is to make the type of the expressions being used explicit. > > > > > > > > I did not change all the recursive calls to operand_equal_p () to recurse > > > > directly to the new function but instead this goes through the top level call > > > > which re-extracts the types. > > > > > > > > This was done because in most of the cases where we recurse type == arg. > > > > The second patch makes use of this new flexibility to implement an overload > > > > of operand_equal_p which checks for equality under two's complement. > > > > > > > > Bootstrapped Regtested on aarch64-none-linux-gnu, > > > > arm-none-linux-gnueabihf, x86_64-pc-linux-gnu > > > > -m32, -m64 and no issues. > > > > > > > > Ok for master? > > > > > > > > Thanks, > > > > Tamar > > > > > > > > gcc/ChangeLog: > > > > > > > > PR tree-optimization/114932 > > > > * fold-const.cc (operand_compare::operand_equal_p): Split into one that > > > > takes explicit type parameters and use that in public one. > > > > * fold-const.h (class operand_compare): Add operand_equal_p private > > > > overload. > > > > > > > > --- > > > > diff --git a/gcc/fold-const.h b/gcc/fold-const.h > > > > index > > > > > > > > > > b82ef137e2f2096f86c20df3c7749747e604177e..878545b1148b839e8a8e866f > > > > 38e31161f0d116c8 100644 > > > > --- a/gcc/fold-const.h > > > > +++ b/gcc/fold-const.h > > > > @@ -273,6 +273,12 @@ protected: > > > > true is returned. Then RET is set to corresponding comparsion result. */ > > > > bool verify_hash_value (const_tree arg0, const_tree arg1, unsigned int > flags, > > > > bool *ret); > > > > + > > > > +private: > > > > + /* Return true if two operands are equal. The flags fields can be used > > > > + to specify OEP flags described in tree-core.h. */ > > > > + bool operand_equal_p (tree, const_tree, tree, const_tree, > > > > + unsigned int flags); > > > > }; > > > > > > > > #endif // GCC_FOLD_CONST_H > > > > diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc > > > > index > > > > > > > > > > 8908e7381e72cbbf4a8fd96f18cbf4436aba8441..71e82b1d76d4106c7c23c54af > > > > 8b35905a1af9f1c 100644 > > > > --- a/gcc/fold-const.cc > > > > +++ b/gcc/fold-const.cc > > > > @@ -3156,6 +3156,17 @@ combine_comparisons (location_t loc, > > > > bool > > > > operand_compare::operand_equal_p (const_tree arg0, const_tree arg1, > > > > unsigned int flags) > > > > +{ > > > > + return operand_equal_p (TREE_TYPE (arg0), arg0, TREE_TYPE (arg1), arg1, > > > > flags); > > > > +} > > > > + > > > > +/* The same as operand_equal_p however the type of ARG0 and ARG1 are > > > > assumed to be > > > > + the TYPE0 and TYPE1 respectively. */ > > > > + > > > > +bool > > > > +operand_compare::operand_equal_p (tree type0, const_tree arg0, > > > > + tree type1, const_tree arg1, > > > > + unsigned int flags) > > > > { > > > > bool r; > > > > if (verify_hash_value (arg0, arg1, flags, &r)) > > > > @@ -3166,25 +3177,25 @@ operand_compare::operand_equal_p > > (const_tree > > > > arg0, const_tree arg1, > > > > > > > > /* If either is ERROR_MARK, they aren't equal. */ > > > > if (TREE_CODE (arg0) == ERROR_MARK || TREE_CODE (arg1) == > > ERROR_MARK > > > > - || TREE_TYPE (arg0) == error_mark_node > > > > - || TREE_TYPE (arg1) == error_mark_node) > > > > + || type0 == error_mark_node > > > > + || type1 == error_mark_node) > > > > return false; > > > > > > > > /* Similar, if either does not have a type (like a template id), > > > > they aren't equal. */ > > > > - if (!TREE_TYPE (arg0) || !TREE_TYPE (arg1)) > > > > + if (!type0 || !type1) > > > > return false; > > > > > > > > /* Bitwise identity makes no sense if the values have different layouts. */ > > > > if ((flags & OEP_BITWISE) > > > > - && !tree_nop_conversion_p (TREE_TYPE (arg0), TREE_TYPE (arg1))) > > > > + && !tree_nop_conversion_p (type0, type1)) > > > > return false; > > > > > > > > /* 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))))) > > > > + if (POINTER_TYPE_P (type0) > > > > + && POINTER_TYPE_P (type1) > > > > + && (TYPE_ADDR_SPACE (TREE_TYPE (type0)) > > > > + != TYPE_ADDR_SPACE (TREE_TYPE (type1)))) > > > > return false; > > > > > > > > /* Check equality of integer constants before bailing out due to > > > > @@ -3211,12 +3222,15 @@ operand_compare::operand_equal_p > > (const_tree > > > > arg0, const_tree arg1, > > > > > > > > /* 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))) > > > > + if (element_precision (type0) > > > > + != element_precision (type1)) > > > > return false; > > > > > > > > STRIP_NOPS (arg0); > > > > STRIP_NOPS (arg1); > > > > + > > > > + type0 = TREE_TYPE (arg0); > > > > + type1 = TREE_TYPE (arg1); > > > > } > > > > #if 0 > > > > /* FIXME: Fortran FE currently produce ADDR_EXPR of NOP_EXPR. Enable > the > > > > @@ -3275,9 +3289,9 @@ operand_compare::operand_equal_p (const_tree > > > arg0, > > > > const_tree arg1, > > > > > > > > /* When not checking adddresses, this is needed for conversions and for > > > > COMPONENT_REF. Might as well play it safe and always test this. */ > > > > - if (TREE_CODE (TREE_TYPE (arg0)) == ERROR_MARK > > > > - || TREE_CODE (TREE_TYPE (arg1)) == ERROR_MARK > > > > - || (TYPE_MODE (TREE_TYPE (arg0)) != TYPE_MODE (TREE_TYPE (arg1)) > > > > + if (TREE_CODE (type0) == ERROR_MARK > > > > + || TREE_CODE (type1) == ERROR_MARK > > > > + || (TYPE_MODE (type0) != TYPE_MODE (type1) > > > > && !(flags & OEP_ADDRESS_OF))) > > > > return false; > > > > > > > > @@ -3364,8 +3378,8 @@ operand_compare::operand_equal_p (const_tree > > > arg0, > > > > const_tree arg1, > > > > return true; > > > > > > > > /* See sem_variable::equals in ipa-icf for a similar approach. */ > > > > - tree typ0 = TREE_TYPE (arg0); > > > > - tree typ1 = TREE_TYPE (arg1); > > > > + tree typ0 = type0; > > > > + tree typ1 = type1; > > > > > > > > if (TREE_CODE (typ0) != TREE_CODE (typ1)) > > > > return false; > > > > @@ -3444,8 +3458,8 @@ operand_compare::operand_equal_p (const_tree > > > arg0, > > > > const_tree arg1, > > > > { > > > > CASE_CONVERT: > > > > case FIX_TRUNC_EXPR: > > > > - if (TYPE_UNSIGNED (TREE_TYPE (arg0)) > > > > - != TYPE_UNSIGNED (TREE_TYPE (arg1))) > > > > + if (TYPE_UNSIGNED (type0) > > > > + != TYPE_UNSIGNED (type1)) > > > > return false; > > > > break; > > > > default: > > > > @@ -3481,12 +3495,12 @@ operand_compare::operand_equal_p > > (const_tree > > > > arg0, const_tree arg1, > > > > case INDIRECT_REF: > > > > if (!(flags & OEP_ADDRESS_OF)) > > > > { > > > > - if (TYPE_ALIGN (TREE_TYPE (arg0)) > > > > - != TYPE_ALIGN (TREE_TYPE (arg1))) > > > > + if (TYPE_ALIGN (type0) > > > > + != TYPE_ALIGN (type1)) > > > > return false; > > > > /* Verify that the access types are compatible. */ > > > > - if (TYPE_MAIN_VARIANT (TREE_TYPE (arg0)) > > > > - != TYPE_MAIN_VARIANT (TREE_TYPE (arg1))) > > > > + if (TYPE_MAIN_VARIANT (type0) > > > > + != TYPE_MAIN_VARIANT (type1)) > > > > return false; > > > > } > > > > flags &= ~OEP_ADDRESS_OF; > > > > @@ -3494,8 +3508,8 @@ operand_compare::operand_equal_p (const_tree > > > arg0, > > > > const_tree arg1, > > > > > > > > case IMAGPART_EXPR: > > > > /* Require the same offset. */ > > > > - if (!operand_equal_p (TYPE_SIZE (TREE_TYPE (arg0)), > > > > - TYPE_SIZE (TREE_TYPE (arg1)), > > > > + if (!operand_equal_p (TYPE_SIZE (type0), > > > > + TYPE_SIZE (type1), > > > > flags & ~OEP_ADDRESS_OF)) > > > > return false; > > > > > > > > @@ -3509,15 +3523,15 @@ operand_compare::operand_equal_p > > (const_tree > > > > arg0, const_tree arg1, > > > > 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)), > > > > + if (TYPE_SIZE (type0) != TYPE_SIZE (type1) > > > > + && (!TYPE_SIZE (type0) > > > > + || !TYPE_SIZE (type1) > > > > + || !operand_equal_p (TYPE_SIZE (type0), > > > > + TYPE_SIZE (type1), > > > > flags))) > > > > return false; > > > > /* Verify that access happens in similar types. */ > > > > - if (!types_compatible_p (TREE_TYPE (arg0), TREE_TYPE (arg1))) > > > > + if (!types_compatible_p (type0, type1)) > > > > return false; > > > > /* Verify that accesses are TBAA compatible. */ > > > > if (!alias_ptr_types_compatible_p > > > > @@ -3529,8 +3543,8 @@ operand_compare::operand_equal_p (const_tree > > > arg0, > > > > const_tree arg1, > > > > != MR_DEPENDENCE_BASE (arg1))) > > > > return false; > > > > /* Verify that alignment is compatible. */ > > > > - if (TYPE_ALIGN (TREE_TYPE (arg0)) > > > > - != TYPE_ALIGN (TREE_TYPE (arg1))) > > > > + if (TYPE_ALIGN (type0) > > > > + != TYPE_ALIGN (type1)) > > > > return false; > > > > } > > > > flags &= ~OEP_ADDRESS_OF; > > > > @@ -3802,16 +3816,16 @@ operand_compare::operand_equal_p > > (const_tree > > > > arg0, const_tree arg1, > > > > indexed in increasing order and form an initial sequence. > > > > > > > > We make no effort to compare nonconstant ones in GENERIC. */ > > > > - if (!VECTOR_TYPE_P (TREE_TYPE (arg0)) > > > > - || !VECTOR_TYPE_P (TREE_TYPE (arg1))) > > > > + if (!VECTOR_TYPE_P (type0) > > > > + || !VECTOR_TYPE_P (type1)) > > > > return false; > > > > > > > > /* Be sure that vectors constructed have the same representation. > > > > We only tested element precision and modes to match. > > > > Vectors may be BLKmode and thus also check that the number of > > > > parts match. */ > > > > - if (maybe_ne (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)), > > > > - TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg1)))) > > > > + if (maybe_ne (TYPE_VECTOR_SUBPARTS (type0), > > > > + TYPE_VECTOR_SUBPARTS (type1))) > > > > return false; > > > > > > > > vec<constructor_elt, va_gc> *v0 = CONSTRUCTOR_ELTS (arg0); > > > > > > > > > > > > > > > > > > > > --
diff --git a/gcc/fold-const.h b/gcc/fold-const.h index b82ef137e2f2096f86c20df3c7749747e604177e..878545b1148b839e8a8e866f38e31161f0d116c8 100644 --- a/gcc/fold-const.h +++ b/gcc/fold-const.h @@ -273,6 +273,12 @@ protected: true is returned. Then RET is set to corresponding comparsion result. */ bool verify_hash_value (const_tree arg0, const_tree arg1, unsigned int flags, bool *ret); + +private: + /* Return true if two operands are equal. The flags fields can be used + to specify OEP flags described in tree-core.h. */ + bool operand_equal_p (tree, const_tree, tree, const_tree, + unsigned int flags); }; #endif // GCC_FOLD_CONST_H diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index 8908e7381e72cbbf4a8fd96f18cbf4436aba8441..71e82b1d76d4106c7c23c54af8b35905a1af9f1c 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -3156,6 +3156,17 @@ combine_comparisons (location_t loc, bool operand_compare::operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) +{ + return operand_equal_p (TREE_TYPE (arg0), arg0, TREE_TYPE (arg1), arg1, flags); +} + +/* The same as operand_equal_p however the type of ARG0 and ARG1 are assumed to be + the TYPE0 and TYPE1 respectively. */ + +bool +operand_compare::operand_equal_p (tree type0, const_tree arg0, + tree type1, const_tree arg1, + unsigned int flags) { bool r; if (verify_hash_value (arg0, arg1, flags, &r)) @@ -3166,25 +3177,25 @@ operand_compare::operand_equal_p (const_tree arg0, const_tree arg1, /* If either is ERROR_MARK, they aren't equal. */ if (TREE_CODE (arg0) == ERROR_MARK || TREE_CODE (arg1) == ERROR_MARK - || TREE_TYPE (arg0) == error_mark_node - || TREE_TYPE (arg1) == error_mark_node) + || type0 == error_mark_node + || type1 == error_mark_node) return false; /* Similar, if either does not have a type (like a template id), they aren't equal. */ - if (!TREE_TYPE (arg0) || !TREE_TYPE (arg1)) + if (!type0 || !type1) return false; /* Bitwise identity makes no sense if the values have different layouts. */ if ((flags & OEP_BITWISE) - && !tree_nop_conversion_p (TREE_TYPE (arg0), TREE_TYPE (arg1))) + && !tree_nop_conversion_p (type0, type1)) return false; /* 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))))) + if (POINTER_TYPE_P (type0) + && POINTER_TYPE_P (type1) + && (TYPE_ADDR_SPACE (TREE_TYPE (type0)) + != TYPE_ADDR_SPACE (TREE_TYPE (type1)))) return false; /* Check equality of integer constants before bailing out due to @@ -3211,12 +3222,15 @@ operand_compare::operand_equal_p (const_tree arg0, const_tree arg1, /* 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))) + if (element_precision (type0) + != element_precision (type1)) return false; STRIP_NOPS (arg0); STRIP_NOPS (arg1); + + type0 = TREE_TYPE (arg0); + type1 = TREE_TYPE (arg1); } #if 0 /* FIXME: Fortran FE currently produce ADDR_EXPR of NOP_EXPR. Enable the @@ -3275,9 +3289,9 @@ operand_compare::operand_equal_p (const_tree arg0, const_tree arg1, /* When not checking adddresses, this is needed for conversions and for COMPONENT_REF. Might as well play it safe and always test this. */ - if (TREE_CODE (TREE_TYPE (arg0)) == ERROR_MARK - || TREE_CODE (TREE_TYPE (arg1)) == ERROR_MARK - || (TYPE_MODE (TREE_TYPE (arg0)) != TYPE_MODE (TREE_TYPE (arg1)) + if (TREE_CODE (type0) == ERROR_MARK + || TREE_CODE (type1) == ERROR_MARK + || (TYPE_MODE (type0) != TYPE_MODE (type1) && !(flags & OEP_ADDRESS_OF))) return false; @@ -3364,8 +3378,8 @@ operand_compare::operand_equal_p (const_tree arg0, const_tree arg1, return true; /* See sem_variable::equals in ipa-icf for a similar approach. */ - tree typ0 = TREE_TYPE (arg0); - tree typ1 = TREE_TYPE (arg1); + tree typ0 = type0; + tree typ1 = type1; if (TREE_CODE (typ0) != TREE_CODE (typ1)) return false; @@ -3444,8 +3458,8 @@ operand_compare::operand_equal_p (const_tree arg0, const_tree arg1, { CASE_CONVERT: case FIX_TRUNC_EXPR: - if (TYPE_UNSIGNED (TREE_TYPE (arg0)) - != TYPE_UNSIGNED (TREE_TYPE (arg1))) + if (TYPE_UNSIGNED (type0) + != TYPE_UNSIGNED (type1)) return false; break; default: @@ -3481,12 +3495,12 @@ operand_compare::operand_equal_p (const_tree arg0, const_tree arg1, case INDIRECT_REF: if (!(flags & OEP_ADDRESS_OF)) { - if (TYPE_ALIGN (TREE_TYPE (arg0)) - != TYPE_ALIGN (TREE_TYPE (arg1))) + if (TYPE_ALIGN (type0) + != TYPE_ALIGN (type1)) return false; /* Verify that the access types are compatible. */ - if (TYPE_MAIN_VARIANT (TREE_TYPE (arg0)) - != TYPE_MAIN_VARIANT (TREE_TYPE (arg1))) + if (TYPE_MAIN_VARIANT (type0) + != TYPE_MAIN_VARIANT (type1)) return false; } flags &= ~OEP_ADDRESS_OF; @@ -3494,8 +3508,8 @@ operand_compare::operand_equal_p (const_tree arg0, const_tree arg1, case IMAGPART_EXPR: /* Require the same offset. */ - if (!operand_equal_p (TYPE_SIZE (TREE_TYPE (arg0)), - TYPE_SIZE (TREE_TYPE (arg1)), + if (!operand_equal_p (TYPE_SIZE (type0), + TYPE_SIZE (type1), flags & ~OEP_ADDRESS_OF)) return false; @@ -3509,15 +3523,15 @@ operand_compare::operand_equal_p (const_tree arg0, const_tree arg1, 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)), + if (TYPE_SIZE (type0) != TYPE_SIZE (type1) + && (!TYPE_SIZE (type0) + || !TYPE_SIZE (type1) + || !operand_equal_p (TYPE_SIZE (type0), + TYPE_SIZE (type1), flags))) return false; /* Verify that access happens in similar types. */ - if (!types_compatible_p (TREE_TYPE (arg0), TREE_TYPE (arg1))) + if (!types_compatible_p (type0, type1)) return false; /* Verify that accesses are TBAA compatible. */ if (!alias_ptr_types_compatible_p @@ -3529,8 +3543,8 @@ operand_compare::operand_equal_p (const_tree arg0, const_tree arg1, != MR_DEPENDENCE_BASE (arg1))) return false; /* Verify that alignment is compatible. */ - if (TYPE_ALIGN (TREE_TYPE (arg0)) - != TYPE_ALIGN (TREE_TYPE (arg1))) + if (TYPE_ALIGN (type0) + != TYPE_ALIGN (type1)) return false; } flags &= ~OEP_ADDRESS_OF; @@ -3802,16 +3816,16 @@ operand_compare::operand_equal_p (const_tree arg0, const_tree arg1, indexed in increasing order and form an initial sequence. We make no effort to compare nonconstant ones in GENERIC. */ - if (!VECTOR_TYPE_P (TREE_TYPE (arg0)) - || !VECTOR_TYPE_P (TREE_TYPE (arg1))) + if (!VECTOR_TYPE_P (type0) + || !VECTOR_TYPE_P (type1)) return false; /* Be sure that vectors constructed have the same representation. We only tested element precision and modes to match. Vectors may be BLKmode and thus also check that the number of parts match. */ - if (maybe_ne (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)), - TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg1)))) + if (maybe_ne (TYPE_VECTOR_SUBPARTS (type0), + TYPE_VECTOR_SUBPARTS (type1))) return false; vec<constructor_elt, va_gc> *v0 = CONSTRUCTOR_ELTS (arg0);