> 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.

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

Reply via email to