aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vectorizer.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2015-06-17 19:59:25 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2015-06-17 19:59:25 +0200
commit8c8b9f3265820507a1a9472fee7384b265692380 (patch)
tree2678bfd5b1d0ccb490085b30a993176696dcaf3b /gcc/tree-vectorizer.c
parentf6e3667f976a0592eb156d948a9dfe240250778d (diff)
downloadgcc-8c8b9f3265820507a1a9472fee7384b265692380.zip
gcc-8c8b9f3265820507a1a9472fee7384b265692380.tar.gz
gcc-8c8b9f3265820507a1a9472fee7384b265692380.tar.bz2
re PR middle-end/66429 (ICE in expand_GOMP_SIMD_LAST_LANE)
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. From-SVN: r224568
Diffstat (limited to 'gcc/tree-vectorizer.c')
-rw-r--r--gcc/tree-vectorizer.c139
1 files changed, 102 insertions, 37 deletions
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index ff46a52..9d17802 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 {