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!