On Fri, Sep 26, 2014 at 12:00 AM, Jan Hubicka <hubi...@ucw.cz> wrote: >> Hello. >> >> I've been finalizing IPA ICF testing process and I met a condition >> for lto-bootstrap, where cgraph_node::verify encounters error: >> >> In WPA, I prove that gen_vec_initv16qi can be merged with >> gen_vec_initv2sf. In the following case, ale local calls are >> redirected: >> >> while (alias->callers) >> { >> cgraph_edge *e = alias->callers; >> e->redirect_callee (local_original); >> push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl)); >> >> if (e->call_stmt) >> e->redirect_call_stmt_to_callee (); >> >> pop_cfun (); >> redirected = true; >> } >> >> To be more precise, the modification play role in WPA, where >> e->call_stmt == NULL (bodies are not loaded). >> And a LTRANS produces following error: >> >> In function ‘gen_rotlv16qi3’: >> lto1: error: edge points to wrong declaration: >> <function_decl 0x7fe495b381b0 gen_vec_initv2sf >> ... >> Instead of: <function_decl 0x7fe495eaed80 gen_vec_initv16qi > > Yep, this check basically verifies that the edge redirections are ones that we > legaly do (that is currently by inliner and ipa-cp). We need to either drop > this check or extend it to accept ICF merging. > > In longer term, I am quite sure we will want to record functions that ICF > proved > equivalent to a given function for debug info purposes. For now what about > "icf_merged" flag on node that will disable this check? > (the check is quite useful to catch various strange errors in the code as > Martin J. knows quite well ;) > > With complete list we can of course check that the call was previously > targetting one of the functions that was proved to be equivalent. >> >> As I talked to Martin Jambor, problematic BT: >> #0 cgraph_node::verify_node (this=0x7ffff483b5e0) at >> ../../gcc/cgraph.c:2837 >> #1 0x00000000006d5a40 in symtab_node::verify (this=0x7ffff483b5e0) >> at ../../gcc/symtab.c:1158 >> #2 0x0000000000b00c7c in expand_call_inline (bb=0x7ffff2875340, >> stmt=0x7ffff2870990, id=0x7fffffffda70) at >> ../../gcc/tree-inline.c:4234 >> #3 0x0000000000b018a3 in gimple_expand_calls_inline >> (bb=0x7ffff2875340, id=0x7fffffffda70) at >> ../../gcc/tree-inline.c:4522 >> #4 0x0000000000b01e69 in optimize_inline_calls (fn=0x7ffff624a870) >> at ../../gcc/tree-inline.c:4663 >> >> Checking code is called from tree_inline, where checking is called >> right after: cg_edge->callee->get_body (); >> That means, no redirect_call_stmt_to_callee () hasn't been called >> for the edge. >> >> Possible solutions: >> 1) We can call get_body in WPA for each caller I do a redirection. >> So that, call_stmt is fixed for the edge. (ugly solution) > > We do not want to do this. > >> 2) We can somehow fix edges in tree_inline, I tried: > > Actually the code is intended to run before redirection happen, just to check > that cgraph and the actual IL seems to be in sync. Lets just relax it on > ICF merged functions for now.
Btw, isn't cgraph edge redirection a "transform" step? Thus why is it performed at WPA time at all? Shouldn't it be performed at LTRANS time the same time we materialize clones and inline? Richard. > Honza >> >> cg_edge->callee->get_body (); >> >> if (cg_edge->callee->decl != id->dst_node->decl) >> { >> xxx = cg_edge->callee->callees; >> while(xxx) >> { >> push_cfun (DECL_STRUCT_FUNCTION (cg_edge->callee->decl)); >> xxx->redirect_call_stmt_to_callee (); >> pop_cfun (); >> xxx = xxx->next_callee; >> } >> >> cg_edge->callee->verify (); >> } >> >> But there's an ICE: >> 0x82e03e gsi_start_bb >> ../../gcc/gimple-iterator.h:118 >> 0x82f3f2 gsi_for_stmt(gimple_statement_base*) >> ../../gcc/gimple-iterator.c:623 >> 0x6dcb1e cgraph_edge::redirect_call_stmt_to_callee() >> ../../gcc/cgraph.c:1375 >> >> 3) We can somehow reduce checking code or remove this sub-condition? >> >> Thank you, >> Martin