Question about function body and function specialization

Martin Jambor mjambor@suse.cz
Thu Jul 16 10:11:00 GMT 2020


Hi,

On Wed, Jul 15 2020, Erick Ochoa wrote:
> On 15.07.20 05:03, Martin Jambor wrote:

[...]

>> At IPA time, the best way is always to look at the call graph edges,
>> something like:
>> 
>>     cgraph_edge *cs = caller_cgraph_node->get_edge (s);
>>     examine (e->callee);
>> 
>> Note that if the call is truly an indirect one cs->callee will be NULL
>> (and cs->indirect_unknown_callee will be set).  Things can also get
>> quite a bit more complicated if cs->speculative is set, then there is
>> both an indirect and guessed direct edge for a single call.
>
> Thanks! I did read a bunch of source code and I was wondering why all 
> the constant propagation and specialization happens by navigating the 
> call graph edges and not the gimple code.

It is designed that way in order to save memory.  When LTOing huge
applications, you do not want to load bodies of all functions into
memory at once, that way you might not be able to build Firefox,
Chromium and others even with very many gigabytes of RAM.

> I initially thought that 
> gimple_call_set_fndecl was not called because I couldn't find anything 
> except call graph edges. However, this was not the case.

The redirection is bound to eventually happen in
cgraph_edge::redirect_call_stmt_to_callee - but as you can see, it may be
a complicated process and may need to rebuild the call statement instead
of just setting the fndecl.

[...]

>> 
>> I can only guess but it seems that something has created specialized
>> clone for all contexts and you happen to be looking at the gimple bodies
>> after clone materialization but before edge redirection... but I am only
>> guessing.
>
> I think this is close to the truth. So... the function I am interested 
> in finding has indeed been specialized for "all contexts", but I think 
> this "all contexts" did not take into account the function pointers.

IPA-CP can specialize for "all known contexts" too, leaving the original
function behind for indirect calls and calls from outside of the current
compilation unit (or dll), in that case it does include code duplication
in its cost estimate.

>
> During ipa-cp I looked at the code where the function call has been 
> changed from an indirect call to a direct call and I was able to find 
> that callee->has_gimple_body_p() returns true and that it was also found 
> in FOR_EACH_FUNCTION_WITH_GIMPLE_BODY loop.
>
> I also did this during ipa-sra and the same was true.
>
> But for the pass just after materialization it was false.
>
> As mentioned in a sibling post, I found out that during the inlining 
> phase, the function is "reclaimed". I'm not 100% sure yet, but I think 
> the indirect functions are not inlined. I used -fdump-ipa-inline and in 
> my pass (after materialization) I used cnode->dump_name() to find its 
> dump name... I then looked for its dump_name and only found the following:
>
> IPA function summary for $dump_name inlinable
>
> $dump_name ($name) @0x40002a1936d8
>    Type: function
>    Body removed by symtab_remove_unreachable_nodes
>    Visibility: prevailing_def_ironly
>    Address is taken.
>    References:
>    Referring:
>    Read from file: $file
>    Availability: not_available
>    Profile id: 1677473182
>    Unit id: 2
>    Function flags: count:17343 (adjusted) first_run:3 hot
>    Called by:
>    Calls:

It looks quite unreachable, no Callers, no Referring nodes - that's
where the address references which I wrote in another email are stored
in the symbol table.

Martin


More information about the Gcc mailing list