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;

Reply via email to