summaryrefslogtreecommitdiff
path: root/gcc/c-family/c-cilkplus.c
diff options
context:
space:
mode:
authorkyukhin <kyukhin@138bc75d-0d04-0410-961f-82ee72b054a4>2014-09-02 12:52:29 +0000
committerkyukhin <kyukhin@138bc75d-0d04-0410-961f-82ee72b054a4>2014-09-02 12:52:29 +0000
commit407509954982a4c81744de81eeb6c01ad67c4707 (patch)
tree88fc4c24c6347b42ca239861cc28a6716e4730ab /gcc/c-family/c-cilkplus.c
parent88599a7ab3e2747a5908c4446ea5fb16f7e0ba89 (diff)
downloadgcc-407509954982a4c81744de81eeb6c01ad67c4707.tar.gz
gcc/
* cilk-builtins.def (__cilkrts_cilk_for_32): New. (__cilkrts_cilk_for_64): Likewise. * cilk-common.c (declare_cilk_for_builtin): New function. (cilk_init_builtins): Declare __cilkrts_cilk_for_32 and __cilkrts_cilk_for_64 bultins. * cilk.h (enum cilk_tree_index): Added CILK_TI_F_LOOP_32 and CILK_TI_F_LOOP_64. (cilk_for_32_fndecl): New define. (cilk_for_64_fndecl): Likewise. * gimple-pretty-print.c (dump_gimple_omp_for): Correct hadling of GF_OMP_FOR_KIND_CILKFOR cases; Added NE_EXPR case. * gimple.h (enum gf_mask): Added GF_OMP_FOR_KIND_CILKFOR; adjusted GF_OMP_FOR_KIND_MASK, GF_OMP_FOR_SIMD, GF_OMP_FOR_COMBINED, GF_OMP_FOR_COMBINED_INTO. * gimplify.c (gimplify_scan_omp_clauses): Added OMP_CLAUSE__CILK_FOR_COUNT_ case. (gimplify_adjust_omp_clauses): Ditto. (gimplify_omp_for): Added CILK_FOR case. (gimplify_expr): Ditto. * omp-low.c: Include cilk.h. (extract_omp_for_data): Set appropriate kind for GF_OMP_FOR_KIND_CILKFOR; added check for GF_OMP_FOR_KIND_CILKFOR. (scan_sharing_clauses): Added OMP_CLAUSE__CILK_FOR_COUNT_ cases. (create_omp_child_function_name): Added second argument to handle cilk_for case. (cilk_for_check_loop_diff_type): New function. (expand_cilk_for_call): Likewise. (expand_cilk_for): Likewise. (create_omp_child_function): Set cilk_for_count; handle the cases when it is true; call create_omp_child_function_name with second argument. (expand_omp_taskreg): Set is_cilk_for and handle cases when it's true. (expand_omp_for): Handle case of GF_OMP_FOR_KIND_CILKFOR. * tree-core.h (omp_clause_code): Added OMP_CLAUSE__CILK_FOR_COUNT_. * tree-nested.c (convert_nonlocal_omp_clauses): Added OMP_CLAUSE__CILK_FOR_COUNT_ case. (convert_local_omp_clauses): Ditto. * tree-pretty-print.c (dump_omp_clause): Added OMP_CLAUSE__CILK_FOR_COUNT_ and OMP_CLAUSE_SCHEDULE_CILKFOR cases. (dump_generic_node): Added CILK_FOR case. * tree.c (omp_clause_num_ops): New element OMP_CLAUSE__CILK_FOR_COUNT_ (1). (omp_clause_code_name): New element _Cilk_for_count_. (walk_tree_1): Added OMP_CLAUSE__CILK_FOR_COUNT_ case. * tree.def: Add tree code for CILK_FOR. gcc/c/ * c-parser.c (c_parser_cilk_for): New function. (c_parser_cilk_grainsize): Likewise. (c_get_temp_regvar): Likewise. (c_parser_statement_after_labels): Added RID_CILK_FOR case. (c_parser_pragma): Added PRAGMA_CILK_GRAINSIZE case. (c_parser_omp_for_loop): Added CILK_FOR and CILK_SIMD checks. * c-typeck.c (c_finish_omp_clauses): Added OMP_CLAUSE__CILK_FOR_COUNT_ case. gcc/cp/ * cp-cilkplus.c (cpp_validate_cilk_plus_loop_aux): Loc definition simplified. * parser.c (cp_parser_cilk_for): New function. (cp_parser_cilk_grainsize): Likewise. (cp_parser_statement): Added RID_CILK_FOR case. (cp_parser_omp_for_cond): Added CILK_FOR check. (cp_parser_omp_for_loop_init): Change function argument to accept tree_code instead just a bool flag; change the check to use that tree_code; check for initialization declaration in case of Cilk_for. (cp_parser_omp_for_loop): Added checks for CILK_FOR and RID_CILK_FOR; changed call to cp_parser_omp_for_loop_init according new arguments' list. (cp_parser_pragma): Added PRAGMA_CILK_GRAINSIZE case. * pt.c (tsubst_expr): Added CILK_FOR case. * semantics.c: Include convert.h. (finish_omp_clauses): Properly handle OMP_CLAUSE_SCHEDULE_CILKFOR case; added OMP_CLAUSE__CILK_FOR_COUNT_. (handle_omp_for_class_iterator): New argument lastp and its usage; added NE_EXPR case. (finish_omp_for): Changed call to handle_omp_for_class_iterator according new arguments' list; in case of Cilk_for save very first decl and create empty stmt_list block; use block to build correct statement tree. gcc/c-family/ * c-cilkplus.c (cilk_for_number_of_iterations): New function. * c-common.c (c_common_reswords): Added _Cilk_for. * c-common.h (enum rid): Added RID_CILK_FOR. (cilk_for_number_of_iterations): Add declaration. * c-omp.c (c_finish_omp_for): Added checks for CILK_SIMD and CILK_FOR. * c-pragma.c (init_pragma): Register "grainsize" pragma. * c-pragma.h (enum pragma_kind): Add PRAGMA_CILK_GRAINSIZE. gcc/testsuite/ * c-c++-common/cilk-plus/CK/cilk-fors.c: New test. * c-c++-common/cilk-plus/CK/cilk-for-2.c: New test. * c-c++-common/cilk-plus/CK/cilk-for-3.c: New test. * c-c++-common/cilk-plus/CK/cilk_for_errors.c: New test. * c-c++-common/cilk-plus/CK/cilk_for_grain.c: New test. * c-c++-common/cilk-plus/CK/cilk_for_grain_errors.c: New test. * c-c++-common/cilk-plus/CK/cilk_for_ptr_iter.c: New test. * c-c++-common/cilk-plus/CK/nested_cilk_for.c: New test. * g++.dg/cilk-plus/CK/cf3.cc: New test. * g++.dg/cilk-plus/CK/cilk-for-tplt.cc: New test. * g++.dg/cilk-plus/CK/for1.cc: New test. * g++.dg/cilk-plus/CK/stl_iter.cc: New test. * g++.dg/cilk-plus/CK/stl_rev_iter.cc: New test. * g++.dg/cilk-plus/CK/stl_test.cc: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@214818 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-family/c-cilkplus.c')
-rw-r--r--gcc/c-family/c-cilkplus.c133
1 files changed, 133 insertions, 0 deletions
diff --git a/gcc/c-family/c-cilkplus.c b/gcc/c-family/c-cilkplus.c
index 1a16f6690b0..131da0b3fea 100644
--- a/gcc/c-family/c-cilkplus.c
+++ b/gcc/c-family/c-cilkplus.c
@@ -91,3 +91,136 @@ c_finish_cilk_clauses (tree clauses)
}
return clauses;
}
+
+/* Calculate number of iterations of CILK_FOR. */
+
+tree
+cilk_for_number_of_iterations (tree cilk_for)
+{
+ tree t, v, n1, n2, step, type, init, cond, incr, itype;
+ enum tree_code cond_code;
+ location_t loc = EXPR_LOCATION (cilk_for);
+
+ init = TREE_VEC_ELT (OMP_FOR_INIT (cilk_for), 0);
+ v = TREE_OPERAND (init, 0);
+ cond = TREE_VEC_ELT (OMP_FOR_COND (cilk_for), 0);
+ incr = TREE_VEC_ELT (OMP_FOR_INCR (cilk_for), 0);
+ type = TREE_TYPE (v);
+
+ gcc_assert (TREE_CODE (TREE_TYPE (v)) == INTEGER_TYPE
+ || TREE_CODE (TREE_TYPE (v)) == POINTER_TYPE);
+ n1 = TREE_OPERAND (init, 1);
+ cond_code = TREE_CODE (cond);
+ n2 = TREE_OPERAND (cond, 1);
+ switch (cond_code)
+ {
+ case LT_EXPR:
+ case GT_EXPR:
+ case NE_EXPR:
+ break;
+ case LE_EXPR:
+ if (POINTER_TYPE_P (TREE_TYPE (n2)))
+ n2 = fold_build_pointer_plus_hwi_loc (loc, n2, 1);
+ else
+ n2 = fold_build2_loc (loc, PLUS_EXPR, TREE_TYPE (n2), n2,
+ build_int_cst (TREE_TYPE (n2), 1));
+ cond_code = LT_EXPR;
+ break;
+ case GE_EXPR:
+ if (POINTER_TYPE_P (TREE_TYPE (n2)))
+ n2 = fold_build_pointer_plus_hwi_loc (loc, n2, -1);
+ else
+ n2 = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (n2), n2,
+ build_int_cst (TREE_TYPE (n2), 1));
+ cond_code = GT_EXPR;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ step = NULL_TREE;
+ switch (TREE_CODE (incr))
+ {
+ case PREINCREMENT_EXPR:
+ case POSTINCREMENT_EXPR:
+ step = build_int_cst (TREE_TYPE (v), 1);
+ break;
+ case PREDECREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ step = build_int_cst (TREE_TYPE (v), -1);
+ break;
+ case MODIFY_EXPR:
+ t = TREE_OPERAND (incr, 1);
+ gcc_assert (TREE_OPERAND (t, 0) == v);
+ switch (TREE_CODE (t))
+ {
+ case PLUS_EXPR:
+ step = TREE_OPERAND (t, 1);
+ break;
+ case POINTER_PLUS_EXPR:
+ step = fold_convert (ssizetype, TREE_OPERAND (t, 1));
+ break;
+ case MINUS_EXPR:
+ step = TREE_OPERAND (t, 1);
+ step = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (step), step);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ itype = type;
+ if (POINTER_TYPE_P (itype))
+ itype = signed_type_for (itype);
+ if (cond_code == NE_EXPR)
+ {
+ /* For NE_EXPR, we need to find out if the iterator increases
+ or decreases from whether step is positive or negative. */
+ tree stype = itype;
+ if (TYPE_UNSIGNED (stype))
+ stype = signed_type_for (stype);
+ cond = fold_build2_loc (loc, GE_EXPR, boolean_type_node,
+ fold_convert_loc (loc, stype, step),
+ build_int_cst (stype, 0));
+ t = fold_build3_loc (loc, COND_EXPR, itype, cond,
+ build_int_cst (itype, -1),
+ build_int_cst (itype, 1));
+ }
+ else
+ t = build_int_cst (itype, (cond_code == LT_EXPR ? -1 : 1));
+ t = fold_build2_loc (loc, PLUS_EXPR, itype,
+ fold_convert_loc (loc, itype, step), t);
+ t = fold_build2_loc (loc, PLUS_EXPR, itype, t,
+ fold_convert_loc (loc, itype, n2));
+ t = fold_build2_loc (loc, MINUS_EXPR, itype, t,
+ fold_convert_loc (loc, itype, n1));
+ if (TYPE_UNSIGNED (itype) && cond_code == GT_EXPR)
+ t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype,
+ fold_build1_loc (loc, NEGATE_EXPR, itype, t),
+ fold_build1_loc (loc, NEGATE_EXPR, itype,
+ fold_convert_loc (loc, itype,
+ step)));
+ else if (TYPE_UNSIGNED (itype) && cond_code == NE_EXPR)
+ {
+ tree t1
+ = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, t,
+ fold_convert_loc (loc, itype, step));
+ tree t2
+ = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype,
+ fold_build1_loc (loc, NEGATE_EXPR, itype, t),
+ fold_build1_loc (loc, NEGATE_EXPR, itype,
+ fold_convert_loc (loc, itype,
+ step)));
+ t = fold_build3_loc (loc, COND_EXPR, itype, cond, t1, t2);
+ }
+ else
+ t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, t,
+ fold_convert_loc (loc, itype, step));
+ cond = fold_build2_loc (loc, cond_code, boolean_type_node, n1, n2);
+ t = fold_build3_loc (loc, COND_EXPR, itype, cond, t,
+ build_int_cst (itype, 0));
+ return t;
+}