diff mbox

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

Message ID 20101102233811.GL29412@tyan-ft48-01.lab.bos.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Nov. 2, 2010, 11:38 p.m. UTC
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

Comments

Richard Biener Nov. 3, 2010, 10:42 a.m. UTC | #1
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
>
diff mbox

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" } } */