marshalling to implement data sharing and copying clauses.
Contributed by Diego Novillo <dnovillo@redhat.com>
- Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
- Free Software Foundation, Inc.
+ Copyright (C) 2005-2013 Free Software Foundation, Inc.
This file is part of GCC.
#include "langhooks.h"
#include "diagnostic-core.h"
#include "tree-flow.h"
-#include "timevar.h"
#include "flags.h"
#include "function.h"
#include "expr.h"
struct omp_region *root_omp_region;
static bitmap task_shared_vars;
-static void scan_omp (gimple_seq, omp_context *);
+static void scan_omp (gimple_seq *, omp_context *);
static tree scan_omp_1_op (tree *, int *, void *);
#define WALK_SUBSTMTS \
return walk_tree (tp, scan_omp_1_op, &wi, NULL);
}
-static void lower_omp (gimple_seq, omp_context *);
+static void lower_omp (gimple_seq *, omp_context *);
static tree lookup_decl_in_outer_ctx (tree, omp_context *);
static tree maybe_lookup_decl_in_outer_ctx (tree, omp_context *);
switch (TREE_CODE (t))
{
case PLUS_EXPR:
- case POINTER_PLUS_EXPR:
loop->step = TREE_OPERAND (t, 1);
break;
+ case POINTER_PLUS_EXPR:
+ loop->step = fold_convert (ssizetype, TREE_OPERAND (t, 1));
+ break;
case MINUS_EXPR:
loop->step = TREE_OPERAND (t, 1);
loop->step = fold_build1_loc (loc,
if (collapse_count && *collapse_count == NULL)
{
- if ((i == 0 || count != NULL_TREE)
- && TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
- && TREE_CONSTANT (loop->n1)
- && TREE_CONSTANT (loop->n2)
- && TREE_CODE (loop->step) == INTEGER_CST)
+ t = fold_binary (loop->cond_code, boolean_type_node,
+ fold_convert (TREE_TYPE (loop->v), loop->n1),
+ fold_convert (TREE_TYPE (loop->v), loop->n2));
+ if (t && integer_zerop (t))
+ count = build_zero_cst (long_long_unsigned_type_node);
+ else if ((i == 0 || count != NULL_TREE)
+ && TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
+ && TREE_CONSTANT (loop->n1)
+ && TREE_CONSTANT (loop->n2)
+ && TREE_CODE (loop->step) == INTEGER_CST)
{
tree itype = TREE_TYPE (loop->v);
if (POINTER_TYPE_P (itype))
- itype
- = lang_hooks.types.type_for_size (TYPE_PRECISION (itype), 0);
+ itype = signed_type_for (itype);
t = build_int_cst (itype, (loop->cond_code == LT_EXPR ? -1 : 1));
t = fold_build2_loc (loc,
PLUS_EXPR, itype,
if (TREE_CODE (count) != INTEGER_CST)
count = NULL_TREE;
}
- else
+ else if (count && !integer_zerop (count))
count = NULL_TREE;
}
}
parallel+workshare call. WS_STMT is the workshare directive being
expanded. */
-static VEC(tree,gc) *
+static vec<tree, va_gc> *
get_ws_args_for (gimple ws_stmt)
{
tree t;
location_t loc = gimple_location (ws_stmt);
- VEC(tree,gc) *ws_args;
+ vec<tree, va_gc> *ws_args;
if (gimple_code (ws_stmt) == GIMPLE_OMP_FOR)
{
extract_omp_for_data (ws_stmt, &fd, NULL);
- ws_args = VEC_alloc (tree, gc, 3 + (fd.chunk_size != 0));
+ vec_alloc (ws_args, 3 + (fd.chunk_size != 0));
t = fold_convert_loc (loc, long_integer_type_node, fd.loop.n1);
- VEC_quick_push (tree, ws_args, t);
+ ws_args->quick_push (t);
t = fold_convert_loc (loc, long_integer_type_node, fd.loop.n2);
- VEC_quick_push (tree, ws_args, t);
+ ws_args->quick_push (t);
t = fold_convert_loc (loc, long_integer_type_node, fd.loop.step);
- VEC_quick_push (tree, ws_args, t);
+ ws_args->quick_push (t);
if (fd.chunk_size)
{
t = fold_convert_loc (loc, long_integer_type_node, fd.chunk_size);
- VEC_quick_push (tree, ws_args, t);
+ ws_args->quick_push (t);
}
return ws_args;
the exit of the sections region. */
basic_block bb = single_succ (gimple_bb (ws_stmt));
t = build_int_cst (unsigned_type_node, EDGE_COUNT (bb->succs) - 1);
- ws_args = VEC_alloc (tree, gc, 1);
- VEC_quick_push (tree, ws_args, t);
+ vec_alloc (ws_args, 1);
+ ws_args->quick_push (t);
return ws_args;
}
finalize_task_copyfn (gimple task_stmt)
{
struct function *child_cfun;
- tree child_fn, old_fn;
- gimple_seq seq, new_seq;
+ tree child_fn;
+ gimple_seq seq = NULL, new_seq;
gimple bind;
child_fn = gimple_omp_task_copy_fn (task_stmt);
/* Inform the callgraph about the new function. */
DECL_STRUCT_FUNCTION (child_fn)->curr_properties
- = cfun->curr_properties;
+ = cfun->curr_properties & ~PROP_loops;
- old_fn = current_function_decl;
push_cfun (child_cfun);
- current_function_decl = child_fn;
bind = gimplify_body (child_fn, false);
- seq = gimple_seq_alloc ();
gimple_seq_add_stmt (&seq, bind);
new_seq = maybe_catch_exception (seq);
if (new_seq != seq)
{
bind = gimple_build_bind (NULL, new_seq, NULL);
- seq = gimple_seq_alloc ();
+ seq = NULL;
gimple_seq_add_stmt (&seq, bind);
}
gimple_set_body (child_fn, seq);
pop_cfun ();
- current_function_decl = old_fn;
cgraph_add_new_function (child_fn, false);
}
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
&& OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
{
- scan_omp (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
- scan_omp (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
+ scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
+ scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
}
else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
&& OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
- scan_omp (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
+ scan_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
}
/* Create a new name for omp child function. Returns an identifier. */
gimple_omp_parallel_set_child_fn (stmt, ctx->cb.dst_fn);
scan_sharing_clauses (gimple_omp_parallel_clauses (stmt), ctx);
- scan_omp (gimple_omp_body (stmt), ctx);
+ scan_omp (gimple_omp_body_ptr (stmt), ctx);
if (TYPE_FIELDS (ctx->record_type) == NULL)
ctx->record_type = ctx->receiver_decl = NULL;
create_omp_child_function (ctx, true);
}
- scan_omp (gimple_omp_body (stmt), ctx);
+ scan_omp (gimple_omp_body_ptr (stmt), ctx);
if (TYPE_FIELDS (ctx->record_type) == NULL)
{
scan_sharing_clauses (gimple_omp_for_clauses (stmt), ctx);
- scan_omp (gimple_omp_for_pre_body (stmt), ctx);
+ scan_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
{
scan_omp_op (gimple_omp_for_index_ptr (stmt, i), ctx);
scan_omp_op (gimple_omp_for_final_ptr (stmt, i), ctx);
scan_omp_op (gimple_omp_for_incr_ptr (stmt, i), ctx);
}
- scan_omp (gimple_omp_body (stmt), ctx);
+ scan_omp (gimple_omp_body_ptr (stmt), ctx);
}
/* Scan an OpenMP sections directive. */
ctx = new_omp_context (stmt, outer_ctx);
scan_sharing_clauses (gimple_omp_sections_clauses (stmt), ctx);
- scan_omp (gimple_omp_body (stmt), ctx);
+ scan_omp (gimple_omp_body_ptr (stmt), ctx);
}
/* Scan an OpenMP single directive. */
TYPE_NAME (ctx->record_type) = name;
scan_sharing_clauses (gimple_omp_single_clauses (stmt), ctx);
- scan_omp (gimple_omp_body (stmt), ctx);
+ scan_omp (gimple_omp_body_ptr (stmt), ctx);
if (TYPE_FIELDS (ctx->record_type) == NULL)
ctx->record_type = NULL;
case GIMPLE_OMP_ORDERED:
case GIMPLE_OMP_CRITICAL:
ctx = new_omp_context (stmt, ctx);
- scan_omp (gimple_omp_body (stmt), ctx);
+ scan_omp (gimple_omp_body_ptr (stmt), ctx);
break;
case GIMPLE_BIND:
clauses found during the scan. */
static void
-scan_omp (gimple_seq body, omp_context *ctx)
+scan_omp (gimple_seq *body_p, omp_context *ctx)
{
location_t saved_location;
struct walk_stmt_info wi;
wi.want_locations = true;
saved_location = input_location;
- walk_gimple_seq (body, scan_omp_1_stmt, scan_omp_1_op, &wi);
+ walk_gimple_seq_mod (body_p, scan_omp_1_stmt, scan_omp_1_op, &wi);
input_location = saved_location;
}
\f
lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
omp_context *ctx)
{
- gimple_stmt_iterator diter;
tree c, dtor, copyin_seq, x, ptr;
bool copyin_by_ref = false;
bool lastprivate_firstprivate = false;
int pass;
- *dlist = gimple_seq_alloc ();
- diter = gsi_start (*dlist);
copyin_seq = NULL;
/* Do all the fixed sized types in the first pass, and the variable sized
dtor = x;
gimplify_stmt (&dtor, &tseq);
- gsi_insert_seq_before (&diter, tseq, GSI_SAME_STMT);
+ gimple_seq_add_seq (dlist, tseq);
}
break;
x = build_fold_addr_expr_loc (clause_loc, x);
SET_DECL_VALUE_EXPR (placeholder, x);
DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
- lower_omp (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
+ lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
gimple_seq_add_seq (ilist,
OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
{
- lower_omp (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
+ lower_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
gimple_seq_add_seq (stmt_list,
OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
}
ref = build_fold_addr_expr_loc (clause_loc, ref);
SET_DECL_VALUE_EXPR (placeholder, ref);
DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
- lower_omp (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
+ lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
gimple_seq_add_seq (&sub_seq, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
static void
expand_parallel_call (struct omp_region *region, basic_block bb,
- gimple entry_stmt, VEC(tree,gc) *ws_args)
+ gimple entry_stmt, vec<tree, va_gc> *ws_args)
{
tree t, t1, t2, val, cond, c, clauses;
gimple_stmt_iterator gsi;
enum built_in_function start_ix;
int start_ix2;
location_t clause_loc;
- VEC(tree,gc) *args;
+ vec<tree, va_gc> *args;
clauses = gimple_omp_parallel_clauses (entry_stmt);
if (gimple_in_ssa_p (cfun))
{
gimple phi = create_phi_node (tmp_join, bb);
- SSA_NAME_DEF_STMT (tmp_join) = phi;
add_phi_arg (phi, tmp_then, e_then, UNKNOWN_LOCATION);
add_phi_arg (phi, tmp_else, e_else, UNKNOWN_LOCATION);
}
t1 = build_fold_addr_expr (t);
t2 = build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt));
- args = VEC_alloc (tree, gc, 3 + VEC_length (tree, ws_args));
- VEC_quick_push (tree, args, t2);
- VEC_quick_push (tree, args, t1);
- VEC_quick_push (tree, args, val);
- VEC_splice (tree, args, ws_args);
+ vec_alloc (args, 3 + vec_safe_length (ws_args));
+ args->quick_push (t2);
+ args->quick_push (t1);
+ args->quick_push (val);
+ if (ws_args)
+ args->splice (*ws_args);
t = build_call_expr_loc_vec (UNKNOWN_LOCATION,
builtin_decl_explicit (start_ix), args);
/* Chain all the DECLs in LIST by their TREE_CHAIN fields. */
static tree
-vec2chain (VEC(tree,gc) *v)
+vec2chain (vec<tree, va_gc> *v)
{
tree chain = NULL_TREE, t;
unsigned ix;
- FOR_EACH_VEC_ELT_REVERSE (tree, v, ix, t)
+ FOR_EACH_VEC_SAFE_ELT_REVERSE (v, ix, t)
{
DECL_CHAIN (t) = chain;
chain = t;
}
}
+/* Callback for expand_omp_build_assign. Return non-NULL if *tp needs to be
+ regimplified. */
+
+static tree
+expand_omp_regimplify_p (tree *tp, int *walk_subtrees, void *)
+{
+ tree t = *tp;
+
+ /* Any variable with DECL_VALUE_EXPR needs to be regimplified. */
+ if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t))
+ return t;
+
+ if (TREE_CODE (t) == ADDR_EXPR)
+ recompute_tree_invariant_for_addr_expr (t);
+
+ *walk_subtrees = !TYPE_P (t) && !DECL_P (t);
+ return NULL_TREE;
+}
+
/* Expand the OpenMP parallel or task directive starting at REGION. */
static void
basic_block entry_bb, exit_bb, new_bb;
struct function *child_cfun;
tree child_fn, block, t;
- tree save_current;
gimple_stmt_iterator gsi;
gimple entry_stmt, stmt;
edge e;
- VEC(tree,gc) *ws_args;
+ vec<tree, va_gc> *ws_args;
entry_stmt = last_stmt (region->entry);
child_fn = gimple_omp_taskreg_child_fn (entry_stmt);
child_cfun = DECL_STRUCT_FUNCTION (child_fn);
- /* If this function has been already instrumented, make sure
- the child function isn't instrumented again. */
- child_cfun->after_tree_profile = cfun->after_tree_profile;
entry_bb = region->entry;
exit_bb = region->exit;
/* If we are in ssa form, we must load the value from the default
definition of the argument. That should not be defined now,
since the argument is not used uninitialized. */
- gcc_assert (gimple_default_def (cfun, arg) == NULL);
+ gcc_assert (ssa_default_def (cfun, arg) == NULL);
narg = make_ssa_name (arg, gimple_build_nop ());
- set_default_def (arg, narg);
+ set_ssa_default_def (cfun, arg, narg);
/* ?? Is setting the subcode really necessary ?? */
gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (narg));
gimple_assign_set_rhs1 (parcopy_stmt, narg);
&& !DECL_EXTERNAL (t))
varpool_finalize_decl (t);
DECL_SAVED_TREE (child_fn) = NULL;
- gimple_set_body (child_fn, bb_seq (single_succ (entry_bb)));
+ /* We'll create a CFG for child_fn, so no gimple body is needed. */
+ gimple_set_body (child_fn, NULL);
TREE_USED (block) = 1;
/* Reset DECL_CONTEXT on function arguments. */
if (gimple_in_ssa_p (cfun))
{
- push_cfun (child_cfun);
init_tree_ssa (child_cfun);
- init_ssa_operands ();
- cfun->gimple_df->in_ssa_p = true;
- pop_cfun ();
+ init_ssa_operands (child_cfun);
+ child_cfun->gimple_df->in_ssa_p = true;
block = NULL_TREE;
}
else
single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
/* Remove non-local VAR_DECLs from child_cfun->local_decls list. */
- num = VEC_length (tree, child_cfun->local_decls);
+ num = vec_safe_length (child_cfun->local_decls);
for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++)
{
- t = VEC_index (tree, child_cfun->local_decls, srcidx);
+ t = (*child_cfun->local_decls)[srcidx];
if (DECL_CONTEXT (t) == cfun->decl)
continue;
if (srcidx != dstidx)
- VEC_replace (tree, child_cfun->local_decls, dstidx, t);
+ (*child_cfun->local_decls)[dstidx] = t;
dstidx++;
}
if (dstidx != num)
- VEC_truncate (tree, child_cfun->local_decls, dstidx);
+ vec_safe_truncate (child_cfun->local_decls, dstidx);
/* Inform the callgraph about the new function. */
DECL_STRUCT_FUNCTION (child_fn)->curr_properties
- = cfun->curr_properties;
+ = cfun->curr_properties & ~PROP_loops;
cgraph_add_new_function (child_fn, true);
/* Fix the callgraph edges for child_cfun. Those for cfun will be
fixed in a following pass. */
push_cfun (child_cfun);
- save_current = current_function_decl;
- current_function_decl = child_fn;
if (optimize)
optimize_omp_library_calls (entry_stmt);
rebuild_cgraph_edges ();
}
if (gimple_in_ssa_p (cfun))
update_ssa (TODO_update_ssa);
- current_function_decl = save_current;
pop_cfun ();
}
expand_parallel_call (region, new_bb, entry_stmt, ws_args);
else
expand_task_call (new_bb, entry_stmt);
- update_ssa (TODO_update_ssa_only_virtuals);
+ if (gimple_in_ssa_p (cfun))
+ update_ssa (TODO_update_ssa_only_virtuals);
}
we generate pseudocode
+ if (__builtin_expect (N32 cond3 N31, 0)) goto Z0;
if (cond3 is <)
adj = STEP3 - 1;
else
adj = STEP3 + 1;
count3 = (adj + N32 - N31) / STEP3;
+ if (__builtin_expect (N22 cond2 N21, 0)) goto Z0;
if (cond2 is <)
adj = STEP2 - 1;
else
adj = STEP2 + 1;
count2 = (adj + N22 - N21) / STEP2;
+ if (__builtin_expect (N12 cond1 N11, 0)) goto Z0;
if (cond1 is <)
adj = STEP1 - 1;
else
adj = STEP1 + 1;
count1 = (adj + N12 - N11) / STEP1;
count = count1 * count2 * count3;
+ goto Z1;
+ Z0:
+ count = 0;
+ Z1:
more = GOMP_loop_foo_start (0, count, 1, CHUNK, &istart0, &iend0);
if (more) goto L0; else goto L3;
L0:
iend0 = create_tmp_var (fd->iter_type, ".iend0");
TREE_ADDRESSABLE (istart0) = 1;
TREE_ADDRESSABLE (iend0) = 1;
- if (gimple_in_ssa_p (cfun))
- {
- add_referenced_var (istart0);
- add_referenced_var (iend0);
- }
/* See if we need to bias by LLONG_MIN. */
if (fd->iter_type == long_long_unsigned_type_node
gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
if (fd->collapse > 1)
{
+ basic_block zero_iter_bb = NULL;
+ int first_zero_iter = -1;
+
/* collapsed loops need work for expansion in SSA form. */
gcc_assert (!gimple_in_ssa_p (cfun));
counts = (tree *) alloca (fd->collapse * sizeof (tree));
{
tree itype = TREE_TYPE (fd->loops[i].v);
+ if (SSA_VAR_P (fd->loop.n2)
+ && ((t = fold_binary (fd->loops[i].cond_code, boolean_type_node,
+ fold_convert (itype, fd->loops[i].n1),
+ fold_convert (itype, fd->loops[i].n2)))
+ == NULL_TREE || !integer_onep (t)))
+ {
+ tree n1, n2;
+ n1 = fold_convert (itype, unshare_expr (fd->loops[i].n1));
+ n1 = force_gimple_operand_gsi (&gsi, n1, true, NULL_TREE,
+ true, GSI_SAME_STMT);
+ n2 = fold_convert (itype, unshare_expr (fd->loops[i].n2));
+ n2 = force_gimple_operand_gsi (&gsi, n2, true, NULL_TREE,
+ true, GSI_SAME_STMT);
+ stmt = gimple_build_cond (fd->loops[i].cond_code, n1, n2,
+ NULL_TREE, NULL_TREE);
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+ if (walk_tree (gimple_cond_lhs_ptr (stmt),
+ expand_omp_regimplify_p, NULL, NULL)
+ || walk_tree (gimple_cond_rhs_ptr (stmt),
+ expand_omp_regimplify_p, NULL, NULL))
+ {
+ gsi = gsi_for_stmt (stmt);
+ gimple_regimplify_operands (stmt, &gsi);
+ }
+ e = split_block (entry_bb, stmt);
+ if (zero_iter_bb == NULL)
+ {
+ first_zero_iter = i;
+ zero_iter_bb = create_empty_bb (entry_bb);
+ if (current_loops)
+ add_bb_to_loop (zero_iter_bb, entry_bb->loop_father);
+ gsi = gsi_after_labels (zero_iter_bb);
+ stmt = gimple_build_assign (fd->loop.n2,
+ build_zero_cst (type));
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+ set_immediate_dominator (CDI_DOMINATORS, zero_iter_bb,
+ entry_bb);
+ }
+ ne = make_edge (entry_bb, zero_iter_bb, EDGE_FALSE_VALUE);
+ ne->probability = REG_BR_PROB_BASE / 2000 - 1;
+ e->flags = EDGE_TRUE_VALUE;
+ e->probability = REG_BR_PROB_BASE - ne->probability;
+ entry_bb = e->dest;
+ gsi = gsi_last_bb (entry_bb);
+ }
if (POINTER_TYPE_P (itype))
- itype = lang_hooks.types.type_for_size (TYPE_PRECISION (itype), 0);
+ itype = signed_type_for (itype);
t = build_int_cst (itype, (fd->loops[i].cond_code == LT_EXPR
? -1 : 1));
t = fold_build2 (PLUS_EXPR, itype,
counts[i] = t;
else
{
- counts[i] = create_tmp_var (type, ".count");
+ counts[i] = create_tmp_reg (type, ".count");
t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
true, GSI_SAME_STMT);
stmt = gimple_build_assign (counts[i], t);
gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
}
}
+ if (zero_iter_bb)
+ {
+ /* Some counts[i] vars might be uninitialized if
+ some loop has zero iterations. But the body shouldn't
+ be executed in that case, so just avoid uninit warnings. */
+ for (i = first_zero_iter; i < fd->collapse; i++)
+ if (SSA_VAR_P (counts[i]))
+ TREE_NO_WARNING (counts[i]) = 1;
+ gsi_prev (&gsi);
+ e = split_block (entry_bb, gsi_stmt (gsi));
+ entry_bb = e->dest;
+ make_edge (zero_iter_bb, entry_bb, EDGE_FALLTHRU);
+ gsi = gsi_last_bb (entry_bb);
+ set_immediate_dominator (CDI_DOMINATORS, entry_bb,
+ get_immediate_dominator (CDI_DOMINATORS,
+ zero_iter_bb));
+ }
}
if (in_combined_parallel)
{
&& TYPE_PRECISION (type) != TYPE_PRECISION (fd->iter_type))
{
/* Avoid casting pointers to integer of a different size. */
- tree itype
- = lang_hooks.types.type_for_size (TYPE_PRECISION (type), 0);
+ tree itype = signed_type_for (type);
t1 = fold_convert (fd->iter_type, fold_convert (itype, fd->loop.n2));
t0 = fold_convert (fd->iter_type, fold_convert (itype, fd->loop.n1));
}
if (bias)
t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
if (POINTER_TYPE_P (type))
- t = fold_convert (lang_hooks.types.type_for_size (TYPE_PRECISION (type),
- 0), t);
+ t = fold_convert (signed_type_for (type), t);
t = fold_convert (type, t);
- t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
- false, GSI_CONTINUE_LINKING);
+ t = force_gimple_operand_gsi (&gsi, t,
+ DECL_P (fd->loop.v)
+ && TREE_ADDRESSABLE (fd->loop.v),
+ NULL_TREE, false, GSI_CONTINUE_LINKING);
stmt = gimple_build_assign (fd->loop.v, t);
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
if (bias)
t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
if (POINTER_TYPE_P (type))
- t = fold_convert (lang_hooks.types.type_for_size (TYPE_PRECISION (type),
- 0), t);
+ t = fold_convert (signed_type_for (type), t);
t = fold_convert (type, t);
iend = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
false, GSI_CONTINUE_LINKING);
if (fd->collapse > 1)
{
- tree tem = create_tmp_var (type, ".tem");
-
+ tree tem = create_tmp_reg (type, ".tem");
stmt = gimple_build_assign (tem, fd->loop.v);
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
for (i = fd->collapse - 1; i >= 0; i--)
tree vtype = TREE_TYPE (fd->loops[i].v), itype;
itype = vtype;
if (POINTER_TYPE_P (vtype))
- itype = lang_hooks.types.type_for_size (TYPE_PRECISION (vtype), 0);
+ itype = signed_type_for (vtype);
t = fold_build2 (TRUNC_MOD_EXPR, type, tem, counts[i]);
t = fold_convert (itype, t);
t = fold_build2 (MULT_EXPR, itype, t,
t = fold_build_pointer_plus (fd->loops[i].n1, t);
else
t = fold_build2 (PLUS_EXPR, itype, fd->loops[i].n1, t);
- t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
- false, GSI_CONTINUE_LINKING);
+ t = force_gimple_operand_gsi (&gsi, t,
+ DECL_P (fd->loops[i].v)
+ && TREE_ADDRESSABLE (fd->loops[i].v),
+ NULL_TREE, false,
+ GSI_CONTINUE_LINKING);
stmt = gimple_build_assign (fd->loops[i].v, t);
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
if (i != 0)
t = fold_build_pointer_plus (vmain, fd->loop.step);
else
t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
- t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
- true, GSI_SAME_STMT);
+ t = force_gimple_operand_gsi (&gsi, t,
+ DECL_P (vback) && TREE_ADDRESSABLE (vback),
+ NULL_TREE, true, GSI_SAME_STMT);
stmt = gimple_build_assign (vback, t);
gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
- t = build2 (fd->loop.cond_code, boolean_type_node, vback, iend);
+ t = build2 (fd->loop.cond_code, boolean_type_node,
+ DECL_P (vback) && TREE_ADDRESSABLE (vback) ? t : vback,
+ iend);
stmt = gimple_build_cond_empty (t);
gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
e->probability = REG_BR_PROB_BASE / 8;
t = fd->loops[i + 1].n1;
- t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
- false, GSI_CONTINUE_LINKING);
+ t = force_gimple_operand_gsi (&gsi, t,
+ DECL_P (fd->loops[i + 1].v)
+ && TREE_ADDRESSABLE
+ (fd->loops[i + 1].v),
+ NULL_TREE, false,
+ GSI_CONTINUE_LINKING);
stmt = gimple_build_assign (fd->loops[i + 1].v, t);
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
}
else
t = fold_build2 (PLUS_EXPR, vtype, fd->loops[i].v,
fd->loops[i].step);
- t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
- false, GSI_CONTINUE_LINKING);
+ t = force_gimple_operand_gsi (&gsi, t,
+ DECL_P (fd->loops[i].v)
+ && TREE_ADDRESSABLE (fd->loops[i].v),
+ NULL_TREE, false,
+ GSI_CONTINUE_LINKING);
stmt = gimple_build_assign (fd->loops[i].v, t);
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
t = fd->loops[i].n2;
t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
false, GSI_CONTINUE_LINKING);
+ tree v = fd->loops[i].v;
+ if (DECL_P (v) && TREE_ADDRESSABLE (v))
+ v = force_gimple_operand_gsi (&gsi, v, true, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
t = fold_build2 (fd->loops[i].cond_code, boolean_type_node,
- fd->loops[i].v, t);
+ v, t);
stmt = gimple_build_cond_empty (t);
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
e = make_edge (bb, l1_bb, EDGE_TRUE_VALUE);
where COND is "<" or ">", we generate pseudocode
+ if ((__typeof (V)) -1 > 0 && N2 cond N1) goto L2;
if (cond is <)
adj = STEP - 1;
else
itype = type = TREE_TYPE (fd->loop.v);
if (POINTER_TYPE_P (type))
- itype = lang_hooks.types.type_for_size (TYPE_PRECISION (type), 0);
+ itype = signed_type_for (type);
entry_bb = region->entry;
cont_bb = region->cont;
gsi = gsi_last_bb (entry_bb);
gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
+ t = fold_binary (fd->loop.cond_code, boolean_type_node,
+ fold_convert (type, fd->loop.n1),
+ fold_convert (type, fd->loop.n2));
+ if (TYPE_UNSIGNED (type)
+ && (t == NULL_TREE || !integer_onep (t)))
+ {
+ tree n1, n2;
+ n1 = fold_convert (type, unshare_expr (fd->loop.n1));
+ n1 = force_gimple_operand_gsi (&gsi, n1, true, NULL_TREE,
+ true, GSI_SAME_STMT);
+ n2 = fold_convert (type, unshare_expr (fd->loop.n2));
+ n2 = force_gimple_operand_gsi (&gsi, n2, true, NULL_TREE,
+ true, GSI_SAME_STMT);
+ stmt = gimple_build_cond (fd->loop.cond_code, n1, n2,
+ NULL_TREE, NULL_TREE);
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+ if (walk_tree (gimple_cond_lhs_ptr (stmt),
+ expand_omp_regimplify_p, NULL, NULL)
+ || walk_tree (gimple_cond_rhs_ptr (stmt),
+ expand_omp_regimplify_p, NULL, NULL))
+ {
+ gsi = gsi_for_stmt (stmt);
+ gimple_regimplify_operands (stmt, &gsi);
+ }
+ ep = split_block (entry_bb, stmt);
+ ep->flags = EDGE_TRUE_VALUE;
+ entry_bb = ep->dest;
+ ep->probability = REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 2000 - 1);
+ ep = make_edge (ep->src, fin_bb, EDGE_FALSE_VALUE);
+ ep->probability = REG_BR_PROB_BASE / 2000 - 1;
+ if (gimple_in_ssa_p (cfun))
+ {
+ int dest_idx = find_edge (entry_bb, fin_bb)->dest_idx;
+ for (gsi = gsi_start_phis (fin_bb);
+ !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple phi = gsi_stmt (gsi);
+ add_phi_arg (phi, gimple_phi_arg_def (phi, dest_idx),
+ ep, UNKNOWN_LOCATION);
+ }
+ }
+ gsi = gsi_last_bb (entry_bb);
+ }
+
t = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS), 0);
t = fold_convert (itype, t);
nthreads = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
t = fold_convert (itype, t);
n = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
- q = create_tmp_var (itype, "q");
+ q = create_tmp_reg (itype, "q");
t = fold_build2 (TRUNC_DIV_EXPR, itype, n, nthreads);
t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, true, GSI_SAME_STMT);
gsi_insert_before (&gsi, gimple_build_assign (q, t), GSI_SAME_STMT);
- tt = create_tmp_var (itype, "tt");
+ tt = create_tmp_reg (itype, "tt");
t = fold_build2 (TRUNC_MOD_EXPR, itype, n, nthreads);
t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, true, GSI_SAME_STMT);
gsi_insert_before (&gsi, gimple_build_assign (tt, t), GSI_SAME_STMT);
t = fold_build_pointer_plus (fd->loop.n1, t);
else
t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
- t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
- false, GSI_CONTINUE_LINKING);
+ t = force_gimple_operand_gsi (&gsi, t,
+ DECL_P (fd->loop.v)
+ && TREE_ADDRESSABLE (fd->loop.v),
+ NULL_TREE, false, GSI_CONTINUE_LINKING);
stmt = gimple_build_assign (fd->loop.v, t);
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
t = fold_build_pointer_plus (vmain, fd->loop.step);
else
t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
- t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
- true, GSI_SAME_STMT);
+ t = force_gimple_operand_gsi (&gsi, t,
+ DECL_P (vback) && TREE_ADDRESSABLE (vback),
+ NULL_TREE, true, GSI_SAME_STMT);
stmt = gimple_build_assign (vback, t);
gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
- t = build2 (fd->loop.cond_code, boolean_type_node, vback, e);
+ t = build2 (fd->loop.cond_code, boolean_type_node,
+ DECL_P (vback) && TREE_ADDRESSABLE (vback) ? t : vback, e);
gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
/* Remove the GIMPLE_OMP_CONTINUE statement. */
where COND is "<" or ">", we generate pseudocode
+ if ((__typeof (V)) -1 > 0 && N2 cond N1) goto L2;
if (cond is <)
adj = STEP - 1;
else
itype = type = TREE_TYPE (fd->loop.v);
if (POINTER_TYPE_P (type))
- itype = lang_hooks.types.type_for_size (TYPE_PRECISION (type), 0);
+ itype = signed_type_for (type);
entry_bb = region->entry;
se = split_block (entry_bb, last_stmt (entry_bb));
si = gsi_last_bb (entry_bb);
gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_FOR);
+ t = fold_binary (fd->loop.cond_code, boolean_type_node,
+ fold_convert (type, fd->loop.n1),
+ fold_convert (type, fd->loop.n2));
+ if (TYPE_UNSIGNED (type)
+ && (t == NULL_TREE || !integer_onep (t)))
+ {
+ tree n1, n2;
+ n1 = fold_convert (type, unshare_expr (fd->loop.n1));
+ n1 = force_gimple_operand_gsi (&si, n1, true, NULL_TREE,
+ true, GSI_SAME_STMT);
+ n2 = fold_convert (type, unshare_expr (fd->loop.n2));
+ n2 = force_gimple_operand_gsi (&si, n2, true, NULL_TREE,
+ true, GSI_SAME_STMT);
+ stmt = gimple_build_cond (fd->loop.cond_code, n1, n2,
+ NULL_TREE, NULL_TREE);
+ gsi_insert_before (&si, stmt, GSI_SAME_STMT);
+ if (walk_tree (gimple_cond_lhs_ptr (stmt),
+ expand_omp_regimplify_p, NULL, NULL)
+ || walk_tree (gimple_cond_rhs_ptr (stmt),
+ expand_omp_regimplify_p, NULL, NULL))
+ {
+ si = gsi_for_stmt (stmt);
+ gimple_regimplify_operands (stmt, &si);
+ }
+ se = split_block (entry_bb, stmt);
+ se->flags = EDGE_TRUE_VALUE;
+ entry_bb = se->dest;
+ se->probability = REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 2000 - 1);
+ se = make_edge (se->src, fin_bb, EDGE_FALSE_VALUE);
+ se->probability = REG_BR_PROB_BASE / 2000 - 1;
+ if (gimple_in_ssa_p (cfun))
+ {
+ int dest_idx = find_edge (entry_bb, fin_bb)->dest_idx;
+ for (si = gsi_start_phis (fin_bb);
+ !gsi_end_p (si); gsi_next (&si))
+ {
+ gimple phi = gsi_stmt (si);
+ add_phi_arg (phi, gimple_phi_arg_def (phi, dest_idx),
+ se, UNKNOWN_LOCATION);
+ }
+ }
+ si = gsi_last_bb (entry_bb);
+ }
+
t = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS), 0);
t = fold_convert (itype, t);
nthreads = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
n = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
true, GSI_SAME_STMT);
- trip_var = create_tmp_var (itype, ".trip");
+ trip_var = create_tmp_reg (itype, ".trip");
if (gimple_in_ssa_p (cfun))
{
- add_referenced_var (trip_var);
trip_init = make_ssa_name (trip_var, NULL);
trip_main = make_ssa_name (trip_var, NULL);
trip_back = make_ssa_name (trip_var, NULL);
t = fold_build_pointer_plus (fd->loop.n1, t);
else
t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
- t = force_gimple_operand_gsi (&si, t, false, NULL_TREE,
- false, GSI_CONTINUE_LINKING);
+ t = force_gimple_operand_gsi (&si, t,
+ DECL_P (fd->loop.v)
+ && TREE_ADDRESSABLE (fd->loop.v),
+ NULL_TREE, false, GSI_CONTINUE_LINKING);
stmt = gimple_build_assign (fd->loop.v, t);
gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
t = fold_build_pointer_plus (v_main, fd->loop.step);
else
t = fold_build2 (PLUS_EXPR, type, v_main, fd->loop.step);
+ if (DECL_P (v_back) && TREE_ADDRESSABLE (v_back))
+ t = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
+ true, GSI_SAME_STMT);
stmt = gimple_build_assign (v_back, t);
gsi_insert_before (&si, stmt, GSI_SAME_STMT);
- t = build2 (fd->loop.cond_code, boolean_type_node, v_back, e);
+ t = build2 (fd->loop.cond_code, boolean_type_node,
+ DECL_P (v_back) && TREE_ADDRESSABLE (v_back)
+ ? t : v_back, e);
gsi_insert_before (&si, gimple_build_cond_empty (t), GSI_SAME_STMT);
/* Remove GIMPLE_OMP_CONTINUE. */
gimple_stmt_iterator psi;
gimple phi;
edge re, ene;
- edge_var_map_vector head;
+ edge_var_map_vector *head;
edge_var_map *vm;
size_t i;
ene = single_succ_edge (entry_bb);
psi = gsi_start_phis (fin_bb);
- for (i = 0; !gsi_end_p (psi) && VEC_iterate (edge_var_map, head, i, vm);
+ for (i = 0; !gsi_end_p (psi) && head->iterate (i, &vm);
gsi_next (&psi), ++i)
{
gimple nphi;
t = gimple_phi_result (phi);
gcc_assert (t == redirect_edge_var_map_result (vm));
nphi = create_phi_node (t, iter_part_bb);
- SSA_NAME_DEF_STMT (t) = nphi;
t = PHI_ARG_DEF_FROM_EDGE (phi, se);
locus = gimple_phi_arg_location_from_edge (phi, se);
locus = redirect_edge_var_map_location (vm);
add_phi_arg (nphi, redirect_edge_var_map_def (vm), re, locus);
}
- gcc_assert (!gsi_end_p (psi) && i == VEC_length (edge_var_map, head));
+ gcc_assert (!gsi_end_p (psi) && i == head->length ());
redirect_edge_var_map_clear (re);
while (1)
{
/* Make phi node for trip. */
phi = create_phi_node (trip_main, iter_part_bb);
- SSA_NAME_DEF_STMT (trip_main) = phi;
add_phi_arg (phi, trip_back, single_succ_edge (trip_update_bb),
UNKNOWN_LOCATION);
add_phi_arg (phi, trip_init, single_succ_edge (entry_bb),
(enum built_in_function) next_ix);
}
- update_ssa (TODO_update_ssa_only_virtuals);
+ if (gimple_in_ssa_p (cfun))
+ update_ssa (TODO_update_ssa_only_virtuals);
}
expand_omp_sections (struct omp_region *region)
{
tree t, u, vin = NULL, vmain, vnext, l2;
- VEC (tree,heap) *label_vec;
+ vec<tree> label_vec;
unsigned len;
basic_block entry_bb, l0_bb, l1_bb, l2_bb, default_bb;
gimple_stmt_iterator si, switch_si;
and a default case to abort if something goes wrong. */
len = EDGE_COUNT (l0_bb->succs);
- /* Use VEC_quick_push on label_vec throughout, since we know the size
+ /* Use vec::quick_push on label_vec throughout, since we know the size
in advance. */
- label_vec = VEC_alloc (tree, heap, len);
+ label_vec.create (len);
/* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
GIMPLE_OMP_SECTIONS statement. */
}
t = build_case_label (build_int_cst (unsigned_type_node, 0), NULL, l2);
- VEC_quick_push (tree, label_vec, t);
+ label_vec.quick_push (t);
i = 1;
/* Convert each GIMPLE_OMP_SECTION into a CASE_LABEL_EXPR. */
t = gimple_block_label (s_entry_bb);
u = build_int_cst (unsigned_type_node, casei);
u = build_case_label (u, NULL, t);
- VEC_quick_push (tree, label_vec, u);
+ label_vec.quick_push (u);
si = gsi_last_bb (s_entry_bb);
gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SECTION);
u = build_case_label (NULL, NULL, t);
make_edge (l0_bb, default_bb, 0);
- stmt = gimple_build_switch_vec (vmain, u, label_vec);
+ stmt = gimple_build_switch (vmain, u, label_vec);
gsi_insert_after (&switch_si, stmt, GSI_SAME_STMT);
gsi_remove (&switch_si, true);
- VEC_free (tree, heap, label_vec);
+ label_vec.release ();
si = gsi_start_bb (default_bb);
stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
{
tree iaddr_val;
- iaddr = create_tmp_var (build_pointer_type_for_mode (itype, ptr_mode,
+ iaddr = create_tmp_reg (build_pointer_type_for_mode (itype, ptr_mode,
true), NULL);
iaddr_val
= force_gimple_operand_gsi (&si,
gsi_insert_before (&si, stmt, GSI_SAME_STMT);
loadedi = create_tmp_var (itype, NULL);
if (gimple_in_ssa_p (cfun))
- {
- add_referenced_var (iaddr);
- add_referenced_var (loadedi);
- loadedi = make_ssa_name (loadedi, NULL);
- }
+ loadedi = make_ssa_name (loadedi, NULL);
}
else
{
{
gcc_assert (gimple_seq_empty_p (phi_nodes (loop_header)));
phi = create_phi_node (loadedi, loop_header);
- SSA_NAME_DEF_STMT (loadedi) = phi;
SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, single_succ_edge (load_bb)),
initial);
}
else
{
old_vali = create_tmp_var (TREE_TYPE (loadedi), NULL);
- if (gimple_in_ssa_p (cfun))
- add_referenced_var (old_vali);
stmt = gimple_build_assign (old_vali, loadedi);
gsi_insert_before (&si, stmt, GSI_SAME_STMT);
{
GIMPLE_PASS,
"ompexp", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
gate_expand_omp, /* gate */
execute_expand_omp, /* execute */
NULL, /* sub */
{
tree block, control;
gimple_stmt_iterator tgsi;
- unsigned i, len;
gimple stmt, new_stmt, bind, t;
- gimple_seq ilist, dlist, olist, new_body, body;
+ gimple_seq ilist, dlist, olist, new_body;
struct gimplify_ctx gctx;
stmt = gsi_stmt (*gsi_p);
lower_rec_input_clauses (gimple_omp_sections_clauses (stmt),
&ilist, &dlist, ctx);
- tgsi = gsi_start (gimple_omp_body (stmt));
- for (len = 0; !gsi_end_p (tgsi); len++, gsi_next (&tgsi))
- continue;
-
- tgsi = gsi_start (gimple_omp_body (stmt));
- body = NULL;
- for (i = 0; i < len; i++, gsi_next (&tgsi))
+ new_body = gimple_omp_body (stmt);
+ gimple_omp_set_body (stmt, NULL);
+ tgsi = gsi_start (new_body);
+ for (; !gsi_end_p (tgsi); gsi_next (&tgsi))
{
omp_context *sctx;
gimple sec_start;
sctx = maybe_lookup_ctx (sec_start);
gcc_assert (sctx);
- gimple_seq_add_stmt (&body, sec_start);
-
- lower_omp (gimple_omp_body (sec_start), sctx);
- gimple_seq_add_seq (&body, gimple_omp_body (sec_start));
+ lower_omp (gimple_omp_body_ptr (sec_start), sctx);
+ gsi_insert_seq_after (&tgsi, gimple_omp_body (sec_start),
+ GSI_CONTINUE_LINKING);
gimple_omp_set_body (sec_start, NULL);
- if (i == len - 1)
+ if (gsi_one_before_end_p (tgsi))
{
gimple_seq l = NULL;
lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt), NULL,
&l, ctx);
- gimple_seq_add_seq (&body, l);
+ gsi_insert_seq_after (&tgsi, l, GSI_CONTINUE_LINKING);
gimple_omp_section_set_last (sec_start);
}
- gimple_seq_add_stmt (&body, gimple_build_omp_return (false));
+ gsi_insert_after (&tgsi, gimple_build_omp_return (false),
+ GSI_CONTINUE_LINKING);
}
block = make_node (BLOCK);
- bind = gimple_build_bind (NULL, body, block);
+ bind = gimple_build_bind (NULL, new_body, block);
olist = NULL;
lower_reduction_clauses (gimple_omp_sections_clauses (stmt), &olist, ctx);
block = make_node (BLOCK);
new_stmt = gimple_build_bind (NULL, NULL, block);
+ gsi_replace (gsi_p, new_stmt, true);
pop_gimplify_context (new_stmt);
gimple_bind_append_vars (new_stmt, ctx->block_vars);
gimple_seq_add_stmt (&new_body, t);
gimple_bind_set_body (new_stmt, new_body);
- gimple_omp_set_body (stmt, NULL);
-
- gsi_replace (gsi_p, new_stmt, true);
}
push_gimplify_context (&gctx);
+ block = make_node (BLOCK);
+ bind = gimple_build_bind (NULL, NULL, block);
+ gsi_replace (gsi_p, bind, true);
bind_body = NULL;
+ dlist = NULL;
lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt),
&bind_body, &dlist, ctx);
- lower_omp (gimple_omp_body (single_stmt), ctx);
+ lower_omp (gimple_omp_body_ptr (single_stmt), ctx);
gimple_seq_add_stmt (&bind_body, single_stmt);
(!!find_omp_clause (gimple_omp_single_clauses (single_stmt),
OMP_CLAUSE_NOWAIT));
gimple_seq_add_stmt (&bind_body, t);
-
- block = make_node (BLOCK);
- bind = gimple_build_bind (NULL, bind_body, block);
+ gimple_bind_set_body (bind, bind_body);
pop_gimplify_context (bind);
gimple_bind_append_vars (bind, ctx->block_vars);
BLOCK_VARS (block) = ctx->block_vars;
- gsi_replace (gsi_p, bind, true);
if (BLOCK_VARS (block))
TREE_USED (block) = 1;
}
push_gimplify_context (&gctx);
block = make_node (BLOCK);
- bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt),
- block);
+ bind = gimple_build_bind (NULL, NULL, block);
+ gsi_replace (gsi_p, bind, true);
+ gimple_bind_add_stmt (bind, stmt);
bfn_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
x = build_call_expr_loc (loc, bfn_decl, 0);
gimplify_and_add (x, &tseq);
gimple_bind_add_seq (bind, tseq);
- lower_omp (gimple_omp_body (stmt), ctx);
+ lower_omp (gimple_omp_body_ptr (stmt), ctx);
gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
gimple_bind_add_seq (bind, gimple_omp_body (stmt));
gimple_omp_set_body (stmt, NULL);
gimple_bind_append_vars (bind, ctx->block_vars);
BLOCK_VARS (block) = ctx->block_vars;
- gsi_replace (gsi_p, bind, true);
}
push_gimplify_context (&gctx);
block = make_node (BLOCK);
- bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt),
- block);
+ bind = gimple_build_bind (NULL, NULL, block);
+ gsi_replace (gsi_p, bind, true);
+ gimple_bind_add_stmt (bind, stmt);
x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_START),
0);
gimple_bind_add_stmt (bind, x);
- lower_omp (gimple_omp_body (stmt), ctx);
+ lower_omp (gimple_omp_body_ptr (stmt), ctx);
gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
gimple_bind_add_seq (bind, gimple_omp_body (stmt));
gimple_omp_set_body (stmt, NULL);
gimple_bind_append_vars (bind, ctx->block_vars);
BLOCK_VARS (block) = gimple_bind_vars (bind);
- gsi_replace (gsi_p, bind, true);
}
push_gimplify_context (&gctx);
block = make_node (BLOCK);
- bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt), block);
+ bind = gimple_build_bind (NULL, NULL, block);
+ gsi_replace (gsi_p, bind, true);
+ gimple_bind_add_stmt (bind, stmt);
tbody = gimple_bind_body (bind);
gimplify_and_add (lock, &tbody);
gimple_bind_set_body (bind, tbody);
- lower_omp (gimple_omp_body (stmt), ctx);
+ lower_omp (gimple_omp_body_ptr (stmt), ctx);
gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
gimple_bind_add_seq (bind, gimple_omp_body (stmt));
gimple_omp_set_body (stmt, NULL);
pop_gimplify_context (bind);
gimple_bind_append_vars (bind, ctx->block_vars);
BLOCK_VARS (block) = gimple_bind_vars (bind);
- gsi_replace (gsi_p, bind, true);
}
push_gimplify_context (&gctx);
- lower_omp (gimple_omp_for_pre_body (stmt), ctx);
- lower_omp (gimple_omp_body (stmt), ctx);
+ lower_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
+ lower_omp (gimple_omp_body_ptr (stmt), ctx);
block = make_node (BLOCK);
new_stmt = gimple_build_bind (NULL, NULL, block);
+ /* Replace at gsi right away, so that 'stmt' is no member
+ of a sequence anymore as we're going to add to to a different
+ one below. */
+ gsi_replace (gsi_p, new_stmt, true);
/* Move declaration of temporaries in the loop body before we make
it go away. */
gimple_bind_set_body (new_stmt, body);
gimple_omp_set_body (stmt, NULL);
gimple_omp_for_set_pre_body (stmt, NULL);
- gsi_replace (gsi_p, new_stmt, true);
}
/* Callback for walk_stmts. Check if the current statement only contains
/* Populate the function. */
push_gimplify_context (&gctx);
- current_function_decl = child_fn;
+ push_cfun (child_cfun);
bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
TREE_SIDE_EFFECTS (bind) = 1;
else
tcctx.cb.decl_map = NULL;
- push_cfun (child_cfun);
-
arg = DECL_ARGUMENTS (child_fn);
TREE_TYPE (arg) = build_pointer_type (record_type);
sarg = DECL_CHAIN (arg);
pop_gimplify_context (NULL);
BIND_EXPR_BODY (bind) = list;
pop_cfun ();
- current_function_decl = ctx->cb.src_fn;
}
/* Lower the OpenMP parallel or task directive in the current statement
par_olist = NULL;
par_ilist = NULL;
lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx);
- lower_omp (par_body, ctx);
+ lower_omp (&par_body, ctx);
if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL)
lower_reduction_clauses (clauses, &par_olist, ctx);
gimple_omp_set_body (stmt, new_body);
bind = gimple_build_bind (NULL, NULL, gimple_bind_block (par_bind));
- gimple_bind_add_stmt (bind, stmt);
- if (ilist || olist)
- {
- gimple_seq_add_stmt (&ilist, bind);
- gimple_seq_add_seq (&ilist, olist);
- bind = gimple_build_bind (NULL, ilist, NULL);
- }
-
gsi_replace (gsi_p, bind, true);
+ gimple_bind_add_seq (bind, ilist);
+ gimple_bind_add_stmt (bind, stmt);
+ gimple_bind_add_seq (bind, olist);
pop_gimplify_context (NULL);
}
gimple_regimplify_operands (stmt, gsi_p);
break;
case GIMPLE_CATCH:
- lower_omp (gimple_catch_handler (stmt), ctx);
+ lower_omp (gimple_catch_handler_ptr (stmt), ctx);
break;
case GIMPLE_EH_FILTER:
- lower_omp (gimple_eh_filter_failure (stmt), ctx);
+ lower_omp (gimple_eh_filter_failure_ptr (stmt), ctx);
break;
case GIMPLE_TRY:
- lower_omp (gimple_try_eval (stmt), ctx);
- lower_omp (gimple_try_cleanup (stmt), ctx);
+ lower_omp (gimple_try_eval_ptr (stmt), ctx);
+ lower_omp (gimple_try_cleanup_ptr (stmt), ctx);
break;
case GIMPLE_TRANSACTION:
- lower_omp (gimple_transaction_body (stmt), ctx);
+ lower_omp (gimple_transaction_body_ptr (stmt), ctx);
break;
case GIMPLE_BIND:
- lower_omp (gimple_bind_body (stmt), ctx);
+ lower_omp (gimple_bind_body_ptr (stmt), ctx);
break;
case GIMPLE_OMP_PARALLEL:
case GIMPLE_OMP_TASK:
}
static void
-lower_omp (gimple_seq body, omp_context *ctx)
+lower_omp (gimple_seq *body, omp_context *ctx)
{
location_t saved_location = input_location;
- gimple_stmt_iterator gsi = gsi_start (body);
- for (gsi = gsi_start (body); !gsi_end_p (gsi); gsi_next (&gsi))
+ gimple_stmt_iterator gsi;
+ for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi))
lower_omp_1 (&gsi, ctx);
input_location = saved_location;
}
delete_omp_context);
body = gimple_body (current_function_decl);
- scan_omp (body, NULL);
+ scan_omp (&body, NULL);
gcc_assert (taskreg_nesting_level == 0);
if (all_contexts->root)
if (task_shared_vars)
push_gimplify_context (&gctx);
- lower_omp (body, NULL);
+ lower_omp (&body, NULL);
if (task_shared_vars)
pop_gimplify_context (NULL);
}
{
GIMPLE_PASS,
"omplower", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
NULL, /* gate */
execute_lower_omp, /* execute */
NULL, /* sub */
case GIMPLE_OMP_ORDERED:
case GIMPLE_OMP_CRITICAL:
wi->info = stmt;
- walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_2, NULL, wi);
+ walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
wi->info = context;
break;
wi->info = stmt;
/* gimple_omp_for_{index,initial,final} are all DECLs; no need to
walk them. */
- walk_gimple_seq (gimple_omp_for_pre_body (stmt),
- diagnose_sb_2, NULL, wi);
- walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_2, NULL, wi);
+ walk_gimple_seq_mod (gimple_omp_for_pre_body_ptr (stmt),
+ diagnose_sb_2, NULL, wi);
+ walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
wi->info = context;
break;
memset (&wi, 0, sizeof (wi));
wi.want_locations = true;
- walk_gimple_seq (body, diagnose_sb_2, NULL, &wi);
+ walk_gimple_seq_mod (&body, diagnose_sb_2, NULL, &wi);
+
+ gimple_set_body (current_function_decl, body);
splay_tree_delete (all_labels);
all_labels = NULL;
{
GIMPLE_PASS,
"*diagnose_omp_blocks", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
gate_diagnose_omp_blocks, /* gate */
diagnose_omp_structured_block_errors, /* execute */
NULL, /* sub */