diff options
author | kyukhin <kyukhin@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-09-02 12:52:29 +0000 |
---|---|---|
committer | kyukhin <kyukhin@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-09-02 12:52:29 +0000 |
commit | 407509954982a4c81744de81eeb6c01ad67c4707 (patch) | |
tree | 88fc4c24c6347b42ca239861cc28a6716e4730ab /gcc/c-family/c-cilkplus.c | |
parent | 88599a7ab3e2747a5908c4446ea5fb16f7e0ba89 (diff) | |
download | gcc-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.c | 133 |
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; +} |