public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] PR 60586
@ 2015-09-01  0:05 Iyer, Balaji V
  2015-09-01 22:26 ` Jeff Law
  0 siblings, 1 reply; 6+ messages in thread
From: Iyer, Balaji V @ 2015-09-01  0:05 UTC (permalink / raw)
  To: gcc-patches; +Cc: Zamyatin, Igor

[-- Attachment #1: Type: text/plain, Size: 1243 bytes --]

Hello Everyone,
	This patch will fix the bug reported in Bugzilla, PR 60586. The issue was that the spawned function's function arguments must not be pushed into the nested/lambda function. This patch should fix that issue.

I have tested this on x86_64 (linux and Cygwin flavors). Is this OK for trunk? 

Here are the Changelog entries:

gcc/c-family/ChangeLog
2015-08-31  Balaji V. Iyer  <balaji.v.iyer@intel.com>

        PR middle-end/60586
        * c-common.h: Added two more parameters to the gimplify_cilk_spawn
        function.
        * c-gimplify.c (c_gimplify_expr): Likewise.
        * cilk.c (gimplify_cilk_spawn): Likewise and called
        gimplify_call_params_in_spawned_fn.
        (gimplify_call_params_in_spawned_fn): New function.

gcc/cp/ChangeLog
2015-08-31  Balaji V. Iyer  <balaji.v.iyer@intel.com>

        PR middle-end/60586
        * cp-gimplify.c (cp_gimplify_expr): Added two additional parameters to
        gimplify_cilk_spawn.

gcc/testsuite/ChangeLog
2015-08-31  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.


Thanks,

Balaji V. Iyer.

[-- Attachment #2: diff.txt --]
[-- Type: text/plain, Size: 8131 bytes --]

diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index be63cd2..027bea6 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1423,7 +1423,7 @@ extern vec <tree, va_gc> *fix_sec_implicit_args
 /* In cilk.c.  */
 extern tree insert_cilk_frame (tree);
 extern void cilk_init_builtins (void);
-extern int gimplify_cilk_spawn (tree *);
+extern int gimplify_cilk_spawn (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);
diff --git a/gcc/c-family/c-gimplify.c b/gcc/c-family/c-gimplify.c
index 1c81773..fd954d3 100644
--- a/gcc/c-family/c-gimplify.c
+++ b/gcc/c-family/c-gimplify.c
@@ -288,7 +288,8 @@ 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);
+	return (enum gimplify_status) gimplify_cilk_spawn (expr_p, pre_p,
+							   post_p);
 
     case MODIFY_EXPR:
     case INIT_EXPR:
@@ -299,7 +300,8 @@ 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);
+	return (enum gimplify_status) gimplify_cilk_spawn (expr_p, pre_p,
+							   post_p);
 
     default:;
     }
diff --git a/gcc/c-family/cilk.c b/gcc/c-family/cilk.c
index 1012a4f..1fe6685 100644
--- a/gcc/c-family/cilk.c
+++ b/gcc/c-family/cilk.c
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimplify.h"
 #include "tree-iterator.h"
 #include "tree-inline.h"
+#include "cp/cp-tree.h"
 #include "c-family/c-common.h"
 #include "toplev.h" 
 #include "tm.h"
@@ -762,12 +763,37 @@ 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.  */
+
+static void
+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;
+  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);
+  else if (TREE_CODE (*fix_parm_expr) == AGGR_INIT_EXPR)
+    for (ii = 0; ii < aggr_init_expr_nargs (*fix_parm_expr); ii++)
+      gimplify_expr (&AGGR_INIT_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.  */
 
 int
-gimplify_cilk_spawn (tree *spawn_p)
+gimplify_cilk_spawn (tree *spawn_p, gimple_seq *pre_p, gimple_seq *post_p)
 {
   tree expr = *spawn_p;
   tree function, call1, call2, new_args;
@@ -784,6 +810,8 @@ gimplify_cilk_spawn (tree *spawn_p)
   while (TREE_CODE (expr) == CLEANUP_POINT_EXPR
 	 || TREE_CODE (expr) == EXPR_STMT)
     expr = TREE_OPERAND (expr, 0);
+
+  gimplify_call_params_in_spawned_fn (&expr, pre_p, post_p);  
   
   new_args = NULL;
   function = create_cilk_wrapper (expr, &new_args);
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index c36d339..8aacbbb 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -603,7 +603,8 @@ 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);
+	return (enum gimplify_status) gimplify_cilk_spawn (expr_p, pre_p, 
+							   post_p);
       cp_gimplify_init_expr (expr_p);
       if (TREE_CODE (*expr_p) != INIT_EXPR)
 	return GS_OK;
@@ -614,7 +615,8 @@ 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);
+	  return (enum gimplify_status) gimplify_cilk_spawn (expr_p, pre_p,
+							     post_p);
 
 	/* If the back end isn't clever enough to know that the lhs and rhs
 	   types are the same, add an explicit conversion.  */
@@ -715,13 +717,15 @@ 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);
+	return (enum gimplify_status) gimplify_cilk_spawn (expr_p, pre_p,
+							   post_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);
+	return (enum gimplify_status) gimplify_cilk_spawn (expr_p, pre_p,
+							   post_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
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
index 0000000..c4012a0
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/CK/pr60586.c
@@ -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
index 0000000..6a27cad
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/CK/pr60586.cc
@@ -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-*-* } } } */
+
+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;
+}

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2015-09-02 20:55 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-01  0:05 [PATCH] PR 60586 Iyer, Balaji V
2015-09-01 22:26 ` Jeff Law
2015-09-02  1:16   ` Iyer, Balaji V
2015-09-02  1:22   ` Iyer, Balaji V
2015-09-02  4:30   ` Iyer, Balaji V
2015-09-02 20:58     ` Jeff Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).