public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Enable IPA-CP on functions with variable number of arguments or type attributes
@ 2011-09-02 12:27 Martin Jambor
  2011-09-02 14:03 ` Richard Guenther
  0 siblings, 1 reply; 3+ messages in thread
From: Martin Jambor @ 2011-09-02 12:27 UTC (permalink / raw)
  To: GCC Patches; +Cc: Jan Hubicka

Hi,

currently IPA-CP switches itself off on functions with are called with
variable number of arguments or on those whose signature cannot be
changed because of type attributes.  This patch turns it on for both,
not changing the parameters of its clones in the latter case.

Whether the function's signature can be changed is determined by
looking at node->local.can_change_signature which is set appropriately
already since my last patch (rev 178386).

This patch also replaces ipa-prop's own node_versionable flag with
inline_summary (node)->versionable.  Frankly, I find it very confusing
that this flag is in the inline summary even though it is set in
ipa-prop (except for thunks - a case we currently never care about
anyway) and used only in ipa-cp.  I also think this is a property of
the node (rather than an inlining parameter) as much as
can_change_signature is - would a patch moving it to node->local be
acceptable?

The patch passes bootstrap and testsuite on x86_64-linux.  It also
successfully LTO-builds 465.tonto where it creates 647 clones (498 of
them replacing the original function completely) without changing the
signature of a single one.  (No change in the run-time on this
benchmark, though).

OK for trunk?

Thanks,

Martin



2011-09-01  Martin Jambor  <mjambor@suse.cz>

	* ipa-prop.h (ipa_node_params): Removed fields
	called_with_var_arguments and node_versionable.
	(ipa_set_called_with_variable_arg): Removed.
	(ipa_is_called_with_var_arguments): Likewise.
	* ipa-cp.c (ipa_get_lattice): Fixed index check in an assert.
	(determine_versionability): Do not check for type attributes and va
	builtins.  Record versionability into inline summary.
	(initialize_node_lattices): Do not check
	ipa_is_called_with_var_arguments.
	(propagate_constants_accross_call): Likewise, ignore arguments we do
	not have PARM_DECLs for, set variable flag for parameters that were
	not passed a value.
	(create_specialized_node): Dump info that we cannot change signature.
	* ipa-prop.c (ipa_compute_jump_functions): Do not care about variable
	number of arguments.
	(ipa_make_edge_direct_to_target): Likewise.
	(ipa_update_after_lto_read): Likewise.
	(ipa_node_duplication_hook): Do not copy called_with_var_arguments flag.
	* tree-inline.c (copy_arguments_for_versioning): Copy PARM_DECLs if
	they were remapped.

	* testsuite/gcc.dg/ipa/ipcp-3.c: New test.

Index: src/gcc/ipa-cp.c
===================================================================
--- src.orig/gcc/ipa-cp.c
+++ src/gcc/ipa-cp.c
@@ -221,7 +221,7 @@ static struct ipcp_value *values_topo;
 static inline struct ipcp_lattice *
 ipa_get_lattice (struct ipa_node_params *info, int i)
 {
-  gcc_assert (i >= 0 && i <= ipa_get_param_count (info));
+  gcc_assert (i >= 0 && i < ipa_get_param_count (info));
   gcc_checking_assert (!info->ipcp_orig_node);
   gcc_checking_assert (info->lattices);
   return &(info->lattices[i]);
@@ -360,7 +360,6 @@ print_all_lattices (FILE * f, bool dump_
 static void
 determine_versionability (struct cgraph_node *node)
 {
-  struct cgraph_edge *edge;
   const char *reason = NULL;
 
   /* There are a number of generic reasons functions cannot be versioned.  We
@@ -369,32 +368,15 @@ determine_versionability (struct cgraph_
   if (node->alias || node->thunk.thunk_p)
     reason = "alias or thunk";
   else if (!inline_summary (node)->versionable)
-    reason = "inliner claims it is so";
-  else if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl)))
-    reason = "there are type attributes";
+    reason = "not a tree_versionable_function";
   else if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
     reason = "insufficient body availability";
-  else
-    /* Removing arguments doesn't work if the function takes varargs
-       or use __builtin_apply_args.
-       FIXME: handle this together with can_change_signature flag.  */
-    for (edge = node->callees; edge; edge = edge->next_callee)
-      {
-	tree t = edge->callee->decl;
-	if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
-	    && (DECL_FUNCTION_CODE (t) == BUILT_IN_APPLY_ARGS
-		|| DECL_FUNCTION_CODE (t) == BUILT_IN_VA_START))
-	  {
-	    reason = "prohibitive builtins called";
-	    break;
-	  };
-      }
 
   if (reason && dump_file && !node->alias && !node->thunk.thunk_p)
     fprintf (dump_file, "Function %s/%i is not versionable, reason: %s.\n",
 	     cgraph_node_name (node), node->uid, reason);
 
-  IPA_NODE_REF (node)->node_versionable = (reason == NULL);
+  inline_summary (node)->versionable = (reason == NULL);
 }
 
 /* Return true if it is at all technically possible to create clones of a
@@ -403,7 +385,7 @@ determine_versionability (struct cgraph_
 static bool
 ipcp_versionable_function_p (struct cgraph_node *node)
 {
-  return IPA_NODE_REF (node)->node_versionable;
+  return inline_summary (node)->versionable;
 }
 
 /* Structure holding accumulated information about callers of a node.  */
@@ -610,9 +592,7 @@ initialize_node_lattices (struct cgraph_
   int i;
 
   gcc_checking_assert (cgraph_function_with_gimple_body_p (node));
-  if (ipa_is_called_with_var_arguments (info))
-    disable = true;
-  else if (!node->local.local)
+  if (!node->local.local)
     {
       /* When cloning is allowed, we can assume that externally visible
 	 functions are not called.  We will compensate this by cloning
@@ -1068,18 +1048,17 @@ propagate_constants_accross_call (struct
   struct cgraph_node *callee, *alias_or_thunk;
   struct ipa_edge_args *args;
   bool ret = false;
-  int i, count;
+  int i, args_count, parms_count;
 
   callee = cgraph_function_node (cs->callee, &availability);
   if (!callee->analyzed)
     return false;
   gcc_checking_assert (cgraph_function_with_gimple_body_p (callee));
   callee_info = IPA_NODE_REF (callee);
-  if (ipa_is_called_with_var_arguments (callee_info))
-    return false;
 
   args = IPA_EDGE_REF (cs);
-  count = ipa_get_cs_argument_count (args);
+  args_count = ipa_get_cs_argument_count (args);
+  parms_count = ipa_get_param_count (callee_info);
 
   /* If this call goes through a thunk we must not propagate to the first (0th)
      parameter.  However, we might need to uncover a thunk from below a series
@@ -1095,7 +1074,7 @@ propagate_constants_accross_call (struct
   else
     i = 0;
 
-  for (; i < count; i++)
+  for (; (i < args_count) && (i < parms_count); i++)
     {
       struct ipa_jump_func *jump_func = ipa_get_ith_jump_func (args, i);
       struct ipcp_lattice *dest_lat = ipa_get_lattice (callee_info, i);
@@ -1105,6 +1084,9 @@ propagate_constants_accross_call (struct
       else
 	ret |= propagate_accross_jump_function (cs, jump_func, dest_lat);
     }
+  for (; i < parms_count; i++)
+    ret |= set_lattice_contains_variable (ipa_get_lattice (callee_info, i));
+
   return ret;
 }
 
@@ -2004,7 +1986,11 @@ create_specialized_node (struct cgraph_n
 	}
     }
   else
-    args_to_skip = NULL;
+    {
+      args_to_skip = NULL;
+      if (dump_file && (dump_flags & TDF_DETAILS))
+	fprintf (dump_file, "      cannot change function signature\n");
+    }
 
   for (i = 0; i < count ; i++)
     {
Index: src/gcc/ipa-prop.h
===================================================================
--- src.orig/gcc/ipa-prop.h
+++ src/gcc/ipa-prop.h
@@ -168,11 +168,6 @@ struct ipa_node_params
   /* If this node is an ipa-cp clone, these are the known values that describe
      what it has been specialized for.  */
   VEC (tree, heap) *known_vals;
-  /* Whether this function is called with variable number of actual
-     arguments.  */
-  unsigned called_with_var_arguments : 1;
-  /* Set when it is possible to create specialized versions of this node.  */
-  unsigned node_versionable : 1;
   /* Whether the param uses analysis has already been performed.  */
   unsigned uses_analysis_done : 1;
   /* Whether the function is enqueued in ipa-cp propagation stack.  */
@@ -224,22 +219,6 @@ ipa_is_param_used (struct ipa_node_param
   return VEC_index (ipa_param_descriptor_t, info->descriptors, i)->used;
 }
 
-/* Flag this node as having callers with variable number of arguments.  */
-
-static inline void
-ipa_set_called_with_variable_arg (struct ipa_node_params *info)
-{
-  info->called_with_var_arguments = 1;
-}
-
-/* Have we detected this node was called with variable number of arguments? */
-
-static inline bool
-ipa_is_called_with_var_arguments (struct ipa_node_params *info)
-{
-  return info->called_with_var_arguments;
-}
-
 /* ipa_edge_args stores information related to a callsite and particularly its
    arguments.  It can be accessed by the IPA_EDGE_REF macro.  */
 typedef struct GTY(()) ipa_edge_args
Index: src/gcc/tree-inline.c
===================================================================
--- src.orig/gcc/tree-inline.c
+++ src/gcc/tree-inline.c
@@ -4869,6 +4869,8 @@ copy_arguments_for_versioning (tree orig
     if (!args_to_skip || !bitmap_bit_p (args_to_skip, i))
       {
         tree new_tree = remap_decl (arg, id);
+	if (TREE_CODE (new_tree) != PARM_DECL)
+	  new_tree = id->copy_decl (arg, id);
         lang_hooks.dup_lang_specific_decl (new_tree);
         *parg = new_tree;
 	parg = &DECL_CHAIN (new_tree);
Index: src/gcc/testsuite/gcc.dg/ipa/ipcp-3.c
===================================================================
--- /dev/null
+++ src/gcc/testsuite/gcc.dg/ipa/ipcp-3.c
@@ -0,0 +1,70 @@
+/* Verify that IPA-CP can clone mark_cell without miscompiling it despite its
+   type_attributes.  */
+/* { dg-do run } */
+/* { dg-options "-O3 -fdump-ipa-cp" } */
+
+
+struct PMC {
+    unsigned flags;
+};
+
+typedef struct Pcc_cell
+{
+    struct PMC *p;
+    long bla;
+    long type;
+} Pcc_cell;
+
+int gi;
+
+extern void abort ();
+extern void never_ever(int * interp, struct PMC *pmc)
+     __attribute__((noinline));
+
+void never_ever (int * interp, struct PMC *pmc)
+{
+  abort ();
+}
+
+static void mark_cell(int * interp, Pcc_cell *c)
+        __attribute__((__nonnull__(1)))
+        __attribute__((noinline));
+
+static void
+mark_cell(int * interp, Pcc_cell *c)
+{
+  if (c && c->type == 4 && c->p
+      && !(c->p->flags & (1<<18)))
+    never_ever(interp, c->p);
+}
+
+static void foo(int * interp, Pcc_cell *c)
+  __attribute__((noinline));
+
+static void
+foo(int * interp, Pcc_cell *c)
+{
+  mark_cell(interp, c);
+}
+
+static struct Pcc_cell *
+__attribute__((noinline,noclone))
+getnull(void)
+{
+  return (struct Pcc_cell *) 0;
+}
+
+
+int main()
+{
+  int i;
+
+  for (i = 0; i < 100; i++)
+    foo (&gi, getnull ());
+  return 0;
+}
+
+
+/* { dg-final { scan-ipa-dump "Creating a specialized node of mark_cell" "cp" } } */
+/* { dg-final { cleanup-ipa-dump "cp" } } */
+
Index: src/gcc/ipa-prop.c
===================================================================
--- src.orig/gcc/ipa-prop.c
+++ src/gcc/ipa-prop.c
@@ -1032,19 +1032,13 @@ ipa_compute_jump_functions (struct cgrap
 
   for (cs = node->callees; cs; cs = cs->next_callee)
     {
-      struct cgraph_node *callee = cgraph_function_or_thunk_node (cs->callee, NULL);
+      struct cgraph_node *callee = cgraph_function_or_thunk_node (cs->callee,
+								  NULL);
       /* We do not need to bother analyzing calls to unknown
 	 functions unless they may become known during lto/whopr.  */
-      if (!cs->callee->analyzed && !flag_lto)
+      if (!callee->analyzed && !flag_lto)
 	continue;
       ipa_count_arguments (cs);
-      /* If the descriptor of the callee is not initialized yet, we have to do
-	 it now. */
-      if (callee->analyzed)
-	ipa_initialize_node_params (callee);
-      if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
-	  != ipa_get_param_count (IPA_NODE_REF (callee)))
-	ipa_set_called_with_variable_arg (IPA_NODE_REF (callee));
       ipa_compute_jump_functions_for_edge (parms_info, cs);
     }
 
@@ -1649,10 +1643,6 @@ ipa_make_edge_direct_to_target (struct c
     }
   callee = cgraph_function_or_thunk_node (callee, NULL);
 
-  if (ipa_get_cs_argument_count (IPA_EDGE_REF (ie))
-      != ipa_get_param_count (IPA_NODE_REF (callee)))
-    ipa_set_called_with_variable_arg (IPA_NODE_REF (callee));
-
   return ie;
 }
 
@@ -1964,7 +1954,6 @@ ipa_node_duplication_hook (struct cgraph
   new_info->lattices = NULL;
   new_info->ipcp_orig_node = old_info->ipcp_orig_node;
 
-  new_info->called_with_var_arguments = old_info->called_with_var_arguments;
   new_info->uses_analysis_done = old_info->uses_analysis_done;
   new_info->node_enqueued = old_info->node_enqueued;
 }
@@ -2949,7 +2938,6 @@ void
 ipa_update_after_lto_read (void)
 {
   struct cgraph_node *node;
-  struct cgraph_edge *cs;
 
   ipa_check_create_node_params ();
   ipa_check_create_edge_args ();
@@ -2957,17 +2945,4 @@ ipa_update_after_lto_read (void)
   for (node = cgraph_nodes; node; node = node->next)
     if (node->analyzed)
       ipa_initialize_node_params (node);
-
-  for (node = cgraph_nodes; node; node = node->next)
-    if (node->analyzed)
-      for (cs = node->callees; cs; cs = cs->next_callee)
-	{
-	  struct cgraph_node *callee;
-
-	  callee = cgraph_function_or_thunk_node (cs->callee, NULL);
-	  if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
-	      != ipa_get_param_count (IPA_NODE_REF (callee)))
-	    ipa_set_called_with_variable_arg (IPA_NODE_REF (callee));
-	}
 }
-

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Enable IPA-CP on functions with variable number of arguments or type attributes
  2011-09-02 12:27 [PATCH] Enable IPA-CP on functions with variable number of arguments or type attributes Martin Jambor
@ 2011-09-02 14:03 ` Richard Guenther
  2011-09-02 14:14   ` Jan Hubicka
  0 siblings, 1 reply; 3+ messages in thread
From: Richard Guenther @ 2011-09-02 14:03 UTC (permalink / raw)
  To: GCC Patches, Jan Hubicka

On Fri, Sep 2, 2011 at 2:27 PM, Martin Jambor <mjambor@suse.cz> wrote:
> Hi,
>
> currently IPA-CP switches itself off on functions with are called with
> variable number of arguments or on those whose signature cannot be
> changed because of type attributes.  This patch turns it on for both,
> not changing the parameters of its clones in the latter case.
>
> Whether the function's signature can be changed is determined by
> looking at node->local.can_change_signature which is set appropriately
> already since my last patch (rev 178386).
>
> This patch also replaces ipa-prop's own node_versionable flag with
> inline_summary (node)->versionable.  Frankly, I find it very confusing
> that this flag is in the inline summary even though it is set in
> ipa-prop (except for thunks - a case we currently never care about
> anyway) and used only in ipa-cp.  I also think this is a property of
> the node (rather than an inlining parameter) as much as
> can_change_signature is - would a patch moving it to node->local be
> acceptable?

I think so, or even node->global?

> The patch passes bootstrap and testsuite on x86_64-linux.  It also
> successfully LTO-builds 465.tonto where it creates 647 clones (498 of
> them replacing the original function completely) without changing the
> signature of a single one.  (No change in the run-time on this
> benchmark, though).
>
> OK for trunk?

Ok.

Thanks,
Richard.

> Thanks,
>
> Martin
>
>
>
> 2011-09-01  Martin Jambor  <mjambor@suse.cz>
>
>        * ipa-prop.h (ipa_node_params): Removed fields
>        called_with_var_arguments and node_versionable.
>        (ipa_set_called_with_variable_arg): Removed.
>        (ipa_is_called_with_var_arguments): Likewise.
>        * ipa-cp.c (ipa_get_lattice): Fixed index check in an assert.
>        (determine_versionability): Do not check for type attributes and va
>        builtins.  Record versionability into inline summary.
>        (initialize_node_lattices): Do not check
>        ipa_is_called_with_var_arguments.
>        (propagate_constants_accross_call): Likewise, ignore arguments we do
>        not have PARM_DECLs for, set variable flag for parameters that were
>        not passed a value.
>        (create_specialized_node): Dump info that we cannot change signature.
>        * ipa-prop.c (ipa_compute_jump_functions): Do not care about variable
>        number of arguments.
>        (ipa_make_edge_direct_to_target): Likewise.
>        (ipa_update_after_lto_read): Likewise.
>        (ipa_node_duplication_hook): Do not copy called_with_var_arguments flag.
>        * tree-inline.c (copy_arguments_for_versioning): Copy PARM_DECLs if
>        they were remapped.
>
>        * testsuite/gcc.dg/ipa/ipcp-3.c: New test.
>
> Index: src/gcc/ipa-cp.c
> ===================================================================
> --- src.orig/gcc/ipa-cp.c
> +++ src/gcc/ipa-cp.c
> @@ -221,7 +221,7 @@ static struct ipcp_value *values_topo;
>  static inline struct ipcp_lattice *
>  ipa_get_lattice (struct ipa_node_params *info, int i)
>  {
> -  gcc_assert (i >= 0 && i <= ipa_get_param_count (info));
> +  gcc_assert (i >= 0 && i < ipa_get_param_count (info));
>   gcc_checking_assert (!info->ipcp_orig_node);
>   gcc_checking_assert (info->lattices);
>   return &(info->lattices[i]);
> @@ -360,7 +360,6 @@ print_all_lattices (FILE * f, bool dump_
>  static void
>  determine_versionability (struct cgraph_node *node)
>  {
> -  struct cgraph_edge *edge;
>   const char *reason = NULL;
>
>   /* There are a number of generic reasons functions cannot be versioned.  We
> @@ -369,32 +368,15 @@ determine_versionability (struct cgraph_
>   if (node->alias || node->thunk.thunk_p)
>     reason = "alias or thunk";
>   else if (!inline_summary (node)->versionable)
> -    reason = "inliner claims it is so";
> -  else if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl)))
> -    reason = "there are type attributes";
> +    reason = "not a tree_versionable_function";
>   else if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
>     reason = "insufficient body availability";
> -  else
> -    /* Removing arguments doesn't work if the function takes varargs
> -       or use __builtin_apply_args.
> -       FIXME: handle this together with can_change_signature flag.  */
> -    for (edge = node->callees; edge; edge = edge->next_callee)
> -      {
> -       tree t = edge->callee->decl;
> -       if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
> -           && (DECL_FUNCTION_CODE (t) == BUILT_IN_APPLY_ARGS
> -               || DECL_FUNCTION_CODE (t) == BUILT_IN_VA_START))
> -         {
> -           reason = "prohibitive builtins called";
> -           break;
> -         };
> -      }
>
>   if (reason && dump_file && !node->alias && !node->thunk.thunk_p)
>     fprintf (dump_file, "Function %s/%i is not versionable, reason: %s.\n",
>             cgraph_node_name (node), node->uid, reason);
>
> -  IPA_NODE_REF (node)->node_versionable = (reason == NULL);
> +  inline_summary (node)->versionable = (reason == NULL);
>  }
>
>  /* Return true if it is at all technically possible to create clones of a
> @@ -403,7 +385,7 @@ determine_versionability (struct cgraph_
>  static bool
>  ipcp_versionable_function_p (struct cgraph_node *node)
>  {
> -  return IPA_NODE_REF (node)->node_versionable;
> +  return inline_summary (node)->versionable;
>  }
>
>  /* Structure holding accumulated information about callers of a node.  */
> @@ -610,9 +592,7 @@ initialize_node_lattices (struct cgraph_
>   int i;
>
>   gcc_checking_assert (cgraph_function_with_gimple_body_p (node));
> -  if (ipa_is_called_with_var_arguments (info))
> -    disable = true;
> -  else if (!node->local.local)
> +  if (!node->local.local)
>     {
>       /* When cloning is allowed, we can assume that externally visible
>         functions are not called.  We will compensate this by cloning
> @@ -1068,18 +1048,17 @@ propagate_constants_accross_call (struct
>   struct cgraph_node *callee, *alias_or_thunk;
>   struct ipa_edge_args *args;
>   bool ret = false;
> -  int i, count;
> +  int i, args_count, parms_count;
>
>   callee = cgraph_function_node (cs->callee, &availability);
>   if (!callee->analyzed)
>     return false;
>   gcc_checking_assert (cgraph_function_with_gimple_body_p (callee));
>   callee_info = IPA_NODE_REF (callee);
> -  if (ipa_is_called_with_var_arguments (callee_info))
> -    return false;
>
>   args = IPA_EDGE_REF (cs);
> -  count = ipa_get_cs_argument_count (args);
> +  args_count = ipa_get_cs_argument_count (args);
> +  parms_count = ipa_get_param_count (callee_info);
>
>   /* If this call goes through a thunk we must not propagate to the first (0th)
>      parameter.  However, we might need to uncover a thunk from below a series
> @@ -1095,7 +1074,7 @@ propagate_constants_accross_call (struct
>   else
>     i = 0;
>
> -  for (; i < count; i++)
> +  for (; (i < args_count) && (i < parms_count); i++)
>     {
>       struct ipa_jump_func *jump_func = ipa_get_ith_jump_func (args, i);
>       struct ipcp_lattice *dest_lat = ipa_get_lattice (callee_info, i);
> @@ -1105,6 +1084,9 @@ propagate_constants_accross_call (struct
>       else
>        ret |= propagate_accross_jump_function (cs, jump_func, dest_lat);
>     }
> +  for (; i < parms_count; i++)
> +    ret |= set_lattice_contains_variable (ipa_get_lattice (callee_info, i));
> +
>   return ret;
>  }
>
> @@ -2004,7 +1986,11 @@ create_specialized_node (struct cgraph_n
>        }
>     }
>   else
> -    args_to_skip = NULL;
> +    {
> +      args_to_skip = NULL;
> +      if (dump_file && (dump_flags & TDF_DETAILS))
> +       fprintf (dump_file, "      cannot change function signature\n");
> +    }
>
>   for (i = 0; i < count ; i++)
>     {
> Index: src/gcc/ipa-prop.h
> ===================================================================
> --- src.orig/gcc/ipa-prop.h
> +++ src/gcc/ipa-prop.h
> @@ -168,11 +168,6 @@ struct ipa_node_params
>   /* If this node is an ipa-cp clone, these are the known values that describe
>      what it has been specialized for.  */
>   VEC (tree, heap) *known_vals;
> -  /* Whether this function is called with variable number of actual
> -     arguments.  */
> -  unsigned called_with_var_arguments : 1;
> -  /* Set when it is possible to create specialized versions of this node.  */
> -  unsigned node_versionable : 1;
>   /* Whether the param uses analysis has already been performed.  */
>   unsigned uses_analysis_done : 1;
>   /* Whether the function is enqueued in ipa-cp propagation stack.  */
> @@ -224,22 +219,6 @@ ipa_is_param_used (struct ipa_node_param
>   return VEC_index (ipa_param_descriptor_t, info->descriptors, i)->used;
>  }
>
> -/* Flag this node as having callers with variable number of arguments.  */
> -
> -static inline void
> -ipa_set_called_with_variable_arg (struct ipa_node_params *info)
> -{
> -  info->called_with_var_arguments = 1;
> -}
> -
> -/* Have we detected this node was called with variable number of arguments? */
> -
> -static inline bool
> -ipa_is_called_with_var_arguments (struct ipa_node_params *info)
> -{
> -  return info->called_with_var_arguments;
> -}
> -
>  /* ipa_edge_args stores information related to a callsite and particularly its
>    arguments.  It can be accessed by the IPA_EDGE_REF macro.  */
>  typedef struct GTY(()) ipa_edge_args
> Index: src/gcc/tree-inline.c
> ===================================================================
> --- src.orig/gcc/tree-inline.c
> +++ src/gcc/tree-inline.c
> @@ -4869,6 +4869,8 @@ copy_arguments_for_versioning (tree orig
>     if (!args_to_skip || !bitmap_bit_p (args_to_skip, i))
>       {
>         tree new_tree = remap_decl (arg, id);
> +       if (TREE_CODE (new_tree) != PARM_DECL)
> +         new_tree = id->copy_decl (arg, id);
>         lang_hooks.dup_lang_specific_decl (new_tree);
>         *parg = new_tree;
>        parg = &DECL_CHAIN (new_tree);
> Index: src/gcc/testsuite/gcc.dg/ipa/ipcp-3.c
> ===================================================================
> --- /dev/null
> +++ src/gcc/testsuite/gcc.dg/ipa/ipcp-3.c
> @@ -0,0 +1,70 @@
> +/* Verify that IPA-CP can clone mark_cell without miscompiling it despite its
> +   type_attributes.  */
> +/* { dg-do run } */
> +/* { dg-options "-O3 -fdump-ipa-cp" } */
> +
> +
> +struct PMC {
> +    unsigned flags;
> +};
> +
> +typedef struct Pcc_cell
> +{
> +    struct PMC *p;
> +    long bla;
> +    long type;
> +} Pcc_cell;
> +
> +int gi;
> +
> +extern void abort ();
> +extern void never_ever(int * interp, struct PMC *pmc)
> +     __attribute__((noinline));
> +
> +void never_ever (int * interp, struct PMC *pmc)
> +{
> +  abort ();
> +}
> +
> +static void mark_cell(int * interp, Pcc_cell *c)
> +        __attribute__((__nonnull__(1)))
> +        __attribute__((noinline));
> +
> +static void
> +mark_cell(int * interp, Pcc_cell *c)
> +{
> +  if (c && c->type == 4 && c->p
> +      && !(c->p->flags & (1<<18)))
> +    never_ever(interp, c->p);
> +}
> +
> +static void foo(int * interp, Pcc_cell *c)
> +  __attribute__((noinline));
> +
> +static void
> +foo(int * interp, Pcc_cell *c)
> +{
> +  mark_cell(interp, c);
> +}
> +
> +static struct Pcc_cell *
> +__attribute__((noinline,noclone))
> +getnull(void)
> +{
> +  return (struct Pcc_cell *) 0;
> +}
> +
> +
> +int main()
> +{
> +  int i;
> +
> +  for (i = 0; i < 100; i++)
> +    foo (&gi, getnull ());
> +  return 0;
> +}
> +
> +
> +/* { dg-final { scan-ipa-dump "Creating a specialized node of mark_cell" "cp" } } */
> +/* { dg-final { cleanup-ipa-dump "cp" } } */
> +
> Index: src/gcc/ipa-prop.c
> ===================================================================
> --- src.orig/gcc/ipa-prop.c
> +++ src/gcc/ipa-prop.c
> @@ -1032,19 +1032,13 @@ ipa_compute_jump_functions (struct cgrap
>
>   for (cs = node->callees; cs; cs = cs->next_callee)
>     {
> -      struct cgraph_node *callee = cgraph_function_or_thunk_node (cs->callee, NULL);
> +      struct cgraph_node *callee = cgraph_function_or_thunk_node (cs->callee,
> +                                                                 NULL);
>       /* We do not need to bother analyzing calls to unknown
>         functions unless they may become known during lto/whopr.  */
> -      if (!cs->callee->analyzed && !flag_lto)
> +      if (!callee->analyzed && !flag_lto)
>        continue;
>       ipa_count_arguments (cs);
> -      /* If the descriptor of the callee is not initialized yet, we have to do
> -        it now. */
> -      if (callee->analyzed)
> -       ipa_initialize_node_params (callee);
> -      if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
> -         != ipa_get_param_count (IPA_NODE_REF (callee)))
> -       ipa_set_called_with_variable_arg (IPA_NODE_REF (callee));
>       ipa_compute_jump_functions_for_edge (parms_info, cs);
>     }
>
> @@ -1649,10 +1643,6 @@ ipa_make_edge_direct_to_target (struct c
>     }
>   callee = cgraph_function_or_thunk_node (callee, NULL);
>
> -  if (ipa_get_cs_argument_count (IPA_EDGE_REF (ie))
> -      != ipa_get_param_count (IPA_NODE_REF (callee)))
> -    ipa_set_called_with_variable_arg (IPA_NODE_REF (callee));
> -
>   return ie;
>  }
>
> @@ -1964,7 +1954,6 @@ ipa_node_duplication_hook (struct cgraph
>   new_info->lattices = NULL;
>   new_info->ipcp_orig_node = old_info->ipcp_orig_node;
>
> -  new_info->called_with_var_arguments = old_info->called_with_var_arguments;
>   new_info->uses_analysis_done = old_info->uses_analysis_done;
>   new_info->node_enqueued = old_info->node_enqueued;
>  }
> @@ -2949,7 +2938,6 @@ void
>  ipa_update_after_lto_read (void)
>  {
>   struct cgraph_node *node;
> -  struct cgraph_edge *cs;
>
>   ipa_check_create_node_params ();
>   ipa_check_create_edge_args ();
> @@ -2957,17 +2945,4 @@ ipa_update_after_lto_read (void)
>   for (node = cgraph_nodes; node; node = node->next)
>     if (node->analyzed)
>       ipa_initialize_node_params (node);
> -
> -  for (node = cgraph_nodes; node; node = node->next)
> -    if (node->analyzed)
> -      for (cs = node->callees; cs; cs = cs->next_callee)
> -       {
> -         struct cgraph_node *callee;
> -
> -         callee = cgraph_function_or_thunk_node (cs->callee, NULL);
> -         if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
> -             != ipa_get_param_count (IPA_NODE_REF (callee)))
> -           ipa_set_called_with_variable_arg (IPA_NODE_REF (callee));
> -       }
>  }
> -
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Enable IPA-CP on functions with variable number of arguments or type attributes
  2011-09-02 14:03 ` Richard Guenther
@ 2011-09-02 14:14   ` Jan Hubicka
  0 siblings, 0 replies; 3+ messages in thread
From: Jan Hubicka @ 2011-09-02 14:14 UTC (permalink / raw)
  To: Richard Guenther; +Cc: GCC Patches, Jan Hubicka

> On Fri, Sep 2, 2011 at 2:27 PM, Martin Jambor <mjambor@suse.cz> wrote:
> > Hi,
> >
> > currently IPA-CP switches itself off on functions with are called with
> > variable number of arguments or on those whose signature cannot be
> > changed because of type attributes.  This patch turns it on for both,
> > not changing the parameters of its clones in the latter case.
> >
> > Whether the function's signature can be changed is determined by
> > looking at node->local.can_change_signature which is set appropriately
> > already since my last patch (rev 178386).
> >
> > This patch also replaces ipa-prop's own node_versionable flag with
> > inline_summary (node)->versionable.  Frankly, I find it very confusing
> > that this flag is in the inline summary even though it is set in
> > ipa-prop (except for thunks - a case we currently never care about
> > anyway) and used only in ipa-cp.  I also think this is a property of
> > the node (rather than an inlining parameter) as much as
> > can_change_signature is - would a patch moving it to node->local be
> > acceptable?
> 
> I think so, or even node->global?

It is function local property, so node->local.
I did the same with can_change_signature, so this is fine with me.  They ended up in inline
summaries only becuase they used to be computed there.

Honza

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2011-09-02 14:14 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-02 12:27 [PATCH] Enable IPA-CP on functions with variable number of arguments or type attributes Martin Jambor
2011-09-02 14:03 ` Richard Guenther
2011-09-02 14:14   ` Jan Hubicka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).