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)?

If needed I can reduce the problem, but I don't want to do it if this is the intended behaviour.

Thanks!


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!

Reply via email to