On Mon, 7 Nov 2016, Martin Jambor wrote: > Hi, > > this has been in my TODO list for at least two years, probably longer, > although I do no longer remember why I added it there. The idea is to > introduce a special wrapper around operands_equal_p for TYPE_SIZE > comparisons, which would try simple pointer equality before calling more > complex operand_equal_p (TYPE_SIZE (t1), TYPE_SIZE (t2), 0), because > when equal, the sizes are most likely going to be the same tree anyway. > > All users also test whether both TYPE_SIZEs are NULL, most of them to > test for known size equality, but unfortunately there is one (ODR > warning) that tests for known inequality. Nevertheless, the former use > case seems so much natural that I have outlined it into the new > predicate as well.
But I think this really asks for a tri-state, known equal, known unequal and unknown (both NULL_TREE). Also the checking asserts are redundant with the tree checking done by the TYPE_SIZE accessor. Richard. > I am no longer sure whether it is a scenario that happens so often to > justify a wrapper, but I'd like to propose it anyway, at least to remove > it from the TODO list as a not-so-good-idea-after-all :-) > > Bootstrapped and tested on x86_64-linux. Is it a good idea? OK for > trunk? > > Thanks, > > Martin > > 2016-11-03 Martin Jambor <mjam...@suse.cz> > > * fold-const.c (type_sizes_equal_p): New function. > * fold-const.h (type_sizes_equal_p): Declare. > * ipa-devirt.c (odr_types_equivalent_p): Use it. > * ipa-polymorphic-call.c (meet_with): Likewise. > * tree-ssa-alias.c (stmt_kills_ref_p): Likewise. > --- > gcc/fold-const.c | 19 +++++++++++++++++++ > gcc/fold-const.h | 1 + > gcc/ipa-devirt.c | 2 +- > gcc/ipa-polymorphic-call.c | 10 ++-------- > gcc/tree-ssa-alias.c | 7 +------ > 5 files changed, 24 insertions(+), 15 deletions(-) > > diff --git a/gcc/fold-const.c b/gcc/fold-const.c > index 603aff0..ab77b8d 100644 > --- a/gcc/fold-const.c > +++ b/gcc/fold-const.c > @@ -3342,6 +3342,25 @@ operand_equal_for_comparison_p (tree arg0, tree arg1, > tree other) > > return 0; > } > + > +/* Given two types, return true if both have a non-NULL TYPE_SIZE and these > + sizes have the same value. */ > + > +bool > +type_sizes_equal_p (const_tree t1, const_tree t2) > +{ > + gcc_checking_assert (TYPE_P (t1)); > + gcc_checking_assert (TYPE_P (t2)); > + t1 = TYPE_SIZE (t1); > + t2 = TYPE_SIZE (t2); > + > + if (!t1 || !t2) > + return false; > + else if (t1 == t2) > + return true; > + else > + return operand_equal_p (t1, t2, 0); > +} > > /* See if ARG is an expression that is either a comparison or is performing > arithmetic on comparisons. The comparisons must only be comparing > diff --git a/gcc/fold-const.h b/gcc/fold-const.h > index ae37142..014ca34 100644 > --- a/gcc/fold-const.h > +++ b/gcc/fold-const.h > @@ -89,6 +89,7 @@ extern void fold_undefer_and_ignore_overflow_warnings > (void); > extern bool fold_deferring_overflow_warnings_p (void); > extern void fold_overflow_warning (const char*, enum > warn_strict_overflow_code); > extern int operand_equal_p (const_tree, const_tree, unsigned int); > +extern bool type_sizes_equal_p (const_tree, const_tree); > extern int multiple_of_p (tree, const_tree, const_tree); > #define omit_one_operand(T1,T2,T3)\ > omit_one_operand_loc (UNKNOWN_LOCATION, T1, T2, T3) > diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c > index 49e2195..d2db6f2 100644 > --- a/gcc/ipa-devirt.c > +++ b/gcc/ipa-devirt.c > @@ -1671,7 +1671,7 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, > bool *warned, > > /* Those are better to come last as they are utterly uninformative. */ > if (TYPE_SIZE (t1) && TYPE_SIZE (t2) > - && !operand_equal_p (TYPE_SIZE (t1), TYPE_SIZE (t2), 0)) > + && !type_sizes_equal_p (t1, t2)) > { > warn_odr (t1, t2, NULL, NULL, warn, warned, > G_("a type with different size " > diff --git a/gcc/ipa-polymorphic-call.c b/gcc/ipa-polymorphic-call.c > index 8d9f22a..b66fd76 100644 > --- a/gcc/ipa-polymorphic-call.c > +++ b/gcc/ipa-polymorphic-call.c > @@ -2454,10 +2454,7 @@ ipa_polymorphic_call_context::meet_with > (ipa_polymorphic_call_context ctx, > if (!dynamic > && (ctx.dynamic > || (!otr_type > - && (!TYPE_SIZE (ctx.outer_type) > - || !TYPE_SIZE (outer_type) > - || !operand_equal_p (TYPE_SIZE (ctx.outer_type), > - TYPE_SIZE (outer_type), 0))))) > + && (!type_sizes_equal_p (ctx.outer_type, outer_type))))) > { > dynamic = true; > updated = true; > @@ -2472,10 +2469,7 @@ ipa_polymorphic_call_context::meet_with > (ipa_polymorphic_call_context ctx, > if (!dynamic > && (ctx.dynamic > || (!otr_type > - && (!TYPE_SIZE (ctx.outer_type) > - || !TYPE_SIZE (outer_type) > - || !operand_equal_p (TYPE_SIZE (ctx.outer_type), > - TYPE_SIZE (outer_type), 0))))) > + && (!type_sizes_equal_p (ctx.outer_type, outer_type))))) > dynamic = true; > outer_type = ctx.outer_type; > offset = ctx.offset; > diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c > index ebae6cf..98cd1d7 100644 > --- a/gcc/tree-ssa-alias.c > +++ b/gcc/tree-ssa-alias.c > @@ -2366,12 +2366,7 @@ stmt_kills_ref_p (gimple *stmt, ao_ref *ref) > /* Finally check if the lhs has the same address and size as the > base candidate of the access. */ > if (lhs == base > - || (((TYPE_SIZE (TREE_TYPE (lhs)) > - == TYPE_SIZE (TREE_TYPE (base))) > - || (TYPE_SIZE (TREE_TYPE (lhs)) > - && TYPE_SIZE (TREE_TYPE (base)) > - && operand_equal_p (TYPE_SIZE (TREE_TYPE (lhs)), > - TYPE_SIZE (TREE_TYPE (base)), 0))) > + || (type_sizes_equal_p (TREE_TYPE (lhs), TREE_TYPE (base)) > && operand_equal_p (lhs, base, OEP_ADDRESS_OF))) > return true; > } > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)