aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/omp-low.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/gcc/omp-low.c')
-rw-r--r--gcc-4.9/gcc/omp-low.c140
1 files changed, 113 insertions, 27 deletions
diff --git a/gcc-4.9/gcc/omp-low.c b/gcc-4.9/gcc/omp-low.c
index 1753cad45..6d9206c95 100644
--- a/gcc-4.9/gcc/omp-low.c
+++ b/gcc-4.9/gcc/omp-low.c
@@ -204,6 +204,7 @@ static int taskreg_nesting_level;
static int target_nesting_level;
static struct omp_region *root_omp_region;
static bitmap task_shared_vars;
+static vec<omp_context *> taskreg_contexts;
static void scan_omp (gimple_seq *, omp_context *);
static tree scan_omp_1_op (tree *, int *, void *);
@@ -1632,7 +1633,8 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
#pragma omp target data, there is nothing to map for
those. */
if (gimple_omp_target_kind (ctx->stmt) == GF_OMP_TARGET_KIND_DATA
- && !POINTER_TYPE_P (TREE_TYPE (decl)))
+ && !POINTER_TYPE_P (TREE_TYPE (decl))
+ && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c))
break;
}
if (DECL_P (decl))
@@ -2024,6 +2026,7 @@ scan_omp_parallel (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
}
ctx = new_omp_context (stmt, outer_ctx);
+ taskreg_contexts.safe_push (ctx);
if (taskreg_nesting_level > 1)
ctx->is_nested = true;
ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
@@ -2043,11 +2046,6 @@ scan_omp_parallel (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
if (TYPE_FIELDS (ctx->record_type) == NULL)
ctx->record_type = ctx->receiver_decl = NULL;
- else
- {
- layout_type (ctx->record_type);
- fixup_child_record_type (ctx);
- }
}
/* Scan an OpenMP task directive. */
@@ -2058,7 +2056,6 @@ scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
omp_context *ctx;
tree name, t;
gimple stmt = gsi_stmt (*gsi);
- location_t loc = gimple_location (stmt);
/* Ignore task directives with empty bodies. */
if (optimize > 0
@@ -2069,6 +2066,7 @@ scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
}
ctx = new_omp_context (stmt, outer_ctx);
+ taskreg_contexts.safe_push (ctx);
if (taskreg_nesting_level > 1)
ctx->is_nested = true;
ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
@@ -2106,8 +2104,71 @@ scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
t = build_int_cst (long_integer_type_node, 1);
gimple_omp_task_set_arg_align (stmt, t);
}
+}
+
+
+/* If any decls have been made addressable during scan_omp,
+ adjust their fields if needed, and layout record types
+ of parallel/task constructs. */
+
+static void
+finish_taskreg_scan (omp_context *ctx)
+{
+ if (ctx->record_type == NULL_TREE)
+ return;
+
+ /* If any task_shared_vars were needed, verify all
+ OMP_CLAUSE_SHARED clauses on GIMPLE_OMP_{PARALLEL,TASK}
+ statements if use_pointer_for_field hasn't changed
+ because of that. If it did, update field types now. */
+ if (task_shared_vars)
+ {
+ tree c;
+
+ for (c = gimple_omp_taskreg_clauses (ctx->stmt);
+ c; c = OMP_CLAUSE_CHAIN (c))
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED)
+ {
+ tree decl = OMP_CLAUSE_DECL (c);
+
+ /* Global variables don't need to be copied,
+ the receiver side will use them directly. */
+ if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
+ continue;
+ if (!bitmap_bit_p (task_shared_vars, DECL_UID (decl))
+ || !use_pointer_for_field (decl, ctx))
+ continue;
+ tree field = lookup_field (decl, ctx);
+ if (TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE
+ && TREE_TYPE (TREE_TYPE (field)) == TREE_TYPE (decl))
+ continue;
+ TREE_TYPE (field) = build_pointer_type (TREE_TYPE (decl));
+ TREE_THIS_VOLATILE (field) = 0;
+ DECL_USER_ALIGN (field) = 0;
+ DECL_ALIGN (field) = TYPE_ALIGN (TREE_TYPE (field));
+ if (TYPE_ALIGN (ctx->record_type) < DECL_ALIGN (field))
+ TYPE_ALIGN (ctx->record_type) = DECL_ALIGN (field);
+ if (ctx->srecord_type)
+ {
+ tree sfield = lookup_sfield (decl, ctx);
+ TREE_TYPE (sfield) = TREE_TYPE (field);
+ TREE_THIS_VOLATILE (sfield) = 0;
+ DECL_USER_ALIGN (sfield) = 0;
+ DECL_ALIGN (sfield) = DECL_ALIGN (field);
+ if (TYPE_ALIGN (ctx->srecord_type) < DECL_ALIGN (sfield))
+ TYPE_ALIGN (ctx->srecord_type) = DECL_ALIGN (sfield);
+ }
+ }
+ }
+
+ if (gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL)
+ {
+ layout_type (ctx->record_type);
+ fixup_child_record_type (ctx);
+ }
else
{
+ location_t loc = gimple_location (ctx->stmt);
tree *p, vla_fields = NULL_TREE, *q = &vla_fields;
/* Move VLA fields to the end. */
p = &TYPE_FIELDS (ctx->record_type);
@@ -2127,12 +2188,12 @@ scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
fixup_child_record_type (ctx);
if (ctx->srecord_type)
layout_type (ctx->srecord_type);
- t = fold_convert_loc (loc, long_integer_type_node,
- TYPE_SIZE_UNIT (ctx->record_type));
- gimple_omp_task_set_arg_size (stmt, t);
+ tree t = fold_convert_loc (loc, long_integer_type_node,
+ TYPE_SIZE_UNIT (ctx->record_type));
+ gimple_omp_task_set_arg_size (ctx->stmt, t);
t = build_int_cst (long_integer_type_node,
TYPE_ALIGN_UNIT (ctx->record_type));
- gimple_omp_task_set_arg_align (stmt, t);
+ gimple_omp_task_set_arg_align (ctx->stmt, t);
}
}
@@ -9827,6 +9888,9 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
continue;
}
+ unsigned int talign = TYPE_ALIGN_UNIT (TREE_TYPE (ovar));
+ if (DECL_P (ovar) && DECL_ALIGN_UNIT (ovar) > talign)
+ talign = DECL_ALIGN_UNIT (ovar);
if (nc)
{
tree var = lookup_decl_in_outer_ctx (ovar, ctx);
@@ -9841,6 +9905,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
= create_tmp_var (TREE_TYPE (TREE_TYPE (x)), NULL);
mark_addressable (avar);
gimplify_assign (avar, build_fold_addr_expr (var), &ilist);
+ talign = DECL_ALIGN_UNIT (avar);
avar = build_fold_addr_expr (avar);
gimplify_assign (x, avar, &ilist);
}
@@ -9893,9 +9958,6 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
default:
gcc_unreachable ();
}
- unsigned int talign = TYPE_ALIGN_UNIT (TREE_TYPE (ovar));
- if (DECL_P (ovar) && DECL_ALIGN_UNIT (ovar) > talign)
- talign = DECL_ALIGN_UNIT (ovar);
talign = ceil_log2 (talign);
tkind |= talign << 3;
CONSTRUCTOR_APPEND_ELT (vkind, purpose,
@@ -10269,6 +10331,8 @@ static unsigned int
execute_lower_omp (void)
{
gimple_seq body;
+ int i;
+ omp_context *ctx;
/* This pass always runs, to provide PROP_gimple_lomp.
But there is nothing to do unless -fopenmp is given. */
@@ -10281,6 +10345,9 @@ execute_lower_omp (void)
body = gimple_body (current_function_decl);
scan_omp (&body, NULL);
gcc_assert (taskreg_nesting_level == 0);
+ FOR_EACH_VEC_ELT (taskreg_contexts, i, ctx)
+ finish_taskreg_scan (ctx);
+ taskreg_contexts.release ();
if (all_contexts->root)
{
@@ -11115,24 +11182,24 @@ simd_clone_adjust_return_type (struct cgraph_node *node)
if (orig_rettype == void_type_node)
return NULL_TREE;
TREE_TYPE (fndecl) = build_distinct_type_copy (TREE_TYPE (fndecl));
- if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl)))
- || POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl))))
+ t = TREE_TYPE (TREE_TYPE (fndecl));
+ if (INTEGRAL_TYPE_P (t) || POINTER_TYPE_P (t))
veclen = node->simdclone->vecsize_int;
else
veclen = node->simdclone->vecsize_float;
- veclen /= GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (fndecl))));
+ veclen /= GET_MODE_BITSIZE (TYPE_MODE (t));
if (veclen > node->simdclone->simdlen)
veclen = node->simdclone->simdlen;
+ if (POINTER_TYPE_P (t))
+ t = pointer_sized_int_node;
if (veclen == node->simdclone->simdlen)
- TREE_TYPE (TREE_TYPE (fndecl))
- = build_vector_type (TREE_TYPE (TREE_TYPE (fndecl)),
- node->simdclone->simdlen);
+ t = build_vector_type (t, node->simdclone->simdlen);
else
{
- t = build_vector_type (TREE_TYPE (TREE_TYPE (fndecl)), veclen);
+ t = build_vector_type (t, veclen);
t = build_array_type_nelts (t, node->simdclone->simdlen / veclen);
- TREE_TYPE (TREE_TYPE (fndecl)) = t;
}
+ TREE_TYPE (TREE_TYPE (fndecl)) = t;
if (!node->definition)
return NULL_TREE;
@@ -11221,7 +11288,10 @@ simd_clone_adjust_argument_types (struct cgraph_node *node)
if (veclen > node->simdclone->simdlen)
veclen = node->simdclone->simdlen;
adj.arg_prefix = "simd";
- adj.type = build_vector_type (parm_type, veclen);
+ if (POINTER_TYPE_P (parm_type))
+ adj.type = build_vector_type (pointer_sized_int_node, veclen);
+ else
+ adj.type = build_vector_type (parm_type, veclen);
node->simdclone->args[i].vector_type = adj.type;
for (j = veclen; j < node->simdclone->simdlen; j += veclen)
{
@@ -11262,7 +11332,10 @@ simd_clone_adjust_argument_types (struct cgraph_node *node)
veclen /= GET_MODE_BITSIZE (TYPE_MODE (base_type));
if (veclen > node->simdclone->simdlen)
veclen = node->simdclone->simdlen;
- adj.type = build_vector_type (base_type, veclen);
+ if (POINTER_TYPE_P (base_type))
+ adj.type = build_vector_type (pointer_sized_int_node, veclen);
+ else
+ adj.type = build_vector_type (base_type, veclen);
adjustments.safe_push (adj);
for (j = veclen; j < node->simdclone->simdlen; j += veclen)
@@ -11436,9 +11509,22 @@ ipa_simd_modify_stmt_ops (tree *tp, int *walk_subtrees, void *data)
if (tp != orig_tp)
{
repl = build_fold_addr_expr (repl);
- gimple stmt
- = gimple_build_assign (make_ssa_name (TREE_TYPE (repl), NULL), repl);
- repl = gimple_assign_lhs (stmt);
+ gimple stmt;
+ if (is_gimple_debug (info->stmt))
+ {
+ tree vexpr = make_node (DEBUG_EXPR_DECL);
+ stmt = gimple_build_debug_source_bind (vexpr, repl, NULL);
+ DECL_ARTIFICIAL (vexpr) = 1;
+ TREE_TYPE (vexpr) = TREE_TYPE (repl);
+ DECL_MODE (vexpr) = TYPE_MODE (TREE_TYPE (repl));
+ repl = vexpr;
+ }
+ else
+ {
+ stmt = gimple_build_assign (make_ssa_name (TREE_TYPE (repl),
+ NULL), repl);
+ repl = gimple_assign_lhs (stmt);
+ }
gimple_stmt_iterator gsi = gsi_for_stmt (info->stmt);
gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
*orig_tp = repl;