http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54314



--- Comment #26 from Jan Hubicka <hubicka at ucw dot cz> 2013-01-28 14:56:12 
UTC ---

> perhaps making them hidden whenever possible is really desirable.



Yes, this seems fine to me. Just to be sure I understand the problem fully.

I believe there is still problem with folding. When folding references through

external vtable I think we can still invent direct references to construction

vtable.



While doing so we go through logic in can_refer_decl_in_current_unit_p.

This is trying to validate the reference to the symbol referred only outside

of current unit.



I sort of hacked it together trying to work out what rules are.

This is all wrong for construction vtables where, if I understand it right,

we can not reffer them in any case because other file may be from other

compiler.

(with excetion of ltrans and LTO, also resolution data may tell us that the

symbol is defined?)



  /* We are folding reference from external vtable.  The vtable may reffer

     to a symbol keyed to other compilation unit.  The other compilation

     unit may be in separate DSO and the symbol may be hidden.  */

  if (DECL_VISIBILITY_SPECIFIED (decl)

      && DECL_EXTERNAL (decl)

      && (!(snode = symtab_get_node (decl)) ||

!snode->symbol.in_other_partition))

    return false;

  /* When function is public, we always can introduce new reference.

     Exception are the COMDAT functions where introducing a direct

     reference imply need to include function body in the curren tunit.  */

  if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))

    return true;

  /* We are not at ltrans stage; so don't worry about WHOPR.

     Also when still gimplifying all referred comdat functions will be

     produced.



     As observed in PR20991 for already optimized out comdat virtual functions

     it may be tempting to not necessarily give up because the copy will be

     output elsewhere when corresponding vtable is output.

     This is however not possible - ABI specify that COMDATs are output in

     units where they are used and when the other unit was compiled with LTO

     it is possible that vtable was kept public while the function itself

     was privatized. */

  if (!flag_ltrans && (!DECL_COMDAT (decl) || !cgraph_function_flags_ready))

    return true;



  /* OK we are seeing either COMDAT or static variable.  In this case we must

     check that the definition is still around so we can refer it.  */

  if (TREE_CODE (decl) == FUNCTION_DECL)

    ....

  return true;



I guess we need to add check for construction vtables and disable references

There are options.



1) Just add the check.  We will then miss all devirtualization oppurtunities

   through the construction vtable.  I guess it is what we should do for 4.8

   and earlier.  Marking them hidden will prevent folders from using them, but 

   what happens on targets not supporting visibility?



2) We may teach all optimizers, like ccp/gvn and fold to only "jump across

them"

   and fold only when the reference to construction vtable is used by reference

   to method itself, but it is not how the optimizers are organized - they

   always do one folding at a time and expect that they can reffer to them.



3) Perhaps we can use DECL_VALUE_EXPR or somethin similar to keep track of

   the canonical way to reffer into tthe construction vtable? (i.e. by

reference

   to vtable) We can then lower all direct references to the indirect

   references late, i.e. in expansion?



I suppose 3) makes most sense in longer run.  Implementing 2) without missing

optimization oppurtunities would be hard.

Honza

Reply via email to