aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/semantics.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/semantics.c')
-rw-r--r--gcc/cp/semantics.c152
1 files changed, 145 insertions, 7 deletions
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 168bde8..01748da 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -49,6 +49,7 @@ along with GCC; see the file COPYING3. If not see
#include "bitmap.h"
#include "omp-low.h"
#include "builtins.h"
+#include "convert.h"
static bool verify_constant (tree, bool, bool *, bool *);
#define VERIFY_CONSTANT(X) \
@@ -5424,6 +5425,8 @@ finish_omp_clauses (tree clauses)
else if (t == error_mark_node)
remove = true;
else if (!type_dependent_expression_p (t)
+ && (OMP_CLAUSE_SCHEDULE_KIND (c)
+ != OMP_CLAUSE_SCHEDULE_CILKFOR)
&& !INTEGRAL_TYPE_P (TREE_TYPE (t)))
{
error ("schedule chunk size expression must be integral");
@@ -5433,7 +5436,19 @@ finish_omp_clauses (tree clauses)
{
t = mark_rvalue_use (t);
if (!processing_template_decl)
- t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ {
+ if (OMP_CLAUSE_SCHEDULE_KIND (c)
+ == OMP_CLAUSE_SCHEDULE_CILKFOR)
+ {
+ t = convert_to_integer (long_integer_type_node, t);
+ if (t == error_mark_node)
+ {
+ remove = true;
+ break;
+ }
+ }
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ }
OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
}
break;
@@ -5734,6 +5749,7 @@ finish_omp_clauses (tree clauses)
case OMP_CLAUSE_SECTIONS:
case OMP_CLAUSE_TASKGROUP:
case OMP_CLAUSE_PROC_BIND:
+ case OMP_CLAUSE__CILK_FOR_COUNT_:
break;
case OMP_CLAUSE_INBRANCH:
@@ -6053,7 +6069,7 @@ finish_omp_task (tree clauses, tree body)
static bool
handle_omp_for_class_iterator (int i, location_t locus, tree declv, tree initv,
tree condv, tree incrv, tree *body,
- tree *pre_body, tree clauses)
+ tree *pre_body, tree clauses, tree *lastp)
{
tree diff, iter_init, iter_incr = NULL, last;
tree incr_var = NULL, orig_pre_body, orig_body, c;
@@ -6073,6 +6089,7 @@ handle_omp_for_class_iterator (int i, location_t locus, tree declv, tree initv,
case GE_EXPR:
case LT_EXPR:
case LE_EXPR:
+ case NE_EXPR:
if (TREE_OPERAND (cond, 1) == iter)
cond = build2 (swap_tree_comparison (TREE_CODE (cond)),
TREE_TYPE (cond), iter, TREE_OPERAND (cond, 0));
@@ -6285,6 +6302,7 @@ handle_omp_for_class_iterator (int i, location_t locus, tree declv, tree initv,
TREE_VEC_ELT (initv, i) = init;
TREE_VEC_ELT (condv, i) = cond;
TREE_VEC_ELT (incrv, i) = incr;
+ *lastp = last;
return false;
}
@@ -6301,7 +6319,8 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv, tree initv,
tree condv, tree incrv, tree body, tree pre_body, tree clauses)
{
tree omp_for = NULL, orig_incr = NULL;
- tree decl, init, cond, incr;
+ tree decl = NULL, init, cond, incr, orig_decl = NULL_TREE, block = NULL_TREE;
+ tree last = NULL_TREE;
location_t elocus;
int i;
@@ -6431,8 +6450,11 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv, tree initv,
"iteration variable %qE", decl);
return NULL;
}
+ if (code == CILK_FOR && i == 0)
+ orig_decl = decl;
if (handle_omp_for_class_iterator (i, locus, declv, initv, condv,
- incrv, &body, &pre_body, clauses))
+ incrv, &body, &pre_body,
+ clauses, &last))
return NULL;
continue;
}
@@ -6485,11 +6507,18 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv, tree initv,
if (IS_EMPTY_STMT (pre_body))
pre_body = NULL;
+ if (code == CILK_FOR && !processing_template_decl)
+ block = push_stmt_list ();
+
omp_for = c_finish_omp_for (locus, code, declv, initv, condv, incrv,
body, pre_body);
if (omp_for == NULL)
- return NULL;
+ {
+ if (block)
+ pop_stmt_list (block);
+ return NULL;
+ }
for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INCR (omp_for)); i++)
{
@@ -6523,8 +6552,117 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv, tree initv,
if (orig_incr)
TREE_VEC_ELT (OMP_FOR_INCR (omp_for), i) = TREE_VEC_ELT (orig_incr, i);
}
- if (omp_for != NULL)
- OMP_FOR_CLAUSES (omp_for) = clauses;
+ OMP_FOR_CLAUSES (omp_for) = clauses;
+
+ if (block)
+ {
+ tree omp_par = make_node (OMP_PARALLEL);
+ TREE_TYPE (omp_par) = void_type_node;
+ OMP_PARALLEL_CLAUSES (omp_par) = NULL_TREE;
+ tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
+ TREE_SIDE_EFFECTS (bind) = 1;
+ BIND_EXPR_BODY (bind) = pop_stmt_list (block);
+ OMP_PARALLEL_BODY (omp_par) = bind;
+ if (OMP_FOR_PRE_BODY (omp_for))
+ {
+ add_stmt (OMP_FOR_PRE_BODY (omp_for));
+ OMP_FOR_PRE_BODY (omp_for) = NULL_TREE;
+ }
+ init = TREE_VEC_ELT (OMP_FOR_INIT (omp_for), 0);
+ decl = TREE_OPERAND (init, 0);
+ cond = TREE_VEC_ELT (OMP_FOR_COND (omp_for), 0);
+ incr = TREE_VEC_ELT (OMP_FOR_INCR (omp_for), 0);
+ tree t = TREE_OPERAND (cond, 1), c, clauses, *pc;
+ clauses = OMP_FOR_CLAUSES (omp_for);
+ OMP_FOR_CLAUSES (omp_for) = NULL_TREE;
+ for (pc = &clauses; *pc; )
+ if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_SCHEDULE)
+ {
+ gcc_assert (OMP_FOR_CLAUSES (omp_for) == NULL_TREE);
+ OMP_FOR_CLAUSES (omp_for) = *pc;
+ *pc = OMP_CLAUSE_CHAIN (*pc);
+ OMP_CLAUSE_CHAIN (OMP_FOR_CLAUSES (omp_for)) = NULL_TREE;
+ }
+ else
+ {
+ gcc_assert (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_FIRSTPRIVATE);
+ pc = &OMP_CLAUSE_CHAIN (*pc);
+ }
+ if (TREE_CODE (t) != INTEGER_CST)
+ {
+ TREE_OPERAND (cond, 1) = get_temp_regvar (TREE_TYPE (t), t);
+ c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
+ OMP_CLAUSE_DECL (c) = TREE_OPERAND (cond, 1);
+ OMP_CLAUSE_CHAIN (c) = clauses;
+ clauses = c;
+ }
+ if (TREE_CODE (incr) == MODIFY_EXPR)
+ {
+ t = TREE_OPERAND (TREE_OPERAND (incr, 1), 1);
+ if (TREE_CODE (t) != INTEGER_CST)
+ {
+ TREE_OPERAND (TREE_OPERAND (incr, 1), 1)
+ = get_temp_regvar (TREE_TYPE (t), t);
+ c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
+ OMP_CLAUSE_DECL (c) = TREE_OPERAND (TREE_OPERAND (incr, 1), 1);
+ OMP_CLAUSE_CHAIN (c) = clauses;
+ clauses = c;
+ }
+ }
+ t = TREE_OPERAND (init, 1);
+ if (TREE_CODE (t) != INTEGER_CST)
+ {
+ TREE_OPERAND (init, 1) = get_temp_regvar (TREE_TYPE (t), t);
+ c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
+ OMP_CLAUSE_DECL (c) = TREE_OPERAND (init, 1);
+ OMP_CLAUSE_CHAIN (c) = clauses;
+ clauses = c;
+ }
+ if (orig_decl && orig_decl != decl)
+ {
+ c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
+ OMP_CLAUSE_DECL (c) = orig_decl;
+ OMP_CLAUSE_CHAIN (c) = clauses;
+ clauses = c;
+ }
+ if (last)
+ {
+ c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
+ OMP_CLAUSE_DECL (c) = last;
+ OMP_CLAUSE_CHAIN (c) = clauses;
+ clauses = c;
+ }
+ c = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
+ OMP_CLAUSE_DECL (c) = decl;
+ OMP_CLAUSE_CHAIN (c) = clauses;
+ clauses = c;
+ c = build_omp_clause (input_location, OMP_CLAUSE__CILK_FOR_COUNT_);
+ OMP_CLAUSE_OPERAND (c, 0)
+ = cilk_for_number_of_iterations (omp_for);
+ OMP_CLAUSE_CHAIN (c) = clauses;
+ OMP_PARALLEL_CLAUSES (omp_par) = finish_omp_clauses (c);
+ add_stmt (omp_par);
+ return omp_par;
+ }
+ else if (code == CILK_FOR && processing_template_decl)
+ {
+ tree c, clauses = OMP_FOR_CLAUSES (omp_for);
+ if (orig_decl && orig_decl != decl)
+ {
+ c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
+ OMP_CLAUSE_DECL (c) = orig_decl;
+ OMP_CLAUSE_CHAIN (c) = clauses;
+ clauses = c;
+ }
+ if (last)
+ {
+ c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
+ OMP_CLAUSE_DECL (c) = last;
+ OMP_CLAUSE_CHAIN (c) = clauses;
+ clauses = c;
+ }
+ OMP_FOR_CLAUSES (omp_for) = clauses;
+ }
return omp_for;
}