aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimplify.c
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2020-06-17 07:50:57 -0400
committerAldy Hernandez <aldyh@redhat.com>2020-06-17 07:50:57 -0400
commitb9e67f2840ce0d8859d96e7f8df8fe9584af5eba (patch)
treeed3b7284ff15c802583f6409b9c71b3739642d15 /gcc/gimplify.c
parent1957047ed1c94bf17cf993a2b1866965f493ba87 (diff)
parent56638b9b1853666f575928f8baf17f70e4ed3517 (diff)
downloadgcc-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.c372
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);