Fix spawned function with lambda function
authorBalaji V. Iyer <balaji.v.iyer@intel.com>
Wed, 2 Sep 2015 23:59:21 +0000 (23:59 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Wed, 2 Sep 2015 23:59:21 +0000 (16:59 -0700)
Make sure that the spawned function's arguments will not be pushed
into lambda function.

gcc/c-family/

2015-09-02  Balaji V. Iyer  <balaji.v.iyer@intel.com>

PR middle-end/60586
* c-common.h (cilk_gimplify_call_params_in_spawned_fn): New
prototype.
* c-gimplify.c (c_gimplify_expr): Added a call to the function
cilk_gimplify_call_params_in_spawned_fn.
* cilk.c (cilk_gimplify_call_params_in_spawned_fn): New function.
(gimplify_cilk_spawn): Removed EXPR_STMT and CLEANUP_POINT_EXPR
unwrapping.

gcc/cp/

2015-09-02  Balaji V. Iyer  <balaji.v.iyer@intel.com>

PR middle-end/60586
* cp-gimplify.c (cilk_cp_gimplify_call_params_in_spawned_fn): New
function.
(cp_gimplify_expr): Added a call to the function
cilk_cp_gimplify_call_params_in_spawned_fn.

gcc/testsuite/

2015-09-02  Balaji V. Iyer  <balaji.v.iyer@intel.com>

PR middle-end/60586
* c-c++-common/cilk-plus/CK/pr60586.c: New file.
* g++.dg/cilk-plus/CK/pr60586.cc: Likewise.

From-SVN: r227423

gcc/c-family/ChangeLog
gcc/c-family/c-common.h
gcc/c-family/c-gimplify.c
gcc/c-family/cilk.c
gcc/cp/ChangeLog
gcc/cp/cp-gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/cilk-plus/CK/pr60586.c [new file with mode: 0644]
gcc/testsuite/g++.dg/cilk-plus/CK/pr60586.cc [new file with mode: 0644]

index 8b4009e85fddd08cd84c8fdb05131ffc5de1d8c4..09b425f2b053f96c5b004bd9d7bc10cbafe21581 100644 (file)
@@ -1,3 +1,14 @@
+2015-09-02  Balaji V. Iyer  <balaji.v.iyer@intel.com>
+
+       PR middle-end/60586
+       * c-common.h (cilk_gimplify_call_params_in_spawned_fn): New
+       prototype.
+       * c-gimplify.c (c_gimplify_expr): Added a call to the function
+       cilk_gimplify_call_params_in_spawned_fn.
+       * cilk.c (cilk_gimplify_call_params_in_spawned_fn): New function.
+       (gimplify_cilk_spawn): Removed EXPR_STMT and CLEANUP_POINT_EXPR
+       unwrapping.
+
 2015-08-25  Marek Polacek  <polacek@redhat.com>
 
        PR middle-end/67330
index be63cd203d59c9087eaa621fabdb4c4e818627d3..d24dfdab35efac48bc3032847a67ae4ee639f3d2 100644 (file)
@@ -1424,6 +1424,8 @@ extern vec <tree, va_gc> *fix_sec_implicit_args
 extern tree insert_cilk_frame (tree);
 extern void cilk_init_builtins (void);
 extern int gimplify_cilk_spawn (tree *);
+extern void cilk_gimplify_call_params_in_spawned_fn (tree *, gimple_seq *,
+                                                    gimple_seq *);
 extern void cilk_install_body_with_frame_cleanup (tree, tree, void *);
 extern bool cilk_detect_spawn_and_unwrap (tree *);
 extern bool cilk_set_spawn_marker (location_t, tree);
index 1c81773a91c5c57aa9de350170c8d3dd456e2d19..92987b588f74e8f331cd33aa121836dabf1b6a0e 100644 (file)
@@ -288,8 +288,10 @@ c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
 
       /* If errors are seen, then just process it as a CALL_EXPR.  */
       if (!seen_error ())
-       return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
-
+       {
+         cilk_gimplify_call_params_in_spawned_fn (expr_p, pre_p, post_p);
+         return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
+       }
     case MODIFY_EXPR:
     case INIT_EXPR:
     case CALL_EXPR:
@@ -299,7 +301,10 @@ c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
             original expression (MODIFY/INIT/CALL_EXPR) is processes as
             it is supposed to be.  */
          && !seen_error ())
-       return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
+       {
+         cilk_gimplify_call_params_in_spawned_fn (expr_p, pre_p, post_p);
+         return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
+       }
 
     default:;
     }
index 1012a4fd3aaf47821e96c5732e8cd8c4b9f62384..1c316a4eb7892d879d9e9b7e7ac129a33ddb16d9 100644 (file)
@@ -762,6 +762,34 @@ create_cilk_wrapper (tree exp, tree *args_out)
   return fndecl;
 }
 
+/* Gimplify all the parameters for the Spawned function.  *EXPR_P can be a
+   CALL_EXPR, INIT_EXPR, MODIFY_EXPR or TARGET_EXPR.  *PRE_P and *POST_P are
+   gimple sequences from the caller of gimplify_cilk_spawn.  */
+
+void
+cilk_gimplify_call_params_in_spawned_fn (tree *expr_p, gimple_seq *pre_p,
+                                        gimple_seq *post_p)
+{
+  int ii = 0;
+  tree *fix_parm_expr = expr_p;
+
+  /* Remove CLEANUP_POINT_EXPR and EXPR_STMT from *spawn_p.  */
+  while (TREE_CODE (*fix_parm_expr) == CLEANUP_POINT_EXPR
+        || TREE_CODE (*fix_parm_expr) == EXPR_STMT)
+    *fix_parm_expr = TREE_OPERAND (*fix_parm_expr, 0);
+
+  if ((TREE_CODE (*expr_p) == INIT_EXPR)
+      || (TREE_CODE (*expr_p) == TARGET_EXPR)
+      || (TREE_CODE (*expr_p) == MODIFY_EXPR))
+    fix_parm_expr = &TREE_OPERAND (*expr_p, 1);
+
+  if (TREE_CODE (*fix_parm_expr) == CALL_EXPR)
+    for (ii = 0; ii < call_expr_nargs (*fix_parm_expr); ii++)
+      gimplify_expr (&CALL_EXPR_ARG (*fix_parm_expr, ii), pre_p, post_p,
+                    is_gimple_reg, fb_rvalue);
+}
+
+
 /* Transform *SPAWN_P, a spawned CALL_EXPR, to gimple.  *SPAWN_P can be a
    CALL_EXPR, INIT_EXPR or MODIFY_EXPR.  Returns GS_OK if everything is fine,
    and GS_UNHANDLED, otherwise.  */
@@ -779,12 +807,6 @@ gimplify_cilk_spawn (tree *spawn_p)
 
   cfun->calls_cilk_spawn = 1;
   cfun->is_cilk_function = 1;
-
-  /* Remove CLEANUP_POINT_EXPR and EXPR_STMT from *spawn_p.  */
-  while (TREE_CODE (expr) == CLEANUP_POINT_EXPR
-        || TREE_CODE (expr) == EXPR_STMT)
-    expr = TREE_OPERAND (expr, 0);
-  
   new_args = NULL;
   function = create_cilk_wrapper (expr, &new_args);
 
index 477bb209388b6aafe38ec5f328fabfd674d0a596..cd00395f1135f49b32d540454ba31bc20b0fe9a4 100644 (file)
@@ -1,3 +1,11 @@
+2015-09-02  Balaji V. Iyer  <balaji.v.iyer@intel.com>
+
+       PR middle-end/60586
+       * cp-gimplify.c (cilk_cp_gimplify_call_params_in_spawned_fn): New
+       function.
+       (cp_gimplify_expr): Added a call to the function
+       cilk_cp_gimplify_call_params_in_spawned_fn.
+
 2015-09-01  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/61753
index c36d3399133d1f49241d9b5102f6346961f6fe8a..5ab060431a3f3965dc1448d00278a441c72bf7af 100644 (file)
@@ -95,6 +95,25 @@ finish_bc_block (tree *block, enum bc_t bc, tree label)
   DECL_CHAIN (label) = NULL_TREE;
 }
 
+/* This function is a wrapper for cilk_gimplify_call_params_in_spawned_fn.
+   *EXPR_P can be a CALL_EXPR, INIT_EXPR, MODIFY_EXPR, AGGR_INIT_EXPR or
+   TARGET_EXPR.  *PRE_P and *POST_P are gimple sequences from the caller
+   of gimplify_cilk_spawn.  */
+
+static void
+cilk_cp_gimplify_call_params_in_spawned_fn (tree *expr_p, gimple_seq *pre_p,
+                                           gimple_seq *post_p)
+{
+  int ii = 0;
+
+  cilk_gimplify_call_params_in_spawned_fn (expr_p, pre_p, post_p);  
+  if (TREE_CODE (*expr_p) == AGGR_INIT_EXPR)
+    for (ii = 0; ii < aggr_init_expr_nargs (*expr_p); ii++)
+      gimplify_expr (&AGGR_INIT_EXPR_ARG (*expr_p, ii), pre_p, post_p,
+                    is_gimple_reg, fb_rvalue);
+}
+
+
 /* Get the LABEL_EXPR to represent a break or continue statement
    in the current block scope.  BC indicates which.  */
 
@@ -603,7 +622,10 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
       if (fn_contains_cilk_spawn_p (cfun)
          && cilk_detect_spawn_and_unwrap (expr_p)
          && !seen_error ())
-       return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
+       {
+         cilk_cp_gimplify_call_params_in_spawned_fn (expr_p, pre_p, post_p);
+         return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
+       }
       cp_gimplify_init_expr (expr_p);
       if (TREE_CODE (*expr_p) != INIT_EXPR)
        return GS_OK;
@@ -614,8 +636,10 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
        if (fn_contains_cilk_spawn_p (cfun)
            && cilk_detect_spawn_and_unwrap (expr_p)
            && !seen_error ())
-         return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
-
+         {
+           cilk_cp_gimplify_call_params_in_spawned_fn (expr_p, pre_p, post_p);
+           return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
+         }
        /* If the back end isn't clever enough to know that the lhs and rhs
           types are the same, add an explicit conversion.  */
        tree op0 = TREE_OPERAND (*expr_p, 0);
@@ -715,14 +739,18 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
 
       /* If errors are seen, then just process it as a CALL_EXPR.  */
       if (!seen_error ())
-       return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
-      
+       {
+         cilk_cp_gimplify_call_params_in_spawned_fn (expr_p, pre_p, post_p);
+         return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
+       }
     case CALL_EXPR:
       if (fn_contains_cilk_spawn_p (cfun)
          && cilk_detect_spawn_and_unwrap (expr_p)
          && !seen_error ())
-       return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
-
+       {
+         cilk_cp_gimplify_call_params_in_spawned_fn (expr_p, pre_p, post_p);
+         return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
+       }
       /* DR 1030 says that we need to evaluate the elements of an
         initializer-list in forward order even when it's used as arguments to
         a constructor.  So if the target wants to evaluate them in reverse
index 04328535a034abf749fa9603bca264e3fb38cd6e..2c84f9a684bce6c9a64c5c3bab24d9de5ff9a302 100644 (file)
@@ -1,3 +1,9 @@
+2015-09-02  Balaji V. Iyer  <balaji.v.iyer@intel.com>
+
+       PR middle-end/60586
+       * c-c++-common/cilk-plus/CK/pr60586.c: New file.
+       * g++.dg/cilk-plus/CK/pr60586.cc: Likewise.
+
 2015-09-02  Marek Polacek  <polacek@redhat.com>
 
        PR c/67432
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/CK/pr60586.c b/gcc/testsuite/c-c++-common/cilk-plus/CK/pr60586.c
new file mode 100644 (file)
index 0000000..c4012a0
--- /dev/null
@@ -0,0 +1,28 @@
+/* { dg-do run  { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-fcilkplus -O2" } */
+/* { dg-additional-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
+
+int noop(int x)
+{
+  return x;
+}
+
+int post_increment(int *x)
+{
+  return (*x)++;
+}
+
+int main(int argc, char *argv[])
+{
+  int m = 5;
+  int n = m;
+  int r = _Cilk_spawn noop(post_increment(&n));
+  int n2 = n;
+  _Cilk_sync;
+
+  if (r != m || n2 != m + 1)
+    return 1;
+  else
+    return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/cilk-plus/CK/pr60586.cc b/gcc/testsuite/g++.dg/cilk-plus/CK/pr60586.cc
new file mode 100644 (file)
index 0000000..6a27cad
--- /dev/null
@@ -0,0 +1,89 @@
+/* { dg-options "-fcilkplus" } */
+/* { dg-do run { target i?86-*-* x86_64-*-* arm*-*-* } } */
+/* { dg-options "-fcilkplus -lcilkrts" { target { i?86-*-* x86_64-*-* arm*-*-* } } } */
+
+class Rectangle
+{
+  int area_val, h, w;
+  public:
+    Rectangle (int, int);
+    Rectangle (int, int, int);
+    ~Rectangle ();
+    int area ();
+};
+Rectangle::~Rectangle ()
+{
+  h = 0;
+  w = 0;
+  area_val = 0;
+}
+Rectangle::Rectangle (int height, int width)
+{
+  h = height;
+  w = width;
+  area_val = 0;
+}
+
+int some_func(int &x)
+{
+  x++;
+  return x;
+}
+
+Rectangle::Rectangle (int height, int width, int area_orig)
+{
+  h = height;
+  w = width;
+  area_val = area_orig;
+}
+
+int Rectangle::area()
+{
+  return (area_val += (h*w));
+}
+
+
+int some_func (int &);
+
+/* Spawning constructor.  */
+int main1 (void)
+{
+  int x = 3;
+  Rectangle r = _Cilk_spawn Rectangle (some_func(x), 3);
+  return r.area();
+}
+/* Spawning constructor 2.  */
+int main2 (void)
+{
+  Rectangle r (_Cilk_spawn Rectangle (4, 3));
+  return r.area();
+}
+
+/* Spawning copy constructor.  */
+int main3 (void)
+{
+  int x = 3;
+  Rectangle r = _Cilk_spawn Rectangle (some_func(x), 3, 2);
+  return r.area ();
+}
+
+/* Spawning copy constructor 2.  */
+int main4 (void)
+{
+  Rectangle r ( _Cilk_spawn Rectangle (4, 3, 2));
+  return r.area();
+}
+
+int main (void)
+{
+  if (main1 () != 12)
+    __builtin_abort ();
+  if (main2 () != 12)
+    __builtin_abort ();
+  if (main3 () != 14)
+    __builtin_abort ();
+  if (main4() != 14)
+    __builtin_abort ();
+  return 0;
+}