Question about function body and function specialization

Erick Ochoa erick.ochoa@theobroma-systems.com
Tue Jul 14 11:19:33 GMT 2020


Actually, another interesting hint is that the original foo function 
takes two parameters. The function I am seeing inside the 
FOR_EACH_FUNCTION_WITH_GIMPLE_BODY is a specialized function of foo with 
only 1 parameter. However, the indirect function call is a version of 
foo which has not been specialized (i.e. it takes the original two 
parameters).

I guess my questions would be:

* Does FOR_EACH_FUNCTION_WITH_GIMPLE_BODY only iterates across functions 
which are reachable for main across the call graph?
* Is the the underlying mechanism for FOR_EACH_FUNCTION_WITH_GIMPLE_BODY 
not updated after ipa-prop discovers targets of indirect functions?
* Or is it just that the new callsite does not have a gimple body for 
its function? (This seems implausible since the new direct callsite 
should refer to the original function implementation.) How can I access 
this function's body?

Thanks.


On 14/07/2020 12:37, Erick Ochoa wrote:
> Hello,
> 
> I have a function foo defined on a source file. Sometimes, a function 
> pointer pointing to foo is passed as a parameter to other functions 
> where foo is called indirectly. This indirect call is specialized during 
> link time. Still at link time, I analyze the function call the following 
> way:
> 
>    // s is the gimple statement which corresponds to the indirect call
>    tree fn = gimple_call_fndecl(s);
>    // for this particular call the assertions are true
>    gcc_assert(fn)
>    cgraph_node *node = cgraph_node::get(fn)
>    gcc_assert(node)
> 
> I have analyzed the body of this function previously by using the 
> FOR_EACH_FUNCTION_WITH_GIMPLE_BODY macro. However, I do not know if 
> there's a way to link the cnode_graph (or function decl) analyzed in the 
> macro with the one obtained at the call site. What would be the best way 
> to say something like:
> 
>    tree fn = gimple_call_fndecl(s);
>    // for this particular call the assertions are true
>    gcc_assert(fn)
>    cgraph_node *node = cgraph_node::get(fn)
>    gcc_assert(node)
>    bool i_want_this_to_be_true = saw_fn_in_loop_before(node, fn);
> 
> I don't think that using storing the for loop and checking in 
> saw_fn_in_loop_before is the way to go because I believe cnode->decl 
> pointers can be different. Is this correct? In other words
> 
> 
> FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(cnode)
> {
>    a_std_set.insert(cnode->decl)
> }
> 
> // later
> 
> bool
> saw_fn_in_loop_before(cnode_graph *cn, tree fn)
> {
>    return a_std_set.find(fn) != a_std_set.end();
> }
> 
> Should not work. Something I found interesting is that for the fndecl 
> obtained through the callsite gimple_has_body_p returns false. Even 
> though I saw a fndecl which corresponds to the same function in the 
> FOR_EACH_FUNCTION_WITH_GIMPLE_BODY.
> 
> Thanks! Any hints are appreciated!


More information about the Gcc mailing list