diff options
Diffstat (limited to 'gcc-4.9/gcc/omp-low.c')
-rw-r--r-- | gcc-4.9/gcc/omp-low.c | 215 |
1 files changed, 145 insertions, 70 deletions
diff --git a/gcc-4.9/gcc/omp-low.c b/gcc-4.9/gcc/omp-low.c index 26e484964..a605c45f0 100644 --- a/gcc-4.9/gcc/omp-low.c +++ b/gcc-4.9/gcc/omp-low.c @@ -1509,11 +1509,19 @@ scan_sharing_clauses (tree clauses, omp_context *ctx) break; case OMP_CLAUSE_SHARED: + decl = OMP_CLAUSE_DECL (c); /* Ignore shared directives in teams construct. */ if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS) - break; + { + /* Global variables don't need to be copied, + the receiver side will use them directly. */ + tree odecl = maybe_lookup_decl_in_outer_ctx (decl, ctx); + if (is_global_var (odecl)) + break; + insert_decl_map (&ctx->cb, decl, odecl); + break; + } gcc_assert (is_taskreg_ctx (ctx)); - decl = OMP_CLAUSE_DECL (c); gcc_assert (!COMPLETE_TYPE_P (TREE_TYPE (decl)) || !is_variable_sized (decl)); /* Global variables don't need to be copied, @@ -1670,6 +1678,11 @@ scan_sharing_clauses (tree clauses, omp_context *ctx) } else { + if (ctx->outer) + { + scan_omp_op (&OMP_CLAUSE_DECL (c), ctx->outer); + decl = OMP_CLAUSE_DECL (c); + } gcc_assert (!splay_tree_lookup (ctx->field_map, (splay_tree_key) decl)); tree field @@ -2003,6 +2016,7 @@ scan_omp_parallel (gimple_stmt_iterator *gsi, omp_context *outer_ctx) tree temp = create_tmp_var (type, NULL); tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__LOOPTEMP_); + insert_decl_map (&outer_ctx->cb, temp, temp); OMP_CLAUSE_DECL (c) = temp; OMP_CLAUSE_CHAIN (c) = gimple_omp_parallel_clauses (stmt); gimple_omp_parallel_set_clauses (stmt, c); @@ -2500,6 +2514,23 @@ check_omp_nesting_restrictions (gimple stmt, omp_context *ctx) return false; } break; + case GIMPLE_OMP_TARGET: + for (; ctx != NULL; ctx = ctx->outer) + if (gimple_code (ctx->stmt) == GIMPLE_OMP_TARGET + && gimple_omp_target_kind (ctx->stmt) == GF_OMP_TARGET_KIND_REGION) + { + const char *name; + switch (gimple_omp_target_kind (stmt)) + { + case GF_OMP_TARGET_KIND_REGION: name = "target"; break; + case GF_OMP_TARGET_KIND_DATA: name = "target data"; break; + case GF_OMP_TARGET_KIND_UPDATE: name = "target update"; break; + default: gcc_unreachable (); + } + warning_at (gimple_location (stmt), 0, + "%s construct inside of target region", name); + } + break; default: break; } @@ -2967,8 +2998,10 @@ lower_rec_simd_input_clauses (tree new_var, omp_context *ctx, int &max_vf, { tree c = find_omp_clause (gimple_omp_for_clauses (ctx->stmt), OMP_CLAUSE_SAFELEN); - if (c - && compare_tree_int (OMP_CLAUSE_SAFELEN_EXPR (c), max_vf) == -1) + if (c && TREE_CODE (OMP_CLAUSE_SAFELEN_EXPR (c)) != INTEGER_CST) + max_vf = 1; + else if (c && compare_tree_int (OMP_CLAUSE_SAFELEN_EXPR (c), + max_vf) == -1) max_vf = tree_to_shwi (OMP_CLAUSE_SAFELEN_EXPR (c)); } if (max_vf > 1) @@ -3000,6 +3033,27 @@ lower_rec_simd_input_clauses (tree new_var, omp_context *ctx, int &max_vf, return true; } +/* Helper function of lower_rec_input_clauses. For a reference + in simd reduction, add an underlying variable it will reference. */ + +static void +handle_simd_reference (location_t loc, tree new_vard, gimple_seq *ilist) +{ + tree z = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_vard))); + if (TREE_CONSTANT (z)) + { + const char *name = NULL; + if (DECL_NAME (new_vard)) + name = IDENTIFIER_POINTER (DECL_NAME (new_vard)); + + z = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_vard)), name); + gimple_add_tmp_var (z); + TREE_ADDRESSABLE (z) = 1; + z = build_fold_addr_expr_loc (loc, z); + gimplify_assign (new_vard, z, ilist); + } +} + /* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN, from the receiver (aka child) side and initializers for REFERENCE_TYPE private variables. Initialization statements go in ILIST, while calls @@ -3031,11 +3085,14 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c)) switch (OMP_CLAUSE_CODE (c)) { + case OMP_CLAUSE_LINEAR: + if (OMP_CLAUSE_LINEAR_ARRAY (c)) + max_vf = 1; + /* FALLTHRU */ case OMP_CLAUSE_REDUCTION: case OMP_CLAUSE_PRIVATE: case OMP_CLAUSE_FIRSTPRIVATE: case OMP_CLAUSE_LASTPRIVATE: - case OMP_CLAUSE_LINEAR: if (is_variable_sized (OMP_CLAUSE_DECL (c))) max_vf = 1; break; @@ -3091,6 +3148,13 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, if (pass != 0) continue; } + /* Even without corresponding firstprivate, if + decl is Fortran allocatable, it needs outer var + reference. */ + else if (pass == 0 + && lang_hooks.decls.omp_private_outer_ref + (OMP_CLAUSE_DECL (c))) + lastprivate_firstprivate = true; break; case OMP_CLAUSE_ALIGNED: if (pass == 0) @@ -3191,13 +3255,11 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, } else if (TREE_CONSTANT (x)) { - /* For reduction with placeholder in SIMD loop, - defer adding the initialization of the reference, - because if we decide to use SIMD array for it, - the initilization could cause expansion ICE. */ - if (c_kind == OMP_CLAUSE_REDUCTION - && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) - && is_simd) + /* For reduction in SIMD loop, defer adding the + initialization of the reference, because if we decide + to use SIMD array for it, the initilization could cause + expansion ICE. */ + if (c_kind == OMP_CLAUSE_REDUCTION && is_simd) x = NULL_TREE; else { @@ -3356,34 +3418,37 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR && gimple_omp_for_combined_into_p (ctx->stmt)) { - tree stept = POINTER_TYPE_P (TREE_TYPE (x)) - ? sizetype : TREE_TYPE (x); - tree t = fold_convert (stept, - OMP_CLAUSE_LINEAR_STEP (c)); - tree c = find_omp_clause (clauses, - OMP_CLAUSE__LOOPTEMP_); - gcc_assert (c); - tree l = OMP_CLAUSE_DECL (c); - if (fd->collapse == 1) - { - tree n1 = fd->loop.n1; - tree step = fd->loop.step; - tree itype = TREE_TYPE (l); - if (POINTER_TYPE_P (itype)) - itype = signed_type_for (itype); - l = fold_build2 (MINUS_EXPR, itype, l, n1); - if (TYPE_UNSIGNED (itype) - && fd->loop.cond_code == GT_EXPR) - l = fold_build2 (TRUNC_DIV_EXPR, itype, - fold_build1 (NEGATE_EXPR, - itype, l), - fold_build1 (NEGATE_EXPR, - itype, step)); - else - l = fold_build2 (TRUNC_DIV_EXPR, itype, l, step); - } + tree t = OMP_CLAUSE_LINEAR_STEP (c); + tree stept = TREE_TYPE (t); + tree ct = find_omp_clause (clauses, + OMP_CLAUSE__LOOPTEMP_); + gcc_assert (ct); + tree l = OMP_CLAUSE_DECL (ct); + tree n1 = fd->loop.n1; + tree step = fd->loop.step; + tree itype = TREE_TYPE (l); + if (POINTER_TYPE_P (itype)) + itype = signed_type_for (itype); + l = fold_build2 (MINUS_EXPR, itype, l, n1); + if (TYPE_UNSIGNED (itype) + && fd->loop.cond_code == GT_EXPR) + l = fold_build2 (TRUNC_DIV_EXPR, itype, + fold_build1 (NEGATE_EXPR, itype, l), + fold_build1 (NEGATE_EXPR, + itype, step)); + else + l = fold_build2 (TRUNC_DIV_EXPR, itype, l, step); t = fold_build2 (MULT_EXPR, stept, fold_convert (stept, l), t); + + if (OMP_CLAUSE_LINEAR_ARRAY (c)) + { + x = lang_hooks.decls.omp_clause_linear_ctor + (c, new_var, x, t); + gimplify_and_add (x, ilist); + goto do_dtor; + } + if (POINTER_TYPE_P (TREE_TYPE (x))) x = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (x), x, t); @@ -3407,10 +3472,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, = gimple_build_assign (unshare_expr (lvar), iv); gsi_insert_before_without_update (&gsi, g, GSI_SAME_STMT); - tree stept = POINTER_TYPE_P (TREE_TYPE (x)) - ? sizetype : TREE_TYPE (x); - tree t = fold_convert (stept, - OMP_CLAUSE_LINEAR_STEP (c)); + tree t = OMP_CLAUSE_LINEAR_STEP (c); enum tree_code code = PLUS_EXPR; if (POINTER_TYPE_P (TREE_TYPE (new_var))) code = POINTER_PLUS_EXPR; @@ -3526,25 +3588,10 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, But if they aren't used, we need to emit the deferred initialization now. */ else if (is_reference (var) && is_simd) - { - tree z - = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_vard))); - if (TREE_CONSTANT (z)) - { - const char *name = NULL; - if (DECL_NAME (var)) - name = IDENTIFIER_POINTER (DECL_NAME (new_vard)); - - z = create_tmp_var_raw - (TREE_TYPE (TREE_TYPE (new_vard)), name); - gimple_add_tmp_var (z); - TREE_ADDRESSABLE (z) = 1; - z = build_fold_addr_expr_loc (clause_loc, z); - gimplify_assign (new_vard, z, ilist); - } - } + handle_simd_reference (clause_loc, new_vard, ilist); x = lang_hooks.decls.omp_clause_default_ctor - (c, new_var, unshare_expr (x)); + (c, unshare_expr (new_var), + build_outer_var_ref (var, ctx)); if (x) gimplify_and_add (x, ilist); if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)) @@ -3575,6 +3622,13 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, if (code == MINUS_EXPR) code = PLUS_EXPR; + tree new_vard = new_var; + if (is_simd && is_reference (var)) + { + gcc_assert (TREE_CODE (new_var) == MEM_REF); + new_vard = TREE_OPERAND (new_var, 0); + gcc_assert (DECL_P (new_vard)); + } if (is_simd && lower_rec_simd_input_clauses (new_var, ctx, max_vf, idx, lane, ivar, lvar)) @@ -3586,9 +3640,18 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, x = build2 (code, TREE_TYPE (ref), ref, ivar); ref = build_outer_var_ref (var, ctx); gimplify_assign (ref, x, &llist[1]); + + if (new_vard != new_var) + { + SET_DECL_VALUE_EXPR (new_vard, + build_fold_addr_expr (lvar)); + DECL_HAS_VALUE_EXPR_P (new_vard) = 1; + } } else { + if (is_reference (var) && is_simd) + handle_simd_reference (clause_loc, new_vard, ilist); gimplify_assign (new_var, x, ilist); if (is_simd) { @@ -3689,8 +3752,9 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, tree c = find_omp_clause (gimple_omp_for_clauses (ctx->stmt), OMP_CLAUSE_SAFELEN); if (c == NULL_TREE - || compare_tree_int (OMP_CLAUSE_SAFELEN_EXPR (c), - max_vf) == 1) + || (TREE_CODE (OMP_CLAUSE_SAFELEN_EXPR (c)) == INTEGER_CST + && compare_tree_int (OMP_CLAUSE_SAFELEN_EXPR (c), + max_vf) == 1)) { c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN); OMP_CLAUSE_SAFELEN_EXPR (c) = build_int_cst (integer_type_node, @@ -6854,8 +6918,10 @@ expand_omp_simd (struct omp_region *region, struct omp_for_data *fd) else { safelen = OMP_CLAUSE_SAFELEN_EXPR (safelen); - if (!tree_fits_uhwi_p (safelen) - || tree_to_uhwi (safelen) > INT_MAX) + if (TREE_CODE (safelen) != INTEGER_CST) + loop->safelen = 0; + else if (!tree_fits_uhwi_p (safelen) + || tree_to_uhwi (safelen) > INT_MAX) loop->safelen = INT_MAX; else loop->safelen = tree_to_uhwi (safelen); @@ -8421,10 +8487,14 @@ maybe_add_implicit_barrier_cancel (omp_context *ctx, gimple_seq *body) && gimple_code (ctx->outer->stmt) == GIMPLE_OMP_PARALLEL && ctx->outer->cancellable) { - tree lhs = create_tmp_var (boolean_type_node, NULL); + tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_CANCEL); + tree c_bool_type = TREE_TYPE (TREE_TYPE (fndecl)); + tree lhs = create_tmp_var (c_bool_type, NULL); gimple_omp_return_set_lhs (omp_return, lhs); tree fallthru_label = create_artificial_label (UNKNOWN_LOCATION); - gimple g = gimple_build_cond (NE_EXPR, lhs, boolean_false_node, + gimple g = gimple_build_cond (NE_EXPR, lhs, + fold_convert (c_bool_type, + boolean_false_node), ctx->outer->cancel_label, fallthru_label); gimple_seq_add_stmt (body, g); gimple_seq_add_stmt (body, gimple_build_label (fallthru_label)); @@ -9021,7 +9091,10 @@ lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx) OMP_CLAUSE__LOOPTEMP_); } else - temp = create_tmp_var (type, NULL); + { + temp = create_tmp_var (type, NULL); + insert_decl_map (&ctx->outer->cb, temp, temp); + } *pc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__LOOPTEMP_); OMP_CLAUSE_DECL (*pc) = temp; pc = &OMP_CLAUSE_CHAIN (*pc); @@ -10130,21 +10203,23 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx) } break; } - tree lhs; - lhs = create_tmp_var (boolean_type_node, NULL); if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_GOMP_BARRIER) { fndecl = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER_CANCEL); gimple_call_set_fndecl (stmt, fndecl); gimple_call_set_fntype (stmt, TREE_TYPE (fndecl)); } + tree lhs; + lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (fndecl)), NULL); gimple_call_set_lhs (stmt, lhs); tree fallthru_label; fallthru_label = create_artificial_label (UNKNOWN_LOCATION); gimple g; g = gimple_build_label (fallthru_label); gsi_insert_after (gsi_p, g, GSI_SAME_STMT); - g = gimple_build_cond (NE_EXPR, lhs, boolean_false_node, + g = gimple_build_cond (NE_EXPR, lhs, + fold_convert (TREE_TYPE (lhs), + boolean_false_node), cctx->cancel_label, fallthru_label); gsi_insert_after (gsi_p, g, GSI_SAME_STMT); break; |