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.

Reply via email to