On Mon, Feb 22, 2016 at 11:54:46AM +0100, Tom de Vries wrote: > Following up on your suggestion to implement this during gimplification, I > wrote attached patch. > > I'll put it through some openacc testing and add testcases. Is this approach > acceptable for stage4?
LGTM. > gcc/gimplify.c | 85 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 85 insertions(+) > > diff --git a/gcc/gimplify.c b/gcc/gimplify.c > index 7be6bd7..cec0627 100644 > --- a/gcc/gimplify.c > +++ b/gcc/gimplify.c > @@ -8364,6 +8364,82 @@ find_combined_omp_for (tree *tp, int *walk_subtrees, > void *) > return NULL_TREE; > } > > +/* Gimplify the loops with index I and higher in omp_for FOR_STMT as a > + sequential loop, and append the resulting gimple statements to PRE_P. */ > + > +static void > +gimplify_omp_for_seq (tree for_stmt, gimple_seq *pre_p, unsigned int i) > +{ > + gcc_assert (OMP_FOR_ORIG_DECLS (for_stmt) == NULL_TREE); > + unsigned int len = TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); > + gcc_assert (i < len); > + > + /* Gimplify OMP_FOR[i] as: > + > + if (i == 0) > + OMP_FOR_PRE_BODY; > + OMP_FOR_INIT[i]; > + goto <loop_entry_label>; > + <fall_thru_label>: > + if (i == len - 1) > + OMP_FOR_BODY; > + else > + OMP_FOR[i+1]; > + OMP_FOR_INCR[i]; > + <loop_entry_label>: > + if (OMP_FOR_COND[i]) > + goto <fall_thru_label>; > + else > + goto <loop_exit_label>; > + <loop_exit_label>: > + */ > + > + tree loop_entry_label = create_artificial_label (UNKNOWN_LOCATION); > + tree fall_thru_label = create_artificial_label (UNKNOWN_LOCATION); > + tree loop_exit_label = create_artificial_label (UNKNOWN_LOCATION); > + > + /* if (i = 0) OMP_FOR_PRE_BODY. */ > + if (i == 0) > + gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), pre_p); > + > + /* OMP_FOR_INIT[i]. */ > + tree init = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i); > + gimplify_stmt (&init, pre_p); > + > + /* goto <loop_entry_label>. */ > + gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label)); > + > + /* <fall_thru_label>. */ > + gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label)); > + > + /* if (i == len - 1) OMP_FOR_BODY > + else OMP_FOR[i+1]. */ > + if (i == len - 1) > + gimplify_and_return_first (OMP_FOR_BODY (for_stmt), pre_p); > + else > + gimplify_omp_for_seq (for_stmt, pre_p, i + 1); > + > + /* OMP_FOR_INCR[i]. */ > + tree incr = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i); > + gimplify_stmt (&incr, pre_p); > + > + /* <loop_entry_label>. */ > + gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label)); > + > + /* if (OMP_FOR_COND[i]) goto <fall_thru_label> > + else goto <loop_exit_label>. */ > + tree cond = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i); > + tree var = TREE_OPERAND (cond, 0); > + tree final_val = TREE_OPERAND (cond, 1); > + gimplify_expr (&final_val, pre_p, NULL, is_gimple_val, fb_rvalue); > + gimple *gimple_cond = gimple_build_cond (TREE_CODE (cond), var, final_val, > + fall_thru_label, loop_exit_label); > + gimplify_seq_add_stmt (pre_p, gimple_cond); > + > + /* <loop_exit_label>. */ > + gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label)); > +} > + > /* Gimplify the gross structure of an OMP_FOR statement. */ > > static enum gimplify_status > @@ -8403,6 +8479,15 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) > gcc_unreachable (); > } > > + if (ort == ORT_ACC > + && gimplify_omp_ctxp != NULL > + && gimplify_omp_ctxp->region_type == ORT_ACC_KERNELS) > + { > + /* For now, ignore loop directive in kernels region. */ > + gimplify_omp_for_seq (for_stmt, pre_p, 0); > + return GS_ALL_DONE; > + } > + > /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear > clause for the IV. */ > if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1) Jakub