Hello Everyone, This patch is for the Cilkplus branch affecting mainly the C++ compiler. This compiler was crashing when a continue was inside a cilk_for. This patch should fix that. I have also added a couple test programs to the testsuite.
Thanks, Balaji V. Iyer.
diff --git a/gcc/cp/ChangeLog.cilk b/gcc/cp/ChangeLog.cilk index 4981290..340f710 100644 --- a/gcc/cp/ChangeLog.cilk +++ b/gcc/cp/ChangeLog.cilk @@ -1,4 +1,14 @@ -2012-06-17 balaji.v.iyer <bviyer@nhelv406> +2012-06-20 Balaji V. Iyer <balaji.v.i...@intel.com> + + * cp-gimplify.c (cp_genericize_r): Added a check for cilk-for. + (genericize_cilk_for_stmt): New function. + * cilk.c (resolve_continue_stmts): Likewise. + (cp_build_cilk_for_body): Added a new label to point goto for continue + inside cilk_for. Also did a walk_tree to fix up all these continues. + (cg_hacks): called cp_genericize to breakup all the statements inside + cilk-for nested function. + +2012-06-17 Balaji V. Iyer <balaji.v.i...@intel.com> * cilk.c (cp_build_cilk_for_body): Set CILK_FN_P field to 1. (cp_make_cilk_frame): Likewise. diff --git a/gcc/cp/cilk.c b/gcc/cp/cilk.c index aa23bb0..c65da86 100644 --- a/gcc/cp/cilk.c +++ b/gcc/cp/cilk.c @@ -243,6 +243,34 @@ add_incr (tree incr) } } +/* This function will be used to fixup all the continues inside a cilk_for */ + +static tree +resolve_continue_stmts (tree *tp, int *walk_subtrees, void *data) +{ + tree goto_label = NULL_TREE, goto_stmt = NULL_TREE; + if (!tp || *tp == NULL_TREE) + return NULL_TREE; + + if (TREE_CODE (*tp) == CONTINUE_STMT) + { + goto_label = (tree) data; + goto_stmt = build1 (GOTO_EXPR, void_type_node, goto_label); + *tp = goto_stmt; + *walk_subtrees = 0; + } + else if (TREE_CODE (*tp) == FOR_STMT || TREE_CODE (*tp) == WHILE_STMT + || TREE_CODE (*tp) == DO_STMT) + { + /* Inside these statements, the continue goes to a different place not + * end of cilk_for, you do not want to go into these trees because we + * will resolve those later + */ + *walk_subtrees = 0; + } + + return NULL_TREE; +} /* this function will simplify the cilk loop */ static tree @@ -490,7 +518,8 @@ cp_build_cilk_for_body (struct cilk_for_desc *cfd) char *cc = NULL; char *dd = NULL; tree loop_end_comp = NULL_TREE; - tree c_for_loop, top_label, slab, cond_expr, mod_expr; + tree c_for_loop, top_label, slab, cond_expr, mod_expr, cont_lab; + tree continue_label; push_function_context (); @@ -656,6 +685,13 @@ cp_build_cilk_for_body (struct cilk_for_desc *cfd) DECL_IGNORED_P (slab) = 1; DECL_CONTEXT (slab) = fndecl; + cont_lab = build_decl (UNKNOWN_LOCATION, LABEL_DECL, NULL_TREE, + void_type_node); + DECL_ARTIFICIAL (cont_lab) = 0; + DECL_IGNORED_P (cont_lab) = 1; + DECL_CONTEXT (cont_lab) = fndecl; + continue_label = build1 (LABEL_EXPR, void_type_node, cont_lab); + mod_expr = build2 (MODIFY_EXPR, void_type_node, loop_var, build2 (PLUS_EXPR, count_type, loop_var, build_int_cst (count_type, 1))); @@ -667,10 +703,12 @@ cp_build_cilk_for_body (struct cilk_for_desc *cfd) add_stmt (top_label); add_stmt (loop_body); + add_stmt (continue_label); add_stmt (mod_expr); add_stmt (cond_expr); pop_stmt_list (c_for_loop); + walk_tree (&c_for_loop, resolve_continue_stmts, (void *)cont_lab, NULL); add_stmt (c_for_loop); DECL_INITIAL (fndecl) = make_node (BLOCK); @@ -1901,6 +1939,10 @@ cg_hacks (tree fndecl, bool is_nested) push_cfun (f); current_function_decl = fndecl; + /* We did not do this earlier so that we can do it here in the cilk_for + * nested function body */ + cp_genericize (fndecl); + /* If this is a genuine nested function, the nested function handling will deal with it. If this is not a nested function it must be handled now or the compiler will crash in a diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index f2390f2..30d3d43 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -314,6 +314,17 @@ genericize_for_stmt (tree *stmt_p, int *walk_subtrees, void *data) *stmt_p = expr; } +/* Genericize a Cilk_FOR node *STMT_P. */ + +static void +genericize_cilk_for_stmt (tree *stmt_p ATTRIBUTE_UNUSED, int *walk_subtrees, + void *data ATTRIBUTE_UNUSED) +{ + /* When we have a cilk for we resolve all the internal statements such as + * continue, while, for etc during gimplification */ + *walk_subtrees = 0; +} + /* Genericize a WHILE_STMT node *STMT_P. */ static void @@ -1158,6 +1169,8 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) gcc_assert (!CONVERT_EXPR_VBASE_PATH (stmt)); else if (TREE_CODE (stmt) == FOR_STMT) genericize_for_stmt (stmt_p, walk_subtrees, data); + else if (TREE_CODE (stmt) == CILK_FOR_STMT) + genericize_cilk_for_stmt (stmt_p, walk_subtrees, data); else if (TREE_CODE (stmt) == WHILE_STMT) genericize_while_stmt (stmt_p, walk_subtrees, data); else if (TREE_CODE (stmt) == DO_STMT) diff --git a/gcc/testsuite/ChangeLog.cilk b/gcc/testsuite/ChangeLog.cilk index 19d849b..8201c37 100644 --- a/gcc/testsuite/ChangeLog.cilk +++ b/gcc/testsuite/ChangeLog.cilk @@ -1,3 +1,12 @@ +2012-06-20 Balaji V. Iyer <balaji.v.i...@intel.com> + + * g++.dg/cilk-plus/cilk_for_cont2_inside_for.cc: New test file. + * g++.dg/cilk-plus/cilk_for_cont2_inside_for_tplt.cc: Likewise. + * g++.dg/cilk-plus/cilk_for_cont_inside_for.cc: Likewise. + * g++.dg/cilk-plus/cilk_for_cont_with_for.cc: Likewise. + * g++.dg/cilk-plus/cilk_for_cont_with_if.cc: Likewise. + * g++.dg/cilk-plus/cilk_for_cont_with_while.cc: Likewise. + 2012-06-12 Balaji V. Iyer <balaji.v.i...@intel.com> * gcc.dg/cilk-plus/elem_fn_tests/test7.c: Enclosed the function inside diff --git a/gcc/testsuite/g++.dg/cilk-plus/cilk_for_cont2_inside_for.cc b/gcc/testsuite/g++.dg/cilk-plus/cilk_for_cont2_inside_for.cc new file mode 100644 index 0000000..e27f348 --- /dev/null +++ b/gcc/testsuite/g++.dg/cilk-plus/cilk_for_cont2_inside_for.cc @@ -0,0 +1,21 @@ +int q[10], seq[10]; +int main (int argc, char** argv) +{ + + int max = 10, start = 0; + cilk_for(int ii=max - 1; ii>=start; ii--) + { + if (ii % 2) + continue; /* this continue should jump to a different place than + the one below */ + for (int jj = 0; jj < 10; jj++) + { + if (seq[jj] == 5) + continue; + else + seq[jj] = 2; + } + } + return 0; +} + diff --git a/gcc/testsuite/g++.dg/cilk-plus/cilk_for_cont2_inside_for_tplt.cc b/gcc/testsuite/g++.dg/cilk-plus/cilk_for_cont2_inside_for_tplt.cc new file mode 100644 index 0000000..e833039 --- /dev/null +++ b/gcc/testsuite/g++.dg/cilk-plus/cilk_for_cont2_inside_for_tplt.cc @@ -0,0 +1,27 @@ +int q[10], seq[10]; + +template <typename T> +T my_func (T max ,T start) +{ + cilk_for (T ii = max - 1; ii >= start; ii--) + { + if (ii % 2) + continue; /* this continue should jump to a different place than + the one below */ + for (int jj = 0; jj < 10; jj++) + { + if (seq[jj] == 5) + continue; + else + seq[jj] = 2; + } + } + return 0; +} + +int main (int argc, char** argv) +{ + my_func <int> (10, 0); + my_func <char> (10, 0); + return 0; +} diff --git a/gcc/testsuite/g++.dg/cilk-plus/cilk_for_cont_inside_for.cc b/gcc/testsuite/g++.dg/cilk-plus/cilk_for_cont_inside_for.cc new file mode 100644 index 0000000..0fd6b70 --- /dev/null +++ b/gcc/testsuite/g++.dg/cilk-plus/cilk_for_cont_inside_for.cc @@ -0,0 +1,18 @@ +int q[10], seq[10]; +int main (int argc, char** argv) +{ + + int max = 10, start = 0; + cilk_for(int ii=max - 1; ii>=start; ii--) + { + for (int jj = 0; jj < 10; jj++) + { + if (seq[jj] == 5) + continue; + else + seq[jj] = 2; + } + } + return 0; +} + diff --git a/gcc/testsuite/g++.dg/cilk-plus/cilk_for_cont_with_for.cc b/gcc/testsuite/g++.dg/cilk-plus/cilk_for_cont_with_for.cc new file mode 100644 index 0000000..21e659b --- /dev/null +++ b/gcc/testsuite/g++.dg/cilk-plus/cilk_for_cont_with_for.cc @@ -0,0 +1,14 @@ +int q[10], seq2[10]; +int main (int argc, char** argv) +{ + + int max = 10, start = 0; + cilk_for(int ii=max - 1; ii>=start; ii--) + { + for (int jj = 0; jj < 10; jj++) + seq2[jj] = 5; + continue; + } + return 0; +} + diff --git a/gcc/testsuite/g++.dg/cilk-plus/cilk_for_cont_with_if.cc b/gcc/testsuite/g++.dg/cilk-plus/cilk_for_cont_with_if.cc new file mode 100644 index 0000000..c0b8b01 --- /dev/null +++ b/gcc/testsuite/g++.dg/cilk-plus/cilk_for_cont_with_if.cc @@ -0,0 +1,13 @@ +int q[10], seq2[10]; +int main (int argc, char** argv) +{ + + int max = 10, start = 0; + cilk_for(int ii = max - 1; ii >= start; ii--) + { + if (q[ii] != 0) + continue; + } + return 0; +} + diff --git a/gcc/testsuite/g++.dg/cilk-plus/cilk_for_cont_with_while.cc b/gcc/testsuite/g++.dg/cilk-plus/cilk_for_cont_with_while.cc new file mode 100644 index 0000000..35fbb1b --- /dev/null +++ b/gcc/testsuite/g++.dg/cilk-plus/cilk_for_cont_with_while.cc @@ -0,0 +1,18 @@ +int q[10], seq2[10]; +int main (int argc, char** argv) +{ + + int max = 10, start = 0; + cilk_for(int ii=max - 1; ii>=start; ii--) + { + int jj = 0; + while (jj < 10) + { + seq2[jj] = 1; + jj++; + } + continue; + } + return 0; +} +