Question about function body and function specialization

Martin Jambor mjambor@suse.cz
Wed Jul 15 14:46:13 GMT 2020


Hi,

On Wed, Jul 15 2020, Erick Ochoa wrote:
> Hi,
>
> I narrowed down that ipa-inline is marking these indirect functions as 
> unreachable (these functions have been specialized and therefore should 
> now be direct functions). Therefore, symtab_remove_unreachable_nodes is 
> called on them. Running the following (immediately after materialization):
>
> tree fndecl = gimple_call_fndecl(s)
> cgraph_node *from_fndecl = cgraph_node::get(fndecl);
> cgraph_node *from_symtable = NULL;
> bool found = false;
> FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(from_symtable)
> {
>    found |= from_fndecl == from_symtable;
> }
>
> will result in found always being false.
>
> Is it the desired behaviour that functions which addresses are taken to 
> be marked as unreachable (and therefore being unregistered from the 
> symbol table)?

The individual references are tracked in the symbol table.  When we know
that we converted a former reference into a direct use, the associated
reference is removed.  When the last one is removed, the function is no
longer considered as address taken and is indeed a candidate for
removal.

Martin

>
>
> On 14.07.20 04:19, Erick Ochoa wrote:
>> 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