diff options
author | Jakub Jelinek <jakub@redhat.com> | 2015-06-17 19:59:25 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2015-06-17 19:59:25 +0200 |
commit | 8c8b9f3265820507a1a9472fee7384b265692380 (patch) | |
tree | 2678bfd5b1d0ccb490085b30a993176696dcaf3b /gcc/tree-vectorizer.c | |
parent | f6e3667f976a0592eb156d948a9dfe240250778d (diff) | |
download | gcc-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.c | 139 |
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 { |