* [PATCH] Destroy arguments for _Cilk_spawn calling in the child (PR 80038)
@ 2017-03-31 13:58 Xi Ruoyao
2017-04-06 17:12 ` Jeff Law
0 siblings, 1 reply; 20+ messages in thread
From: Xi Ruoyao @ 2017-03-31 13:58 UTC (permalink / raw)
To: gcc-patches; +Cc: ryxi, Florent Hivert
[-- Attachment #1: Type: text/plain, Size: 2337 bytes --]
Hi,
I''ve sent this patch once (<https://gcc.gnu.org/ml/gcc-patches/2017-03/msg01261.html>).
But I haven't got any response. Â I'd like to resend it instead of pinging, and explain it more.
There was an ancient bug PR middle-end/60586 before r227423. Â At that time GCC evaluated
parameters inside spawn worker, and violated Intel cilk spec. Â To fix it, Balaji V. Iyer explictly
gimplified the "_Cilk_spawn" arguments in the caller, outside of "_cilk_spn_x" helpers.
However there is an unwanted side-effect with r227423. Â Gimplifying arguments in the caller
produced destruction sequence of the arguments in the caller too. Â So the caller would
destruct arguments even if the spawned callee is still running. Â Then the program just dumps
core, or produces wrong result.
For example, NumericMonoid <https://github.com/hivert/NumericMonoid>Â produce wrong
answer in GCC 6/7. Â And passing STL containers as _Cilk_spawn arguments would likely make
the program dump core.
This is also an Intel cilk spec violation, since the spec explicitly contrains the destruction
of arguments in the child. Â See the spec
<https://www.cilkplus.org/sites/default/files/open_specifications/Intel_Cilk_plus_lang_spec_1.2.htm>
3.6 [4]:
> Any unnamed temporary variables created prior to the spawn point are not destroyed until
> after the spawn point (i.e., *their destructors are invoked in the child*).
To fix this, I reverted r227423 at first. Â But the revertion reintroduced PR 60586. Â So I re-fixed
it without violating the spec. Â The pedigree operations are merged into built-in function
_cilkrts_detach like the version in cilk_fake.h within libcilkrts. Â Then we just insert a call to it
in the exact correct location in GIMPLE instead of tree. Â In the tree the argument evaluation
and function call is just a CALL_EXPR and we can not seperate them. Â But in GIMPLE we can
insert detach sequence between them.
The patch has 500+ lines so I would attach it.
Although 80038 is a "c++" PR in the bugzilla, I think it should be "middle-end".
Maybe we should reclassify PR 80038 and modify the ChangeLog as well.
This patch has been bootstrapped and regtested in x86_64-linux-gnu. Â Is it
OK for trunk?
--
Xi Ruoyao <ryxi@stu.xidian.edu.cn>
School of Aerospace Science and Technology, Xidian University
[-- Attachment #2: the patch --]
[-- Type: text/x-patch, Size: 22438 bytes --]
From dfbce2c4aafd4a555ef751af2d7422d2ba79189b Mon Sep 17 00:00:00 2001
From: Xi Ruoyao <xry111@stu.xidian.edu.cn>
Date: Fri, 24 Mar 2017 04:35:23 +0800
Subject: [PATCH] Destroy temps for _Cilk_spawn calling in the child (PR
c++/80038)
Revert r227423, and re-fix PR60586 without breaking cilk specs.
2017-03-24 Xi Ruoyao <ryxi@stu.xidian.edu.cn>
PR c++/80038
* c-family/c-common.h (cilk_gimplify_call_params_in_spawned_fn,
cilk_install_body_pedigree_operations): Remove prototypes.
* c-family/c-gimplify.c (c_gimplify_expr): Remove the calls to
the function cilk_gimplify_call_params_in_spawned_fn.
* c-family/cilk.c: (cilk_set_spawn_marker): Mark the function
calls which should be detached.
(cilk_gimplify_call_params_in_spawned_fn,
cilk_install_body_pedigree_operations): Remove function.
(gimplify_cilk_spawn): Add EXPR_STMT and CLEANUP_POINT_EXPR
unwrapping.
* c/c-typeck.c (cilk_install_body_with_frame_cleanup):
Don't add pedigree operation and detach call here.
* cp/cp-cilkplus.c (cilk_install_body_with_frame_cleanup): Ditto.
* cp/cp-gimplify.c (cilk_cp_gimplify_call_params_in_spawned_fn):
Remove function.
(cp_gimplify_expr): Remove the calls to the function
cilk_cp_gimplify_call_params_in_spawned_fn.
* cp/semantics.c: Preserve the flag of function calls should
be detached.
* cilk_common.c (expand_builtin_cilk_detach): Move pedigree
operations here.
* gimplify.c (gimplify_cilk_detach): New static function.
(gimplify_call_expr, gimplify_modify_expr): Call it for the
function calls should be detached.
* lto/lto-lang.c (lto_init): Set in_lto_p earlier.
* tree-core.h: Document new macro EXPR_CILK_SPAWN.
* tree.h: Add new macro EXPR_CILK_SPAWN.
* testsuite/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 ac86712..40b9845 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 b4f61b0..5d4d70b 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -14203,14 +14203,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 ebb5da9..91d67c0 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. */
@@ -648,11 +629,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;
}
@@ -667,10 +644,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);
@@ -788,20 +762,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 bcfdd66..7f67c9f 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -4102,6 +4102,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 fbf136f..547507a 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -3069,6 +3069,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. */
@@ -3105,6 +3118,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;
@@ -3336,6 +3352,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);
@@ -5610,6 +5628,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 2b1759e..efed993 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 aa137e4..d274015 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, __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). */
--
2.7.1
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] Destroy arguments for _Cilk_spawn calling in the child (PR 80038)
2017-03-31 13:58 [PATCH] Destroy arguments for _Cilk_spawn calling in the child (PR 80038) Xi Ruoyao
@ 2017-04-06 17:12 ` Jeff Law
2017-04-07 14:03 ` Xi Ruoyao
0 siblings, 1 reply; 20+ messages in thread
From: Jeff Law @ 2017-04-06 17:12 UTC (permalink / raw)
To: Xi Ruoyao, gcc-patches; +Cc: Florent Hivert
On 03/31/2017 07:50 AM, Xi Ruoyao wrote:
> Hi,
>
> I''ve sent this patch once (<https://gcc.gnu.org/ml/gcc-patches/2017-03/msg01261.html>).
> But I haven't got any response. I'd like to resend it instead of pinging, and explain it more.
There's a couple things going on here. Cilk+ does not currently have a
maintainer, thus review of Cilk+ changes can easily fall through the
cracks. Additionally, the plan is deprecate Cilk+ in gcc-7, so it's
very very low on our priority list.
With the likely deprecation in mind, I've only done a cursory review of
the changes -- mostly to verify that they hit Cilk+ paths only.
What's the purpose behind changing when we set the in_lto_p flag?
Jeff
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] Destroy arguments for _Cilk_spawn calling in the child (PR 80038)
2017-04-06 17:12 ` Jeff Law
@ 2017-04-07 14:03 ` Xi Ruoyao
2017-04-12 21:17 ` Jeff Law
0 siblings, 1 reply; 20+ messages in thread
From: Xi Ruoyao @ 2017-04-07 14:03 UTC (permalink / raw)
To: Jeff Law, gcc-patches; +Cc: ryxi, Florent Hivert
On 2017-04-06 11:12 -0600, Jeff Law wrote:
> With the likely deprecation in mind, I've only done a cursory review ofÂ
> the changes -- mostly to verify that they hit Cilk+ paths only.
> What's the purpose behind changing when we set the in_lto_p flag?
Without that change, GCC with my patch ICEed with _Cilk_spawn and
-flto -O3 -fcilkplus since __cilkrts_stack_frame.ctx's type (array of void *)
was not TYPE_STRUCTURAL_EQUALITY_P in lto stage.
If this change is not proper, I'll work on modifying my patch to work
without touching in_lto_p.
--
Xi Ruoyao <ryxi@stu.xidian.edu.cn>
School of Aerospace Science and Technology, Xidian University
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] Destroy arguments for _Cilk_spawn calling in the child (PR 80038)
2017-04-07 14:03 ` Xi Ruoyao
@ 2017-04-12 21:17 ` Jeff Law
2017-04-13 7:05 ` Richard Biener
0 siblings, 1 reply; 20+ messages in thread
From: Jeff Law @ 2017-04-12 21:17 UTC (permalink / raw)
To: Xi Ruoyao, gcc-patches; +Cc: Florent Hivert
On 04/07/2017 08:02 AM, Xi Ruoyao wrote:
> On 2017-04-06 11:12 -0600, Jeff Law wrote:
>
>> With the likely deprecation in mind, I've only done a cursory review of
>> the changes -- mostly to verify that they hit Cilk+ paths only.
>
>> What's the purpose behind changing when we set the in_lto_p flag?
>
> Without that change, GCC with my patch ICEed with _Cilk_spawn and
> -flto -O3 -fcilkplus since __cilkrts_stack_frame.ctx's type (array of void *)
> was not TYPE_STRUCTURAL_EQUALITY_P in lto stage.
>
> If this change is not proper, I'll work on modifying my patch to work
> without touching in_lto_p.
It's certainly be preferable to not change in_lto_p-- unless Richi wants
to chime in on the safety of setting in_lto_p earlier.
I'm not familiar enough with the LTO interactions to know if movement of
in_lto_p is safe.
Jeff
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] Destroy arguments for _Cilk_spawn calling in the child (PR 80038)
2017-04-12 21:17 ` Jeff Law
@ 2017-04-13 7:05 ` Richard Biener
2017-04-14 7:00 ` Xi Ruoyao
0 siblings, 1 reply; 20+ messages in thread
From: Richard Biener @ 2017-04-13 7:05 UTC (permalink / raw)
To: Jeff Law, Jan Hubicka; +Cc: Xi Ruoyao, GCC Patches, Florent Hivert
On Wed, Apr 12, 2017 at 11:16 PM, Jeff Law <law@redhat.com> wrote:
> On 04/07/2017 08:02 AM, Xi Ruoyao wrote:
>>
>> On 2017-04-06 11:12 -0600, Jeff Law wrote:
>>
>>> With the likely deprecation in mind, I've only done a cursory review of
>>> the changes -- mostly to verify that they hit Cilk+ paths only.
>>
>>
>>> What's the purpose behind changing when we set the in_lto_p flag?
>>
>>
>> Without that change, GCC with my patch ICEed with _Cilk_spawn and
>> -flto -O3 -fcilkplus since __cilkrts_stack_frame.ctx's type (array of void
>> *)
>> was not TYPE_STRUCTURAL_EQUALITY_P in lto stage.
>> If this change is not proper, I'll work on modifying my patch to work
>> without touching in_lto_p.
>
> It's certainly be preferable to not change in_lto_p-- unless Richi wants to
> chime in on the safety of setting in_lto_p earlier.
>
> I'm not familiar enough with the LTO interactions to know if movement of
> in_lto_p is safe.
It should be safe and even technically more correct given we now have
various conditionals in the type building routines in tree.c that check
in_lto_p and avoid setting TYPE_CANONICAL from them -- TYPE_CANONICAL
is re-computed later, and for the builtin types we first zero TYPE_CANONICAL
(see lto.c:read_cgraph_and_symbols).
Now... I think those checks are somewhat wrong given that the middle-end
_does_ create types later, hopefully not ones we use for alias purposes,
but I'm not 100% sure. So it somewhat feels like a hack ;)
So in theory the change is a good one. I'm still nervous at this stage.
Did you verify LTO bootstrap still works with the patch?
CCing Honza who fiddled with this last (and introduced all those
in_lto_p checks).
Thanks,
Richard.
> Jeff
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] Destroy arguments for _Cilk_spawn calling in the child (PR 80038)
2017-04-13 7:05 ` Richard Biener
@ 2017-04-14 7:00 ` Xi Ruoyao
2017-04-15 4:05 ` Xi Ruoyao
0 siblings, 1 reply; 20+ messages in thread
From: Xi Ruoyao @ 2017-04-14 7:00 UTC (permalink / raw)
To: Richard Biener, Jeff Law, Jan Hubicka; +Cc: ryxi, GCC Patches, Florent Hivert
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.
--
Xi Ruoyao <ryxi@stu.xidian.edu.cn>
School of Aerospace Science and Technology, Xidian University
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] Destroy arguments for _Cilk_spawn calling in the child (PR 80038)
2017-04-14 7:00 ` Xi Ruoyao
@ 2017-04-15 4:05 ` Xi Ruoyao
2017-04-25 15:37 ` Jeff Law
0 siblings, 1 reply; 20+ messages in thread
From: Xi Ruoyao @ 2017-04-15 4:05 UTC (permalink / raw)
To: Richard Biener, Jeff Law, Jan Hubicka; +Cc: ryxi, GCC Patches, Florent Hivert
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.
--
Xi Ruoyao <ryxi@stu.xidian.edu.cn>
School of Aerospace Science and Technology, Xidian University
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] Destroy arguments for _Cilk_spawn calling in the child (PR 80038)
2017-04-15 4:05 ` Xi Ruoyao
@ 2017-04-25 15:37 ` Jeff Law
2017-04-28 14:51 ` Xi Ruoyao
2017-08-21 17:33 ` [PATCH, gcc-7-branch] Backport PR80038 Xi Ruoyao
0 siblings, 2 replies; 20+ messages in thread
From: Jeff Law @ 2017-04-25 15:37 UTC (permalink / raw)
To: Xi Ruoyao, Richard Biener, Jan Hubicka; +Cc: GCC Patches, Florent Hivert
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.
jeff
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] Destroy arguments for _Cilk_spawn calling in the child (PR 80038)
2017-04-25 15:37 ` Jeff Law
@ 2017-04-28 14:51 ` Xi Ruoyao
2017-04-28 15:29 ` Jeff Law
2017-08-21 17:33 ` [PATCH, gcc-7-branch] Backport PR80038 Xi Ruoyao
1 sibling, 1 reply; 20+ messages in thread
From: Xi Ruoyao @ 2017-04-28 14:51 UTC (permalink / raw)
To: Jeff Law, Richard Biener, Jan Hubicka; +Cc: ryxi, GCC Patches, Florent Hivert
On 2017-04-25 09:30 -0600, Jeff Law wrote:
> Given Richi's general agreement around the in_lto_p, let's go with theÂ
> patch on the trunk only.
Should I prepare (re-diff) a patch for current trunk?
> 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.
>
I just noticed GCC 7.0 has been frozen.
--
Xi Ruoyao <ryxi@stu.xidian.edu.cn>
School of Aerospace Science and Technology, Xidian University
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] Destroy arguments for _Cilk_spawn calling in the child (PR 80038)
2017-04-28 14:51 ` Xi Ruoyao
@ 2017-04-28 15:29 ` Jeff Law
2017-04-29 8:51 ` [PATCH v2] " Xi Ruoyao
0 siblings, 1 reply; 20+ messages in thread
From: Jeff Law @ 2017-04-28 15:29 UTC (permalink / raw)
To: Xi Ruoyao, Richard Biener, Jan Hubicka; +Cc: GCC Patches, Florent Hivert
On 04/28/2017 08:31 AM, Xi Ruoyao wrote:
> On 2017-04-25 09:30 -0600, Jeff Law wrote:
>
>> Given Richi's general agreement around the in_lto_p, let's go with the
>> patch on the trunk only.
>
> Should I prepare (re-diff) a patch for current trunk?
If you want for the trunk, yes.
>
>> 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.
>>
>
> I just noticed GCC 7.0 has been frozen.
Right. It'd be for the maintenance release that will likely happen in
the summer.
jeff
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v2] Destroy arguments for _Cilk_spawn calling in the child (PR 80038)
2017-04-28 15:29 ` Jeff Law
@ 2017-04-29 8:51 ` Xi Ruoyao
2017-05-01 22:26 ` Jeff Law
0 siblings, 1 reply; 20+ messages in thread
From: Xi Ruoyao @ 2017-04-29 8:51 UTC (permalink / raw)
To: Jeff Law, Richard Biener, Jan Hubicka; +Cc: ryxi, GCC Patches, Florent Hivert
[-- Attachment #1: Type: text/plain, Size: 310 bytes --]
On 2017-04-28 08:42 -0600, Jeff Law wrote:
> On 04/28/2017 08:31 AM, Xi Ruoyao wrote:
> > Should I prepare (re-diff) a patch for current trunk?
> If you want for the trunk, yes.
Rediff for current GCC trunk.
--
Xi Ruoyao <ryxi@stu.xidian.edu.cn>
School of Aerospace Science and Technology, Xidian University
[-- Attachment #2: the patch --]
[-- Type: text/x-patch, Size: 22438 bytes --]
From aa16cfe3b8f949abc0bb2da4e09f7f61bd01a05d Mon Sep 17 00:00:00 2001
From: Xi Ruoyao <xry111@stu.xidian.edu.cn>
Date: Fri, 24 Mar 2017 04:35:23 +0800
Subject: [PATCH] Destroy temps for _Cilk_spawn calling in the child (PR
c++/80038)
Revert r227423, and re-fix PR60586 without breaking cilk specs.
2017-03-24 Xi Ruoyao <ryxi@stu.xidian.edu.cn>
PR c++/80038
* c-family/c-common.h (cilk_gimplify_call_params_in_spawned_fn,
cilk_install_body_pedigree_operations): Remove prototypes.
* c-family/c-gimplify.c (c_gimplify_expr): Remove the calls to
the function cilk_gimplify_call_params_in_spawned_fn.
* c-family/cilk.c: (cilk_set_spawn_marker): Mark the function
calls which should be detached.
(cilk_gimplify_call_params_in_spawned_fn,
cilk_install_body_pedigree_operations): Remove function.
(gimplify_cilk_spawn): Add EXPR_STMT and CLEANUP_POINT_EXPR
unwrapping.
* c/c-typeck.c (cilk_install_body_with_frame_cleanup):
Don't add pedigree operation and detach call here.
* cp/cp-cilkplus.c (cilk_install_body_with_frame_cleanup): Ditto.
* cp/cp-gimplify.c (cilk_cp_gimplify_call_params_in_spawned_fn):
Remove function.
(cp_gimplify_expr): Remove the calls to the function
cilk_cp_gimplify_call_params_in_spawned_fn.
* cp/semantics.c: Preserve the flag of function calls should
be detached.
* cilk_common.c (expand_builtin_cilk_detach): Move pedigree
operations here.
* gimplify.c (gimplify_cilk_detach): New static function.
(gimplify_call_expr, gimplify_modify_expr): Call it for the
function calls should be detached.
* lto/lto-lang.c (lto_init): Set in_lto_p earlier.
* tree-core.h: Document new macro EXPR_CILK_SPAWN.
* tree.h: Add new macro EXPR_CILK_SPAWN.
* testsuite/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 ff239e2..6f9909c 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 f2c5296..de62414 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 0a69500..4db2462 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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)
{
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index c69d5b9..fd27eb1 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -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
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 6851cd7..3bca90a 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, __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). */
--
2.7.1
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v2] Destroy arguments for _Cilk_spawn calling in the child (PR 80038)
2017-04-29 8:51 ` [PATCH v2] " Xi Ruoyao
@ 2017-05-01 22:26 ` Jeff Law
2017-05-02 7:56 ` Andreas Schwab
0 siblings, 1 reply; 20+ messages in thread
From: Jeff Law @ 2017-05-01 22:26 UTC (permalink / raw)
To: Xi Ruoyao, Richard Biener, Jan Hubicka; +Cc: GCC Patches, Florent Hivert
On 04/28/2017 09:20 PM, Xi Ruoyao wrote:
> On 2017-04-28 08:42 -0600, Jeff Law wrote:
>> On 04/28/2017 08:31 AM, Xi Ruoyao wrote:
>>> Should I prepare (re-diff) a patch for current trunk?
>> If you want for the trunk, yes.
> Rediff for current GCC trunk.
> -- Xi Ruoyao <ryxi@stu.xidian.edu.cn> School of Aerospace Science and
> Technology, Xidian University
>
>
> pr80038-v2.patch
>
>
> From aa16cfe3b8f949abc0bb2da4e09f7f61bd01a05d Mon Sep 17 00:00:00 2001
> From: Xi Ruoyao<xry111@stu.xidian.edu.cn>
> Date: Fri, 24 Mar 2017 04:35:23 +0800
> Subject: [PATCH] Destroy temps for _Cilk_spawn calling in the child (PR
> c++/80038)
>
> Revert r227423, and re-fix PR60586 without breaking cilk specs.
>
> 2017-03-24 Xi Ruoyao<ryxi@stu.xidian.edu.cn>
>
> PR c++/80038
> * c-family/c-common.h (cilk_gimplify_call_params_in_spawned_fn,
> cilk_install_body_pedigree_operations): Remove prototypes.
> * c-family/c-gimplify.c (c_gimplify_expr): Remove the calls to
> the function cilk_gimplify_call_params_in_spawned_fn.
> * c-family/cilk.c: (cilk_set_spawn_marker): Mark the function
> calls which should be detached.
> (cilk_gimplify_call_params_in_spawned_fn,
> cilk_install_body_pedigree_operations): Remove function.
> (gimplify_cilk_spawn): Add EXPR_STMT and CLEANUP_POINT_EXPR
> unwrapping.
> * c/c-typeck.c (cilk_install_body_with_frame_cleanup):
> Don't add pedigree operation and detach call here.
> * cp/cp-cilkplus.c (cilk_install_body_with_frame_cleanup): Ditto.
> * cp/cp-gimplify.c (cilk_cp_gimplify_call_params_in_spawned_fn):
> Remove function.
> (cp_gimplify_expr): Remove the calls to the function
> cilk_cp_gimplify_call_params_in_spawned_fn.
> * cp/semantics.c: Preserve the flag of function calls should
> be detached.
> * cilk_common.c (expand_builtin_cilk_detach): Move pedigree
> operations here.
> * gimplify.c (gimplify_cilk_detach): New static function.
> (gimplify_call_expr, gimplify_modify_expr): Call it for the
> function calls should be detached.
> * lto/lto-lang.c (lto_init): Set in_lto_p earlier.
> * tree-core.h: Document new macro EXPR_CILK_SPAWN.
> * tree.h: Add new macro EXPR_CILK_SPAWN.
> * testsuite/g++.dg/cilk-plus/CK/pr80038.cc: New test.
Thanks. I fixed up the ChangeLog and installed this on the trunk.
jeff
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v2] Destroy arguments for _Cilk_spawn calling in the child (PR 80038)
2017-05-01 22:26 ` Jeff Law
@ 2017-05-02 7:56 ` Andreas Schwab
2017-05-02 8:18 ` Xi Ruoyao
0 siblings, 1 reply; 20+ messages in thread
From: Andreas Schwab @ 2017-05-02 7:56 UTC (permalink / raw)
To: Jeff Law
Cc: Xi Ruoyao, Richard Biener, Jan Hubicka, GCC Patches, Florent Hivert
This could be related to --enable-checking=release:
In file included from ../../gcc/c-family/c-common.h:26:0,
from ../../gcc/c-family/cilk.c:28:
../../gcc/c-family/cilk.c: In function 'bool cilk_set_spawn_marker(location_t, tree)':
../../gcc/tree.h:901:42: error: 'tree_check2' was not declared in this scope
CALL_EXPR, AGGR_INIT_EXPR)->base.u.bits.unsigned_flag)
^
../../gcc/c-family/cilk.c:113:9: note: in expansion of macro 'EXPR_CILK_SPAWN'
EXPR_CILK_SPAWN (fcall) = 1;
^
../../gcc/tree.h:901:42: error: 'tree_check2' was not declared in this scope
CALL_EXPR, AGGR_INIT_EXPR)->base.u.bits.unsigned_flag)
^
../../gcc/c-family/cilk.c:115:9: note: in expansion of macro 'EXPR_CILK_SPAWN'
EXPR_CILK_SPAWN (TREE_OPERAND (fcall, 1)) = 1;
^
Andreas.
--
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v2] Destroy arguments for _Cilk_spawn calling in the child (PR 80038)
2017-05-02 7:56 ` Andreas Schwab
@ 2017-05-02 8:18 ` Xi Ruoyao
2017-05-02 15:45 ` Jeff Law
0 siblings, 1 reply; 20+ messages in thread
From: Xi Ruoyao @ 2017-05-02 8:18 UTC (permalink / raw)
To: Andreas Schwab, Jeff Law
Cc: ryxi, Richard Biener, Jan Hubicka, GCC Patches, Florent Hivert
On 2017-05-02 09:16 +0200, Andreas Schwab wrote:
> This could be related to --enable-checking=release:
>
> In file included from ../../gcc/c-family/c-common.h:26:0,
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â from ../../gcc/c-family/cilk.c:28:
> ../../gcc/c-family/cilk.c: In function 'bool cilk_set_spawn_marker(location_t, tree)':
> ../../gcc/tree.h:901:42: error: 'tree_check2' was not declared in this scope
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â CALL_EXPR, AGGR_INIT_EXPR)->base.u.bits.unsigned_flag)
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ^
> ../../gcc/c-family/cilk.c:113:9: note: in expansion of macro 'EXPR_CILK_SPAWN'
> Â Â Â Â Â Â Â Â Â EXPR_CILK_SPAWN (fcall) = 1;
> Â Â Â Â Â Â Â Â Â ^
> ../../gcc/tree.h:901:42: error: 'tree_check2' was not declared in this scope
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â CALL_EXPR, AGGR_INIT_EXPR)->base.u.bits.unsigned_flag)
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ^
> ../../gcc/c-family/cilk.c:115:9: note: in expansion of macro 'EXPR_CILK_SPAWN'
> Â Â Â Â Â Â Â Â Â EXPR_CILK_SPAWN (TREE_OPERAND (fcall, 1)) = 1;
> Â Â Â Â Â Â Â Â Â ^
>
> Andreas.
>
Sorry T_T. Â I've made a stupid mistake in tree.h.
Let's apply following patch, and alert the RM when backporting r247446.
2017-05-02 Xi Ruoyao <ryxi@stu.xidian.edu.cn>
* tree.h (EXPR_CILK_SPAWN): Use macro TREE_CHECK2 instead of
function tree_check2.
---
 gcc/tree.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/gcc/tree.h b/gcc/tree.h
index 3bca90a..fdaa7af 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -897,8 +897,8 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
 /* 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)
+Â Â (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
--Â
2.7.1
--
Xi Ruoyao <ryxi@stu.xidian.edu.cn>
School of Aerospace Science and Technology, Xidian University
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v2] Destroy arguments for _Cilk_spawn calling in the child (PR 80038)
2017-05-02 8:18 ` Xi Ruoyao
@ 2017-05-02 15:45 ` Jeff Law
0 siblings, 0 replies; 20+ messages in thread
From: Jeff Law @ 2017-05-02 15:45 UTC (permalink / raw)
To: Xi Ruoyao, Andreas Schwab
Cc: Richard Biener, Jan Hubicka, GCC Patches, Florent Hivert
On 05/02/2017 01:56 AM, Xi Ruoyao wrote:
> On 2017-05-02 09:16 +0200, Andreas Schwab wrote:
>
>> This could be related to --enable-checking=release:
>>
>> In file included from ../../gcc/c-family/c-common.h:26:0,
>> from ../../gcc/c-family/cilk.c:28:
>> ../../gcc/c-family/cilk.c: In function 'bool cilk_set_spawn_marker(location_t, tree)':
>> ../../gcc/tree.h:901:42: error: 'tree_check2' was not declared in this scope
>> CALL_EXPR, AGGR_INIT_EXPR)->base.u.bits.unsigned_flag)
>> ^
>> ../../gcc/c-family/cilk.c:113:9: note: in expansion of macro 'EXPR_CILK_SPAWN'
>> EXPR_CILK_SPAWN (fcall) = 1;
>> ^
>> ../../gcc/tree.h:901:42: error: 'tree_check2' was not declared in this scope
>> CALL_EXPR, AGGR_INIT_EXPR)->base.u.bits.unsigned_flag)
>> ^
>> ../../gcc/c-family/cilk.c:115:9: note: in expansion of macro 'EXPR_CILK_SPAWN'
>> EXPR_CILK_SPAWN (TREE_OPERAND (fcall, 1)) = 1;
>> ^
>>
>> Andreas.
>>
>
> Sorry T_T. I've made a stupid mistake in tree.h.
>
> Let's apply following patch, and alert the RM when backporting r247446.
>
> 2017-05-02 Xi Ruoyao <ryxi@stu.xidian.edu.cn>
>
> * tree.h (EXPR_CILK_SPAWN): Use macro TREE_CHECK2 instead of
> function tree_check2.
THanks. Installed.
jeff
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH, gcc-7-branch] Backport PR80038
2017-04-25 15:37 ` Jeff Law
2017-04-28 14:51 ` Xi Ruoyao
@ 2017-08-21 17:33 ` Xi Ruoyao
2017-08-21 17:46 ` Xi Ruoyao
1 sibling, 1 reply; 20+ messages in thread
From: Xi Ruoyao @ 2017-08-21 17:33 UTC (permalink / raw)
To: Jeff Law, Richard Biener, Jan Hubicka; +Cc: ryxi, GCC Patches
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?
--
Xi Ruoyao <ryxi@stu.xidian.edu.cn>
School of Aerospace Science and Technology, Xidian University
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH, gcc-7-branch] Backport PR80038
2017-08-21 17:33 ` [PATCH, gcc-7-branch] Backport PR80038 Xi Ruoyao
@ 2017-08-21 17:46 ` Xi Ruoyao
2017-08-22 9:04 ` Richard Biener
0 siblings, 1 reply; 20+ messages in thread
From: Xi Ruoyao @ 2017-08-21 17:46 UTC (permalink / raw)
To: Jeff Law, Richard Biener, Jan Hubicka; +Cc: ryxi, GCC Patches
[-- Attachment #1: Type: text/plain, Size: 1137 bytes --]
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
[-- Attachment #2: Type: text/x-patch, Size: 22585 bytes --]
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
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH, gcc-7-branch] Backport PR80038
2017-08-21 17:46 ` Xi Ruoyao
@ 2017-08-22 9:04 ` Richard Biener
2017-08-24 13:06 ` Xi Ruoyao
0 siblings, 1 reply; 20+ messages in thread
From: Richard Biener @ 2017-08-22 9:04 UTC (permalink / raw)
To: Xi Ruoyao; +Cc: Jeff Law, Jan Hubicka, GCC Patches
On Mon, Aug 21, 2017 at 5:39 PM, Xi Ruoyao <ryxi@stu.xidian.edu.cn> wrote:
> 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.
Ok for the gcc 7 branch.
Thanks,
Richard.
> --
> Xi Ruoyao <ryxi@stu.xidian.edu.cn>
> School of Aerospace Science and Technology, Xidian University
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH, gcc-7-branch] Backport PR80038
2017-08-22 9:04 ` Richard Biener
@ 2017-08-24 13:06 ` Xi Ruoyao
2017-09-06 4:33 ` Xi Ruoyao
0 siblings, 1 reply; 20+ messages in thread
From: Xi Ruoyao @ 2017-08-24 13:06 UTC (permalink / raw)
To: Richard Biener; +Cc: ryxi, Jeff Law, Jan Hubicka, GCC Patches
On 2017-08-22 10:17 +0200, Richard Biener wrote:
>
> Ok for the gcc 7 branch.
>
Well, I think I should say I don't have SVN write access...
--
Xi Ruoyao <ryxi@stu.xidian.edu.cn>
School of Aerospace Science and Technology, Xidian University
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH, gcc-7-branch] Backport PR80038
2017-08-24 13:06 ` Xi Ruoyao
@ 2017-09-06 4:33 ` Xi Ruoyao
0 siblings, 0 replies; 20+ messages in thread
From: Xi Ruoyao @ 2017-09-06 4:33 UTC (permalink / raw)
To: Richard Biener; +Cc: ryxi, Jeff Law, Jan Hubicka, GCC Patches
[-- Attachment #1: Type: text/plain, Size: 429 bytes --]
On 2017-08-24 20:17 +0800, Xi Ruoyao wrote:
> On 2017-08-22 10:17 +0200, Richard Biener wrote:
> >
> > Ok for the gcc 7 branch.
> >
>
> Well, I think I should say I don't have SVN write access...
Still not installed. Make a rediff.
We don't have a Cilk maintainer now... Someone please install the patch
for gcc 7 branch.
--
Xi Ruoyao <ryxi@stu.xidian.edu.cn>
School of Aerospace Science and Technology, Xidian University
[-- Attachment #2: Type: text/x-patch, Size: 22584 bytes --]
From cfa279f562759ced4274c0426da9f5d791e146b5 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 eae2a55..ad05192 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 375edcd..8832a50 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
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2017-09-06 4:33 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-31 13:58 [PATCH] Destroy arguments for _Cilk_spawn calling in the child (PR 80038) Xi Ruoyao
2017-04-06 17:12 ` Jeff Law
2017-04-07 14:03 ` Xi Ruoyao
2017-04-12 21:17 ` Jeff Law
2017-04-13 7:05 ` Richard Biener
2017-04-14 7:00 ` Xi Ruoyao
2017-04-15 4:05 ` Xi Ruoyao
2017-04-25 15:37 ` Jeff Law
2017-04-28 14:51 ` Xi Ruoyao
2017-04-28 15:29 ` Jeff Law
2017-04-29 8:51 ` [PATCH v2] " Xi Ruoyao
2017-05-01 22:26 ` Jeff Law
2017-05-02 7:56 ` Andreas Schwab
2017-05-02 8:18 ` Xi Ruoyao
2017-05-02 15:45 ` Jeff Law
2017-08-21 17:33 ` [PATCH, gcc-7-branch] Backport PR80038 Xi Ruoyao
2017-08-21 17:46 ` Xi Ruoyao
2017-08-22 9:04 ` Richard Biener
2017-08-24 13:06 ` Xi Ruoyao
2017-09-06 4:33 ` Xi Ruoyao
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).