On Fri, May 15, 2015 at 4:08 PM, Jan Hubicka <hubi...@ucw.cz> wrote:
> Hello,
>>
>> There are codes like
>>
>> extern void foo (void);
>>
>> void
>> bar (void)
>> {
>>   foo ();
>> }
>>
>> Even with LTO, compiler may have to assume foo is external
>> when foo is compiled with LTO.
>
> This is not exactly true if FOO is defined in other translation unit
> compiled with LTO and hidden visibility.

I was meant to say " when foo is compiled without LTO.".

> OK, so as I get it, we get the following cases:
>
>  1) compiler knows it is generating call to a local symbol a current
>     unit (binds_to_current_def_p returns true).
>
>     We handle this correctly by doing IP relative call.
>
>  2) compiler knows it is generating call to a local symbol in DSO
>     (binds_local_p return true)
>     Currently I think this is only the -fno-pic case or case of explicit
>     hidden visibility and in this case we do IP relative call.
>
>     We may want to propose plugin API update adding PREVAILING_DEF_EXP.
>     So copiler would be able to default to this case for PREVAILING_DEF
>     and we will also catch cases where the symbol is defined in current
>     DSO as weak symbol, but the definition is not LTO.
>     This would be also way to communicate -Bsymbolic[-functions] across
>     the plugin API.
>
>  3) compiler knows there is going to be definition in the current DSO
>     (by seeing a COMDAT function body or resolution info) that is interposable
>     but because the function is inline or -fno-semantic-interposition happens,
>     the semantics will not change.
>
>     In this case it would be nice to arrange IP relative call to the
>     hidden alias.  This may require an extension both on compiler and linker
>     side.
>
>     I was thinking of doing so for comdats by adding hidden alias with
>     fixed mangling, like __gnu_<function>.hiddenalias, and referring it.
>     But I think it is not safe as linker may throw away section that
>     is produced by GCC and prevail section that is not leaving to an undefined
>     symbol?
>
>     I think this is rather common case in C++ (never made any stats) because
>     uninlined comdats are quite common.
>
>  4) compiler has no clue but linker may know better
>
>     Here we traditionally always produce a PLT call.  In cases the call
>     is known to be hot in the program it makes sense to trade lazy binding
>     for performance and produce call via GOT reference (-fno-plt).
>     I also see that H.J.'s branch helps us to actually avoid the GOT
>     reference in cases the symbol ends up binding locally. How the lazy
>     binding with relaxation works?

If there is no GOT slot allocated for symbol foo, linker should resolve
foo@GOTPLT(%ebx) to to its PLT slot address + 6, which is the push
instruction, to support  lazy binding.  Otherwise, linker should resolve it
to its GOT slot address.

>     We may try to communicate down the information whether the symbol can
>     or can not semantically interpose to the linker, so it can do
>     -Bsymbolic by default for inline and COMDAT functions.
>     Actually perhaps the linker can just default to this for all comdat
>     defined symbols?
>
>     I think it still make sense to work on non-LTO codegen improvements.
>     As much as I would like everyone to LTO and FDO, most people don't.
>
>  5) Compiler knows it is generating call to external function.
>     We do not special case this, but we could add binds_external_p and
>     make it to determine this case from resolution info during LTO.
>
>     I do not see if this case is any different from 4 from PIC codegen
>     perspective except that perhaps the relax relocation will allow us to lazy
>     bind?

My relax branch proposal works even without LTO.


-- 
H.J.

Reply via email to