re PR c++/80038 (Random segfault using local vectors in Cilk function)
authorXi Ruoyao <ryxi@stu.xidian.edu.cn>
Mon, 1 May 2017 22:26:02 +0000 (22:26 +0000)
committerJeff Law <law@gcc.gnu.org>
Mon, 1 May 2017 22:26:02 +0000 (16:26 -0600)
2017-05-01  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.

        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.

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

        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.

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

PR c++/80038
* g++.dg/cilk-plus/CK/pr80038.cc: New test.

From-SVN: r247446

19 files changed:
gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-common.h
gcc/c-family/c-gimplify.c
gcc/c-family/cilk.c
gcc/c/ChangeLog
gcc/c/c-typeck.c
gcc/cilk-common.c
gcc/cp/ChangeLog
gcc/cp/cp-cilkplus.c
gcc/cp/cp-gimplify.c
gcc/cp/semantics.c
gcc/gimplify.c
gcc/lto/ChangeLog
gcc/lto/lto-lang.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cilk-plus/CK/pr80038.cc [new file with mode: 0644]
gcc/tree-core.h
gcc/tree.h

index 6441ac1e6887468d3e847f3a38622a6c2ef89083..4b01ed82fb837b4e0035c63017de9c94130708e9 100644 (file)
@@ -1,3 +1,13 @@
+2017-05-01  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. 
+
 2017-05-01  David Malcolm  <dmalcolm@redhat.com>
 
        * diagnostic-show-locus.c (layout::get_expanded_location): Rewrite
index 8f6f55b73bfcb30548674bd5d3cf1187c85e38fc..23f52389ee099a1623afa37a54188d61a0954a4f 100644 (file)
@@ -1,3 +1,16 @@
+2017-05-01  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.
+
 2017-04-27  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/80534
index b933342043437488b0ea8684b6af9784930a47a1..138a0a675ac82d737b9eb8f14cc2f51c351af0b1 100644 (file)
@@ -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);
index 57edb41af0f08dfb193965213808d852a5ea53c3..1ae75d294ff6bd9a53c8b63c2dd28a10be981bdf 100644 (file)
@@ -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:;
     }
index 43478fff9144178900cd8da575b0cb75d17d3009..e6df498e471a05d623d579e97e376720ce4808c1 100644 (file)
@@ -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.  */
index 5587e2f8b84ac0b786de36cc8308b603566035ed..3c26eac90508a5fdb6133001848eb95b31cdfe12 100644 (file)
@@ -1,3 +1,9 @@
+2017-05-01  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.
+
 2017-04-25  David Malcolm  <dmalcolm@redhat.com>
 
        * c-parser.c (c_parser_struct_or_union_specifier): Add fix-it
index ff239e2d6282025d855bcd1c39a0bfaab904a26e..6f9909c6396ef77b005c30c89a24984aab5b8856 100644 (file)
@@ -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);
 
index 46626b75b23acb6d034c7e498068081d46a41522..9cbe03f8e02abc010a399eb28ab5829aab1cd98a 100644 (file)
@@ -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
index 9c9818fa9ab83967d085e3b2471c0c0dc9b19d8e..183f7365a5990bb5240616465ad74f888433d4c5 100644 (file)
@@ -1,3 +1,13 @@
+2017-05-01  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.
+
 2017-04-29  Volker Reichelt  <v.reichelt@netcologne.de>
 
        * parser.c (cp_parser_member_declaration): Add fix-it hints for
index d147e7eac133f1ea9d81aa4e930811429eaf86ee..7c664482371539b613993f7e2980ddb731d2d273 100644 (file)
@@ -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)
index f2c52963a9fceb1adbaf744ad715474cbd0dc7a4..de62414ec3c975b376f8dc5f52d4d0fe070ef21f 100644 (file)
@@ -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.  */;
index 0a695008ada950e60a2d298146165e70df33ae4b..4db2462734dc093d80f7e3e1b2e99354e9e6fb3e 100644 (file)
@@ -4103,6 +4103,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)
     {
index c69d5b93534e2243ca23470b9749f70fd7dc7663..fd27eb1523f22f28f0c512d38a3ed54801438d0e 100644 (file)
@@ -3071,6 +3071,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.  */
 
@@ -3107,6 +3120,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;
@@ -3338,6 +3354,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);
@@ -5620,6 +5638,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
index d24dd0cfa0f43f54b2cddc48e122e1e450969af1..62304fcc3a1a92fe07fc0b2a80d976bcb3043e05 100644 (file)
@@ -1,3 +1,8 @@
+2017-05-01  Xi Ruoyao  <ryxi@stu.xidian.edu.cn>
+
+        PR c++/80038
+       * lto-lang.c (lto_init): Set in_lto_p earlier.
+
 2017-04-12  Richard Biener  <rguenther@suse.de>
        Bernd Edlinger  <bernd.edlinger@hotmail.de>
 
index ca8945e53bb5d1e3699f74203e8bdd0c6afac1c3..52ab2a8cb812a0b33d6dc0cd21de1bec45541b8f 100644 (file)
@@ -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;
 }
 
index dc80b563f5fa9ed9b4cf0c321e7c669ba242b9ab..205c083e3be0e756323e344aeafaf47221e37904 100644 (file)
@@ -1,3 +1,8 @@
+2017-05-01  Xi Ruoyao  <ryxi@stu.xidian.edu.cn>
+
+       PR c++/80038
+       * g++.dg/cilk-plus/CK/pr80038.cc: New test.
+
 2017-05-01  David Malcolm  <dmalcolm@redhat.com>
 
        * gcc.dg/Wmissing-braces-fixits.c: Update expected output to
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 (file)
index 0000000..85990e5
--- /dev/null
@@ -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 ();
+}
index a646ecb5c951869fa8bfa3af11c524414c0c6c3b..c76fc7bc8efe58dc70e32ed4dd82e591a061afe2 100644 (file)
@@ -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
index 6851cd7e0fc0ab4c812c39110e1e344d8e5b7eba..3bca90a38a50d8292132ef2133be7193b86ed7bc 100644 (file)
@@ -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, __FILE__, __LINE__, __FUNCTION__, \
+                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).  */