Patchwork Ensure DCE is performed after vectorizer (PR tree-optimization/46172)

login
register
mail settings
Submitter Jakub Jelinek
Date Nov. 2, 2010, 11:38 p.m.
Message ID <20101102233811.GL29412@tyan-ft48-01.lab.bos.redhat.com>
Download mbox | patch
Permalink /patch/69934/
State New
Headers show

Comments

Jakub Jelinek - Nov. 2, 2010, 11:38 p.m.
Hi!

As has been discussed in the PR, vectorizer relies on DCE being performed
after it and we thus get ICEs during expansion if -ftree-vectorize
-fno-tree-dce.  This patch fixes it by making sure at least one DCE is
performed after {,slp} vectorization even if -fno-tree-dce.

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

2010-11-02  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/46172
	* passes.c (init_optimization_passes): Add pass_dce_vect.
	* tree-pass.h (pass_dce_vect): New extern.
	* tree-ssa-dce.c (gate_dce_vect): New function.
	(pass_dce_vect): New variable.

	* gcc.dg/vect/O1-pr46172.c: New test.


	Jakub
Richard Guenther - Nov. 3, 2010, 10:42 a.m.
On Wed, Nov 3, 2010 at 12:38 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> As has been discussed in the PR, vectorizer relies on DCE being performed
> after it and we thus get ICEs during expansion if -ftree-vectorize
> -fno-tree-dce.  This patch fixes it by making sure at least one DCE is
> performed after {,slp} vectorization even if -fno-tree-dce.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

I don't like this solution and rather have this bug not fixed than in this
way.

I think what would be more sensible would be to perform a quick
backward walk over the single loop BB for the versions and nuke
all stmts with has_zero_uses (which should cover all pattern stmts
we inserted).  I think vect_loop_versioning is the only place that
would need to do that.  It would of course be nicer to avoid copying
those in the first place or rewrite how pattern recognition is done
(which is one of the more ugly pieces of the vectorizer), but that
sounds harder.

Thanks,
Richard.

> 2010-11-02  Jakub Jelinek  <jakub@redhat.com>
>
>        PR tree-optimization/46172
>        * passes.c (init_optimization_passes): Add pass_dce_vect.
>        * tree-pass.h (pass_dce_vect): New extern.
>        * tree-ssa-dce.c (gate_dce_vect): New function.
>        (pass_dce_vect): New variable.
>
>        * gcc.dg/vect/O1-pr46172.c: New test.
>
> --- gcc/passes.c.jj     2010-11-01 09:07:24.000000000 +0100
> +++ gcc/passes.c        2010-11-02 20:19:13.000000000 +0100
> @@ -914,6 +914,7 @@ init_optimization_passes (void)
>           NEXT_PASS (pass_predcom);
>          NEXT_PASS (pass_complete_unroll);
>          NEXT_PASS (pass_slp_vectorize);
> +         NEXT_PASS (pass_dce_vect);
>          NEXT_PASS (pass_parallelize_loops);
>          NEXT_PASS (pass_loop_prefetch);
>          NEXT_PASS (pass_iv_optimize);
> --- gcc/tree-pass.h.jj  2010-10-07 19:45:22.000000000 +0200
> +++ gcc/tree-pass.h     2010-11-02 15:40:15.000000000 +0100
> @@ -391,6 +391,7 @@ extern struct gimple_opt_pass pass_build
>  extern struct gimple_opt_pass pass_dominator;
>  extern struct gimple_opt_pass pass_dce;
>  extern struct gimple_opt_pass pass_dce_loop;
> +extern struct gimple_opt_pass pass_dce_vect;
>  extern struct gimple_opt_pass pass_cd_dce;
>  extern struct gimple_opt_pass pass_call_cdce;
>  extern struct gimple_opt_pass pass_merge_phi;
> --- gcc/tree-ssa-dce.c.jj       2010-08-26 19:50:24.000000000 +0200
> +++ gcc/tree-ssa-dce.c  2010-11-02 20:19:01.000000000 +0100
> @@ -1507,6 +1507,14 @@ gate_dce (void)
>   return flag_tree_dce != 0;
>  }
>
> +static bool
> +gate_dce_vect (void)
> +{
> +  /* The vectorizer relies on DCE being performed before expansion.  */
> +  return flag_tree_dce == 0
> +        && (flag_tree_vectorize || flag_tree_slp_vectorize == 1);
> +}
> +
>  struct gimple_opt_pass pass_dce =
>  {
>  {
> @@ -1545,6 +1553,25 @@ struct gimple_opt_pass pass_dce_loop =
>  }
>  };
>
> +struct gimple_opt_pass pass_dce_vect =
> +{
> + {
> +  GIMPLE_PASS,
> +  "dcevect",                           /* name */
> +  gate_dce_vect,                       /* gate */
> +  tree_ssa_dce_loop,                   /* execute */
> +  NULL,                                        /* sub */
> +  NULL,                                        /* next */
> +  0,                                   /* static_pass_number */
> +  TV_TREE_DCE,                         /* tv_id */
> +  PROP_cfg | PROP_ssa,                 /* properties_required */
> +  0,                                   /* properties_provided */
> +  0,                                   /* properties_destroyed */
> +  0,                                   /* todo_flags_start */
> +  TODO_dump_func | TODO_verify_ssa     /* todo_flags_finish */
> + }
> +};
> +
>  struct gimple_opt_pass pass_cd_dce =
>  {
>  {
> --- gcc/testsuite/gcc.dg/vect/O1-pr46172.c.jj   2010-11-02 16:08:14.000000000 +0100
> +++ gcc/testsuite/gcc.dg/vect/O1-pr46172.c      2010-11-02 16:09:25.000000000 +0100
> @@ -0,0 +1,16 @@
> +/* PR tree-optimization/46172 */
> +/* { dg-do compile } */
> +/* { dg-options "-O -ftree-vectorize -fno-tree-dce" } */
> +
> +extern short v[];
> +
> +int foo (int x)
> +{
> +  int i;
> +  int s = 0;
> +  for (i = 0; i < x; i++)
> +    s += v[i] * v[i];
> +  return s;
> +}
> +
> +/* { dg-final { cleanup-tree-dump "vect" } } */
>
>        Jakub
>

Patch

--- gcc/passes.c.jj	2010-11-01 09:07:24.000000000 +0100
+++ gcc/passes.c	2010-11-02 20:19:13.000000000 +0100
@@ -914,6 +914,7 @@  init_optimization_passes (void)
           NEXT_PASS (pass_predcom);
 	  NEXT_PASS (pass_complete_unroll);
 	  NEXT_PASS (pass_slp_vectorize);
+	  NEXT_PASS (pass_dce_vect);
 	  NEXT_PASS (pass_parallelize_loops);
 	  NEXT_PASS (pass_loop_prefetch);
 	  NEXT_PASS (pass_iv_optimize);
--- gcc/tree-pass.h.jj	2010-10-07 19:45:22.000000000 +0200
+++ gcc/tree-pass.h	2010-11-02 15:40:15.000000000 +0100
@@ -391,6 +391,7 @@  extern struct gimple_opt_pass pass_build
 extern struct gimple_opt_pass pass_dominator;
 extern struct gimple_opt_pass pass_dce;
 extern struct gimple_opt_pass pass_dce_loop;
+extern struct gimple_opt_pass pass_dce_vect;
 extern struct gimple_opt_pass pass_cd_dce;
 extern struct gimple_opt_pass pass_call_cdce;
 extern struct gimple_opt_pass pass_merge_phi;
--- gcc/tree-ssa-dce.c.jj	2010-08-26 19:50:24.000000000 +0200
+++ gcc/tree-ssa-dce.c	2010-11-02 20:19:01.000000000 +0100
@@ -1507,6 +1507,14 @@  gate_dce (void)
   return flag_tree_dce != 0;
 }
 
+static bool
+gate_dce_vect (void)
+{
+  /* The vectorizer relies on DCE being performed before expansion.  */
+  return flag_tree_dce == 0
+	 && (flag_tree_vectorize || flag_tree_slp_vectorize == 1);
+}
+
 struct gimple_opt_pass pass_dce =
 {
  {
@@ -1545,6 +1553,25 @@  struct gimple_opt_pass pass_dce_loop =
  }
 };
 
+struct gimple_opt_pass pass_dce_vect =
+{
+ {
+  GIMPLE_PASS,
+  "dcevect",				/* name */
+  gate_dce_vect,			/* gate */
+  tree_ssa_dce_loop,			/* execute */
+  NULL,					/* sub */
+  NULL,					/* next */
+  0,					/* static_pass_number */
+  TV_TREE_DCE,				/* tv_id */
+  PROP_cfg | PROP_ssa,			/* properties_required */
+  0,					/* properties_provided */
+  0,					/* properties_destroyed */
+  0,					/* todo_flags_start */
+  TODO_dump_func | TODO_verify_ssa	/* todo_flags_finish */
+ }
+};
+
 struct gimple_opt_pass pass_cd_dce =
 {
  {
--- gcc/testsuite/gcc.dg/vect/O1-pr46172.c.jj	2010-11-02 16:08:14.000000000 +0100
+++ gcc/testsuite/gcc.dg/vect/O1-pr46172.c	2010-11-02 16:09:25.000000000 +0100
@@ -0,0 +1,16 @@ 
+/* PR tree-optimization/46172 */
+/* { dg-do compile } */
+/* { dg-options "-O -ftree-vectorize -fno-tree-dce" } */
+
+extern short v[];
+
+int foo (int x)
+{
+  int i;
+  int s = 0;
+  for (i = 0; i < x; i++)
+    s += v[i] * v[i];
+  return s;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */