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

Reply via email to