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
This commit is contained in:
parent
f6e3667f97
commit
8c8b9f3265
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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...
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue