Hi, On Mon, Jan 07, 2013 at 01:26:23AM +0100, Jan Hubicka wrote: > Hi, > as discused in the PR log there seems to be ordering issue in > update_indirect_edges_after_inlining that first updates info in call edge to > correspond the situation after inlining and then it tries to devirtualize that > is trying to look up the info prior inlining. > > Bootstrapped/regtested x86_64-linux > Martin, does it look sane?
Yes, this is exactly what needs to be done. I'm quite surprised I had not already added a testcase for this. > Can you also, please, look into why ipa-cp is not handling both calls? I will. Thanks, a lot for the patch, Martin > > Honza > > PR tree-optimization/55823 > * g++.dg/ipa/devirt-10.C: New testcase. > > * ipa-prop.c (update_indirect_edges_after_inlining): Fix ordering issue. > Index: testsuite/g++.dg/ipa/devirt-10.C > =================================================================== > *** testsuite/g++.dg/ipa/devirt-10.C (revision 0) > --- testsuite/g++.dg/ipa/devirt-10.C (revision 0) > *************** > *** 0 **** > --- 1,34 ---- > + /* { dg-do compile } */ > + /* { dg-options "-O3 -fdump-ipa-inline -fdump-ipa-cp" } */ > + class wxPaintEvent { }; > + struct wxDCBase > + { > + wxDCBase (); > + virtual int GetLayoutDirection() const{} > + virtual void SetLayoutDirection(int){} > + }; > + struct wxWindowDC : public wxDCBase {}; > + struct wxBufferedDC : public wxDCBase > + { > + void Init(wxDCBase*dc) { > + InitCommon(dc); > + } > + void InitCommon(wxDCBase*dc) { > + if (dc) > + SetLayoutDirection(dc->GetLayoutDirection()); > + } > + }; > + struct wxBufferedPaintDC : public wxBufferedDC { > + wxBufferedPaintDC() { > + Init(&m_paintdc); > + } > + wxWindowDC m_paintdc; > + }; > + void OnPaint(wxPaintEvent & event) { > + wxBufferedPaintDC dc; > + } > + /* IPA-CP should really discover both cases, but for time being the second > is handled by inliner. */ > + /* { dg-final { scan-ipa-dump-times "Discovered a virtual call to a known > target" 1 "inline" } } */ > + /* { dg-final { scan-ipa-dump-times "Discovered a virtual call to a known > target" 1 "cp" } } */ > + /* { dg-final { cleanup-ipa-dump "inline" } } */ > + /* { dg-final { cleanup-ipa-dump "cp" } } */ > Index: ipa-prop.c > =================================================================== > *** ipa-prop.c (revision 194918) > --- ipa-prop.c (working copy) > *************** update_indirect_edges_after_inlining (st > *** 2264,2303 **** > > param_index = ici->param_index; > jfunc = ipa_get_ith_jump_func (top, param_index); > - if (jfunc->type == IPA_JF_PASS_THROUGH > - && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR) > - { > - if (ici->agg_contents > - && !ipa_get_jf_pass_through_agg_preserved (jfunc)) > - ici->param_index = -1; > - else > - ici->param_index = ipa_get_jf_pass_through_formal_id (jfunc); > - } > - else if (jfunc->type == IPA_JF_ANCESTOR) > - { > - if (ici->agg_contents > - && !ipa_get_jf_ancestor_agg_preserved (jfunc)) > - ici->param_index = -1; > - else > - { > - ici->param_index = ipa_get_jf_ancestor_formal_id (jfunc); > - ici->offset += ipa_get_jf_ancestor_offset (jfunc); > - } > - } > - else > - /* Either we can find a destination for this edge now or never. */ > - ici->param_index = -1; > > if (!flag_indirect_inlining) > ! continue; > ! > ! if (ici->polymorphic) > new_direct_edge = try_make_edge_direct_virtual_call (ie, jfunc, > new_root_info); > else > new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc, > new_root_info); > - > if (new_direct_edge) > { > new_direct_edge->indirect_inlining_edge = 1; > --- 2264,2278 ---- > > param_index = ici->param_index; > jfunc = ipa_get_ith_jump_func (top, param_index); > > if (!flag_indirect_inlining) > ! new_direct_edge = NULL; > ! else if (ici->polymorphic) > new_direct_edge = try_make_edge_direct_virtual_call (ie, jfunc, > new_root_info); > else > new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc, > new_root_info); > if (new_direct_edge) > { > new_direct_edge->indirect_inlining_edge = 1; > *************** update_indirect_edges_after_inlining (st > *** 2312,2317 **** > --- 2287,2315 ---- > res = true; > } > } > + else if (jfunc->type == IPA_JF_PASS_THROUGH > + && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR) > + { > + if (ici->agg_contents > + && !ipa_get_jf_pass_through_agg_preserved (jfunc)) > + ici->param_index = -1; > + else > + ici->param_index = ipa_get_jf_pass_through_formal_id (jfunc); > + } > + else if (jfunc->type == IPA_JF_ANCESTOR) > + { > + if (ici->agg_contents > + && !ipa_get_jf_ancestor_agg_preserved (jfunc)) > + ici->param_index = -1; > + else > + { > + ici->param_index = ipa_get_jf_ancestor_formal_id (jfunc); > + ici->offset += ipa_get_jf_ancestor_offset (jfunc); > + } > + } > + else > + /* Either we can find a destination for this edge now or never. */ > + ici->param_index = -1; > } > > return res;