diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2020-06-17 07:50:57 -0400 |
---|---|---|
committer | Aldy Hernandez <aldyh@redhat.com> | 2020-06-17 07:50:57 -0400 |
commit | b9e67f2840ce0d8859d96e7f8df8fe9584af5eba (patch) | |
tree | ed3b7284ff15c802583f6409b9c71b3739642d15 /gcc/gimplify.c | |
parent | 1957047ed1c94bf17cf993a2b1866965f493ba87 (diff) | |
parent | 56638b9b1853666f575928f8baf17f70e4ed3517 (diff) | |
download | gcc-b9e67f2840ce0d8859d96e7f8df8fe9584af5eba.zip gcc-b9e67f2840ce0d8859d96e7f8df8fe9584af5eba.tar.gz gcc-b9e67f2840ce0d8859d96e7f8df8fe9584af5eba.tar.bz2 |
Merge from trunk at:
commit 56638b9b1853666f575928f8baf17f70e4ed3517
Author: GCC Administrator <gccadmin@gcc.gnu.org>
Date: Wed Jun 17 00:16:36 2020 +0000
Daily bump.
Diffstat (limited to 'gcc/gimplify.c')
-rw-r--r-- | gcc/gimplify.c | 372 |
1 files changed, 227 insertions, 145 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 73fb2e7..dd10119 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -559,9 +559,6 @@ create_tmp_from_val (tree val) /* Drop all qualifiers and address-space information from the value type. */ tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val)); tree var = create_tmp_var (type, get_name (val)); - if (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE - || TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE) - DECL_GIMPLE_REG_P (var) = 1; return var; } @@ -937,7 +934,7 @@ copy_if_shared_r (tree *tp, int *walk_subtrees, void *data) /* Unshare most of the shared trees rooted at *TP. DATA is passed to the copy_if_shared_r callback unmodified. */ -static inline void +void copy_if_shared (tree *tp, void *data) { walk_tree (tp, copy_if_shared_r, data, NULL); @@ -1400,16 +1397,6 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p) if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun) cfun->has_local_explicit_reg_vars = true; } - - /* Preliminarily mark non-addressed complex variables as eligible - for promotion to gimple registers. We'll transform their uses - as we find them. */ - if ((TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE - || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE) - && !TREE_THIS_VOLATILE (t) - && (VAR_P (t) && !DECL_HARD_REGISTER (t)) - && !needs_to_live_in_memory (t)) - DECL_GIMPLE_REG_P (t) = 1; } bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL, @@ -1599,6 +1586,14 @@ gimplify_return_expr (tree stmt, gimple_seq *pre_p) if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))) result_decl = NULL_TREE; + else if (TREE_CODE (ret_expr) == COMPOUND_EXPR) + { + /* Used in C++ for handling EH cleanup of the return value if a local + cleanup throws. Assume the front-end knows what it's doing. */ + result_decl = DECL_RESULT (current_function_decl); + /* But crash if we end up trying to modify ret_expr below. */ + ret_expr = NULL_TREE; + } else { result_decl = TREE_OPERAND (ret_expr, 0); @@ -1624,7 +1619,7 @@ gimplify_return_expr (tree stmt, gimple_seq *pre_p) result = NULL_TREE; else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_decl))) { - if (TREE_CODE (DECL_SIZE (result_decl)) != INTEGER_CST) + if (!poly_int_tree_p (DECL_SIZE (result_decl))) { if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl))) gimplify_type_sizes (TREE_TYPE (result_decl), pre_p); @@ -4300,7 +4295,7 @@ prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p) { /* Do not allow an SSA name as the temporary. */ tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false); - DECL_GIMPLE_REG_P (var) = 0; + DECL_NOT_GIMPLE_REG_P (var) = 1; *expr_p = var; } } @@ -4766,15 +4761,6 @@ gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p, return GS_OK; } - /* Preliminarily mark non-addressed complex variables as eligible - for promotion to gimple registers. We'll transform their uses - as we find them. */ - if ((TREE_CODE (TREE_TYPE (decl)) == COMPLEX_TYPE - || TREE_CODE (TREE_TYPE (decl)) == VECTOR_TYPE) - && !TREE_THIS_VOLATILE (decl) - && !needs_to_live_in_memory (decl)) - DECL_GIMPLE_REG_P (decl) = 1; - /* If the decl is not addressable, then it is being used in some expression or on the right hand side of a statement, and it can be put into a readonly data section. */ @@ -4879,10 +4865,6 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, case QUAL_UNION_TYPE: case ARRAY_TYPE: { - struct gimplify_init_ctor_preeval_data preeval_data; - HOST_WIDE_INT num_ctor_elements, num_nonzero_elements; - HOST_WIDE_INT num_unique_nonzero_elements; - bool cleared, complete_p, valid_const_initializer; /* Use readonly data for initializers of this or smaller size regardless of the num_nonzero_elements / num_unique_nonzero_elements ratio. */ @@ -4890,6 +4872,17 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, /* If num_nonzero_elements / num_unique_nonzero_elements ratio is smaller than this, use readonly data. */ const int unique_nonzero_ratio = 8; + /* True if a single access of the object must be ensured. This is the + case if the target is volatile, the type is non-addressable and more + than one field need to be assigned. */ + const bool ensure_single_access + = TREE_THIS_VOLATILE (object) + && !TREE_ADDRESSABLE (type) + && vec_safe_length (elts) > 1; + struct gimplify_init_ctor_preeval_data preeval_data; + HOST_WIDE_INT num_ctor_elements, num_nonzero_elements; + HOST_WIDE_INT num_unique_nonzero_elements; + bool cleared, complete_p, valid_const_initializer; /* Aggregate types must lower constructors to initialization of individual elements. The exception is that a CONSTRUCTOR node @@ -4915,6 +4908,7 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, && num_nonzero_elements > 1 && TREE_READONLY (object) && VAR_P (object) + && !DECL_REGISTER (object) && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object)) /* For ctors that have many repeated nonzero elements represented through RANGE_EXPRs, prefer initializing @@ -4927,6 +4921,7 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, { if (notify_temp_creation) return GS_ERROR; + DECL_INITIAL (object) = ctor; TREE_STATIC (object) = 1; if (!DECL_NAME (object)) @@ -4974,6 +4969,10 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, /* If there are "lots" of zeros, it's more efficient to clear the memory and then set the nonzero elements. */ cleared = true; + else if (ensure_single_access && num_nonzero_elements == 0) + /* If a single access to the target must be ensured and all elements + are zero, then it's optimal to clear whatever their number. */ + cleared = true; else cleared = false; @@ -4986,8 +4985,8 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, all-zero initializers (which aren't big enough to merit clearing), and don't try to make bitwise copies of TREE_ADDRESSABLE types. */ - if (valid_const_initializer + && complete_p && !(cleared || num_nonzero_elements == 0) && !TREE_ADDRESSABLE (type)) { @@ -5042,13 +5041,14 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, } } - /* If the target is volatile, we have non-zero elements and more than - one field to assign, initialize the target from a temporary. */ - if (TREE_THIS_VOLATILE (object) - && !TREE_ADDRESSABLE (type) - && (num_nonzero_elements > 0 || !cleared) - && vec_safe_length (elts) > 1) + /* If a single access to the target must be ensured and there are + nonzero elements or the zero elements are not assigned en masse, + initialize the target from a temporary. */ + if (ensure_single_access && (num_nonzero_elements > 0 || !cleared)) { + if (notify_temp_creation) + return GS_ERROR; + tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type)); TREE_OPERAND (*expr_p, 0) = temp; *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p), @@ -5256,14 +5256,20 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, { case VAR_DECL: /* If we're assigning from a read-only variable initialized with - a constructor, do the direct assignment from the constructor, - but only if neither source nor target are volatile since this - latter assignment might end up being done on a per-field basis. */ - if (DECL_INITIAL (*from_p) - && TREE_READONLY (*from_p) + a constructor and not volatile, do the direct assignment from + the constructor, but only if the target is not volatile either + since this latter assignment might end up being done on a per + field basis. However, if the target is volatile and the type + is aggregate and non-addressable, gimplify_init_constructor + knows that it needs to ensure a single access to the target + and it will return GS_OK only in this case. */ + if (TREE_READONLY (*from_p) + && DECL_INITIAL (*from_p) + && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR && !TREE_THIS_VOLATILE (*from_p) - && !TREE_THIS_VOLATILE (*to_p) - && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR) + && (!TREE_THIS_VOLATILE (*to_p) + || (AGGREGATE_TYPE_P (TREE_TYPE (*to_p)) + && !TREE_ADDRESSABLE (TREE_TYPE (*to_p))))) { tree old_from = *from_p; enum gimplify_status subret; @@ -5608,8 +5614,7 @@ is_gimple_stmt (tree t) /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is - a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a variable with - DECL_GIMPLE_REG_P set. + a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register. IMPORTANT NOTE: This promotion is performed by introducing a load of the other, unmodified part of the complex object just before the total store. @@ -6172,7 +6177,9 @@ gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) /* For various reasons, the gimplification of the expression may have made a new INDIRECT_REF. */ - if (TREE_CODE (op0) == INDIRECT_REF) + if (TREE_CODE (op0) == INDIRECT_REF + || (TREE_CODE (op0) == MEM_REF + && integer_zerop (TREE_OPERAND (op0, 1)))) goto do_indirect_ref; mark_addressable (TREE_OPERAND (expr, 0)); @@ -6706,7 +6713,7 @@ gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) /* TARGET_EXPR temps aren't part of the enclosing block, so add it to the temps list. Handle also variable length TARGET_EXPRs. */ - if (TREE_CODE (DECL_SIZE (temp)) != INTEGER_CST) + if (!poly_int_tree_p (DECL_SIZE (temp))) { if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp))) gimplify_type_sizes (TREE_TYPE (temp), pre_p); @@ -7444,6 +7451,7 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code) if (!is_declare_target) { int gdmk; + enum omp_clause_defaultmap_kind kind; if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) @@ -7453,7 +7461,17 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code) gdmk = GDMK_SCALAR; else gdmk = GDMK_AGGREGATE; - if (ctx->defaultmap[gdmk] == 0) + kind = lang_hooks.decls.omp_predetermined_mapping (decl); + if (kind != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED) + { + if (kind == OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE) + nflags |= GOVD_FIRSTPRIVATE; + else if (kind == OMP_CLAUSE_DEFAULTMAP_TO) + nflags |= GOVD_MAP | GOVD_MAP_TO_ONLY; + else + gcc_unreachable (); + } + else if (ctx->defaultmap[gdmk] == 0) { tree d = lang_hooks.decls.omp_report_decl (decl); error ("%qE not specified in enclosing %<target%>", @@ -7913,7 +7931,7 @@ gimplify_omp_depend (tree *list_p, gimple_seq *pre_p) tree type = build_array_type (ptr_type_node, build_index_type (totalpx)); tree array = create_tmp_var_raw (type); TREE_ADDRESSABLE (array) = 1; - if (TREE_CODE (totalpx) != INTEGER_CST) + if (!poly_int_tree_p (totalpx)) { if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array))) gimplify_type_sizes (TREE_TYPE (array), pre_p); @@ -8774,10 +8792,16 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, 'exit data' - and in particular for 'delete:' - having an 'alloc:' does not make sense. Likewise, for 'update' only transferring the data itself is needed as the rest has been handled in previous - directives. */ - if ((code == OMP_TARGET_EXIT_DATA || code == OMP_TARGET_UPDATE) - && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER - || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET)) + directives. However, for 'exit data', the array descriptor needs + to be delete; hence, we turn the MAP_TO_PSET into a MAP_DELETE. */ + if (code == OMP_TARGET_EXIT_DATA + && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET) + OMP_CLAUSE_SET_MAP_KIND (c, OMP_CLAUSE_MAP_KIND (*prev_list_p) + == GOMP_MAP_DELETE + ? GOMP_MAP_DELETE : GOMP_MAP_RELEASE); + else if ((code == OMP_TARGET_EXIT_DATA || code == OMP_TARGET_UPDATE) + && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER + || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET)) remove = true; if (remove) @@ -9456,9 +9480,13 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, == POINTER_TYPE)))) omp_firstprivatize_variable (outer_ctx, decl); else - omp_add_variable (outer_ctx, decl, - GOVD_SEEN | GOVD_SHARED); - omp_notice_variable (outer_ctx, decl, true); + { + omp_add_variable (outer_ctx, decl, + GOVD_SEEN | GOVD_SHARED); + if (outer_ctx->outer_context) + omp_notice_variable (outer_ctx->outer_context, decl, + true); + } } } if (outer_ctx) @@ -9894,6 +9922,22 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data) error ("%<_Atomic%> %qD in implicit %<map%> clause", decl); return 0; } + if (VAR_P (decl) + && DECL_IN_CONSTANT_POOL (decl) + && !lookup_attribute ("omp declare target", + DECL_ATTRIBUTES (decl))) + { + tree id = get_identifier ("omp declare target"); + DECL_ATTRIBUTES (decl) + = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl)); + varpool_node *node = varpool_node::get (decl); + if (node) + { + node->offloadable = 1; + if (ENABLE_OFFLOADING) + g->have_offload = true; + } + } } else if (flags & GOVD_SHARED) { @@ -10371,7 +10415,8 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p, } } else if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT - && code == OMP_TARGET_EXIT_DATA) + && (code == OMP_TARGET_EXIT_DATA + || code == OACC_EXIT_DATA)) remove = true; else if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST @@ -10949,62 +10994,6 @@ gimplify_omp_task (tree *expr_p, gimple_seq *pre_p) *expr_p = NULL_TREE; } -/* Helper function of gimplify_omp_for, find OMP_FOR resp. OMP_SIMD - with non-NULL OMP_FOR_INIT. Also, fill in pdata array, - pdata[0] non-NULL if there is anything non-trivial in between, pdata[1] - is address of OMP_PARALLEL in between if any, pdata[2] is address of - OMP_FOR in between if any and pdata[3] is address of the inner - OMP_FOR/OMP_SIMD. */ - -static tree -find_combined_omp_for (tree *tp, int *walk_subtrees, void *data) -{ - tree **pdata = (tree **) data; - *walk_subtrees = 0; - switch (TREE_CODE (*tp)) - { - case OMP_FOR: - if (OMP_FOR_INIT (*tp) != NULL_TREE) - { - pdata[3] = tp; - return *tp; - } - pdata[2] = tp; - *walk_subtrees = 1; - break; - case OMP_SIMD: - if (OMP_FOR_INIT (*tp) != NULL_TREE) - { - pdata[3] = tp; - return *tp; - } - break; - case BIND_EXPR: - if (BIND_EXPR_VARS (*tp) - || (BIND_EXPR_BLOCK (*tp) - && BLOCK_VARS (BIND_EXPR_BLOCK (*tp)))) - pdata[0] = tp; - *walk_subtrees = 1; - break; - case STATEMENT_LIST: - if (!tsi_one_before_end_p (tsi_start (*tp))) - pdata[0] = tp; - *walk_subtrees = 1; - break; - case TRY_FINALLY_EXPR: - pdata[0] = tp; - *walk_subtrees = 1; - break; - case OMP_PARALLEL: - pdata[1] = tp; - *walk_subtrees = 1; - break; - default: - break; - } - return NULL_TREE; -} - /* Gimplify the gross structure of an OMP_FOR statement. */ static enum gimplify_status @@ -11193,7 +11182,26 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) switch (TREE_CODE (for_stmt)) { case OMP_FOR: + if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt)) + { + if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), + OMP_CLAUSE_SCHEDULE)) + error_at (EXPR_LOCATION (for_stmt), + "%qs clause may not appear on non-rectangular %qs", + "schedule", "for"); + if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED)) + error_at (EXPR_LOCATION (for_stmt), + "%qs clause may not appear on non-rectangular %qs", + "ordered", "for"); + } + break; case OMP_DISTRIBUTE: + if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt) + && omp_find_clause (OMP_FOR_CLAUSES (for_stmt), + OMP_CLAUSE_DIST_SCHEDULE)) + error_at (EXPR_LOCATION (for_stmt), + "%qs clause may not appear on non-rectangular %qs", + "dist_schedule", "distribute"); break; case OACC_LOOP: ort = ORT_ACC; @@ -11768,8 +11776,18 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) else var = decl; - tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL, - is_gimple_val, fb_rvalue, false); + if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC) + { + tree lb = TREE_OPERAND (t, 1); + tret = gimplify_expr (&TREE_VEC_ELT (lb, 1), &for_pre_body, NULL, + is_gimple_val, fb_rvalue, false); + ret = MIN (ret, tret); + tret = gimplify_expr (&TREE_VEC_ELT (lb, 2), &for_pre_body, NULL, + is_gimple_val, fb_rvalue, false); + } + else + tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL, + is_gimple_val, fb_rvalue, false); ret = MIN (ret, tret); if (ret == GS_ERROR) return ret; @@ -11779,8 +11797,18 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) gcc_assert (COMPARISON_CLASS_P (t)); gcc_assert (TREE_OPERAND (t, 0) == decl); - tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL, - is_gimple_val, fb_rvalue, false); + if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC) + { + tree ub = TREE_OPERAND (t, 1); + tret = gimplify_expr (&TREE_VEC_ELT (ub, 1), &for_pre_body, NULL, + is_gimple_val, fb_rvalue, false); + ret = MIN (ret, tret); + tret = gimplify_expr (&TREE_VEC_ELT (ub, 2), &for_pre_body, NULL, + is_gimple_val, fb_rvalue, false); + } + else + tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL, + is_gimple_val, fb_rvalue, false); ret = MIN (ret, tret); /* Handle OMP_FOR_INCR. */ @@ -11922,6 +11950,20 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) pop_gimplify_context (bind); } } + if (OMP_FOR_NON_RECTANGULAR (for_stmt) && var != decl) + for (int j = i + 1; j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++) + { + t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j); + gcc_assert (TREE_CODE (t) == MODIFY_EXPR); + if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC + && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl) + TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var; + t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j); + gcc_assert (COMPARISON_CLASS_P (t)); + if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC + && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl) + TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var; + } } BITMAP_FREE (has_decl_expr); @@ -11966,6 +12008,27 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i); TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1)); TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var; + if (OMP_FOR_NON_RECTANGULAR (for_stmt)) + for (int j = i + 1; + j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++) + { + t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j); + gcc_assert (TREE_CODE (t) == MODIFY_EXPR); + if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC + && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl) + { + TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1)); + TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var; + } + t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j); + gcc_assert (COMPARISON_CLASS_P (t)); + if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC + && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl) + { + TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1)); + TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var; + } + } } gimplify_adjust_omp_clauses (pre_p, for_body, @@ -12802,14 +12865,21 @@ gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p) stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA, OMP_CLAUSES (expr)); break; - case OACC_KERNELS: - stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS, - OMP_CLAUSES (expr)); - break; case OACC_HOST_DATA: + if (omp_find_clause (OMP_CLAUSES (expr), OMP_CLAUSE_IF_PRESENT)) + { + for (tree c = OMP_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c)) + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR) + OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c) = 1; + } + stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA, OMP_CLAUSES (expr)); break; + case OACC_KERNELS: + stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS, + OMP_CLAUSES (expr)); + break; case OACC_PARALLEL: stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL, OMP_CLAUSES (expr)); @@ -14622,7 +14692,8 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, { /* Avoid the extra copy if possible. */ *expr_p = create_tmp_reg (TREE_TYPE (name)); - gimple_set_lhs (SSA_NAME_DEF_STMT (name), *expr_p); + if (!gimple_nop_p (SSA_NAME_DEF_STMT (name))) + gimple_set_lhs (SSA_NAME_DEF_STMT (name), *expr_p); release_ssa_name (name); } } @@ -14812,7 +14883,7 @@ gimplify_body (tree fndecl, bool do_parms) /* Gimplify the function's body. */ seq = NULL; gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq); - outer_stmt = gimple_seq_first_stmt (seq); + outer_stmt = gimple_seq_first_nondebug_stmt (seq); if (!outer_stmt) { outer_stmt = gimple_build_nop (); @@ -14822,8 +14893,37 @@ gimplify_body (tree fndecl, bool do_parms) /* The body must contain exactly one statement, a GIMPLE_BIND. If this is not the case, wrap everything in a GIMPLE_BIND to make it so. */ if (gimple_code (outer_stmt) == GIMPLE_BIND - && gimple_seq_first (seq) == gimple_seq_last (seq)) - outer_bind = as_a <gbind *> (outer_stmt); + && (gimple_seq_first_nondebug_stmt (seq) + == gimple_seq_last_nondebug_stmt (seq))) + { + outer_bind = as_a <gbind *> (outer_stmt); + if (gimple_seq_first_stmt (seq) != outer_stmt + || gimple_seq_last_stmt (seq) != outer_stmt) + { + /* If there are debug stmts before or after outer_stmt, move them + inside of outer_bind body. */ + gimple_stmt_iterator gsi = gsi_for_stmt (outer_stmt, &seq); + gimple_seq second_seq = NULL; + if (gimple_seq_first_stmt (seq) != outer_stmt + && gimple_seq_last_stmt (seq) != outer_stmt) + { + second_seq = gsi_split_seq_after (gsi); + gsi_remove (&gsi, false); + } + else if (gimple_seq_first_stmt (seq) != outer_stmt) + gsi_remove (&gsi, false); + else + { + gsi_remove (&gsi, false); + second_seq = seq; + seq = NULL; + } + gimple_seq_add_seq_without_update (&seq, + gimple_bind_body (outer_bind)); + gimple_seq_add_seq_without_update (&seq, second_seq); + gimple_bind_set_body (outer_bind, seq); + } + } else outer_bind = gimple_build_bind (NULL_TREE, seq, NULL); @@ -14920,7 +15020,6 @@ flag_instrument_functions_exclude_p (tree fndecl) void gimplify_function_tree (tree fndecl) { - tree parm, ret; gimple_seq seq; gbind *bind; @@ -14935,24 +15034,6 @@ gimplify_function_tree (tree fndecl) if necessary. */ cfun->curr_properties |= PROP_gimple_lva; - for (parm = DECL_ARGUMENTS (fndecl); parm ; parm = DECL_CHAIN (parm)) - { - /* Preliminarily mark non-addressed complex variables as eligible - for promotion to gimple registers. We'll transform their uses - as we find them. */ - if ((TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE - || TREE_CODE (TREE_TYPE (parm)) == VECTOR_TYPE) - && !TREE_THIS_VOLATILE (parm) - && !needs_to_live_in_memory (parm)) - DECL_GIMPLE_REG_P (parm) = 1; - } - - ret = DECL_RESULT (fndecl); - if ((TREE_CODE (TREE_TYPE (ret)) == COMPLEX_TYPE - || TREE_CODE (TREE_TYPE (ret)) == VECTOR_TYPE) - && !needs_to_live_in_memory (ret)) - DECL_GIMPLE_REG_P (ret) = 1; - if (asan_sanitize_use_after_scope () && sanitize_flags_p (SANITIZE_ADDRESS)) asan_poisoned_variables = new hash_set<tree> (); bind = gimplify_body (fndecl, true); @@ -15023,7 +15104,8 @@ gimplify_function_tree (tree fndecl) bind = new_bind; } - if (sanitize_flags_p (SANITIZE_THREAD)) + if (sanitize_flags_p (SANITIZE_THREAD) + && param_tsan_instrument_func_entry_exit) { gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0); gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY); |