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)