This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH, gcc-7-branch] Backport PR80038


On 2017-08-21 23:37 +0800, Xi Ruoyao wrote:
> On 2017-04-25 09:30 -0600, Jeff Law wrote:
> > On 04/14/2017 06:44 PM, Xi Ruoyao wrote:
> > > On 2017-04-14 15:00 +0800, Xi Ruoyao wrote:
> > > > On 2017-04-13 09:05 +0200, Richard Biener wrote:
> > > > 
> > > > > Did you verify LTO bootstrap still works with the patch?
> > > > 
> > > > I've just done a LTO bootstrapp (boarding a train :) ).
> > > > It works with my patch.
> > > 
> > > I've done dejagnu tests in lto.exp and built a Linux kernel
> > > with lto bootstrapped GCC.   They seem good.
> > 
> > Given Richi's general agreement around the in_lto_p, let's go with the 
> > patch on the trunk only.
> > 
> > If you get positive feedback from Jan, then this can be backported to 
> > gcc-7 after it's been on the trunk for at least a week.
> 
> We have 15 weeks now :)
> 
> Re-tested on gcc-7-branch with lto-bootstrap.  No regressions.  Is it
> OK to backport this to gcc-7-branch?

I was too stupid so I didn't attach the patch :(

It's attached here.
-- 
Xi Ruoyao <ryxi@stu.xidian.edu.cn>
School of Aerospace Science and Technology, Xidian University
From dc5359834ea62ea547cee6608db59b45c25b3263 Mon Sep 17 00:00:00 2001
From: Xi Ruoyao <ryxi@stu.xidian.edu.cn>
Date: Mon, 21 Aug 2017 09:41:59 +0800
Subject: [PATCH] Destroy temps for _Cilk_spawn calling in the child (PR
 c++/80038)

Backport r247446 and r247508 from trunk.

gcc/ChangeLog:

2017-08-21  Xi Ruoyao  <ryxi@stu.xidian.edu.cn>

	PR c++/80038
	* cilk_common.c (expand_builtin_cilk_detach): Move pedigree
	operations here.
	* gimplify.c (gimplify_cilk_detach): New function.
	(gimplify_call_expr, gimplify_modify_expr): Call it as needed.
	* tree-core.h: Document EXPR_CILK_SPAWN.
	* tree.h (EXPR_CILK_SPAWN): Define.

gcc/c-family/ChangeLog:

2017-08-21  Xi Ruoyao <ryxi@stu.xidian.edu.cn>

	PR c++/80038
	* c-common.h (cilk_gimplify_call_params_in_spawned_fn): Remove
	prototype.
	(cilk_install_body_pedigree_operations): Likewise.
	* cilk.c (cilk_set_spawn_marker): Mark functions that should be
	detatched.
	(cilk_gimplify_call_params_in_spawned_fn): Remove.
	(cilk_install_body_pedigree_operations): Likewise.
	(gimplify_cilk_spawn): Add EXPR_STMT and CLEANUP_POINT_EXPR
	unwrapping.

gcc/c/ChangeLog:

2017-08-21  Xi Ruoyao <ryxi@stu.xidian.edu.cn>

	PR c++/80038
	* c-gimplify.c (c_gimplify_expr): Remove calls to
	cilk_gimplify_call_params_in_spawned_fn.

gcc/cp/ChangeLog:

2017-08-21  Xi Ruoyao <ryxi@stu.xidian.edu.cn>

	PR c++/80038
	* cp-cilkplus.c (cilk_install_body_with_frame_cleanup): Don't
	add pedigree operation and detach call here.
	* cp-gimplify.c (cp_gimplify_expr): Remove the calls to
	cilk_cp_gimplify_call_params_in_spawned_fn.
	(cilk_cp_gimplify_call_params_in_spawned_fn): Remove function.
	* semantics.c (simplify_aggr_init_expr): Copy EXPR_CILK_SPAWN.

gcc/lto/ChangeLog:

2017-08-21  Xi Ruoyao <ryxi@stu.xidian.edu.cn>

	PR c++/80038
	* lto-lang.c (lto_init): Set in_lto_p earlier.

gcc/testsuite/ChangeLog:

2017-08-21  Xi Ruoyao <ryxi@stu.xidian.edu.cn>

	PR c++/80038
	* g++.dg/cilk-plus/CK/pr80038.cc: New test.
---
 gcc/c-family/c-common.h                      |   2 -
 gcc/c-family/c-gimplify.c                    |  10 +--
 gcc/c-family/cilk.c                          | 102 +++------------------------
 gcc/c/c-typeck.c                             |   8 +--
 gcc/cilk-common.c                            |  49 +++++++++++++
 gcc/cp/cp-cilkplus.c                         |   6 +-
 gcc/cp/cp-gimplify.c                         |  40 ++---------
 gcc/cp/semantics.c                           |   2 +
 gcc/gimplify.c                               |  21 ++++++
 gcc/lto/lto-lang.c                           |   6 +-
 gcc/testsuite/g++.dg/cilk-plus/CK/pr80038.cc |  47 ++++++++++++
 gcc/tree-core.h                              |   4 ++
 gcc/tree.h                                   |   6 ++
 13 files changed, 150 insertions(+), 153 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cilk-plus/CK/pr80038.cc

diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index b933342..138a0a6 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1463,7 +1463,6 @@ extern bool is_cilkplus_vector_p (tree);
 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 *);
 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);
@@ -1471,7 +1470,6 @@ extern tree build_cilk_sync (void);
 extern tree build_cilk_spawn (location_t, tree);
 extern tree make_cilk_frame (tree);
 extern tree create_cilk_function_exit (tree, bool, bool);
-extern tree cilk_install_body_pedigree_operations (tree);
 extern void cilk_outline (tree, tree *, void *);
 extern bool contains_cilk_spawn_stmt (tree);
 extern tree cilk_for_number_of_iterations (tree);
diff --git a/gcc/c-family/c-gimplify.c b/gcc/c-family/c-gimplify.c
index 57edb41..1ae75d2 100644
--- a/gcc/c-family/c-gimplify.c
+++ b/gcc/c-family/c-gimplify.c
@@ -280,10 +280,7 @@ c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
 		 && cilk_detect_spawn_and_unwrap (expr_p));
 
       if (!seen_error ())
-	{
-	  cilk_gimplify_call_params_in_spawned_fn (expr_p, pre_p);
-	  return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
-	}
+        return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
       return GS_ERROR;
 
     case MODIFY_EXPR:
@@ -295,10 +292,7 @@ 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 ())
-	{
-	  cilk_gimplify_call_params_in_spawned_fn (expr_p, pre_p);
-	  return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
-	}
+        return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
 
     default:;
     }
diff --git a/gcc/c-family/cilk.c b/gcc/c-family/cilk.c
index 43478ff..e6df498 100644
--- a/gcc/c-family/cilk.c
+++ b/gcc/c-family/cilk.c
@@ -109,6 +109,10 @@ cilk_set_spawn_marker (location_t loc, tree fcall)
   else
     {
       cfun->calls_cilk_spawn = true;
+      if (TREE_CODE (fcall) == CALL_EXPR)
+        EXPR_CILK_SPAWN (fcall) = 1;
+      else /* TREE_CODE (fcall) == TARGET_EXPR */
+        EXPR_CILK_SPAWN (TREE_OPERAND (fcall, 1)) = 1;
       return true;
     }
 }
@@ -775,37 +779,6 @@ 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)
-{
-  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)
-    {
-      /* Cilk outlining assumes GENERIC bodies, avoid leaking SSA names
-         via parameters.  */
-      for (ii = 0; ii < call_expr_nargs (*fix_parm_expr); ii++)
-	gimplify_arg (&CALL_EXPR_ARG (*fix_parm_expr, ii), pre_p,
-		      EXPR_LOCATION (*fix_parm_expr), false);
-    }
-}
-
-
 /* 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.  */
@@ -823,6 +796,12 @@ 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);
 
@@ -889,67 +868,6 @@ make_cilk_frame (tree fn)
   return decl;
 }
 
-/* Returns a STATEMENT_LIST with all the pedigree operations required for
-   install body with frame cleanup functions.  FRAME_PTR is the pointer to
-   __cilkrts_stack_frame created by make_cilk_frame.  */
-
-tree
-cilk_install_body_pedigree_operations (tree frame_ptr)
-{
-  tree body_list = alloc_stmt_list ();
-  tree enter_frame = build_call_expr (cilk_enter_fast_fndecl, 1, frame_ptr); 
-  append_to_statement_list (enter_frame, &body_list);
-  
-  tree parent = cilk_arrow (frame_ptr, CILK_TI_FRAME_PARENT, 0);
-  tree worker = cilk_arrow (frame_ptr, CILK_TI_FRAME_WORKER, 0);
-
-  tree pedigree = cilk_arrow (frame_ptr, CILK_TI_FRAME_PEDIGREE, 0);
-  tree pedigree_rank = cilk_dot (pedigree, CILK_TI_PEDIGREE_RANK, 0);
-  tree parent_pedigree = cilk_dot (pedigree, CILK_TI_PEDIGREE_PARENT, 0);
-  tree pedigree_parent = cilk_arrow (parent, CILK_TI_FRAME_PEDIGREE, 0);
-  tree pedigree_parent_rank = cilk_dot (pedigree_parent, 
-					CILK_TI_PEDIGREE_RANK, 0);
-  tree pedigree_parent_parent = cilk_dot (pedigree_parent, 
-				     CILK_TI_PEDIGREE_PARENT, 0);
-  tree worker_pedigree = cilk_arrow (worker, CILK_TI_WORKER_PEDIGREE, 1);
-  tree w_pedigree_rank = cilk_dot (worker_pedigree, CILK_TI_PEDIGREE_RANK, 0);
-  tree w_pedigree_parent = cilk_dot (worker_pedigree, 
-				     CILK_TI_PEDIGREE_PARENT, 0);
-
-  /* sf.pedigree.rank = worker->pedigree.rank.  */
-  tree exp1 = build2 (MODIFY_EXPR, void_type_node, pedigree_rank,
-		     w_pedigree_rank);
-  append_to_statement_list (exp1, &body_list);
-
-  /* sf.pedigree.parent = worker->pedigree.parent.  */
-  exp1 = build2 (MODIFY_EXPR, void_type_node, parent_pedigree,
-		 w_pedigree_parent);
-  append_to_statement_list (exp1, &body_list);
-
-  /* sf.call_parent->pedigree.rank = worker->pedigree.rank.  */
-  exp1 = build2 (MODIFY_EXPR, void_type_node, pedigree_parent_rank,
-		 w_pedigree_rank);
-  append_to_statement_list (exp1, &body_list);
-
-  /* sf.call_parent->pedigree.parent = worker->pedigree.parent.  */
-  exp1 = build2 (MODIFY_EXPR, void_type_node, pedigree_parent_parent,
-		 w_pedigree_parent);
-  append_to_statement_list (exp1, &body_list);
-
-  /* sf->worker.pedigree.rank = 0.  */
-  exp1 = build2 (MODIFY_EXPR, void_type_node, w_pedigree_rank, 
-		 build_zero_cst (uint64_type_node));
-  append_to_statement_list (exp1, &body_list);
-
-  /* sf->pedigree.parent = &sf->pedigree.  */
-  exp1 = build2 (MODIFY_EXPR, void_type_node, w_pedigree_parent,
-		 build1 (ADDR_EXPR,
-			 build_pointer_type (cilk_pedigree_type_decl),
-			 pedigree));
-  append_to_statement_list (exp1, &body_list);
-  return body_list;
-}
-
 /* Add a new variable, VAR to a variable list in WD->DECL_MAP.  HOW indicates
    whether the variable is previously defined, currently defined, or a variable 
    that is being written to.  */
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index ee36531..62bf46e 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -14215,14 +14215,8 @@ cilk_install_body_with_frame_cleanup (tree fndecl, tree body, void *w)
   add_local_decl (cfun, frame);
   
   DECL_SAVED_TREE (fndecl) = list;
-  tree frame_ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (frame)), 
-			   frame);
-  tree body_list = cilk_install_body_pedigree_operations (frame_ptr);
-  gcc_assert (TREE_CODE (body_list) == STATEMENT_LIST);
-  
-  tree detach_expr = build_call_expr (cilk_detach_fndecl, 1, frame_ptr); 
-  append_to_statement_list (detach_expr, &body_list);
 
+  tree body_list = alloc_stmt_list ();
   cilk_outline (fndecl, &body, (struct wrapper_data *) w);
   body = fold_build_cleanup_point_expr (void_type_node, body);
 
diff --git a/gcc/cilk-common.c b/gcc/cilk-common.c
index 46626b7..9cbe03f 100644
--- a/gcc/cilk-common.c
+++ b/gcc/cilk-common.c
@@ -365,11 +365,60 @@ expand_builtin_cilk_detach (tree exp)
   tree worker = cilk_dot (fptr, CILK_TI_FRAME_WORKER, 0);
   tree tail = cilk_arrow (worker, CILK_TI_WORKER_TAIL, 1);
 
+  tree faddr = build1 (ADDR_EXPR, cilk_frame_ptr_type_decl, fptr);
+  tree enter_frame = build_call_expr (cilk_enter_fast_fndecl, 1, faddr);
+  expand_expr (enter_frame, const0_rtx, VOIDmode, EXPAND_NORMAL);
+
+  tree pedigree = cilk_dot (fptr, CILK_TI_FRAME_PEDIGREE, 0);
+  tree pedigree_rank = cilk_dot (pedigree, CILK_TI_PEDIGREE_RANK, 0);
+  tree parent_pedigree = cilk_dot (pedigree, CILK_TI_PEDIGREE_PARENT, 0);
+  tree pedigree_parent = cilk_arrow (parent, CILK_TI_FRAME_PEDIGREE, 0);
+  tree pedigree_parent_rank = cilk_dot (pedigree_parent,
+					CILK_TI_PEDIGREE_RANK, 0);
+  tree pedigree_parent_parent = cilk_dot (pedigree_parent,
+				     CILK_TI_PEDIGREE_PARENT, 0);
+  tree worker_pedigree = cilk_arrow (worker, CILK_TI_WORKER_PEDIGREE, 1);
+  tree w_pedigree_rank = cilk_dot (worker_pedigree, CILK_TI_PEDIGREE_RANK, 0);
+  tree w_pedigree_parent = cilk_dot (worker_pedigree,
+				     CILK_TI_PEDIGREE_PARENT, 0);
+
   rtx wreg = expand_expr (worker, NULL_RTX, Pmode, EXPAND_NORMAL);
   if (GET_CODE (wreg) != REG)
     wreg = copy_to_reg (wreg);
   rtx preg = expand_expr (parent, NULL_RTX, Pmode, EXPAND_NORMAL);
 
+  /* sf.pedigree.rank = worker->pedigree.rank.  */
+  tree exp1 = build2 (MODIFY_EXPR, void_type_node, pedigree_rank,
+		     w_pedigree_rank);
+  expand_expr (exp1, const0_rtx, VOIDmode, EXPAND_NORMAL);
+
+  /* sf.pedigree.parent = worker->pedigree.parent.  */
+  exp1 = build2 (MODIFY_EXPR, void_type_node, parent_pedigree,
+		 w_pedigree_parent);
+  expand_expr (exp1, const0_rtx, VOIDmode, EXPAND_NORMAL);
+
+  /* sf.call_parent->pedigree.rank = worker->pedigree.rank.  */
+  exp1 = build2 (MODIFY_EXPR, void_type_node, pedigree_parent_rank,
+		 w_pedigree_rank);
+  expand_expr (exp1, const0_rtx, VOIDmode, EXPAND_NORMAL);
+
+  /* sf.call_parent->pedigree.parent = worker->pedigree.parent.  */
+  exp1 = build2 (MODIFY_EXPR, void_type_node, pedigree_parent_parent,
+		 w_pedigree_parent);
+  expand_expr (exp1, const0_rtx, VOIDmode, EXPAND_NORMAL);
+
+  /* sf->worker.pedigree.rank = 0.  */
+  exp1 = build2 (MODIFY_EXPR, void_type_node, w_pedigree_rank,
+		 build_zero_cst (uint64_type_node));
+  expand_expr (exp1, const0_rtx, VOIDmode, EXPAND_NORMAL);
+
+  /* sf->pedigree.parent = &sf->pedigree.  */
+  exp1 = build2 (MODIFY_EXPR, void_type_node, w_pedigree_parent,
+		 build1 (ADDR_EXPR,
+			 build_pointer_type (cilk_pedigree_type_decl),
+			 pedigree));
+  expand_expr (exp1, const0_rtx, VOIDmode, EXPAND_NORMAL);
+
   /* TMP <- WORKER.TAIL
     *TMP <- PARENT
      TMP <- TMP + 1
diff --git a/gcc/cp/cp-cilkplus.c b/gcc/cp/cp-cilkplus.c
index d147e7e..7c66448 100644
--- a/gcc/cp/cp-cilkplus.c
+++ b/gcc/cp/cp-cilkplus.c
@@ -223,11 +223,7 @@ cilk_install_body_with_frame_cleanup (tree fndecl, tree orig_body, void *wd)
   location_t loc = EXPR_LOCATION (orig_body);
   tree list = alloc_stmt_list ();
   DECL_SAVED_TREE (fndecl) = list;
-  tree fptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (frame)), frame);
-  tree body = cilk_install_body_pedigree_operations (fptr);
-  gcc_assert (TREE_CODE (body) == STATEMENT_LIST);
-  tree detach_expr = build_call_expr (cilk_detach_fndecl, 1, fptr);
-  append_to_statement_list (detach_expr, &body);
+  tree body = alloc_stmt_list ();
   cilk_outline (fndecl, &orig_body, (struct wrapper_data *) wd);
   append_to_statement_list (orig_body, &body);
   if (flag_exceptions)
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 0ff1dd4..9402234f 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -88,25 +88,6 @@ 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);
-  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.  */
 
@@ -647,11 +628,7 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
       if (fn_contains_cilk_spawn_p (cfun))
 	{
 	  if (cilk_cp_detect_spawn_and_unwrap (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);
-	    }
+	    return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
 	  if (seen_error () && contains_cilk_spawn_stmt (*expr_p))
 	    return GS_ERROR;
 	}
@@ -666,10 +643,7 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
 	if (fn_contains_cilk_spawn_p (cfun)
 	    && cilk_cp_detect_spawn_and_unwrap (expr_p)
 	    && !seen_error ())
-	  {
-	    cilk_cp_gimplify_call_params_in_spawned_fn (expr_p, pre_p, post_p);
-	    return (enum gimplify_status) gimplify_cilk_spawn (expr_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);
@@ -787,20 +761,14 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
 		 && cilk_cp_detect_spawn_and_unwrap (expr_p));
 
       if (!seen_error ())
-	{
-	  cilk_cp_gimplify_call_params_in_spawned_fn (expr_p, pre_p, post_p);
-	  return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
-	}
+        return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
       return GS_ERROR;
 
     case CALL_EXPR:
       if (fn_contains_cilk_spawn_p (cfun)
 	  && cilk_cp_detect_spawn_and_unwrap (expr_p)
 	  && !seen_error ())
-	{
-	  cilk_cp_gimplify_call_params_in_spawned_fn (expr_p, pre_p, post_p);
-	  return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
-	}
+        return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
       ret = GS_OK;
       if (!CALL_EXPR_FN (*expr_p))
 	/* Internal function call.  */;
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index ecfa4e2..6acc188 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -4116,6 +4116,8 @@ simplify_aggr_init_expr (tree *tp)
     = CALL_EXPR_OPERATOR_SYNTAX (aggr_init_expr);
   CALL_EXPR_ORDERED_ARGS (call_expr) = CALL_EXPR_ORDERED_ARGS (aggr_init_expr);
   CALL_EXPR_REVERSE_ARGS (call_expr) = CALL_EXPR_REVERSE_ARGS (aggr_init_expr);
+  /* Preserve CILK_SPAWN flag.  */
+  EXPR_CILK_SPAWN (call_expr) = EXPR_CILK_SPAWN (aggr_init_expr);
 
   if (style == ctor)
     {
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 201ffc1..c59bfec 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -3072,6 +3072,19 @@ maybe_fold_stmt (gimple_stmt_iterator *gsi)
   return fold_stmt (gsi);
 }
 
+/* Add a gimple call to __builtin_cilk_detach to GIMPLE sequence PRE_P,
+   with the pointer to the proper cilk frame.  */
+static void
+gimplify_cilk_detach (gimple_seq *pre_p)
+{
+  tree frame = cfun->cilk_frame_decl;
+  tree ptrf = build1 (ADDR_EXPR, cilk_frame_ptr_type_decl,
+		      frame);
+  gcall *detach = gimple_build_call (cilk_detach_fndecl, 1,
+				     ptrf);
+  gimplify_seq_add_stmt(pre_p, detach);
+}
+
 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
    WANT_VALUE is true if the result of the call is desired.  */
 
@@ -3108,6 +3121,9 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
 			EXPR_LOCATION (*expr_p));
 	  vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
 	}
+
+      if (EXPR_CILK_SPAWN (*expr_p))
+        gimplify_cilk_detach (pre_p);
       gimple *call = gimple_build_call_internal_vec (ifn, vargs);
       gimplify_seq_add_stmt (pre_p, call);
       return GS_ALL_DONE;
@@ -3339,6 +3355,8 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
       call = gimple_build_call_from_tree (*expr_p);
       gimple_call_set_fntype (call, TREE_TYPE (fnptrtype));
       notice_special_calls (call);
+      if (EXPR_CILK_SPAWN (*expr_p))
+        gimplify_cilk_detach (pre_p);
       gimplify_seq_add_stmt (pre_p, call);
       gsi = gsi_last (*pre_p);
       maybe_fold_stmt (&gsi);
@@ -5621,6 +5639,9 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
 	   SSA name w/o a definition.  We may have uses in the GIMPLE IL.
 	   ???  This doesn't make it a default-def.  */
 	SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
+
+      if (EXPR_CILK_SPAWN (*from_p))
+        gimplify_cilk_detach (pre_p);
       assign = call_stmt;
     }
   else
diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c
index ca8945e..52ab2a8 100644
--- a/gcc/lto/lto-lang.c
+++ b/gcc/lto/lto-lang.c
@@ -1201,6 +1201,9 @@ lto_init (void)
 {
   int i;
 
+  /* Initialize LTO-specific data structures.  */
+  in_lto_p = true;
+
   /* We need to generate LTO if running in WPA mode.  */
   flag_generate_lto = (flag_wpa != NULL);
 
@@ -1283,9 +1286,6 @@ lto_init (void)
       }
 #undef NAME_TYPE
 
-  /* Initialize LTO-specific data structures.  */
-  in_lto_p = true;
-
   return true;
 }
 
diff --git a/gcc/testsuite/g++.dg/cilk-plus/CK/pr80038.cc b/gcc/testsuite/g++.dg/cilk-plus/CK/pr80038.cc
new file mode 100644
index 0000000..85990e5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/CK/pr80038.cc
@@ -0,0 +1,47 @@
+/* { dg-options "-fcilkplus" } */
+/* { dg-do run } */
+/* { dg-require-effective-target cilkplus_runtime } */
+
+#include <unistd.h>
+extern "C" {
+  extern int __cilkrts_set_param (const char *, const char *);
+}
+
+int objcnt = 0;
+
+struct foo
+{
+  int live;
+  foo ()
+    { objcnt++; }
+  foo (const foo &)
+    { objcnt++; }
+  ~foo ()
+    { objcnt--; }
+};
+
+void
+spawnee (foo f)
+{
+  usleep(2000);
+  /* Now both my_test::f and spawnee::f should be alive.  */
+  if (objcnt != 2)
+    __builtin_abort ();
+}
+
+void
+my_test ()
+{
+  foo f;
+  _Cilk_spawn spawnee (f);
+  _Cilk_sync ;
+}
+
+int
+main ()
+{
+  if (__cilkrts_set_param ("nworkers", "2") != 0)
+    __builtin_abort ();
+
+  my_test ();
+}
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index a646ecb..c76fc7b 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -1194,6 +1194,10 @@ struct GTY(()) tree_base {
        SSA_NAME_OCCURS_IN_ABNORMAL_PHI in
            SSA_NAME
 
+       EXPR_CILK_SPAWN in
+           CALL_EXPR
+           AGGR_INIT_EXPR
+
    used_flag:
 
        TREE_USED in
diff --git a/gcc/tree.h b/gcc/tree.h
index 0d805c0..5e01a8f 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -894,6 +894,12 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
 /* Cilk keywords accessors.  */
 #define CILK_SPAWN_FN(NODE) TREE_OPERAND (CILK_SPAWN_STMT_CHECK (NODE), 0)
 
+/* If this is true, we should insert a __cilk_detach call just before
+   this function call.  */
+#define EXPR_CILK_SPAWN(NODE) \
+  (TREE_CHECK2 (NODE, CALL_EXPR, \
+                AGGR_INIT_EXPR)->base.u.bits.unsigned_flag)
+
 /* In a RESULT_DECL, PARM_DECL and VAR_DECL, means that it is
    passed by invisible reference (and the TREE_TYPE is a pointer to the true
    type).  */
-- 
2.7.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]