https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64812
--- Comment #13 from rguenther at suse dot de <rguenther at suse dot de> --- On Thu, 3 Dec 2015, hubicka at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64812 > > Jan Hubicka <hubicka at gcc dot gnu.org> changed: > > What |Removed |Added > ---------------------------------------------------------------------------- > CC| |rguenther at suse dot de > > --- Comment #12 from Jan Hubicka <hubicka at gcc dot gnu.org> --- > Markus, > the devirtualization seems valid to me. You are supposed to link with the > implementaiton of the class. It is possible to overwrite this by manually > setting the visibility. > > We however end up with funny code in optimized dump: > > <bb 2>: > _3 = this_2(D)->D.2399.D.2325._vptr.B; > _4 = *_3; > PROF_6 = [obj_type_ref] OBJ_TYPE_REF(_4;(struct > WindowListenerMultiplexer)this_2(D)->0); > if (PROF_6 == acquire) > goto <bb 3>; > else > goto <bb 18>; > > <bb 3>: > PROF_10 = [obj_type_ref] OBJ_TYPE_REF(_4;(struct > WindowListenerMultiplexer)this_2(D)->0); > if (PROF_10 == acquire) > goto <bb 4>; > else > goto <bb 17>; > > <bb 4>: > PROF_14 = [obj_type_ref] OBJ_TYPE_REF(_4;(struct > WindowListenerMultiplexer)this_2(D)->0); > if (PROF_14 == acquire) > goto <bb 5>; > else > goto <bb 16>; > > <bb 5>: > PROF_18 = [obj_type_ref] OBJ_TYPE_REF(_4;(struct > WindowListenerMultiplexer)this_2(D)->0); > if (PROF_18 == acquire) > goto <bb 6>; > else > goto <bb 15>; > > <bb 6>: > PROF_22 = [obj_type_ref] OBJ_TYPE_REF(_4;(struct > WindowListenerMultiplexer)this_2(D)->0); > if (PROF_22 == acquire) > goto <bb 7>; > else > goto <bb 14>; > > <bb 7>: > PROF_26 = [obj_type_ref] OBJ_TYPE_REF(_4;(struct > WindowListenerMultiplexer)this_2(D)->0); > if (PROF_26 == acquire) > goto <bb 8>; > else > goto <bb 13>; > <bb 8>: > PROF_30 = [obj_type_ref] OBJ_TYPE_REF(_4;(struct > WindowListenerMultiplexer)this_2(D)->0); > if (PROF_30 == acquire) > goto <bb 9>; > else > goto <bb 12>; > > <bb 9>: > PROF_34 = [obj_type_ref] OBJ_TYPE_REF(_4;(struct > WindowListenerMultiplexer)this_2(D)->0); > if (PROF_34 == acquire) > goto <bb 10>; > else > goto <bb 11>; > > <bb 10>: > OBJ_TYPE_REF(_4;(struct WindowListenerMultiplexer)this_2(D)->0) (this_2(D)); > [tail call] > goto <bb 19>; > > <bb 11>: > OBJ_TYPE_REF(_4;(struct WindowListenerMultiplexer)this_2(D)->0) (this_2(D)); > [tail call] > goto <bb 19>; > > <bb 12>: > OBJ_TYPE_REF(_4;(struct WindowListenerMultiplexer)this_2(D)->0) (this_2(D)); > [tail call] > goto <bb 19>; > > <bb 13>: > OBJ_TYPE_REF(_4;(struct WindowListenerMultiplexer)this_2(D)->0) (this_2(D)); > [tail call] > goto <bb 19>; > > <bb 14>: > OBJ_TYPE_REF(_4;(struct WindowListenerMultiplexer)this_2(D)->0) (this_2(D)); > [tail call] > goto <bb 19>; > > <bb 15>: > OBJ_TYPE_REF(_4;(struct WindowListenerMultiplexer)this_2(D)->0) (this_2(D)); > [tail call] > goto <bb 19>; > > <bb 16>: > OBJ_TYPE_REF(_4;(struct WindowListenerMultiplexer)this_2(D)->0) (this_2(D)); > [tail call] > goto <bb 19>; > > <bb 17>: > OBJ_TYPE_REF(_4;(struct WindowListenerMultiplexer)this_2(D)->0) (this_2(D)); > [tail call] > goto <bb 19>; > > <bb 18>: > OBJ_TYPE_REF(_4;(struct WindowListenerMultiplexer)this_2(D)->0) (this_2(D)); > [tail call] > > <bb 19>: > return; > > } > > this is result of recursive inlining over the devirtualized call that sort of > seem legit even though it is bit of overkill. > > RTL optimizers simplify this to: > > _ZN25WindowListenerMultiplexer7acquireEv: > .LFB1: > .cfi_startproc > movq (%rdi), %rax > jmp *(%rax) > .cfi_endproc > .LFE1: > > RIchi, I think PRE is supposed to optimize this? Ah, for some reason OBJ_TYPE_REF is a GENERIC tree (single RHS) and SCCVN doesn't handle it at all. I have a patch which will produce <bb 2>: _3 = this_2(D)->D.2399.D.2325._vptr.B; _4 = *_3; PROF_6 = [obj_type_ref] OBJ_TYPE_REF(_4;(struct WindowListenerMultiplexer)this_2(D)->0); if (PROF_6 == acquire) goto <bb 3>; else goto <bb 4>; <bb 3>: OBJ_TYPE_REF(_4;(struct WindowListenerMultiplexer)this_2(D)->0) (this_2(D)); [tail call] goto <bb 5>; <bb 4>: OBJ_TYPE_REF(_4;(struct WindowListenerMultiplexer)this_2(D)->0) (this_2(D)); [tail call] thus it also misses to "propagate" acquire into the tailcall. That could be fixed as well but only in two steps, first replacing the OBJ_TYPE_REF in the call with PROF_6 ("CSE" it) and later DOM might propagate the equivalence.