aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2015-06-17 17:59:25 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2015-06-17 17:59:25 +0000
commit9918db4464b0b328d14819541fbc3bf855c6ade1 (patch)
tree2678bfd5b1d0ccb490085b30a993176696dcaf3b
parent4a875e1f1d7dca1f03cc71a8234862aaf03e5d18 (diff)
PR middle-end/66429
* omp-low.c (expand_omp_taskreg): Use child_cfun instead of DECL_STRUCT_FUNCTION (child_fn). Or in has_simduid_loops and has_force_vectorize_loops flags from cfun into child_cfun. (expand_omp_simd): For broken loop, set cfun->has_simduid_loops if simduid is non-NULL. * tree-pass.h (make_pass_simduid_cleanup): New prototype. * passes.def (pass_simduid_cleanup): Add new pass after loop passes. * tree-vectorizer.c (adjust_simduid_builtins): Remove one unnecessary indirection from htab argument's type. (shrink_simd_arrays): New function. (vectorize_loops): Use it. Adjust adjust_simduid_builtins caller. Don't call adjust_simduid_builtins if there are no loops. (pass_data_simduid_cleanup, pass_simduid_cleanup): New variables. (pass_simduid_cleanup::execute): New method. (make_pass_simduid_cleanup): New function. * c-c++-common/gomp/pr66429.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@224568 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog21
-rw-r--r--gcc/omp-low.c6
-rw-r--r--gcc/passes.def1
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/c-c++-common/gomp/pr66429.c41
-rw-r--r--gcc/tree-pass.h1
-rw-r--r--gcc/tree-vectorizer.c139
7 files changed, 176 insertions, 38 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 868a70808a4..8f92fecf5af 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,24 @@
+2015-06-17 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/66429
+ * omp-low.c (expand_omp_taskreg): Use child_cfun instead of
+ DECL_STRUCT_FUNCTION (child_fn). Or in has_simduid_loops
+ and has_force_vectorize_loops flags from cfun into
+ child_cfun.
+ (expand_omp_simd): For broken loop, set cfun->has_simduid_loops
+ if simduid is non-NULL.
+ * tree-pass.h (make_pass_simduid_cleanup): New prototype.
+ * passes.def (pass_simduid_cleanup): Add new pass after loop
+ passes.
+ * tree-vectorizer.c (adjust_simduid_builtins): Remove one unnecessary
+ indirection from htab argument's type.
+ (shrink_simd_arrays): New function.
+ (vectorize_loops): Use it. Adjust adjust_simduid_builtins caller.
+ Don't call adjust_simduid_builtins if there are no loops.
+ (pass_data_simduid_cleanup, pass_simduid_cleanup): New variables.
+ (pass_simduid_cleanup::execute): New method.
+ (make_pass_simduid_cleanup): New function.
+
2017-06-17 Andrew MacLeod <amacleod@redhat.com>
* tree-core.h (tree_target_option): Make opts field a pointer to a
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 64b5c66e933..6325b826010 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -5587,7 +5587,9 @@ expand_omp_taskreg (struct omp_region *region)
vec_safe_truncate (child_cfun->local_decls, dstidx);
/* Inform the callgraph about the new function. */
- DECL_STRUCT_FUNCTION (child_fn)->curr_properties = cfun->curr_properties;
+ child_cfun->curr_properties = cfun->curr_properties;
+ child_cfun->has_simduid_loops |= cfun->has_simduid_loops;
+ child_cfun->has_force_vectorize_loops |= cfun->has_force_vectorize_loops;
cgraph_node *node = cgraph_node::get_create (child_fn);
node->parallelized_function = 1;
cgraph_node::add_new_function (child_fn, true);
@@ -7836,6 +7838,8 @@ expand_omp_simd (struct omp_region *region, struct omp_for_data *fd)
cfun->has_force_vectorize_loops = true;
}
}
+ else if (simduid)
+ cfun->has_simduid_loops = true;
}
diff --git a/gcc/passes.def b/gcc/passes.def
index 4690e23afb2..9ced6558000 100644
--- a/gcc/passes.def
+++ b/gcc/passes.def
@@ -270,6 +270,7 @@ along with GCC; see the file COPYING3. If not see
PUSH_INSERT_PASSES_WITHIN (pass_tree_no_loop)
NEXT_PASS (pass_slp_vectorize);
POP_INSERT_PASSES ()
+ NEXT_PASS (pass_simduid_cleanup);
NEXT_PASS (pass_lower_vector_ssa);
NEXT_PASS (pass_cse_reciprocals);
NEXT_PASS (pass_reassoc);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index bc86c88e1e0..10c61ef2cf6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2015-06-17 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/66429
+ * c-c++-common/gomp/pr66429.c: New test.
+
2015-06-17 David Malcolm <dmalcolm@redhat.com>
* jit.dg/test-error-accessing-field-in-other-struct.c: Rename to...
diff --git a/gcc/testsuite/c-c++-common/gomp/pr66429.c b/gcc/testsuite/c-c++-common/gomp/pr66429.c
new file mode 100644
index 00000000000..01c795fef40
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/pr66429.c
@@ -0,0 +1,41 @@
+/* PR middle-end/66429 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fopenmp" } */
+
+float b[10][15][10];
+
+__attribute__ ((noreturn)) void
+noreturn (void)
+{
+ for (;;);
+}
+
+__attribute__ ((noinline, noclone)) void
+foo (int n)
+{
+ int i;
+
+#pragma omp parallel for simd schedule(static, 32) collapse(3)
+ for (i = 0; i < 10; i++)
+ for (int j = n; j < 8; j++)
+ for (long k = -10; k < 10; k++)
+ {
+ b[i][j][k] += 16;
+ noreturn ();
+ b[i][j][k] -= 32;
+ }
+}
+
+__attribute__ ((noinline, noclone)) void
+bar (void)
+{
+ int i;
+
+#pragma omp parallel for simd schedule(static, 32)
+ for (i = 0; i < 10; i++)
+ {
+ b[0][0][i] += 16;
+ noreturn ();
+ b[0][0][i] -= 32;
+ }
+}
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 172bd821902..454555653db 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -372,6 +372,7 @@ extern gimple_opt_pass *make_pass_graphite_transforms (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_if_conversion (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_loop_distribution (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_vectorize (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_simduid_cleanup (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_slp_vectorize (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_complete_unroll (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_complete_unrolli (gcc::context *ctxt);
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index ff46a52fc82..9d178026a2f 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -168,7 +168,7 @@ simd_array_to_simduid::equal (const simd_array_to_simduid *p1,
into their corresponding constants. */
static void
-adjust_simduid_builtins (hash_table<simduid_to_vf> **htab)
+adjust_simduid_builtins (hash_table<simduid_to_vf> *htab)
{
basic_block bb;
@@ -200,10 +200,12 @@ adjust_simduid_builtins (hash_table<simduid_to_vf> **htab)
gcc_assert (TREE_CODE (arg) == SSA_NAME);
simduid_to_vf *p = NULL, data;
data.simduid = DECL_UID (SSA_NAME_VAR (arg));
- if (*htab)
- p = (*htab)->find (&data);
- if (p)
- vf = p->vf;
+ if (htab)
+ {
+ p = htab->find (&data);
+ if (p)
+ vf = p->vf;
+ }
switch (ifn)
{
case IFN_GOMP_SIMD_VF:
@@ -306,6 +308,38 @@ note_simd_array_uses (hash_table<simd_array_to_simduid> **htab)
walk_gimple_op (use_stmt, note_simd_array_uses_cb, &wi);
}
}
+
+/* Shrink arrays with "omp simd array" attribute to the corresponding
+ vectorization factor. */
+
+static void
+shrink_simd_arrays
+ (hash_table<simd_array_to_simduid> *simd_array_to_simduid_htab,
+ hash_table<simduid_to_vf> *simduid_to_vf_htab)
+{
+ for (hash_table<simd_array_to_simduid>::iterator iter
+ = simd_array_to_simduid_htab->begin ();
+ iter != simd_array_to_simduid_htab->end (); ++iter)
+ if ((*iter)->simduid != -1U)
+ {
+ tree decl = (*iter)->decl;
+ int vf = 1;
+ if (simduid_to_vf_htab)
+ {
+ simduid_to_vf *p = NULL, data;
+ data.simduid = (*iter)->simduid;
+ p = simduid_to_vf_htab->find (&data);
+ if (p)
+ vf = p->vf;
+ }
+ tree atype
+ = build_array_type_nelts (TREE_TYPE (TREE_TYPE (decl)), vf);
+ TREE_TYPE (decl) = atype;
+ relayout_decl (decl);
+ }
+
+ delete simd_array_to_simduid_htab;
+}
/* A helper function to free data refs. */
@@ -442,11 +476,7 @@ vectorize_loops (void)
/* Bail out if there are no loops. */
if (vect_loops_num <= 1)
- {
- if (cfun->has_simduid_loops)
- adjust_simduid_builtins (&simduid_to_vf_htab);
- return 0;
- }
+ return 0;
if (cfun->has_simduid_loops)
note_simd_array_uses (&simd_array_to_simduid_htab);
@@ -555,37 +585,14 @@ vectorize_loops (void)
/* Fold IFN_GOMP_SIMD_{VF,LANE,LAST_LANE} builtins. */
if (cfun->has_simduid_loops)
- adjust_simduid_builtins (&simduid_to_vf_htab);
+ adjust_simduid_builtins (simduid_to_vf_htab);
/* Shrink any "omp array simd" temporary arrays to the
actual vectorization factors. */
if (simd_array_to_simduid_htab)
- {
- for (hash_table<simd_array_to_simduid>::iterator iter
- = simd_array_to_simduid_htab->begin ();
- iter != simd_array_to_simduid_htab->end (); ++iter)
- if ((*iter)->simduid != -1U)
- {
- tree decl = (*iter)->decl;
- int vf = 1;
- if (simduid_to_vf_htab)
- {
- simduid_to_vf *p = NULL, data;
- data.simduid = (*iter)->simduid;
- p = simduid_to_vf_htab->find (&data);
- if (p)
- vf = p->vf;
- }
- tree atype
- = build_array_type_nelts (TREE_TYPE (TREE_TYPE (decl)), vf);
- TREE_TYPE (decl) = atype;
- relayout_decl (decl);
- }
-
- delete simd_array_to_simduid_htab;
- }
- delete simduid_to_vf_htab;
- simduid_to_vf_htab = NULL;
+ shrink_simd_arrays (simd_array_to_simduid_htab, simduid_to_vf_htab);
+ delete simduid_to_vf_htab;
+ cfun->has_simduid_loops = false;
if (num_vectorized_loops > 0)
{
@@ -600,6 +607,64 @@ vectorize_loops (void)
}
+/* Entry point to the simduid cleanup pass. */
+
+namespace {
+
+const pass_data pass_data_simduid_cleanup =
+{
+ GIMPLE_PASS, /* type */
+ "simduid", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ TV_NONE, /* tv_id */
+ ( PROP_ssa | PROP_cfg ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
+};
+
+class pass_simduid_cleanup : public gimple_opt_pass
+{
+public:
+ pass_simduid_cleanup (gcc::context *ctxt)
+ : gimple_opt_pass (pass_data_simduid_cleanup, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_simduid_cleanup (m_ctxt); }
+ virtual bool gate (function *fun) { return fun->has_simduid_loops; }
+ virtual unsigned int execute (function *);
+
+}; // class pass_simduid_cleanup
+
+unsigned int
+pass_simduid_cleanup::execute (function *fun)
+{
+ hash_table<simd_array_to_simduid> *simd_array_to_simduid_htab = NULL;
+
+ note_simd_array_uses (&simd_array_to_simduid_htab);
+
+ /* Fold IFN_GOMP_SIMD_{VF,LANE,LAST_LANE} builtins. */
+ adjust_simduid_builtins (NULL);
+
+ /* Shrink any "omp array simd" temporary arrays to the
+ actual vectorization factors. */
+ if (simd_array_to_simduid_htab)
+ shrink_simd_arrays (simd_array_to_simduid_htab, NULL);
+ fun->has_simduid_loops = false;
+ return 0;
+}
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_simduid_cleanup (gcc::context *ctxt)
+{
+ return new pass_simduid_cleanup (ctxt);
+}
+
+
/* Entry point to basic block SLP phase. */
namespace {