diff options
author | Tom de Vries <tom@codesourcery.com> | 2018-03-21 12:25:03 +0000 |
---|---|---|
committer | Tom de Vries <vries@gcc.gnu.org> | 2018-03-21 12:25:03 +0000 |
commit | c75c35e0f52a4f4feca1058a67bb78c660605e24 (patch) | |
tree | 89fc88f54ef5d689e690b8555d9dd7a0c188dc40 /gcc/tree-parloops.c | |
parent | f82ece6b59622033b3dabf124d999d6f2fb1b6d7 (diff) | |
download | gcc-c75c35e0f52a4f4feca1058a67bb78c660605e24.zip gcc-c75c35e0f52a4f4feca1058a67bb78c660605e24.tar.gz gcc-c75c35e0f52a4f4feca1058a67bb78c660605e24.tar.bz2 |
[parloops] Handle canonicalize_loop_ivs failure
2018-03-21 Tom de Vries <tom@codesourcery.com>
PR tree-optimization/83126
* tree-parloops.c (num_phis): New function.
(gen_parallel_loop): Detect and handle canonicalize_loop_ivs failure.
* gcc.dg/graphite/pr83126.c: New test.
From-SVN: r258713
Diffstat (limited to 'gcc/tree-parloops.c')
-rw-r--r-- | gcc/tree-parloops.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c index e44ad5e..3a788cc 100644 --- a/gcc/tree-parloops.c +++ b/gcc/tree-parloops.c @@ -2235,6 +2235,25 @@ create_parallel_loop (struct loop *loop, tree loop_fn, tree data, calculate_dominance_info (CDI_DOMINATORS); } +/* Return number of phis in bb. If COUNT_VIRTUAL_P is false, don't count the + virtual phi. */ + +static unsigned int +num_phis (basic_block bb, bool count_virtual_p) +{ + unsigned int nr_phis = 0; + gphi_iterator gsi; + for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + { + if (!count_virtual_p && virtual_operand_p (PHI_RESULT (gsi.phi ()))) + continue; + + nr_phis++; + } + + return nr_phis; +} + /* Generates code to execute the iterations of LOOP in N_THREADS threads in parallel, which can be 0 if that number is to be determined later. @@ -2370,6 +2389,26 @@ gen_parallel_loop (struct loop *loop, /* Base all the induction variables in LOOP on a single control one. */ canonicalize_loop_ivs (loop, &nit, true); + if (num_phis (loop->header, false) != reduction_list->elements () + 1) + { + /* The call to canonicalize_loop_ivs above failed to "base all the + induction variables in LOOP on a single control one". Do damage + control. */ + basic_block preheader = loop_preheader_edge (loop)->src; + basic_block cond_bb = single_pred (preheader); + gcond *cond = as_a <gcond *> (gsi_stmt (gsi_last_bb (cond_bb))); + gimple_cond_make_true (cond); + update_stmt (cond); + /* We've gotten rid of the duplicate loop created by loop_version, but + we can't undo whatever canonicalize_loop_ivs has done. + TODO: Fix this properly by ensuring that the call to + canonicalize_loop_ivs succeeds. */ + if (dump_file + && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "canonicalize_loop_ivs failed for loop %d," + " aborting transformation\n", loop->num); + return; + } /* Ensure that the exit condition is the first statement in the loop. The common case is that latch of the loop is empty (apart from the |