On Mon, Nov 10, 2014 at 4:48 PM, Ilya Enkovich <enkovich....@gmail.com> wrote:
> Hi,
>
> Here is a fix for PR63766.  Currently all functions are transformed into SSA 
> before local optimizations and it allows function to be inlined and removed 
> before it goes through local optimzations.  But this requires removal of 
> these functions from working queue.
>
> Bootstrapped and tested on x86_64-unknown-linux-gnu.  OK for trunk?
>
> Thanks,
> Ilya
> --
> gcc/
>
> 2014-11-10  Ilya Enkovich  <ilya.enkov...@intel.com>
>
>         * passes.c (remove_cgraph_node_from_order): New.
>         (do_per_function_toporder): Register cgraph removal
>         hook.
>
> gcc/testsuite/
>
> 2014-11-10  Ilya Enkovich  <ilya.enkov...@intel.com>
>
>         * g++.dg/pr63766.C: New.
>
>
> diff --git a/gcc/passes.c b/gcc/passes.c
> index 5e91a79..b6a0b0c 100644
> --- a/gcc/passes.c
> +++ b/gcc/passes.c
> @@ -1609,6 +1609,24 @@ do_per_function (void (*callback) (function *, void 
> *data), void *data)
>  static int nnodes;
>  static GTY ((length ("nnodes"))) cgraph_node **order;
>
> +/* Hook called when NODE is removed and therefore should be
> +   excluded from order vector.  DATA is an array of integers.
> +   DATA[0] holds max index it may be accessed by.  For cgraph
> +   node DATA[node->uid + 1] holds index of this node in order
> +   vector.  */
> +static void
> +remove_cgraph_node_from_order (cgraph_node *node, void *data)
> +{
> +  int *order_idx = (int *)data;
> +
> +  if (node->uid >= order_idx[0])
> +    return;
> +
> +  int idx = order_idx[node->uid + 1];
> +  if (idx >= 0 && idx < nnodes && order[idx] == node)
> +    order[idx] = NULL;
> +}
> +
>  /* If we are in IPA mode (i.e., current_function_decl is NULL), call
>     function CALLBACK for every function in the call graph.  Otherwise,
>     call CALLBACK on the current function.
> @@ -1622,13 +1640,29 @@ do_per_function_toporder (void (*callback) (function 
> *, void *data), void *data)
>      callback (cfun, data);
>    else
>      {
> +      cgraph_node_hook_list *hook;
> +      int *order_idx;
>        gcc_assert (!order);
>        order = ggc_vec_alloc<cgraph_node *> (symtab->cgraph_count);
> +
> +      order_idx = (int *)xmalloc (sizeof(int) * (symtab->cgraph_max_uid + 
> 1));

XALLOCAVEC (int, symtab->graph_max_uid + 1)

Ok with that change.

Thanks,
Richard.

> +      memset (order_idx + 1, -1, sizeof (int) * symtab->cgraph_max_uid);
> +      order_idx[0] = symtab->cgraph_max_uid;
> +
>        nnodes = ipa_reverse_postorder (order);
>        for (i = nnodes - 1; i >= 0; i--)
> -        order[i]->process = 1;
> +       {
> +         order[i]->process = 1;
> +         order_idx[order[i]->uid + 1] = i;
> +       }
> +      hook = symtab->add_cgraph_removal_hook (remove_cgraph_node_from_order,
> +                                             order_idx);
>        for (i = nnodes - 1; i >= 0; i--)
>         {
> +         /* Function could be inlined and removed as unreachable.  */
> +         if (!order[i])
> +           continue;
> +
>           struct cgraph_node *node = order[i];
>
>           /* Allow possibly removed nodes to be garbage collected.  */
> @@ -1637,6 +1671,8 @@ do_per_function_toporder (void (*callback) (function *, 
> void *data), void *data)
>           if (node->has_gimple_body_p ())
>             callback (DECL_STRUCT_FUNCTION (node->decl), data);
>         }
> +      symtab->remove_cgraph_removal_hook (hook);
> +      free (order_idx);
>      }
>    ggc_free (order);
>    order = NULL;
> diff --git a/gcc/testsuite/g++.dg/pr63766.C b/gcc/testsuite/g++.dg/pr63766.C
> new file mode 100644
> index 0000000..1414fbe
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/pr63766.C
> @@ -0,0 +1,48 @@
> +/* { dg-do compile } */
> +/* { dg-options "-std=c++11 -O2" } */
> +
> +class A
> +{
> + public:
> +  void
> +    getValueType ()
> +  {
> +  }
> +  void getTypeClass ();
> +};
> +template <typename ImplClass> class B
> +{
> + public:
> +  void
> +    Visit (A *p1)
> +  {
> +    p1->getTypeClass ();
> +    static_cast<ImplClass *> (0)->VisitAtomicType (0);
> +  }
> +};
> +class C : B<C>
> +{
> +  template <typename Fn>
> +  void
> +    dumpChild (Fn p1)
> +    {
> +      p1 ();
> +    }
> +
> + public:
> +  void dumpTypeAsChild (int);
> +  void
> +    VisitAtomicType (A *p1)
> +  {
> +    p1->getValueType ();
> +    dumpTypeAsChild (0);
> +  }
> +};
> +void
> +C::dumpTypeAsChild (int)
> +{
> +  dumpChild ([=]
> +             {
> +               Visit (0);
> +             });
> +}

Reply via email to