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.