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