1 /* This file is part of the Intel(R) Cilk(TM) Plus support
2 This file contains the CilkPlus Intrinsics
3 Copyright (C) 2013-2014 Free Software Foundation, Inc.
4 Contributed by Balaji V. Iyer <balaji.v.iyer@intel.com>,
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
14 GCC is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 #include "coretypes.h"
27 #include "stringpool.h"
29 #include "langhooks.h"
30 #include "pointer-set.h"
31 #include "gimple-expr.h"
33 #include "tree-iterator.h"
34 #include "tree-inline.h"
35 #include "c-family/c-common.h"
38 #include "diagnostic.h"
41 enum add_variable_type
{
42 /* Reference to previously-defined variable. */
44 /* Definition of a new variable in inner-scope. */
46 /* Write to possibly previously-defined variable. */
50 enum cilk_block_type
{
51 /* Indicates a _Cilk_spawn block. 30 was an arbitary number picked for
53 CILK_BLOCK_SPAWN
= 30,
54 /* Indicates _Cilk_for statement block. */
60 /* Kind of function to be created. */
61 enum cilk_block_type type
;
62 /* Signature of helper function. */
64 /* Containing function. */
66 /* Disposition of all variables in the inner statement. */
67 struct pointer_map_t
*decl_map
;
68 /* True if this function needs a static chain. */
70 /* Arguments to be passed to wrapper function, currently a list. */
72 /* Argument types, a list. */
74 /* Incoming parameters. */
76 /* Outer BLOCK object. */
80 static void extract_free_variables (tree
, struct wrapper_data
*,
81 enum add_variable_type
);
82 static HOST_WIDE_INT cilk_wrapper_count
;
84 /* Marks the CALL_EXPR or FUNCTION_DECL, FCALL, as a spawned function call
85 and the current function as a spawner. Emit error if the function call
86 is outside a function or if a non function-call is spawned. */
89 cilk_set_spawn_marker (location_t loc
, tree fcall
)
91 if (!current_function_decl
)
93 error_at (loc
, "%<_Cilk_spawn%> may only be used inside a function");
96 else if (fcall
== error_mark_node
)
97 /* Error reporting here is not necessary here since if FCALL is an
98 error_mark_node, the function marking it as error would have reported
101 else if (TREE_CODE (fcall
) != CALL_EXPR
102 && TREE_CODE (fcall
) != FUNCTION_DECL
103 /* In C++, TARGET_EXPR is generated when we have an overloaded
105 && TREE_CODE (fcall
) != TARGET_EXPR
)
107 error_at (loc
, "only function calls can be spawned");
112 cfun
->calls_cilk_spawn
= true;
117 /* This function will output the exit conditions for a spawn call. */
120 create_cilk_function_exit (tree frame
, bool detaches
, bool needs_sync
)
122 tree epi
= alloc_stmt_list ();
125 append_to_statement_list (build_cilk_sync (), &epi
);
126 tree func_ptr
= build1 (ADDR_EXPR
, cilk_frame_ptr_type_decl
, frame
);
127 tree pop_frame
= build_call_expr (cilk_pop_fndecl
, 1, func_ptr
);
128 tree worker
= cilk_dot (frame
, CILK_TI_FRAME_WORKER
, 0);
129 tree current
= cilk_arrow (worker
, CILK_TI_WORKER_CUR
, 0);
130 tree parent
= cilk_dot (frame
, CILK_TI_FRAME_PARENT
, 0);
131 tree set_current
= build2 (MODIFY_EXPR
, void_type_node
, current
, parent
);
132 append_to_statement_list (set_current
, &epi
);
133 append_to_statement_list (pop_frame
, &epi
);
134 tree call
= build_call_expr (cilk_leave_fndecl
, 1, func_ptr
);
137 tree flags
= cilk_dot (frame
, CILK_TI_FRAME_FLAGS
, false);
138 tree flags_cmp_expr
= fold_build2 (NE_EXPR
, TREE_TYPE (flags
), flags
,
139 build_int_cst (TREE_TYPE (flags
),
140 CILK_FRAME_VERSION
));
141 call
= fold_build3 (COND_EXPR
, void_type_node
, flags_cmp_expr
,
142 call
, build_empty_stmt (EXPR_LOCATION (flags
)));
144 append_to_statement_list (call
, &epi
);
148 /* Trying to get the correct cfun for the FUNCTION_DECL indicated by OUTER. */
151 pop_cfun_to (tree outer
)
154 current_function_decl
= outer
;
155 gcc_assert (cfun
== DECL_STRUCT_FUNCTION (current_function_decl
));
156 gcc_assert (cfun
->decl
== current_function_decl
);
159 /* This function does whatever is necessary to make the compiler emit a newly
160 generated function, FNDECL. */
163 call_graph_add_fn (tree fndecl
)
165 const tree outer
= current_function_decl
;
166 struct function
*f
= DECL_STRUCT_FUNCTION (fndecl
);
167 gcc_assert (TREE_CODE (fndecl
) == FUNCTION_DECL
);
169 f
->is_cilk_function
= 1;
170 f
->curr_properties
= cfun
->curr_properties
;
171 gcc_assert (cfun
== DECL_STRUCT_FUNCTION (outer
));
172 gcc_assert (cfun
->decl
== outer
);
175 cgraph_create_node (fndecl
);
179 /* Return true if this is a tree which is allowed to contain a spawn as
181 A spawn call may be wrapped in a series of unary operations such
182 as conversions. These conversions need not be "useless"
183 to be disregarded because they are retained in the spawned
184 statement. They are bypassed only to look for a spawn
186 A comparison to constant is simple enough to allow, and
187 is used to convert to bool. */
190 cilk_ignorable_spawn_rhs_op (tree exp
)
192 enum tree_code code
= TREE_CODE (exp
);
193 switch (TREE_CODE_CLASS (code
))
196 return code
== ADDR_EXPR
;
198 /* We need the spawn as operand 0 for now. That's where it
199 appears in the only case we really care about, conversion
201 return (TREE_CODE (TREE_OPERAND (exp
, 1)) == INTEGER_CST
);
210 /* Helper function for walk_tree. If *TP is a CILK_SPAWN_STMT, then unwrap
211 this "wrapper." The function returns NULL_TREE regardless. */
214 unwrap_cilk_spawn_stmt (tree
*tp
, int *walk_subtrees
, void *)
216 if (TREE_CODE (*tp
) == CILK_SPAWN_STMT
)
218 *tp
= CILK_SPAWN_FN (*tp
);
224 /* Returns true when EXP is a CALL_EXPR with _Cilk_spawn in front. Unwraps
225 CILK_SPAWN_STMT wrapper from the CALL_EXPR in *EXP0 statement. */
228 recognize_spawn (tree exp
, tree
*exp0
)
230 bool spawn_found
= false;
231 if (TREE_CODE (exp
) == CILK_SPAWN_STMT
)
233 /* Remove the CALL_EXPR from CILK_SPAWN_STMT wrapper. */
234 exp
= CILK_SPAWN_FN (exp
);
235 walk_tree (exp0
, unwrap_cilk_spawn_stmt
, NULL
, NULL
);
241 /* Returns true if *EXP0 is a recognized form of spawn. Recognized forms are,
242 after conversion to void, a call expression at outer level or an assignment
243 at outer level with the right hand side being a spawned call.
244 In addition to this, it also unwraps the CILK_SPAWN_STMT cover from the
245 CALL_EXPR that is being spawned.
246 Note that `=' in C++ may turn into a CALL_EXPR rather than a MODIFY_EXPR. */
249 cilk_detect_spawn_and_unwrap (tree
*exp0
)
253 if (!TREE_SIDE_EFFECTS (exp
))
256 /* Strip off any conversion to void. It does not affect whether spawn
257 is supported here. */
258 if (TREE_CODE (exp
) == CONVERT_EXPR
&& VOID_TYPE_P (TREE_TYPE (exp
)))
259 exp
= TREE_OPERAND (exp
, 0);
261 if (TREE_CODE (exp
) == MODIFY_EXPR
|| TREE_CODE (exp
) == INIT_EXPR
)
262 exp
= TREE_OPERAND (exp
, 1);
264 while (cilk_ignorable_spawn_rhs_op (exp
))
265 exp
= TREE_OPERAND (exp
, 0);
267 if (TREE_CODE (exp
) == TARGET_EXPR
)
268 if (TARGET_EXPR_INITIAL (exp
)
269 && TREE_CODE (TARGET_EXPR_INITIAL (exp
)) != AGGR_INIT_EXPR
)
270 exp
= TARGET_EXPR_INITIAL (exp
);
272 /* Happens with C++ TARGET_EXPR. */
273 if (exp
== NULL_TREE
)
276 while (TREE_CODE (exp
) == CLEANUP_POINT_EXPR
|| TREE_CODE (exp
) == EXPR_STMT
)
277 exp
= TREE_OPERAND (exp
, 0);
279 /* Now we should have a CALL_EXPR with a CILK_SPAWN_STMT wrapper around
280 it, or return false. */
281 if (recognize_spawn (exp
, exp0
))
286 /* This function will build and return a FUNCTION_DECL using information
290 create_cilk_helper_decl (struct wrapper_data
*wd
)
293 if (wd
->type
== CILK_BLOCK_FOR
)
294 sprintf (name
, "_cilk_for_" HOST_WIDE_INT_PRINT_DEC
, cilk_wrapper_count
++);
295 else if (wd
->type
== CILK_BLOCK_SPAWN
)
296 sprintf (name
, "_cilk_spn_" HOST_WIDE_INT_PRINT_DEC
, cilk_wrapper_count
++);
300 clean_symbol_name (name
);
301 tree fndecl
= build_decl (UNKNOWN_LOCATION
, FUNCTION_DECL
,
302 get_identifier (name
), wd
->fntype
);
304 TREE_PUBLIC (fndecl
) = 0;
305 TREE_STATIC (fndecl
) = 1;
306 TREE_USED (fndecl
) = 1;
307 DECL_ARTIFICIAL (fndecl
) = 0;
308 DECL_IGNORED_P (fndecl
) = 0;
309 DECL_EXTERNAL (fndecl
) = 0;
311 DECL_CONTEXT (fndecl
) = wd
->context
;
312 tree block
= make_node (BLOCK
);
313 DECL_INITIAL (fndecl
) = block
;
314 TREE_USED (block
) = 1;
315 gcc_assert (!DECL_SAVED_TREE (fndecl
));
317 /* Inlining would defeat the purpose of this wrapper.
318 Either it secretly switches stack frames or it allocates
319 a stable stack frame to hold function arguments even if
320 the parent stack frame is stolen. */
321 DECL_UNINLINABLE (fndecl
) = 1;
323 tree result_decl
= build_decl (UNKNOWN_LOCATION
, RESULT_DECL
, NULL_TREE
,
325 DECL_ARTIFICIAL (result_decl
) = 0;
326 DECL_IGNORED_P (result_decl
) = 1;
327 DECL_CONTEXT (result_decl
) = fndecl
;
328 DECL_RESULT (fndecl
) = result_decl
;
333 /* A function used by walk tree to find wrapper parms. */
336 wrapper_parm_cb (const void *key0
, void **val0
, void *data
)
338 struct wrapper_data
*wd
= (struct wrapper_data
*) data
;
339 tree arg
= * (tree
*)&key0
;
340 tree val
= (tree
)*val0
;
343 if (val
== error_mark_node
|| val
== arg
)
346 if (TREE_CODE (val
) == PAREN_EXPR
)
348 /* We should not reach here with a register receiver.
349 We may see a register variable modified in the
350 argument list. Because register variables are
351 worker-local we don't need to work hard to support
352 them in code that spawns. */
353 if ((TREE_CODE (arg
) == VAR_DECL
) && DECL_HARD_REGISTER (arg
))
355 error_at (EXPR_LOCATION (arg
),
356 "explicit register variable %qD may not be modified in "
358 arg
= null_pointer_node
;
361 arg
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (arg
)), arg
);
363 val
= TREE_OPERAND (val
, 0);
365 gcc_assert (TREE_CODE (val
) == INDIRECT_REF
);
366 parm
= TREE_OPERAND (val
, 0);
371 TREE_CHAIN (parm
) = wd
->parms
;
373 wd
->argtypes
= tree_cons (NULL_TREE
, TREE_TYPE (parm
), wd
->argtypes
);
374 wd
->arglist
= tree_cons (NULL_TREE
, arg
, wd
->arglist
);
378 /* This function is used to build a wrapper of a certain type. */
381 build_wrapper_type (struct wrapper_data
*wd
)
383 wd
->arglist
= NULL_TREE
;
384 wd
->parms
= NULL_TREE
;
385 wd
->argtypes
= void_list_node
;
387 pointer_map_traverse (wd
->decl_map
, wrapper_parm_cb
, wd
);
388 gcc_assert (wd
->type
!= CILK_BLOCK_FOR
);
390 /* Now build a function.
391 Its return type is void (all side effects are via explicit parameters).
392 Its parameters are WRAPPER_PARMS with type WRAPPER_TYPES.
393 Actual arguments in the caller are WRAPPER_ARGS. */
394 wd
->fntype
= build_function_type (void_type_node
, wd
->argtypes
);
397 /* This function checks all the CALL_EXPRs in *TP found by cilk_outline. */
400 check_outlined_calls (tree
*tp
, int *walk_subtrees ATTRIBUTE_UNUSED
,
403 bool *throws
= (bool *) data
;
407 if (TREE_CODE (t
) != CALL_EXPR
)
409 flags
= call_expr_flags (t
);
411 if (!(flags
& ECF_NOTHROW
) && flag_exceptions
)
413 if (flags
& ECF_RETURNS_TWICE
)
414 error_at (EXPR_LOCATION (t
),
415 "cannot spawn call to function that returns twice");
419 /* Each DECL in the source code (spawned statement) is passed to this function
420 once. Each instance of the DECL is replaced with the result of this
423 The parameters of the wrapper should have been entered into the map already.
424 This function only deals with variables with scope limited to the
425 spawned expression. */
428 copy_decl_for_cilk (tree decl
, copy_body_data
*id
)
430 switch (TREE_CODE (decl
))
433 return copy_decl_no_change (decl
, id
);
436 error_at (EXPR_LOCATION (decl
), "invalid use of label %q+D in "
439 return error_mark_node
;
443 /* RESULT_DECL and PARM_DECL has already been entered into the map. */
446 return error_mark_node
;
450 /* Copy all local variables. */
453 for_local_cb (const void *k_v
, void **vp
, void *p
)
455 tree k
= *(tree
*) &k_v
;
458 if (v
== error_mark_node
)
459 *vp
= copy_decl_no_change (k
, (copy_body_data
*) p
);
463 /* Copy all local declarations from a _Cilk_spawned function's body. */
466 wrapper_local_cb (const void *k_v
, void **vp
, void *data
)
468 copy_body_data
*id
= (copy_body_data
*) data
;
469 tree key
= *(tree
*) &k_v
;
470 tree val
= (tree
) *vp
;
472 if (val
== error_mark_node
)
473 *vp
= copy_decl_for_cilk (key
, id
);
478 /* Alter a tree STMT from OUTER_FN to form the body of INNER_FN. */
481 cilk_outline (tree inner_fn
, tree
*stmt_p
, void *w
)
483 struct wrapper_data
*wd
= (struct wrapper_data
*) w
;
484 const tree outer_fn
= wd
->context
;
485 const bool nested
= (wd
->type
== CILK_BLOCK_FOR
);
489 DECL_STATIC_CHAIN (outer_fn
) = 1;
491 memset (&id
, 0, sizeof (id
));
492 /* Copy from the function containing the spawn... */
493 id
.src_fn
= outer_fn
;
495 /* ...to the wrapper. */
496 id
.dst_fn
= inner_fn
;
497 id
.src_cfun
= DECL_STRUCT_FUNCTION (outer_fn
);
499 /* There shall be no RETURN in spawn helper. */
501 id
.decl_map
= wd
->decl_map
;
502 id
.copy_decl
= nested
? copy_decl_no_change
: copy_decl_for_cilk
;
503 id
.block
= DECL_INITIAL (inner_fn
);
504 id
.transform_lang_insert_block
= NULL
;
506 id
.transform_new_cfg
= true;
507 id
.transform_call_graph_edges
= CB_CGE_MOVE
;
508 id
.remap_var_for_cilk
= true;
509 id
.regimplify
= true; /* unused? */
511 insert_decl_map (&id
, wd
->block
, DECL_INITIAL (inner_fn
));
513 /* We don't want the private variables any more. */
514 pointer_map_traverse (wd
->decl_map
, nested
? for_local_cb
: wrapper_local_cb
,
516 walk_tree (stmt_p
, copy_tree_body_r
, (void *) &id
, NULL
);
518 /* See if this function can throw or calls something that should
519 not be spawned. The exception part is only necessary if
520 flag_exceptions && !flag_non_call_exceptions. */
522 (void) walk_tree_without_duplicates (stmt_p
, check_outlined_calls
, &throws
);
525 /* Generate the body of a wrapper function that assigns the
526 result of the expression RHS into RECEIVER. RECEIVER must
527 be NULL if this is not a spawn -- the wrapper will return
528 a value. If this is a spawn, the wrapper will return void. */
531 create_cilk_wrapper_body (tree stmt
, struct wrapper_data
*wd
)
533 const tree outer
= current_function_decl
;
537 /* Build the type of the wrapper and its argument list from the
538 variables that it requires. */
539 build_wrapper_type (wd
);
541 /* Emit a function that takes WRAPPER_PARMS incoming and applies ARGS
542 (modified) to the wrapped function. Return the wrapper and modified ARGS
543 to the caller to generate a function call. */
544 fndecl
= create_cilk_helper_decl (wd
);
545 push_struct_function (fndecl
);
546 if (wd
->nested
&& (wd
->type
== CILK_BLOCK_FOR
))
548 gcc_assert (TREE_VALUE (wd
->arglist
) == NULL_TREE
);
549 TREE_VALUE (wd
->arglist
) = build2 (FDESC_EXPR
, ptr_type_node
,
550 fndecl
, integer_one_node
);
552 DECL_ARGUMENTS (fndecl
) = wd
->parms
;
554 for (p
= wd
->parms
; p
; p
= TREE_CHAIN (p
))
555 DECL_CONTEXT (p
) = fndecl
;
557 gcc_assert (!DECL_SAVED_TREE (fndecl
));
558 cilk_install_body_with_frame_cleanup (fndecl
, stmt
, (void *) wd
);
559 gcc_assert (DECL_SAVED_TREE (fndecl
));
563 /* Recognize the new function. */
564 call_graph_add_fn (fndecl
);
568 /* Initializes the wrapper data structure. */
571 init_wd (struct wrapper_data
*wd
, enum cilk_block_type type
)
574 wd
->fntype
= NULL_TREE
;
575 wd
->context
= current_function_decl
;
576 wd
->decl_map
= pointer_map_create ();
577 /* _Cilk_for bodies are always nested. Others start off as
579 wd
->nested
= (type
== CILK_BLOCK_FOR
);
580 wd
->arglist
= NULL_TREE
;
581 wd
->argtypes
= NULL_TREE
;
582 wd
->block
= NULL_TREE
;
585 /* Clears the wrapper data structure. */
588 free_wd (struct wrapper_data
*wd
)
590 pointer_map_destroy (wd
->decl_map
);
592 wd
->arglist
= NULL_TREE
;
593 wd
->argtypes
= NULL_TREE
;
594 wd
->parms
= NULL_TREE
;
598 /* Given a variable in an expression to be extracted into
599 a helper function, declare the helper function parameter
602 On entry the value of the (key, value) pair may be
604 (*, error_mark_node) -- Variable is private to helper function,
607 (var, var) -- Reference to outer scope (function or global scope).
609 (var, integer 0) -- Capture by value, save newly-declared PARM_DECL
610 for value in value slot.
612 (var, integer 1) -- Capture by reference, declare pointer to type
613 as new PARM_DECL and store (spawn_stmt (indirect_ref (parm)).
615 (var, ???) -- Pure output argument, handled similarly to above.
619 declare_one_free_variable (const void *var0
, void **map0
,
620 void *data ATTRIBUTE_UNUSED
)
622 const_tree var
= (const_tree
) var0
;
623 tree map
= (tree
)*map0
;
624 tree var_type
= TREE_TYPE (var
), arg_type
;
628 gcc_assert (DECL_P (var
));
630 /* Ignore truly local variables. */
631 if (map
== error_mark_node
)
633 /* Ignore references to the parent function. */
637 gcc_assert (TREE_CODE (map
) == INTEGER_CST
);
639 /* A value is passed by reference if:
641 1. It is addressable, so that a copy may not be made.
642 2. It is modified in the spawned statement.
643 In the future this function may want to arrange
644 a warning if the spawned statement is a loop body
645 because an output argument would indicate a race.
646 Note: Earlier passes must have marked the variable addressable.
647 3. It is expensive to copy. */
649 (TREE_ADDRESSABLE (var_type
)
650 /* Arrays must be passed by reference. This is required for C
651 semantics -- arrays are not first class objects. Other
652 aggregate types can and should be passed by reference if
653 they are not passed to the spawned function. We aren't yet
654 distinguishing safe uses in argument calculation from unsafe
655 uses as outgoing function arguments, so we make a copy to
656 stabilize the value. */
657 || TREE_CODE (var_type
) == ARRAY_TYPE
658 || (tree
) map
== integer_one_node
);
661 var_type
= build_qualified_type (build_pointer_type (var_type
),
663 gcc_assert (!TREE_ADDRESSABLE (var_type
));
665 /* Maybe promote to int. */
666 if (INTEGRAL_TYPE_P (var_type
) && COMPLETE_TYPE_P (var_type
)
667 && INT_CST_LT_UNSIGNED (TYPE_SIZE (var_type
),
668 TYPE_SIZE (integer_type_node
)))
669 arg_type
= integer_type_node
;
673 parm
= build_decl (UNKNOWN_LOCATION
, PARM_DECL
, NULL_TREE
, var_type
);
674 DECL_ARG_TYPE (parm
) = arg_type
;
675 DECL_ARTIFICIAL (parm
) = 0;
676 TREE_READONLY (parm
) = 1;
680 parm
= build1 (INDIRECT_REF
, TREE_TYPE (var_type
), parm
);
681 parm
= build1 (PAREN_EXPR
, void_type_node
, parm
);
687 /* Returns a wrapper function for a _Cilk_spawn. */
690 create_cilk_wrapper (tree exp
, tree
*args_out
)
692 struct wrapper_data wd
;
695 init_wd (&wd
, CILK_BLOCK_SPAWN
);
697 if (TREE_CODE (exp
) == CONVERT_EXPR
)
698 exp
= TREE_OPERAND (exp
, 0);
700 /* Special handling for top level INIT_EXPR. Usually INIT_EXPR means the
701 variable is defined in the spawned expression and can be private to the
702 spawn helper. A top level INIT_EXPR defines a variable to be initialized
703 by spawn and the variable must remain in the outer function. */
704 if (TREE_CODE (exp
) == INIT_EXPR
)
706 extract_free_variables (TREE_OPERAND (exp
, 0), &wd
, ADD_WRITE
);
707 extract_free_variables (TREE_OPERAND (exp
, 1), &wd
, ADD_READ
);
708 /* TREE_TYPE should be void. Be defensive. */
709 if (TREE_TYPE (exp
) != void_type_node
)
710 extract_free_variables (TREE_TYPE (exp
), &wd
, ADD_READ
);
713 extract_free_variables (exp
, &wd
, ADD_READ
);
714 pointer_map_traverse (wd
.decl_map
, declare_one_free_variable
, &wd
);
715 wd
.block
= TREE_BLOCK (exp
);
717 wd
.block
= DECL_INITIAL (current_function_decl
);
719 /* Now fvars maps the old variable to incoming variable. Update
720 the expression and arguments to refer to the new names. */
721 fndecl
= create_cilk_wrapper_body (exp
, &wd
);
722 *args_out
= wd
.arglist
;
729 /* Transform *SPAWN_P, a spawned CALL_EXPR, to gimple. *SPAWN_P can be a
730 CALL_EXPR, INIT_EXPR or MODIFY_EXPR. Returns GS_OK if everything is fine,
731 and GS_UNHANDLED, otherwise. */
734 gimplify_cilk_spawn (tree
*spawn_p
)
736 tree expr
= *spawn_p
;
737 tree function
, call1
, call2
, new_args
;
738 tree ii_args
= NULL_TREE
;
739 int total_args
= 0, ii
= 0;
741 tree setjmp_cond_expr
= NULL_TREE
;
742 tree setjmp_expr
, spawn_expr
, setjmp_value
= NULL_TREE
;
744 cfun
->calls_cilk_spawn
= 1;
745 cfun
->is_cilk_function
= 1;
747 /* Remove CLEANUP_POINT_EXPR and EXPR_STMT from *spawn_p. */
748 while (TREE_CODE (expr
) == CLEANUP_POINT_EXPR
749 || TREE_CODE (expr
) == EXPR_STMT
)
750 expr
= TREE_OPERAND (expr
, 0);
753 function
= create_cilk_wrapper (expr
, &new_args
);
755 /* This should give the number of parameters. */
756 total_args
= list_length (new_args
);
758 arg_array
= XNEWVEC (tree
, total_args
);
763 for (ii
= 0; ii
< total_args
; ii
++)
765 arg_array
[ii
] = TREE_VALUE (ii_args
);
766 ii_args
= TREE_CHAIN (ii_args
);
769 TREE_USED (function
) = 1;
770 rest_of_decl_compilation (function
, 0, 0);
772 call1
= cilk_call_setjmp (cfun
->cilk_frame_decl
);
774 if (arg_array
== NULL
|| *arg_array
== NULL_TREE
)
775 call2
= build_call_expr (function
, 0);
777 call2
= build_call_expr_loc_array (EXPR_LOCATION (*spawn_p
), function
,
778 total_args
, arg_array
);
779 *spawn_p
= alloc_stmt_list ();
780 tree f_ptr_type
= build_pointer_type (TREE_TYPE (cfun
->cilk_frame_decl
));
781 tree frame_ptr
= build1 (ADDR_EXPR
, f_ptr_type
, cfun
->cilk_frame_decl
);
782 tree save_fp
= build_call_expr (cilk_save_fp_fndecl
, 1, frame_ptr
);
783 append_to_statement_list (save_fp
, spawn_p
);
784 setjmp_value
= create_tmp_var (TREE_TYPE (call1
), NULL
);
785 setjmp_expr
= fold_build2 (MODIFY_EXPR
, void_type_node
, setjmp_value
, call1
);
787 append_to_statement_list_force (setjmp_expr
, spawn_p
);
789 setjmp_cond_expr
= fold_build2 (EQ_EXPR
, TREE_TYPE (call1
), setjmp_value
,
790 build_int_cst (TREE_TYPE (call1
), 0));
791 spawn_expr
= fold_build3 (COND_EXPR
, void_type_node
, setjmp_cond_expr
,
792 call2
, build_empty_stmt (EXPR_LOCATION (call1
)));
793 append_to_statement_list (spawn_expr
, spawn_p
);
798 /* Make the frames necessary for a spawn call. */
801 make_cilk_frame (tree fn
)
803 struct function
*f
= DECL_STRUCT_FUNCTION (fn
);
806 if (f
->cilk_frame_decl
)
807 return f
->cilk_frame_decl
;
809 decl
= build_decl (EXPR_LOCATION (fn
), VAR_DECL
, NULL_TREE
,
810 cilk_frame_type_decl
);
811 DECL_CONTEXT (decl
) = fn
;
812 DECL_SEEN_IN_BIND_EXPR_P (decl
) = 1;
813 f
->cilk_frame_decl
= decl
;
817 /* Returns a STATEMENT_LIST with all the pedigree operations required for
818 install body with frame cleanup functions. FRAME_PTR is the pointer to
819 __cilkrts_stack_frame created by make_cilk_frame. */
822 cilk_install_body_pedigree_operations (tree frame_ptr
)
824 tree body_list
= alloc_stmt_list ();
825 tree enter_frame
= build_call_expr (cilk_enter_fast_fndecl
, 1, frame_ptr
);
826 append_to_statement_list (enter_frame
, &body_list
);
828 tree parent
= cilk_arrow (frame_ptr
, CILK_TI_FRAME_PARENT
, 0);
829 tree worker
= cilk_arrow (frame_ptr
, CILK_TI_FRAME_WORKER
, 0);
831 tree pedigree
= cilk_arrow (frame_ptr
, CILK_TI_FRAME_PEDIGREE
, 0);
832 tree pedigree_rank
= cilk_dot (pedigree
, CILK_TI_PEDIGREE_RANK
, 0);
833 tree parent_pedigree
= cilk_dot (pedigree
, CILK_TI_PEDIGREE_PARENT
, 0);
834 tree pedigree_parent
= cilk_arrow (parent
, CILK_TI_FRAME_PEDIGREE
, 0);
835 tree pedigree_parent_rank
= cilk_dot (pedigree_parent
,
836 CILK_TI_PEDIGREE_RANK
, 0);
837 tree pedigree_parent_parent
= cilk_dot (pedigree_parent
,
838 CILK_TI_PEDIGREE_PARENT
, 0);
839 tree worker_pedigree
= cilk_arrow (worker
, CILK_TI_WORKER_PEDIGREE
, 1);
840 tree w_pedigree_rank
= cilk_dot (worker_pedigree
, CILK_TI_PEDIGREE_RANK
, 0);
841 tree w_pedigree_parent
= cilk_dot (worker_pedigree
,
842 CILK_TI_PEDIGREE_PARENT
, 0);
844 /* sf.pedigree.rank = worker->pedigree.rank. */
845 tree exp1
= build2 (MODIFY_EXPR
, void_type_node
, pedigree_rank
,
847 append_to_statement_list (exp1
, &body_list
);
849 /* sf.pedigree.parent = worker->pedigree.parent. */
850 exp1
= build2 (MODIFY_EXPR
, void_type_node
, parent_pedigree
,
852 append_to_statement_list (exp1
, &body_list
);
854 /* sf.call_parent->pedigree.rank = worker->pedigree.rank. */
855 exp1
= build2 (MODIFY_EXPR
, void_type_node
, pedigree_parent_rank
,
857 append_to_statement_list (exp1
, &body_list
);
859 /* sf.call_parent->pedigree.parent = worker->pedigree.parent. */
860 exp1
= build2 (MODIFY_EXPR
, void_type_node
, pedigree_parent_parent
,
862 append_to_statement_list (exp1
, &body_list
);
864 /* sf->worker.pedigree.rank = 0. */
865 exp1
= build2 (MODIFY_EXPR
, void_type_node
, w_pedigree_rank
,
866 build_zero_cst (uint64_type_node
));
867 append_to_statement_list (exp1
, &body_list
);
869 /* sf->pedigree.parent = &sf->pedigree. */
870 exp1
= build2 (MODIFY_EXPR
, void_type_node
, w_pedigree_parent
,
872 build_pointer_type (cilk_pedigree_type_decl
),
874 append_to_statement_list (exp1
, &body_list
);
878 /* Add a new variable, VAR to a variable list in WD->DECL_MAP. HOW indicates
879 whether the variable is previously defined, currently defined, or a variable
880 that is being written to. */
883 add_variable (struct wrapper_data
*wd
, tree var
, enum add_variable_type how
)
887 valp
= pointer_map_contains (wd
->decl_map
, (void *) var
);
890 tree val
= (tree
) *valp
;
891 /* If the variable is local, do nothing. */
892 if (val
== error_mark_node
)
894 /* If the variable was entered with itself as value,
895 meaning it belongs to an outer scope, do not alter
899 /* A statement expression may cause a variable to be
900 bound twice, once in BIND_EXPR and again in a
901 DECL_EXPR. That case caused a return in the
902 test above. Any other duplicate definition is
904 gcc_assert (how
!= ADD_BIND
);
905 if (how
!= ADD_WRITE
)
907 /* This variable might have been entered as read but is now written. */
908 *valp
= (void *) var
;
914 tree val
= NULL_TREE
;
916 /* Nested function rewriting silently discards hard register
917 assignments for function scope variables, and they wouldn't
918 work anyway. Warn here. This misses one case: if the
919 register variable is used as the loop bound or increment it
920 has already been added to the map. */
921 if ((how
!= ADD_BIND
) && (TREE_CODE (var
) == VAR_DECL
)
922 && !DECL_EXTERNAL (var
) && DECL_HARD_REGISTER (var
))
923 warning (0, "register assignment ignored for %qD used in Cilk block",
928 /* ADD_BIND means always make a fresh new variable. */
930 val
= error_mark_node
;
933 1. For cilk_for, refer to the outer scope definition as-is
934 2. For a spawned block, take a scalar in an rgument
935 and otherwise refer to the outer scope definition as-is.
936 3. For a spawned call, take a scalar in an argument. */
943 case CILK_BLOCK_SPAWN
:
944 if (TREE_ADDRESSABLE (var
))
950 val
= integer_zero_node
;
961 case CILK_BLOCK_SPAWN
:
962 if (TREE_ADDRESSABLE (var
))
963 val
= integer_one_node
;
972 *pointer_map_insert (wd
->decl_map
, (void *) var
) = val
;
976 /* Find the variables referenced in an expression T. This does not avoid
977 duplicates because a variable may be read in one context and written in
978 another. HOW describes the context in which the reference is seen. If
979 NESTED is true a nested function is being generated and variables in the
980 original context should not be remapped. */
983 extract_free_variables (tree t
, struct wrapper_data
*wd
,
984 enum add_variable_type how
)
989 enum tree_code code
= TREE_CODE (t
);
990 bool is_expr
= IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code
));
993 extract_free_variables (TREE_TYPE (t
), wd
, ADD_READ
);
998 case IDENTIFIER_NODE
:
1004 case PLACEHOLDER_EXPR
:
1008 /* These do not contain variable references. */
1012 /* Currently we don't see SSA_NAME. */
1013 extract_free_variables (SSA_NAME_VAR (t
), wd
, how
);
1017 /* This might be a reference to a label outside the Cilk block,
1018 which is an error, or a reference to a label in the Cilk block
1019 that we haven't seen yet. We can't tell. Ignore it. An
1020 invalid use will cause an error later in copy_decl_for_cilk. */
1024 if (wd
->type
!= CILK_BLOCK_SPAWN
)
1025 TREE_ADDRESSABLE (t
) = 1;
1028 if (!TREE_STATIC (t
) && !DECL_EXTERNAL (t
))
1029 add_variable (wd
, t
, how
);
1032 case NON_LVALUE_EXPR
:
1035 extract_free_variables (TREE_OPERAND (t
, 0), wd
, ADD_READ
);
1040 extract_free_variables (TREE_OPERAND (t
, 0), wd
, ADD_BIND
);
1041 extract_free_variables (TREE_OPERAND (t
, 1), wd
, ADD_READ
);
1045 case PREDECREMENT_EXPR
:
1046 case PREINCREMENT_EXPR
:
1047 case POSTDECREMENT_EXPR
:
1048 case POSTINCREMENT_EXPR
:
1049 /* These write their result. */
1050 extract_free_variables (TREE_OPERAND (t
, 0), wd
, ADD_WRITE
);
1051 extract_free_variables (TREE_OPERAND (t
, 1), wd
, ADD_READ
);
1055 /* This might modify its argument, and the value needs to be
1056 passed by reference in any case to preserve identity and
1057 type if is a promoting type. In the case of a nested loop
1058 just notice that we touch the variable. It will already
1059 be addressable, and marking it modified will cause a spurious
1060 warning about writing the control variable. */
1061 if (wd
->type
!= CILK_BLOCK_SPAWN
)
1062 extract_free_variables (TREE_OPERAND (t
, 0), wd
, ADD_READ
);
1064 extract_free_variables (TREE_OPERAND (t
, 0), wd
, ADD_WRITE
);
1068 /* Treating ARRAY_REF and BIT_FIELD_REF identically may
1069 mark the array as written but the end result is correct
1070 because the array is passed by pointer anyway. */
1072 /* Propagate the access type to the object part of which
1073 is being accessed here. As for ADDR_EXPR, don't do this
1074 in a nested loop, unless the access is to a fixed index. */
1075 if (wd
->type
!= CILK_BLOCK_FOR
|| TREE_CONSTANT (TREE_OPERAND (t
, 1)))
1076 extract_free_variables (TREE_OPERAND (t
, 0), wd
, how
);
1078 extract_free_variables (TREE_OPERAND (t
, 0), wd
, ADD_READ
);
1079 extract_free_variables (TREE_OPERAND (t
, 1), wd
, ADD_READ
);
1080 extract_free_variables (TREE_OPERAND (t
, 2), wd
, ADD_READ
);
1084 extract_free_variables (TREE_PURPOSE (t
), wd
, ADD_READ
);
1085 extract_free_variables (TREE_VALUE (t
), wd
, ADD_READ
);
1086 extract_free_variables (TREE_CHAIN (t
), wd
, ADD_READ
);
1091 int len
= TREE_VEC_LENGTH (t
);
1093 for (i
= 0; i
< len
; i
++)
1094 extract_free_variables (TREE_VEC_ELT (t
, i
), wd
, ADD_READ
);
1101 for (ii
= 0; ii
< VECTOR_CST_NELTS (t
); ii
++)
1102 extract_free_variables (VECTOR_CST_ELT (t
, ii
), wd
, ADD_READ
);
1107 extract_free_variables (TREE_REALPART (t
), wd
, ADD_READ
);
1108 extract_free_variables (TREE_IMAGPART (t
), wd
, ADD_READ
);
1114 for (decl
= BIND_EXPR_VARS (t
); decl
; decl
= TREE_CHAIN (decl
))
1116 add_variable (wd
, decl
, ADD_BIND
);
1117 /* A self-referential initialization is no problem because
1118 we already entered the variable into the map as local. */
1119 extract_free_variables (DECL_INITIAL (decl
), wd
, ADD_READ
);
1120 extract_free_variables (DECL_SIZE (decl
), wd
, ADD_READ
);
1121 extract_free_variables (DECL_SIZE_UNIT (decl
), wd
, ADD_READ
);
1123 extract_free_variables (BIND_EXPR_BODY (t
), wd
, ADD_READ
);
1127 case STATEMENT_LIST
:
1129 tree_stmt_iterator i
;
1130 for (i
= tsi_start (t
); !tsi_end_p (i
); tsi_next (&i
))
1131 extract_free_variables (*tsi_stmt_ptr (i
), wd
, ADD_READ
);
1137 extract_free_variables (TREE_OPERAND (t
, 0), wd
, ADD_BIND
);
1138 extract_free_variables (TREE_OPERAND (t
, 1), wd
, ADD_READ
);
1139 extract_free_variables (TREE_OPERAND (t
, 2), wd
, ADD_READ
);
1140 if (TREE_OPERAND (t
, 3) != TREE_OPERAND (t
, 1))
1141 extract_free_variables (TREE_OPERAND (t
, 3), wd
, ADD_READ
);
1146 if (TREE_NO_WARNING (t
))
1148 gcc_assert (errorcount
);
1154 if (TREE_CODE (DECL_EXPR_DECL (t
)) != TYPE_DECL
)
1155 extract_free_variables (DECL_EXPR_DECL (t
), wd
, ADD_BIND
);
1161 extract_free_variables (TYPE_MIN_VALUE (t
), wd
, ADD_READ
);
1162 extract_free_variables (TYPE_MAX_VALUE (t
), wd
, ADD_READ
);
1166 extract_free_variables (TREE_TYPE (t
), wd
, ADD_READ
);
1170 extract_free_variables (TREE_TYPE (t
), wd
, ADD_READ
);
1171 extract_free_variables (TYPE_DOMAIN (t
), wd
, ADD_READ
);
1175 extract_free_variables (TYPE_FIELDS (t
), wd
, ADD_READ
);
1179 extract_free_variables (TYPE_ARG_TYPES (t
), wd
, ADD_READ
);
1180 extract_free_variables (TYPE_METHOD_BASETYPE (t
), wd
, ADD_READ
);
1183 case AGGR_INIT_EXPR
:
1188 if (TREE_CODE (TREE_OPERAND (t
, 0)) == INTEGER_CST
)
1190 len
= TREE_INT_CST_LOW (TREE_OPERAND (t
, 0));
1192 for (ii
= 0; ii
< len
; ii
++)
1193 extract_free_variables (TREE_OPERAND (t
, ii
), wd
, ADD_READ
);
1194 extract_free_variables (TREE_TYPE (t
), wd
, ADD_READ
);
1201 unsigned HOST_WIDE_INT idx
= 0;
1202 constructor_elt
*ce
;
1203 for (idx
= 0; vec_safe_iterate (CONSTRUCTOR_ELTS (t
), idx
, &ce
); idx
++)
1204 extract_free_variables (ce
->value
, wd
, ADD_READ
);
1213 /* Walk over all the sub-trees of this operand. */
1214 len
= TREE_CODE_LENGTH (code
);
1216 /* Go through the subtrees. We need to do this in forward order so
1217 that the scope of a FOR_EXPR is handled properly. */
1218 for (i
= 0; i
< len
; ++i
)
1219 extract_free_variables (TREE_OPERAND (t
, i
), wd
, ADD_READ
);
1224 /* Add appropriate frames needed for a Cilk spawned function call, FNDECL.
1225 Returns the __cilkrts_stack_frame * variable. */
1228 insert_cilk_frame (tree fndecl
)
1230 tree addr
, body
, enter
, out
, orig_body
;
1231 location_t loc
= EXPR_LOCATION (fndecl
);
1233 if (!cfun
|| cfun
->decl
!= fndecl
)
1234 push_cfun (DECL_STRUCT_FUNCTION (fndecl
));
1236 tree decl
= cfun
->cilk_frame_decl
;
1239 tree
*saved_tree
= &DECL_SAVED_TREE (fndecl
);
1240 decl
= make_cilk_frame (fndecl
);
1241 add_local_decl (cfun
, decl
);
1243 addr
= build1 (ADDR_EXPR
, cilk_frame_ptr_type_decl
, decl
);
1244 enter
= build_call_expr (cilk_enter_fndecl
, 1, addr
);
1245 out
= create_cilk_function_exit (cfun
->cilk_frame_decl
, false, true);
1247 /* The new body will be:
1248 __cilkrts_enter_frame_1 (&sf);
1253 __cilkrts_pop_frame (&sf);
1254 __cilkrts_leave_frame (&sf);
1257 body
= alloc_stmt_list ();
1258 orig_body
= *saved_tree
;
1260 if (TREE_CODE (orig_body
) == BIND_EXPR
)
1261 orig_body
= BIND_EXPR_BODY (orig_body
);
1263 append_to_statement_list (enter
, &body
);
1264 append_to_statement_list (build_stmt (loc
, TRY_FINALLY_EXPR
, orig_body
,
1266 if (TREE_CODE (*saved_tree
) == BIND_EXPR
)
1267 BIND_EXPR_BODY (*saved_tree
) = body
;
1274 /* Wraps CALL, a CALL_EXPR, into a CILK_SPAWN_STMT tree and returns it. */
1277 build_cilk_spawn (location_t loc
, tree call
)
1279 if (!cilk_set_spawn_marker (loc
, call
))
1280 return error_mark_node
;
1281 tree spawn_stmt
= build1 (CILK_SPAWN_STMT
, TREE_TYPE (call
), call
);
1282 TREE_SIDE_EFFECTS (spawn_stmt
) = 1;
1286 /* Returns a tree of type CILK_SYNC_STMT. */
1289 build_cilk_sync (void)
1291 tree sync
= build0 (CILK_SYNC_STMT
, void_type_node
);
1292 TREE_SIDE_EFFECTS (sync
) = 1;