/* Building the ADDR_EXPR will compute a set of properties for
that ADDR_EXPR. Those properties are unfortunately context
- specific. ie, they are dependent on CURRENT_FUNCTION_DECL.
+ specific, i.e., they are dependent on CURRENT_FUNCTION_DECL.
Temporarily set CURRENT_FUNCTION_DECL to the desired context,
build the ADDR_EXPR, then restore CURRENT_FUNCTION_DECL. That
if (insert == NO_INSERT)
{
slot = pointer_map_contains (info->field_map, decl);
- return slot ? *slot : NULL;
+ return slot ? (tree) *slot : NULL_TREE;
}
slot = pointer_map_insert (info->field_map, decl);
info->any_parm_remapped = true;
}
- return *slot;
+ return (tree) *slot;
}
/* Build or return the variable that holds the static chain within
if (insert == NO_INSERT)
{
slot = pointer_map_contains (info->var_map, decl);
- return slot ? *slot : NULL;
+ return slot ? (tree) *slot : NULL_TREE;
}
slot = pointer_map_insert (info->var_map, decl);
info->any_tramp_created = true;
}
- return *slot;
+ return (tree) *slot;
}
/* Build or return the field within the non-local frame state that holds
{
struct walk_stmt_info wi;
tree t, list = NULL, empty;
+ int i;
walk_body (callback, info, &OMP_FOR_PRE_BODY (for_stmt));
wi.info = info;
wi.tsi = tsi_last (list);
- t = OMP_FOR_INIT (for_stmt);
- gcc_assert (TREE_CODE (t) == GIMPLE_MODIFY_STMT);
- SET_EXPR_LOCUS (empty, EXPR_LOCUS (t));
- wi.val_only = false;
- walk_tree (&GIMPLE_STMT_OPERAND (t, 0), callback, &wi, NULL);
- wi.val_only = true;
- wi.is_lhs = false;
- walk_tree (&GIMPLE_STMT_OPERAND (t, 1), callback, &wi, NULL);
-
- t = OMP_FOR_COND (for_stmt);
- gcc_assert (COMPARISON_CLASS_P (t));
- SET_EXPR_LOCUS (empty, EXPR_LOCUS (t));
- wi.val_only = false;
- walk_tree (&TREE_OPERAND (t, 0), callback, &wi, NULL);
- wi.val_only = true;
- wi.is_lhs = false;
- walk_tree (&TREE_OPERAND (t, 1), callback, &wi, NULL);
-
- t = OMP_FOR_INCR (for_stmt);
- gcc_assert (TREE_CODE (t) == GIMPLE_MODIFY_STMT);
- SET_EXPR_LOCUS (empty, EXPR_LOCUS (t));
- wi.val_only = false;
- walk_tree (&GIMPLE_STMT_OPERAND (t, 0), callback, &wi, NULL);
- t = GIMPLE_STMT_OPERAND (t, 1);
- gcc_assert (BINARY_CLASS_P (t));
- wi.val_only = false;
- walk_tree (&TREE_OPERAND (t, 0), callback, &wi, NULL);
- wi.val_only = true;
- wi.is_lhs = false;
- walk_tree (&TREE_OPERAND (t, 1), callback, &wi, NULL);
+ for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
+ {
+ t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
+ gcc_assert (TREE_CODE (t) == GIMPLE_MODIFY_STMT);
+ SET_EXPR_LOCUS (empty, EXPR_LOCUS (t));
+ wi.val_only = false;
+ walk_tree (&GIMPLE_STMT_OPERAND (t, 0), callback, &wi, NULL);
+ wi.val_only = true;
+ wi.is_lhs = false;
+ walk_tree (&GIMPLE_STMT_OPERAND (t, 1), callback, &wi, NULL);
+
+ t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
+ gcc_assert (COMPARISON_CLASS_P (t));
+ SET_EXPR_LOCUS (empty, EXPR_LOCUS (t));
+ wi.val_only = false;
+ walk_tree (&TREE_OPERAND (t, 0), callback, &wi, NULL);
+ wi.val_only = true;
+ wi.is_lhs = false;
+ walk_tree (&TREE_OPERAND (t, 1), callback, &wi, NULL);
+
+ t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
+ gcc_assert (TREE_CODE (t) == GIMPLE_MODIFY_STMT);
+ SET_EXPR_LOCUS (empty, EXPR_LOCUS (t));
+ wi.val_only = false;
+ walk_tree (&GIMPLE_STMT_OPERAND (t, 0), callback, &wi, NULL);
+ t = GIMPLE_STMT_OPERAND (t, 1);
+ gcc_assert (BINARY_CLASS_P (t));
+ wi.val_only = false;
+ walk_tree (&TREE_OPERAND (t, 0), callback, &wi, NULL);
+ wi.val_only = true;
+ wi.is_lhs = false;
+ walk_tree (&TREE_OPERAND (t, 1), callback, &wi, NULL);
+ }
/* Remove empty statement added above from the end of statement list. */
tsi_delink (&wi.tsi);
for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
{
for (arg = DECL_ARGUMENTS (cgn->decl); arg; arg = TREE_CHAIN (arg))
- if (variably_modified_type_p (TREE_TYPE (arg), 0), orig_fndecl)
+ if (variably_modified_type_p (TREE_TYPE (arg), orig_fndecl))
return true;
if (check_for_nested_with_variably_modified (cgn->decl, orig_fndecl))
slot = pointer_map_insert (info->var_map, decl);
if (*slot)
- return *slot;
+ return (tree) *slot;
target_context = decl_function_context (decl);
convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data)
{
struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
- struct nesting_info *info = wi->info;
+ struct nesting_info *const info = (struct nesting_info *) wi->info;
tree t = *tp;
tree save_local_var_chain;
bitmap save_suppress;
where we only accept variables (and min_invariant, presumably),
then compute the address into a temporary. */
if (save_val_only)
- *tp = tsi_gimplify_val (wi->info, t, &wi->tsi);
+ *tp = tsi_gimplify_val ((struct nesting_info *) wi->info,
+ t, &wi->tsi);
}
}
break;
break;
case OMP_PARALLEL:
+ case OMP_TASK:
save_suppress = info->suppress_expansion;
- if (convert_nonlocal_omp_clauses (&OMP_PARALLEL_CLAUSES (t), wi))
+ if (convert_nonlocal_omp_clauses (&OMP_TASKREG_CLAUSES (t), wi))
{
tree c, decl;
decl = get_chain_decl (info);
c = build_omp_clause (OMP_CLAUSE_FIRSTPRIVATE);
OMP_CLAUSE_DECL (c) = decl;
- OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (t);
- OMP_PARALLEL_CLAUSES (t) = c;
+ OMP_CLAUSE_CHAIN (c) = OMP_TASKREG_CLAUSES (t);
+ OMP_TASKREG_CLAUSES (t) = c;
}
save_local_var_chain = info->new_local_var_chain;
info->new_local_var_chain = NULL;
- walk_body (convert_nonlocal_reference, info, &OMP_PARALLEL_BODY (t));
+ walk_body (convert_nonlocal_reference, info, &OMP_TASKREG_BODY (t));
if (info->new_local_var_chain)
- declare_vars (info->new_local_var_chain, OMP_PARALLEL_BODY (t), false);
+ declare_vars (info->new_local_var_chain, OMP_TASKREG_BODY (t), false);
info->new_local_var_chain = save_local_var_chain;
info->suppress_expansion = save_suppress;
break;
static bool
convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
{
- struct nesting_info *info = wi->info;
- bool need_chain = false;
+ struct nesting_info *const info = (struct nesting_info *) wi->info;
+ bool need_chain = false, need_stmts = false;
tree clause, decl;
int dummy;
bitmap new_suppress;
{
switch (OMP_CLAUSE_CODE (clause))
{
+ case OMP_CLAUSE_REDUCTION:
+ if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
+ need_stmts = true;
+ goto do_decl_clause;
+
+ case OMP_CLAUSE_LASTPRIVATE:
+ if (OMP_CLAUSE_LASTPRIVATE_STMT (clause))
+ need_stmts = true;
+ goto do_decl_clause;
+
case OMP_CLAUSE_PRIVATE:
case OMP_CLAUSE_FIRSTPRIVATE:
- case OMP_CLAUSE_LASTPRIVATE:
- case OMP_CLAUSE_REDUCTION:
case OMP_CLAUSE_COPYPRIVATE:
case OMP_CLAUSE_SHARED:
+ do_decl_clause:
decl = OMP_CLAUSE_DECL (clause);
+ if (TREE_CODE (decl) == VAR_DECL
+ && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
+ break;
if (decl_function_context (decl) != info->context)
{
bitmap_set_bit (new_suppress, DECL_UID (decl));
case OMP_CLAUSE_ORDERED:
case OMP_CLAUSE_DEFAULT:
case OMP_CLAUSE_COPYIN:
+ case OMP_CLAUSE_COLLAPSE:
+ case OMP_CLAUSE_UNTIED:
break;
default:
info->suppress_expansion = new_suppress;
+ if (need_stmts)
+ for (clause = *pclauses; clause ; clause = OMP_CLAUSE_CHAIN (clause))
+ switch (OMP_CLAUSE_CODE (clause))
+ {
+ case OMP_CLAUSE_REDUCTION:
+ if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
+ {
+ tree old_context
+ = DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause));
+ DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
+ = info->context;
+ walk_body (convert_nonlocal_reference, info,
+ &OMP_CLAUSE_REDUCTION_INIT (clause));
+ walk_body (convert_nonlocal_reference, info,
+ &OMP_CLAUSE_REDUCTION_MERGE (clause));
+ DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
+ = old_context;
+ }
+ break;
+
+ case OMP_CLAUSE_LASTPRIVATE:
+ walk_body (convert_nonlocal_reference, info,
+ &OMP_CLAUSE_LASTPRIVATE_STMT (clause));
+ break;
+
+ default:
+ break;
+ }
+
return need_chain;
}
slot = pointer_map_insert (info->var_map, decl);
if (*slot)
- return *slot;
+ return (tree) *slot;
/* Make sure frame_decl gets created. */
(void) get_frame_type (info);
convert_local_reference (tree *tp, int *walk_subtrees, void *data)
{
struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
- struct nesting_info *info = wi->info;
+ struct nesting_info *const info = (struct nesting_info *) wi->info;
tree t = *tp, field, x;
bool save_val_only;
tree save_local_var_chain;
/* If we are in a context where we only accept values, then
compute the address into a temporary. */
if (save_val_only)
- *tp = tsi_gimplify_val (wi->info, t, &wi->tsi);
+ *tp = tsi_gimplify_val ((struct nesting_info *)wi->info, t, &wi->tsi);
}
break;
break;
case OMP_PARALLEL:
+ case OMP_TASK:
save_suppress = info->suppress_expansion;
- if (convert_local_omp_clauses (&OMP_PARALLEL_CLAUSES (t), wi))
+ if (convert_local_omp_clauses (&OMP_TASKREG_CLAUSES (t), wi))
{
tree c;
(void) get_frame_type (info);
c = build_omp_clause (OMP_CLAUSE_SHARED);
OMP_CLAUSE_DECL (c) = info->frame_decl;
- OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (t);
- OMP_PARALLEL_CLAUSES (t) = c;
+ OMP_CLAUSE_CHAIN (c) = OMP_TASKREG_CLAUSES (t);
+ OMP_TASKREG_CLAUSES (t) = c;
}
save_local_var_chain = info->new_local_var_chain;
info->new_local_var_chain = NULL;
- walk_body (convert_local_reference, info, &OMP_PARALLEL_BODY (t));
+ walk_body (convert_local_reference, info, &OMP_TASKREG_BODY (t));
if (info->new_local_var_chain)
- declare_vars (info->new_local_var_chain, OMP_PARALLEL_BODY (t), false);
+ declare_vars (info->new_local_var_chain, OMP_TASKREG_BODY (t), false);
info->new_local_var_chain = save_local_var_chain;
info->suppress_expansion = save_suppress;
break;
static bool
convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
{
- struct nesting_info *info = wi->info;
- bool need_frame = false;
+ struct nesting_info *const info = (struct nesting_info *) wi->info;
+ bool need_frame = false, need_stmts = false;
tree clause, decl;
int dummy;
bitmap new_suppress;
{
switch (OMP_CLAUSE_CODE (clause))
{
+ case OMP_CLAUSE_REDUCTION:
+ if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
+ need_stmts = true;
+ goto do_decl_clause;
+
+ case OMP_CLAUSE_LASTPRIVATE:
+ if (OMP_CLAUSE_LASTPRIVATE_STMT (clause))
+ need_stmts = true;
+ goto do_decl_clause;
+
case OMP_CLAUSE_PRIVATE:
case OMP_CLAUSE_FIRSTPRIVATE:
- case OMP_CLAUSE_LASTPRIVATE:
- case OMP_CLAUSE_REDUCTION:
case OMP_CLAUSE_COPYPRIVATE:
case OMP_CLAUSE_SHARED:
+ do_decl_clause:
decl = OMP_CLAUSE_DECL (clause);
+ if (TREE_CODE (decl) == VAR_DECL
+ && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
+ break;
if (decl_function_context (decl) == info->context
&& !use_pointer_in_frame (decl))
{
case OMP_CLAUSE_ORDERED:
case OMP_CLAUSE_DEFAULT:
case OMP_CLAUSE_COPYIN:
+ case OMP_CLAUSE_COLLAPSE:
+ case OMP_CLAUSE_UNTIED:
break;
default:
info->suppress_expansion = new_suppress;
+ if (need_stmts)
+ for (clause = *pclauses; clause ; clause = OMP_CLAUSE_CHAIN (clause))
+ switch (OMP_CLAUSE_CODE (clause))
+ {
+ case OMP_CLAUSE_REDUCTION:
+ if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
+ {
+ tree old_context
+ = DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause));
+ DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
+ = info->context;
+ walk_body (convert_local_reference, info,
+ &OMP_CLAUSE_REDUCTION_INIT (clause));
+ walk_body (convert_local_reference, info,
+ &OMP_CLAUSE_REDUCTION_MERGE (clause));
+ DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
+ = old_context;
+ }
+ break;
+
+ case OMP_CLAUSE_LASTPRIVATE:
+ walk_body (convert_local_reference, info,
+ &OMP_CLAUSE_LASTPRIVATE_STMT (clause));
+ break;
+
+ default:
+ break;
+ }
+
return need_frame;
}
convert_nl_goto_reference (tree *tp, int *walk_subtrees, void *data)
{
struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
- struct nesting_info *info = wi->info, *i;
+ struct nesting_info *const info = (struct nesting_info *) wi->info, *i;
tree t = *tp, label, new_label, target_context, x, field;
void **slot;
*slot = new_label;
}
else
- new_label = *slot;
+ new_label = (tree) *slot;
/* Build: __builtin_nl_goto(new_label, &chain->nl_goto_field). */
field = get_nl_goto_field (i);
convert_nl_goto_receiver (tree *tp, int *walk_subtrees, void *data)
{
struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
- struct nesting_info *info = wi->info;
+ struct nesting_info *const info = (struct nesting_info *) wi->info;
tree t = *tp, label, new_label, x;
tree_stmt_iterator tmp_tsi;
void **slot;
convert_tramp_reference (tree *tp, int *walk_subtrees, void *data)
{
struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
- struct nesting_info *info = wi->info, *i;
+ struct nesting_info *const info = (struct nesting_info *) wi->info, *i;
tree t = *tp, decl, target_context, x;
*walk_subtrees = 0;
if (DECL_NO_STATIC_CHAIN (decl))
break;
+ /* If we don't want a trampoline, then don't build one. */
+ if (TREE_NO_TRAMPOLINE (t))
+ break;
+
/* Lookup the immediate parent of the callee, as that's where
we need to insert the trampoline. */
for (i = info; i->context != target_context; i = i->outer)
convert_call_expr (tree *tp, int *walk_subtrees, void *data)
{
struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
- struct nesting_info *info = wi->info;
+ struct nesting_info *const info = (struct nesting_info *) wi->info;
tree t = *tp, decl, target_context;
char save_static_chain_added;
int i;
break;
case OMP_PARALLEL:
+ case OMP_TASK:
save_static_chain_added = info->static_chain_added;
info->static_chain_added = 0;
- walk_body (convert_call_expr, info, &OMP_PARALLEL_BODY (t));
+ walk_body (convert_call_expr, info, &OMP_TASKREG_BODY (t));
for (i = 0; i < 2; i++)
{
tree c, decl;
continue;
decl = i ? get_chain_decl (info) : info->frame_decl;
/* Don't add CHAIN.* or FRAME.* twice. */
- for (c = OMP_PARALLEL_CLAUSES (t); c; c = OMP_CLAUSE_CHAIN (c))
+ for (c = OMP_TASKREG_CLAUSES (t); c; c = OMP_CLAUSE_CHAIN (c))
if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
|| OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED)
&& OMP_CLAUSE_DECL (c) == decl)
c = build_omp_clause (i ? OMP_CLAUSE_FIRSTPRIVATE
: OMP_CLAUSE_SHARED);
OMP_CLAUSE_DECL (c) = decl;
- OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (t);
- OMP_PARALLEL_CLAUSES (t) = c;
+ OMP_CLAUSE_CHAIN (c) = OMP_TASKREG_CLAUSES (t);
+ OMP_TASKREG_CLAUSES (t) = c;
}
}
info->static_chain_added |= save_static_chain_added;