Patchwork Avoid IPA-CP versioning if type mismatch prevents it (PR tree-optimization/47967)

login
register
mail settings
Submitter Jakub Jelinek
Date March 4, 2011, 8:48 p.m.
Message ID <20110304204821.GL30899@tyan-ft48-01.lab.bos.redhat.com>
Download mbox | patch
Permalink /patch/85439/
State New
Headers show

Comments

Jakub Jelinek - March 4, 2011, 8:48 p.m.
Hi!

If conversion between parameter type and passed argument is not useless,
is not fold convertible and has different size, then even VCE is not
appropriate, but for something so undefined we shouldn't be IMHO
trying to optimize anything.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2011-03-04  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/47967
	* ipa-cp.c (build_const_val): Return NULL instead of creating
	VIEW_CONVERT_EXPR for mismatching sizes.
	(ipcp_create_replace_map): Return NULL if build_const_val failed.
	(ipcp_insert_stage): If ipcp_create_replace_map returns NULL,
	give up on versioning.

	* gcc.c-torture/compile/pr47967.c: New test.


	Jakub
Richard Guenther - March 4, 2011, 9:53 p.m.
On Fri, Mar 4, 2011 at 9:48 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> If conversion between parameter type and passed argument is not useless,
> is not fold convertible and has different size, then even VCE is not
> appropriate, but for something so undefined we shouldn't be IMHO
> trying to optimize anything.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok.

Thanks,
Richard.

> 2011-03-04  Jakub Jelinek  <jakub@redhat.com>
>
>        PR tree-optimization/47967
>        * ipa-cp.c (build_const_val): Return NULL instead of creating
>        VIEW_CONVERT_EXPR for mismatching sizes.
>        (ipcp_create_replace_map): Return NULL if build_const_val failed.
>        (ipcp_insert_stage): If ipcp_create_replace_map returns NULL,
>        give up on versioning.
>
>        * gcc.c-torture/compile/pr47967.c: New test.
>
> --- gcc/ipa-cp.c.jj     2011-02-15 15:34:33.000000000 +0100
> +++ gcc/ipa-cp.c        2011-03-04 14:29:23.000000000 +0100
> @@ -587,8 +587,9 @@ ipcp_initialize_node_lattices (struct cg
>     }
>  }
>
> -/* build INTEGER_CST tree with type TREE_TYPE and value according to LAT.
> -   Return the tree.  */
> +/* Build a constant tree with type TREE_TYPE and value according to LAT.
> +   Return the tree, or, if it is not possible to convert such value
> +   to TREE_TYPE, NULL.  */
>  static tree
>  build_const_val (struct ipcp_lattice *lat, tree tree_type)
>  {
> @@ -601,8 +602,10 @@ build_const_val (struct ipcp_lattice *la
>     {
>       if (fold_convertible_p (tree_type, val))
>        return fold_build1 (NOP_EXPR, tree_type, val);
> -      else
> +      else if (TYPE_SIZE (tree_type) == TYPE_SIZE (TREE_TYPE (val)))
>        return fold_build1 (VIEW_CONVERT_EXPR, tree_type, val);
> +      else
> +       return NULL;
>     }
>   return val;
>  }
> @@ -976,8 +979,20 @@ ipcp_create_replace_map (tree parm_tree,
>   struct ipa_replace_map *replace_map;
>   tree const_val;
>
> -  replace_map = ggc_alloc_ipa_replace_map ();
>   const_val = build_const_val (lat, TREE_TYPE (parm_tree));
> +  if (const_val == NULL_TREE)
> +    {
> +      if (dump_file)
> +       {
> +         fprintf (dump_file, "  const ");
> +         print_generic_expr (dump_file, lat->constant, 0);
> +         fprintf (dump_file, "  can't be converted to param ");
> +         print_generic_expr (dump_file, parm_tree, 0);
> +         fprintf (dump_file, "\n");
> +       }
> +      return NULL;
> +    }
> +  replace_map = ggc_alloc_ipa_replace_map ();
>   if (dump_file)
>     {
>       fprintf (dump_file, "  replacing param ");
> @@ -1378,15 +1393,6 @@ ipcp_insert_stage (void)
>          continue;
>        }
>
> -      new_size += growth;
> -
> -      /* Look if original function becomes dead after cloning.  */
> -      for (cs = node->callers; cs != NULL; cs = cs->next_caller)
> -       if (cs->caller == node || ipcp_need_redirect_p (cs))
> -         break;
> -      if (!cs && cgraph_will_be_removed_from_program_if_no_direct_calls (node))
> -       bitmap_set_bit (dead_nodes, node->uid);
> -
>       info = IPA_NODE_REF (node);
>       count = ipa_get_param_count (info);
>
> @@ -1413,11 +1419,28 @@ ipcp_insert_stage (void)
>            {
>              replace_param =
>                ipcp_create_replace_map (parm_tree, lat);
> +             if (replace_param == NULL)
> +               break;
>              VEC_safe_push (ipa_replace_map_p, gc, replace_trees, replace_param);
>              if (args_to_skip)
>                bitmap_set_bit (args_to_skip, i);
>            }
>        }
> +      if (i < count)
> +       {
> +         if (dump_file)
> +           fprintf (dump_file, "Not versioning, some parameters couldn't be replaced");
> +         continue;
> +       }
> +
> +      new_size += growth;
> +
> +      /* Look if original function becomes dead after cloning.  */
> +      for (cs = node->callers; cs != NULL; cs = cs->next_caller)
> +       if (cs->caller == node || ipcp_need_redirect_p (cs))
> +         break;
> +      if (!cs && cgraph_will_be_removed_from_program_if_no_direct_calls (node))
> +       bitmap_set_bit (dead_nodes, node->uid);
>
>       /* Compute how many callers node has.  */
>       node_callers = 0;
> --- gcc/testsuite/gcc.c-torture/compile/pr47967.c.jj    2011-03-04 14:31:29.000000000 +0100
> +++ gcc/testsuite/gcc.c-torture/compile/pr47967.c       2011-03-04 14:31:12.000000000 +0100
> @@ -0,0 +1,17 @@
> +/* PR tree-optimization/47967 */
> +
> +extern void abort (void);
> +static void bar ();
> +
> +void
> +foo ()
> +{
> +  bar (1);
> +}
> +
> +static void
> +bar (double i)
> +{
> +  if (i)
> +    abort ();
> +}
>
>        Jakub
>

Patch

--- gcc/ipa-cp.c.jj	2011-02-15 15:34:33.000000000 +0100
+++ gcc/ipa-cp.c	2011-03-04 14:29:23.000000000 +0100
@@ -587,8 +587,9 @@  ipcp_initialize_node_lattices (struct cg
     }
 }
 
-/* build INTEGER_CST tree with type TREE_TYPE and value according to LAT.
-   Return the tree.  */
+/* Build a constant tree with type TREE_TYPE and value according to LAT.
+   Return the tree, or, if it is not possible to convert such value
+   to TREE_TYPE, NULL.  */
 static tree
 build_const_val (struct ipcp_lattice *lat, tree tree_type)
 {
@@ -601,8 +602,10 @@  build_const_val (struct ipcp_lattice *la
     {
       if (fold_convertible_p (tree_type, val))
 	return fold_build1 (NOP_EXPR, tree_type, val);
-      else
+      else if (TYPE_SIZE (tree_type) == TYPE_SIZE (TREE_TYPE (val)))
 	return fold_build1 (VIEW_CONVERT_EXPR, tree_type, val);
+      else
+	return NULL;
     }
   return val;
 }
@@ -976,8 +979,20 @@  ipcp_create_replace_map (tree parm_tree,
   struct ipa_replace_map *replace_map;
   tree const_val;
 
-  replace_map = ggc_alloc_ipa_replace_map ();
   const_val = build_const_val (lat, TREE_TYPE (parm_tree));
+  if (const_val == NULL_TREE)
+    {
+      if (dump_file)
+	{
+	  fprintf (dump_file, "  const ");
+	  print_generic_expr (dump_file, lat->constant, 0);
+	  fprintf (dump_file, "  can't be converted to param ");
+	  print_generic_expr (dump_file, parm_tree, 0);
+	  fprintf (dump_file, "\n");
+	}
+      return NULL;
+    }
+  replace_map = ggc_alloc_ipa_replace_map ();
   if (dump_file)
     {
       fprintf (dump_file, "  replacing param ");
@@ -1378,15 +1393,6 @@  ipcp_insert_stage (void)
 	  continue;
 	}
 
-      new_size += growth;
-
-      /* Look if original function becomes dead after cloning.  */
-      for (cs = node->callers; cs != NULL; cs = cs->next_caller)
-	if (cs->caller == node || ipcp_need_redirect_p (cs))
-	  break;
-      if (!cs && cgraph_will_be_removed_from_program_if_no_direct_calls (node))
-	bitmap_set_bit (dead_nodes, node->uid);
-
       info = IPA_NODE_REF (node);
       count = ipa_get_param_count (info);
 
@@ -1413,11 +1419,28 @@  ipcp_insert_stage (void)
 	    {
 	      replace_param =
 		ipcp_create_replace_map (parm_tree, lat);
+	      if (replace_param == NULL)
+		break;
 	      VEC_safe_push (ipa_replace_map_p, gc, replace_trees, replace_param);
 	      if (args_to_skip)
 	        bitmap_set_bit (args_to_skip, i);
 	    }
 	}
+      if (i < count)
+	{
+	  if (dump_file)
+	    fprintf (dump_file, "Not versioning, some parameters couldn't be replaced");
+	  continue;
+	}
+
+      new_size += growth;
+
+      /* Look if original function becomes dead after cloning.  */
+      for (cs = node->callers; cs != NULL; cs = cs->next_caller)
+	if (cs->caller == node || ipcp_need_redirect_p (cs))
+	  break;
+      if (!cs && cgraph_will_be_removed_from_program_if_no_direct_calls (node))
+	bitmap_set_bit (dead_nodes, node->uid);
 
       /* Compute how many callers node has.  */
       node_callers = 0;
--- gcc/testsuite/gcc.c-torture/compile/pr47967.c.jj	2011-03-04 14:31:29.000000000 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr47967.c	2011-03-04 14:31:12.000000000 +0100
@@ -0,0 +1,17 @@ 
+/* PR tree-optimization/47967 */
+
+extern void abort (void);
+static void bar ();
+
+void
+foo ()
+{
+  bar (1);
+}
+
+static void
+bar (double i)
+{
+  if (i)
+    abort ();
+}