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;
+}
+

Reply via email to