This patch prevents inlining into SIMT code by introducing a new loop property 'in_simtreg' and using ANNOTATE_EXPR (_, 'simtreg') to carry this property between omp-low and the cfg pass (this is needed only for SIMD reduction helper loops; for main bodies of SIMD loops omp-expand sets loop->in_simtreg directly).
Technically the gimplify.c hunk is not needed since the frontends wouldn't produce annot_expr_simtreg_kind. Eventually inlining should be possible to do by remapping callee's variables to use storage provided by IFN_GOMP_SIMT_ENTER (). * cfgloop.h (struct loop): New field 'in_simtreg'. Use it... * ipa-inline.c (can_inline_edge_p): ...here to disallow inlining. * omp-expand.c (expand_omp_simd): Set loop->in_simtreg. * omp-low.c (lower_rec_input_clauses): Annotate condition of SIMT reduction loops with annot_expr_simtreg_kind. * tree-core.h (enum annot_expr_kind): New entry 'annot_expr_simtreg_kind'. * tree-cfg.c (replace_loop_annotate_in_block): Handle annot_expr_simtreg_kind. (replace_loop_annotate): Ditto. * tree-pretty-print.c (dump_generic_node): Ditto. * gimplify.c (gimple_boolify): Ditto. --- gcc/cfgloop.h | 3 +++ gcc/gimplify.c | 1 + gcc/ipa-inline.c | 14 ++++++++++++++ gcc/omp-expand.c | 1 + gcc/omp-low.c | 9 ++++++++- gcc/tree-cfg.c | 4 ++++ gcc/tree-core.h | 1 + gcc/tree-pretty-print.c | 3 +++ 8 files changed, 35 insertions(+), 1 deletion(-) diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h index 0448a61..25b441c 100644 --- a/gcc/cfgloop.h +++ b/gcc/cfgloop.h @@ -220,6 +220,9 @@ struct GTY ((chain_next ("%h.next"))) loop { /* True if the loop is part of an oacc kernels region. */ bool in_oacc_kernels_region; + /* True if the loop corresponds to a SIMT variant of OpenMP SIMD region. */ + bool in_simtreg; + /* For SIMD loops, this is a unique identifier of the loop, referenced by IFN_GOMP_SIMD_VF, IFN_GOMP_SIMD_LANE and IFN_GOMP_SIMD_LAST_LANE builtins. */ diff --git a/gcc/gimplify.c b/gcc/gimplify.c index a300133..a09037b 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -3682,6 +3682,7 @@ gimple_boolify (tree expr) case annot_expr_ivdep_kind: case annot_expr_no_vector_kind: case annot_expr_vector_kind: + case annot_expr_simtreg_kind: TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0)); if (TREE_CODE (type) != BOOLEAN_TYPE) TREE_TYPE (expr) = boolean_type_node; diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 5f2371c..dd4c0948 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -101,6 +101,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-pass.h" #include "gimple-ssa.h" #include "cgraph.h" +#include "cfgloop.h" #include "lto-streamer.h" #include "trans-mem.h" #include "calls.h" @@ -374,6 +375,19 @@ can_inline_edge_p (struct cgraph_edge *e, bool report, e->inline_failed = CIF_ATTRIBUTE_MISMATCH; inlinable = false; } + /* Don't inline into SIMT variants of OpenMP SIMD regions: inlining needs to + remap addressable variables to use storage provided by IFN_SIMT_ENTER. */ + else if (flag_openmp && gimple_has_body_p (caller->decl)) + { + struct loop *l; + for (l = gimple_bb (e->call_stmt)->loop_father; l; l = loop_outer (l)) + if (l->in_simtreg) + { + e->inline_failed = CIF_UNSPECIFIED; + inlinable = false; + break; + } + } /* Check if caller growth allows the inlining. */ else if (!DECL_DISREGARD_INLINE_LIMITS (callee->decl) && !disregard_limits diff --git a/gcc/omp-expand.c b/gcc/omp-expand.c index 1f1055c..6a29df6 100644 --- a/gcc/omp-expand.c +++ b/gcc/omp-expand.c @@ -4794,6 +4794,7 @@ expand_omp_simd (struct omp_region *region, struct omp_for_data *fd) loop->latch = cont_bb; add_loop (loop, l1_bb->loop_father); loop->safelen = safelen_int; + loop->in_simtreg = is_simt; if (simduid) { loop->simduid = OMP_CLAUSE__SIMDUID__DECL (simduid); diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 13d9b6b..a5f8bf65 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -4510,7 +4510,14 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, gimple_seq_add_stmt (dlist, g); gimple_seq_add_stmt (dlist, gimple_build_label (header)); - g = gimple_build_cond (LT_EXPR, simt_lane, simt_vf, body, end); + t = create_tmp_var (boolean_type_node); + g = gimple_build_assign (t, LT_EXPR, simt_lane, simt_vf); + gimple_seq_add_stmt (dlist, g); + tree ann = build_int_cst (integer_type_node, annot_expr_simtreg_kind); + g = gimple_build_call_internal (IFN_ANNOTATE, 2, t, ann); + gimple_call_set_lhs (g, t); + gimple_seq_add_stmt (dlist, g); + g = gimple_build_cond (NE_EXPR, t, boolean_false_node, body, end); gimple_seq_add_stmt (dlist, g); gimple_seq_add_stmt (dlist, gimple_build_label (end)); diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index d4a7db8..c1392be 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -286,6 +286,9 @@ replace_loop_annotate_in_block (basic_block bb, struct loop *loop) loop->force_vectorize = true; cfun->has_force_vectorize_loops = true; break; + case annot_expr_simtreg_kind: + loop->in_simtreg = true; + break; default: gcc_unreachable (); } @@ -335,6 +338,7 @@ replace_loop_annotate (void) case annot_expr_ivdep_kind: case annot_expr_no_vector_kind: case annot_expr_vector_kind: + case annot_expr_simtreg_kind: break; default: gcc_unreachable (); diff --git a/gcc/tree-core.h b/gcc/tree-core.h index eec2d4f3..568cb1e 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -843,6 +843,7 @@ enum annot_expr_kind { annot_expr_ivdep_kind, annot_expr_no_vector_kind, annot_expr_vector_kind, + annot_expr_simtreg_kind, annot_expr_kind_last }; diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c index 5b3e23e..e0693dc 100644 --- a/gcc/tree-pretty-print.c +++ b/gcc/tree-pretty-print.c @@ -2569,6 +2569,9 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, int flags, case annot_expr_vector_kind: pp_string (pp, ", vector"); break; + case annot_expr_simtreg_kind: + pp_string (pp, ", simtreg"); + break; default: gcc_unreachable (); } -- 1.8.3.1