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!