On Sat, Oct 24, 2015 at 7:31 PM, Jan Hubicka <hubi...@ucw.cz> wrote:
> Hello,
> this patch adds OBJ_TYPE_REF that is the only code handled by ipa-icf-gimple
> but not bu operand_equal_p.  I tried to make the following testcase:
>
> /* { dg-do compile } */
> /* { dg-options "-O2 -fdump-tree-pre" } */
> struct foo {
>   virtual int test ();
> };
>
> int ret (struct foo *f, int v)
> {
>    return v ? f->test() : f->test();
> }
> /* { dg-final { scan-tree-dump-not "if " "pre"} } */
>
> But we fail to tailmerge the code:
>   <bb 2>:
>   if (v_3(D) != 0)
>     goto <bb 3>;
>   else
>     goto <bb 4>;
>
>   <bb 3>:
>   _6 = f_5(D)->_vptr.foo;
>   _7 = *_6;
>   _9 = OBJ_TYPE_REF(_7;(struct foo)f_5(D)->0) (f_5(D)); [tail call]
>   goto <bb 5>;
>
>   <bb 4>:
>   _10 = f_5(D)->_vptr.foo;
>   _11 = *_10;
>   _13 = OBJ_TYPE_REF(_11;(struct foo)f_5(D)->0) (f_5(D)); [tail call]
>
> This is because the OBJ_TYPE_REF are not equal without unifing _7 with _11
> and _6 with _10 that we don't do, because we don't have head merging.
>
> We ought to be able to do so once tail merge is witched to ipa-icf-gimple
> and ipa-icf-gimple to operand_equal_p.  Otherwsie i think we are hitting to
> limitation of tree-ssa-sccvn that may want similar matching somewhere.
>
> Once I have bit of time I will work on removing of OBJ_TYPE_REF wrappers
> produced by objective-C in gimplification and then all the
> virtual_method_call_p calls can go. The naive approach of simply not building
> them does not work, perhaps we want to have separate OBJC tree code, since 
> they
> do not really represent virtual calls after all, but I got stuck on adding new
> tree codes to objc becuase handling of tree.def between C/C++/obj-C/obj-C++
> FEs is very convoluted.
>
> Bootstrapped/regtested x86_64-linx, OK?
>
> Honza
>
>
>         * fold-const.c (operand_equal_p): Handle OBJ_TYPE_REF
>
> Index: fold-const.c
> ===================================================================
> --- fold-const.c        (revision 229278)
> +++ fold-const.c        (working copy)
> @@ -3085,6 +3082,27 @@ operand_equal_p (const_tree arg0, const_
>         case DOT_PROD_EXPR:
>           return OP_SAME (0) && OP_SAME (1) && OP_SAME (2);
>
> +       case OBJ_TYPE_REF:
> +         /* OBJ_TYPE_REF is just a wrapper around OBJ_TYP_REF_EXPR.  */
> +         if (!operand_equal_p (OBJ_TYPE_REF_EXPR (arg0),
> +                               OBJ_TYPE_REF_EXPR (arg1), flags))
> +           return false;
> +
> +         /* Objective-C frontend produce ill formed OBJ_TYPE_REF which
> +            probably should be dropped before reaching middle-end.  */
> +         if (!virtual_method_call_p (arg0) || !virtual_method_call_p (arg1))
> +           return false;

So what kind of brokeness is this?

> +         /* Match the type information stored in the wrapper.  */
> +
> +         flags &= ~(OEP_CONSTANT_ADDRESS_OF|OEP_ADDRESS_OF);
> +         return (tree_to_uhwi (OBJ_TYPE_REF_TOKEN (arg0))
> +                 == tree_to_uhwi (OBJ_TYPE_REF_TOKEN (arg1))

Err, please use tree_int_cst_eq ()

> +                 && types_same_for_odr (obj_type_ref_class (arg0),
> +                                        obj_type_ref_class (arg1))

Why do you need this check?  The args of OBJ_TYPE_REF should be fully
specifying the object, no?

> +                 && operand_equal_p (OBJ_TYPE_REF_OBJECT (arg0),
> +                                     OBJ_TYPE_REF_OBJECT (arg1),
> +                                     flags));
>         default:
>           return 0;
>         }

Reply via email to