On Fri, 4 Dec 2015, Jan Hubicka wrote:

> > Indeed we don't do code hoisting yet.  Maybe one could trick PPRE
> > into doing it.
> > 
> > Note that for OBJ_TYPE_REFs in calls you probably should better use
> > gimple_call_fntype instead of the type of the OBJ_TYPE_REF anyway
> > (well, fntype will be the method-type, not pointer-to-method-type).
> > 
> > Not sure if you need OBJ_TYPE_REFs type in non-call contexts?
> 
> Well, to optimize speculative call sequences
> 
> if (funptr == thismethod)
>   inlined this method body
> else
>   funptr ();
> 
> Here you want to devirtualize the conditional, not the call in order
> to get the inlined method unconditonally.
> 
> In general I think OBJ_TYPE_REF is misplaced - it should be on vtable load
> instead of the call/conditional. It is a property of the vtable lookup.
> Then it would work for method pointers too.

Even better.  Make it a tcc_reference tree then.

> > 
> >   if (fn
> >       && (!POINTER_TYPE_P (TREE_TYPE (fn))
> >           || (TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) != FUNCTION_TYPE
> >               && TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) != METHOD_TYPE)))
> >     {
> >       error ("non-function in gimple call");
> >       return true;
> >     }
> > 
> > and in useless_type_conversion_p:
> > 
> >       /* Do not lose casts to function pointer types.  */
> >       if ((TREE_CODE (TREE_TYPE (outer_type)) == FUNCTION_TYPE
> >            || TREE_CODE (TREE_TYPE (outer_type)) == METHOD_TYPE)
> >           && !(TREE_CODE (TREE_TYPE (inner_type)) == FUNCTION_TYPE
> >                || TREE_CODE (TREE_TYPE (inner_type)) == METHOD_TYPE))
> >         return false;
> 
> Yeah, this does not make much sense to me anymore.  Something to track next
> stage1.

Btw, might be necessary for targets with function descriptors - not sure
though.

Richard.

> > 
> > probably from the times we didn't have gimple_call_fntype.  So if I
> > paper over the ICE (in the verifier) then the libreoffice testcase
> > gets optimized to
> > 
> >   <bb 2>:
> >   _3 = this_2(D)->D.2399.D.2325._vptr.B;
> >   _4 = *_3;
> >   PROF_6 = OBJ_TYPE_REF(_4;(struct 
> > WindowListenerMultiplexer)this_2(D)->0);
> >   if (PROF_6 == acquire)
> >     goto <bb 3>;
> >   else
> >     goto <bb 4>;
> > 
> >   <bb 3>:
> >   PROF_6 (this_2(D));
> >   goto <bb 5>;
> > 
> >   <bb 4>:
> >   PROF_6 (this_2(D));
> > 
> > by FRE2 and either VRP or DOM will propagate the equivalency to
> > 
> >   <bb 2>:
> >   _3 = this_2(D)->D.2399.D.2325._vptr.B;
> >   _4 = *_3;
> >   PROF_6 = OBJ_TYPE_REF(_4;(struct 
> > WindowListenerMultiplexer)this_2(D)->0);
> >   if (PROF_6 == acquire)
> >     goto <bb 3>;
> >   else
> >     goto <bb 4>;
> > 
> >   <bb 3>:
> >   WindowListenerMultiplexer::acquire (this_2(D));
> >   goto <bb 5>;
> > 
> >   <bb 4>:
> >   PROF_6 (this_2(D));
> > 
> > Richard.
> 
> LGTM.
> Honza
> > 
> > 2015-12-03  Richard Biener  <rguent...@suse.de>
> > 
> >     PR tree-optimization/64812
> >     * tree-ssa-sccvn.c (vn_get_stmt_kind): Handle OBJ_TYPE_REF.
> >     (vn_nary_length_from_stmt): Likewise.
> >     (init_vn_nary_op_from_stmt): Likewise.
> >     * gimple-match-head.c (maybe_build_generic_op): Likewise.
> >     * gimple-pretty-print.c (dump_unary_rhs): Likewise.
> >     * gimple-fold.c (gimple_build): Likewise.
> >     * gimple.h (gimple_expr_type): Likewise.
> > 
> >     * g++.dg/tree-ssa/ssa-fre-1.C: New testcase.
> > 
> > Index: gcc/tree-ssa-sccvn.c
> > ===================================================================
> > *** gcc/tree-ssa-sccvn.c    (revision 231221)
> > --- gcc/tree-ssa-sccvn.c    (working copy)
> > *************** vn_get_stmt_kind (gimple *stmt)
> > *** 460,465 ****
> > --- 460,467 ----
> >                       ? VN_CONSTANT : VN_REFERENCE);
> >             else if (code == CONSTRUCTOR)
> >               return VN_NARY;
> > +           else if (code == OBJ_TYPE_REF)
> > +             return VN_NARY;
> >             return VN_NONE;
> >           }
> >       default:
> > *************** vn_nary_length_from_stmt (gimple *stmt)
> > *** 2479,2484 ****
> > --- 2481,2487 ----
> >         return 1;
> >   
> >       case BIT_FIELD_REF:
> > +     case OBJ_TYPE_REF:
> >         return 3;
> >   
> >       case CONSTRUCTOR:
> > *************** init_vn_nary_op_from_stmt (vn_nary_op_t
> > *** 2508,2513 ****
> > --- 2511,2517 ----
> >         break;
> >   
> >       case BIT_FIELD_REF:
> > +     case OBJ_TYPE_REF:
> >         vno->length = 3;
> >         vno->op[0] = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
> >         vno->op[1] = TREE_OPERAND (gimple_assign_rhs1 (stmt), 1);
> > Index: gcc/gimple-match-head.c
> > ===================================================================
> > *** gcc/gimple-match-head.c (revision 231221)
> > --- gcc/gimple-match-head.c (working copy)
> > *************** maybe_build_generic_op (enum tree_code c
> > *** 243,248 ****
> > --- 243,249 ----
> >         *op0 = build1 (code, type, *op0);
> >         break;
> >       case BIT_FIELD_REF:
> > +     case OBJ_TYPE_REF:
> >         *op0 = build3 (code, type, *op0, op1, op2);
> >         break;
> >       default:;
> > Index: gcc/gimple-pretty-print.c
> > ===================================================================
> > *** gcc/gimple-pretty-print.c       (revision 231221)
> > --- gcc/gimple-pretty-print.c       (working copy)
> > *************** dump_unary_rhs (pretty_printer *buffer,
> > *** 302,308 ****
> >       || TREE_CODE_CLASS (rhs_code) == tcc_reference
> >       || rhs_code == SSA_NAME
> >       || rhs_code == ADDR_EXPR
> > !     || rhs_code == CONSTRUCTOR)
> >     {
> >       dump_generic_node (buffer, rhs, spc, flags, false);
> >       break;
> > --- 302,309 ----
> >       || TREE_CODE_CLASS (rhs_code) == tcc_reference
> >       || rhs_code == SSA_NAME
> >       || rhs_code == ADDR_EXPR
> > !     || rhs_code == CONSTRUCTOR
> > !     || rhs_code == OBJ_TYPE_REF)
> >     {
> >       dump_generic_node (buffer, rhs, spc, flags, false);
> >       break;
> > Index: gcc/testsuite/g++.dg/tree-ssa/ssa-fre-1.C
> > ===================================================================
> > *** gcc/testsuite/g++.dg/tree-ssa/ssa-fre-1.C       (revision 0)
> > --- gcc/testsuite/g++.dg/tree-ssa/ssa-fre-1.C       (working copy)
> > ***************
> > *** 0 ****
> > --- 1,44 ----
> > + /* { dg-do compile } */
> > + /* { dg-options "-O2 -fdump-tree-fre2" } */
> > + 
> > + template <class T> class A
> > + {
> > +   T *p;
> > + 
> > + public:
> > +   A (T *p1) : p (p1) { p->acquire (); }
> > + };
> > + 
> > + class B
> > + {
> > + public:
> > +     virtual void acquire ();
> > + };
> > + class D : public B
> > + {
> > + };
> > + class F : B
> > + {
> > +   int mrContext;
> > + };
> > + class WindowListenerMultiplexer : F, public D
> > + {
> > +   void acquire () { acquire (); }
> > + };
> > + class C
> > + {
> > +   void createPeer () throw ();
> > +   WindowListenerMultiplexer maWindowListeners;
> > + };
> > + class FmXGridPeer
> > + {
> > + public:
> > +     void addWindowListener (A<D>);
> > + } a;
> > + void
> > + C::createPeer () throw ()
> > + {
> > +   a.addWindowListener (&maWindowListeners);
> > + }
> > + 
> > + /* { dg-final { scan-tree-dump-times "= OBJ_TYPE_REF" 1 "fre2" } } */
> > Index: gcc/gimple-fold.c
> > ===================================================================
> > --- gcc/gimple-fold.c       (revision 231221)
> > +++ gcc/gimple-fold.c       (working copy)
> > @@ -6038,7 +6038,8 @@ gimple_build (gimple_seq *seq, location_
> >        else
> >     res = create_tmp_reg (type);
> >        gimple *stmt;
> > -      if (code == BIT_FIELD_REF)
> > +      if (code == BIT_FIELD_REF
> > +     || code == OBJ_TYPE_REF)
> >     stmt = gimple_build_assign (res, code,
> >                                 build3 (code, type, op0, op1, op2));
> >        else
> > Index: gcc/gimple.h
> > ===================================================================
> > --- gcc/gimple.h    (revision 231221)
> > +++ gcc/gimple.h    (working copy)
> > @@ -6079,7 +6079,9 @@ gimple_expr_type (const gimple *stmt)
> >      }
> >    else if (code == GIMPLE_ASSIGN)
> >      {
> > -      if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
> > +      enum tree_code rcode = gimple_assign_rhs_code (stmt);
> > +      if (rcode == POINTER_PLUS_EXPR
> > +     || rcode == OBJ_TYPE_REF)
> >          return TREE_TYPE (gimple_assign_rhs1 (stmt));
> >        else
> >          /* As fallback use the type of the LHS.  */
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 
21284 (AG Nuernberg)

Reply via email to