1 /* This file is part of the Intel(R) Cilk(TM) Plus support
2 This file contains the CilkPlus Intrinsics
3 Copyright (C) 2013-2015 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"
29 #include "double-int.h"
37 #include "fold-const.h"
38 #include "stringpool.h"
40 #include "langhooks.h"
41 #include "gimple-expr.h"
43 #include "tree-iterator.h"
44 #include "tree-inline.h"
45 #include "c-family/c-common.h"
49 #include "plugin-api.h"
55 #include "hard-reg-set.h"
60 #include "diagnostic.h"
64 enum add_variable_type {
65 /* Reference to previously-defined variable. */
67 /* Definition of a new variable in inner-scope. */
69 /* Write to possibly previously-defined variable. */
73 enum cilk_block_type {
74 /* Indicates a _Cilk_spawn block. 30 was an arbitary number picked for
76 CILK_BLOCK_SPAWN = 30,
77 /* Indicates _Cilk_for statement block. */
83 /* Kind of function to be created. */
84 enum cilk_block_type type;
85 /* Signature of helper function. */
87 /* Containing function. */
89 /* Disposition of all variables in the inner statement. */
90 hash_map<tree, tree> *decl_map;
91 /* True if this function needs a static chain. */
93 /* Arguments to be passed to wrapper function, currently a list. */
95 /* Argument types, a list. */
97 /* Incoming parameters. */
99 /* Outer BLOCK object. */
103 static void extract_free_variables (tree, struct wrapper_data *,
104 enum add_variable_type);
105 static HOST_WIDE_INT cilk_wrapper_count;
107 /* Marks the CALL_EXPR or FUNCTION_DECL, FCALL, as a spawned function call
108 and the current function as a spawner. Emit error if the function call
109 is outside a function or if a non function-call is spawned. */
112 cilk_set_spawn_marker (location_t loc, tree fcall)
114 if (!current_function_decl)
116 error_at (loc, "%<_Cilk_spawn%> may only be used inside a function");
119 else if (fcall == error_mark_node)
120 /* Error reporting here is not necessary here since if FCALL is an
121 error_mark_node, the function marking it as error would have reported
124 else if (TREE_CODE (fcall) != CALL_EXPR
125 /* In C++, TARGET_EXPR is generated when we have an overloaded
127 && TREE_CODE (fcall) != TARGET_EXPR)
129 error_at (loc, "only function calls can be spawned");
134 cfun->calls_cilk_spawn = true;
139 /* This function will output the exit conditions for a spawn call. */
142 create_cilk_function_exit (tree frame, bool detaches, bool needs_sync)
144 tree epi = alloc_stmt_list ();
147 append_to_statement_list (build_cilk_sync (), &epi);
148 tree func_ptr = build1 (ADDR_EXPR, cilk_frame_ptr_type_decl, frame);
149 tree pop_frame = build_call_expr (cilk_pop_fndecl, 1, func_ptr);
150 tree worker = cilk_dot (frame, CILK_TI_FRAME_WORKER, 0);
151 tree current = cilk_arrow (worker, CILK_TI_WORKER_CUR, 0);
152 tree parent = cilk_dot (frame, CILK_TI_FRAME_PARENT, 0);
153 tree set_current = build2 (MODIFY_EXPR, void_type_node, current, parent);
154 append_to_statement_list (set_current, &epi);
155 append_to_statement_list (pop_frame, &epi);
156 tree call = build_call_expr (cilk_leave_fndecl, 1, func_ptr);
159 tree flags = cilk_dot (frame, CILK_TI_FRAME_FLAGS, false);
160 tree flags_cmp_expr = fold_build2 (NE_EXPR, TREE_TYPE (flags), flags,
161 build_int_cst (TREE_TYPE (flags),
162 CILK_FRAME_VERSION));
163 call = fold_build3 (COND_EXPR, void_type_node, flags_cmp_expr,
164 call, build_empty_stmt (EXPR_LOCATION (flags)));
166 append_to_statement_list (call, &epi);
170 /* Trying to get the correct cfun for the FUNCTION_DECL indicated by OUTER. */
173 pop_cfun_to (tree outer)
176 current_function_decl = outer;
177 gcc_assert (cfun == DECL_STRUCT_FUNCTION (current_function_decl));
178 gcc_assert (cfun->decl == current_function_decl);
181 /* This function does whatever is necessary to make the compiler emit a newly
182 generated function, FNDECL. */
185 call_graph_add_fn (tree fndecl)
187 const tree outer = current_function_decl;
188 struct function *f = DECL_STRUCT_FUNCTION (fndecl);
189 gcc_assert (TREE_CODE (fndecl) == FUNCTION_DECL);
191 f->is_cilk_function = 1;
192 f->curr_properties = cfun->curr_properties;
193 gcc_assert (cfun == DECL_STRUCT_FUNCTION (outer));
194 gcc_assert (cfun->decl == outer);
197 cgraph_node::create (fndecl);
201 /* Return true if this is a tree which is allowed to contain a spawn as
203 A spawn call may be wrapped in a series of unary operations such
204 as conversions. These conversions need not be "useless"
205 to be disregarded because they are retained in the spawned
206 statement. They are bypassed only to look for a spawn
208 A comparison to constant is simple enough to allow, and
209 is used to convert to bool. */
212 cilk_ignorable_spawn_rhs_op (tree exp)
214 enum tree_code code = TREE_CODE (exp);
215 switch (TREE_CODE_CLASS (code))
218 return code == ADDR_EXPR;
220 /* We need the spawn as operand 0 for now. That's where it
221 appears in the only case we really care about, conversion
223 return (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST);
232 /* Helper function for walk_tree. If *TP is a CILK_SPAWN_STMT, then unwrap
233 this "wrapper." The function returns NULL_TREE regardless. */
236 unwrap_cilk_spawn_stmt (tree *tp, int *walk_subtrees, void *)
238 if (TREE_CODE (*tp) == CILK_SPAWN_STMT)
240 *tp = CILK_SPAWN_FN (*tp);
246 /* Returns true when EXP is a CALL_EXPR with _Cilk_spawn in front. Unwraps
247 CILK_SPAWN_STMT wrapper from the CALL_EXPR in *EXP0 statement. */
250 recognize_spawn (tree exp, tree *exp0)
252 bool spawn_found = false;
253 if (TREE_CODE (exp) == CILK_SPAWN_STMT)
255 /* Remove the CALL_EXPR from CILK_SPAWN_STMT wrapper. */
256 exp = CILK_SPAWN_FN (exp);
257 walk_tree (exp0, unwrap_cilk_spawn_stmt, NULL, NULL);
260 /* _Cilk_spawn can't be wrapped in expression such as PLUS_EXPR. */
261 else if (contains_cilk_spawn_stmt (exp))
262 error_at (EXPR_LOCATION (exp), "invalid use of %<_Cilk_spawn%>");
266 /* Returns true if *EXP0 is a recognized form of spawn. Recognized forms are,
267 after conversion to void, a call expression at outer level or an assignment
268 at outer level with the right hand side being a spawned call.
269 In addition to this, it also unwraps the CILK_SPAWN_STMT cover from the
270 CALL_EXPR that is being spawned.
271 Note that `=' in C++ may turn into a CALL_EXPR rather than a MODIFY_EXPR. */
274 cilk_detect_spawn_and_unwrap (tree *exp0)
278 if (!TREE_SIDE_EFFECTS (exp))
281 /* Strip off any conversion to void. It does not affect whether spawn
282 is supported here. */
283 if (TREE_CODE (exp) == CONVERT_EXPR && VOID_TYPE_P (TREE_TYPE (exp)))
284 exp = TREE_OPERAND (exp, 0);
286 if (TREE_CODE (exp) == MODIFY_EXPR || TREE_CODE (exp) == INIT_EXPR)
287 exp = TREE_OPERAND (exp, 1);
289 while (cilk_ignorable_spawn_rhs_op (exp))
290 exp = TREE_OPERAND (exp, 0);
292 if (TREE_CODE (exp) == TARGET_EXPR)
293 if (TARGET_EXPR_INITIAL (exp)
294 && TREE_CODE (TARGET_EXPR_INITIAL (exp)) != AGGR_INIT_EXPR)
295 exp = TARGET_EXPR_INITIAL (exp);
297 /* Happens with C++ TARGET_EXPR. */
298 if (exp == NULL_TREE)
301 while (TREE_CODE (exp) == CLEANUP_POINT_EXPR || TREE_CODE (exp) == EXPR_STMT)
302 exp = TREE_OPERAND (exp, 0);
304 /* Now we should have a CALL_EXPR with a CILK_SPAWN_STMT wrapper around
305 it, or return false. */
306 if (recognize_spawn (exp, exp0))
311 /* This function will build and return a FUNCTION_DECL using information
315 create_cilk_helper_decl (struct wrapper_data *wd)
318 if (wd->type == CILK_BLOCK_FOR)
319 sprintf (name, "_cilk_for_" HOST_WIDE_INT_PRINT_DEC, cilk_wrapper_count++);
320 else if (wd->type == CILK_BLOCK_SPAWN)
321 sprintf (name, "_cilk_spn_" HOST_WIDE_INT_PRINT_DEC, cilk_wrapper_count++);
325 clean_symbol_name (name);
326 tree fndecl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
327 get_identifier (name), wd->fntype);
329 TREE_PUBLIC (fndecl) = 0;
330 TREE_STATIC (fndecl) = 1;
331 TREE_USED (fndecl) = 1;
332 DECL_ARTIFICIAL (fndecl) = 0;
333 DECL_IGNORED_P (fndecl) = 0;
334 DECL_EXTERNAL (fndecl) = 0;
336 DECL_CONTEXT (fndecl) = wd->context;
337 tree block = make_node (BLOCK);
338 DECL_INITIAL (fndecl) = block;
339 TREE_USED (block) = 1;
340 BLOCK_SUPERCONTEXT (block) = fndecl;
341 gcc_assert (!DECL_SAVED_TREE (fndecl));
343 /* Inlining would defeat the purpose of this wrapper.
344 Either it secretly switches stack frames or it allocates
345 a stable stack frame to hold function arguments even if
346 the parent stack frame is stolen. */
347 DECL_UNINLINABLE (fndecl) = 1;
349 tree result_decl = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE,
351 DECL_ARTIFICIAL (result_decl) = 0;
352 DECL_IGNORED_P (result_decl) = 1;
353 DECL_CONTEXT (result_decl) = fndecl;
354 DECL_RESULT (fndecl) = result_decl;
365 /* A function used by traversal to fill vector of decls for further work. */
368 fill_decls_vec (tree const &key0, tree *val0, auto_vec<struct cilk_decls> *v)
371 struct cilk_decls dp;
382 /* Function that actually creates necessary parm lists. */
385 create_parm_list (struct wrapper_data *wd, tree *val0, tree arg)
390 if (val == error_mark_node || val == arg)
393 if (TREE_CODE (val) == PAREN_EXPR)
395 /* We should not reach here with a register receiver.
396 We may see a register variable modified in the
397 argument list. Because register variables are
398 worker-local we don't need to work hard to support
399 them in code that spawns. */
400 if ((TREE_CODE (arg) == VAR_DECL) && DECL_HARD_REGISTER (arg))
402 error_at (EXPR_LOCATION (arg),
403 "explicit register variable %qD may not be modified in "
405 arg = null_pointer_node;
408 arg = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg)), arg);
410 val = TREE_OPERAND (val, 0);
412 gcc_assert (TREE_CODE (val) == INDIRECT_REF);
413 parm = TREE_OPERAND (val, 0);
418 TREE_CHAIN (parm) = wd->parms;
420 wd->argtypes = tree_cons (NULL_TREE, TREE_TYPE (parm), wd->argtypes);
421 wd->arglist = tree_cons (NULL_TREE, arg, wd->arglist);
424 /* Sorting decls in a vector. */
427 compare_decls (const void *a, const void *b)
429 const struct cilk_decls *t1 = (const struct cilk_decls *) a;
430 const struct cilk_decls *t2 = (const struct cilk_decls *) b;
432 if (DECL_UID (t1->key) > DECL_UID (t2->key))
434 else if (DECL_UID (t1->key) < DECL_UID (t2->key))
440 /* This function is used to build a wrapper of a certain type. */
443 build_wrapper_type (struct wrapper_data *wd)
446 struct cilk_decls * c;
447 auto_vec<struct cilk_decls> vd;
448 wd->arglist = NULL_TREE;
449 wd->parms = NULL_TREE;
450 wd->argtypes = void_list_node;
452 gcc_assert (wd->type != CILK_BLOCK_FOR);
453 wd->decl_map->traverse<auto_vec<struct cilk_decls> *, fill_decls_vec> (&vd);
454 vd.qsort (compare_decls);
456 FOR_EACH_VEC_ELT (vd, j, c)
457 create_parm_list (wd, c->val, c->key);
459 /* Now build a function.
460 Its return type is void (all side effects are via explicit parameters).
461 Its parameters are WRAPPER_PARMS with type WRAPPER_TYPES.
462 Actual arguments in the caller are WRAPPER_ARGS. */
463 wd->fntype = build_function_type (void_type_node, wd->argtypes);
466 /* This function checks all the CALL_EXPRs in *TP found by cilk_outline. */
469 check_outlined_calls (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
472 bool *throws = (bool *) data;
476 if (TREE_CODE (t) != CALL_EXPR)
478 flags = call_expr_flags (t);
480 if (!(flags & ECF_NOTHROW) && flag_exceptions)
482 if (flags & ECF_RETURNS_TWICE)
483 error_at (EXPR_LOCATION (t),
484 "cannot spawn call to function that returns twice");
488 /* Each DECL in the source code (spawned statement) is passed to this function
489 once. Each instance of the DECL is replaced with the result of this
492 The parameters of the wrapper should have been entered into the map already.
493 This function only deals with variables with scope limited to the
494 spawned expression. */
497 copy_decl_for_cilk (tree decl, copy_body_data *id)
499 switch (TREE_CODE (decl))
502 return copy_decl_no_change (decl, id);
505 error_at (EXPR_LOCATION (decl), "invalid use of label %q+D in "
508 return error_mark_node;
512 /* RESULT_DECL and PARM_DECL has already been entered into the map. */
515 return error_mark_node;
519 /* Alter a tree STMT from OUTER_FN to form the body of INNER_FN. */
522 cilk_outline (tree inner_fn, tree *stmt_p, void *w)
524 struct wrapper_data *wd = (struct wrapper_data *) w;
525 const tree outer_fn = wd->context;
526 const bool nested = (wd->type == CILK_BLOCK_FOR);
529 auto_vec<struct cilk_decls> vd;
531 struct cilk_decls * c;
533 DECL_STATIC_CHAIN (outer_fn) = 1;
535 memset (&id, 0, sizeof (id));
536 /* Copy from the function containing the spawn... */
537 id.src_fn = outer_fn;
539 /* ...to the wrapper. */
540 id.dst_fn = inner_fn;
541 id.src_cfun = DECL_STRUCT_FUNCTION (outer_fn);
543 /* There shall be no RETURN in spawn helper. */
545 id.decl_map = wd->decl_map;
546 id.copy_decl = nested ? copy_decl_no_change : copy_decl_for_cilk;
547 id.block = DECL_INITIAL (inner_fn);
548 id.transform_lang_insert_block = NULL;
550 id.transform_new_cfg = true;
551 id.transform_call_graph_edges = CB_CGE_MOVE;
552 id.remap_var_for_cilk = true;
553 id.regimplify = true; /* unused? */
555 insert_decl_map (&id, wd->block, DECL_INITIAL (inner_fn));
557 wd->decl_map->traverse<auto_vec<struct cilk_decls> *, fill_decls_vec> (&vd);
558 vd.qsort (compare_decls);
559 /* We don't want the private variables any more. */
560 FOR_EACH_VEC_ELT (vd, j, c)
561 if (*(c->val) == error_mark_node)
562 *(c->val) = nested ? copy_decl_no_change (c->key, &id)
563 : copy_decl_for_cilk (c->key, &id);
565 walk_tree (stmt_p, copy_tree_body_r, (void *) &id, NULL);
567 /* See if this function can throw or calls something that should
568 not be spawned. The exception part is only necessary if
569 flag_exceptions && !flag_non_call_exceptions. */
571 (void) walk_tree_without_duplicates (stmt_p, check_outlined_calls, &throws);
574 /* Generate the body of a wrapper function that assigns the
575 result of the expression RHS into RECEIVER. RECEIVER must
576 be NULL if this is not a spawn -- the wrapper will return
577 a value. If this is a spawn, the wrapper will return void. */
580 create_cilk_wrapper_body (tree stmt, struct wrapper_data *wd)
582 const tree outer = current_function_decl;
586 /* Build the type of the wrapper and its argument list from the
587 variables that it requires. */
588 build_wrapper_type (wd);
590 /* Emit a function that takes WRAPPER_PARMS incoming and applies ARGS
591 (modified) to the wrapped function. Return the wrapper and modified ARGS
592 to the caller to generate a function call. */
593 fndecl = create_cilk_helper_decl (wd);
594 push_struct_function (fndecl);
595 if (wd->nested && (wd->type == CILK_BLOCK_FOR))
597 gcc_assert (TREE_VALUE (wd->arglist) == NULL_TREE);
598 TREE_VALUE (wd->arglist) = build2 (FDESC_EXPR, ptr_type_node,
599 fndecl, integer_one_node);
601 DECL_ARGUMENTS (fndecl) = wd->parms;
603 for (p = wd->parms; p; p = TREE_CHAIN (p))
604 DECL_CONTEXT (p) = fndecl;
606 gcc_assert (!DECL_SAVED_TREE (fndecl));
607 cilk_install_body_with_frame_cleanup (fndecl, stmt, (void *) wd);
608 gcc_assert (DECL_SAVED_TREE (fndecl));
612 /* Recognize the new function. */
613 call_graph_add_fn (fndecl);
617 /* Initializes the wrapper data structure. */
620 init_wd (struct wrapper_data *wd, enum cilk_block_type type)
623 wd->fntype = NULL_TREE;
624 wd->context = current_function_decl;
625 wd->decl_map = new hash_map<tree, tree>;
626 /* _Cilk_for bodies are always nested. Others start off as
628 wd->nested = (type == CILK_BLOCK_FOR);
629 wd->arglist = NULL_TREE;
630 wd->argtypes = NULL_TREE;
631 wd->block = NULL_TREE;
634 /* Clears the wrapper data structure. */
637 free_wd (struct wrapper_data *wd)
641 wd->arglist = NULL_TREE;
642 wd->argtypes = NULL_TREE;
643 wd->parms = NULL_TREE;
647 /* Given a variable in an expression to be extracted into
648 a helper function, declare the helper function parameter
651 On entry the value of the (key, value) pair may be
653 (*, error_mark_node) -- Variable is private to helper function,
656 (var, var) -- Reference to outer scope (function or global scope).
658 (var, integer 0) -- Capture by value, save newly-declared PARM_DECL
659 for value in value slot.
661 (var, integer 1) -- Capture by reference, declare pointer to type
662 as new PARM_DECL and store (spawn_stmt (indirect_ref (parm)).
664 (var, ???) -- Pure output argument, handled similarly to above.
668 declare_one_free_variable (tree var0, tree *map0)
670 const_tree var = var0;
672 tree var_type = TREE_TYPE (var), arg_type;
676 gcc_assert (DECL_P (var));
678 /* Ignore truly local variables. */
679 if (map == error_mark_node)
681 /* Ignore references to the parent function. */
685 gcc_assert (TREE_CODE (map) == INTEGER_CST);
687 /* A value is passed by reference if:
689 1. It is addressable, so that a copy may not be made.
690 2. It is modified in the spawned statement.
691 In the future this function may want to arrange
692 a warning if the spawned statement is a loop body
693 because an output argument would indicate a race.
694 Note: Earlier passes must have marked the variable addressable.
695 3. It is expensive to copy. */
697 (TREE_ADDRESSABLE (var_type)
698 /* Arrays must be passed by reference. This is required for C
699 semantics -- arrays are not first class objects. Other
700 aggregate types can and should be passed by reference if
701 they are not passed to the spawned function. We aren't yet
702 distinguishing safe uses in argument calculation from unsafe
703 uses as outgoing function arguments, so we make a copy to
704 stabilize the value. */
705 || TREE_CODE (var_type) == ARRAY_TYPE
706 || (tree) map == integer_one_node);
709 var_type = build_qualified_type (build_pointer_type (var_type),
711 gcc_assert (!TREE_ADDRESSABLE (var_type));
713 /* Maybe promote to int. */
714 if (INTEGRAL_TYPE_P (var_type) && COMPLETE_TYPE_P (var_type)
715 && tree_int_cst_lt (TYPE_SIZE (var_type), TYPE_SIZE (integer_type_node)))
716 arg_type = integer_type_node;
720 parm = build_decl (UNKNOWN_LOCATION, PARM_DECL, NULL_TREE, var_type);
721 DECL_ARG_TYPE (parm) = arg_type;
722 DECL_ARTIFICIAL (parm) = 0;
723 TREE_READONLY (parm) = 1;
727 parm = build1 (INDIRECT_REF, TREE_TYPE (var_type), parm);
728 parm = build1 (PAREN_EXPR, void_type_node, parm);
734 /* Returns a wrapper function for a _Cilk_spawn. */
737 create_cilk_wrapper (tree exp, tree *args_out)
739 struct wrapper_data wd;
742 struct cilk_decls * c;
743 auto_vec<struct cilk_decls> vd;
745 init_wd (&wd, CILK_BLOCK_SPAWN);
747 if (TREE_CODE (exp) == CONVERT_EXPR)
748 exp = TREE_OPERAND (exp, 0);
750 /* Special handling for top level INIT_EXPR. Usually INIT_EXPR means the
751 variable is defined in the spawned expression and can be private to the
752 spawn helper. A top level INIT_EXPR defines a variable to be initialized
753 by spawn and the variable must remain in the outer function. */
754 if (TREE_CODE (exp) == INIT_EXPR)
756 extract_free_variables (TREE_OPERAND (exp, 0), &wd, ADD_WRITE);
757 extract_free_variables (TREE_OPERAND (exp, 1), &wd, ADD_READ);
758 /* TREE_TYPE should be void. Be defensive. */
759 if (TREE_TYPE (exp) != void_type_node)
760 extract_free_variables (TREE_TYPE (exp), &wd, ADD_READ);
763 extract_free_variables (exp, &wd, ADD_READ);
764 wd.decl_map->traverse<auto_vec<struct cilk_decls> *, fill_decls_vec> (&vd);
765 vd.qsort (compare_decls);
766 FOR_EACH_VEC_ELT (vd, j, c)
767 declare_one_free_variable (c->key, c->val);
769 wd.block = TREE_BLOCK (exp);
771 wd.block = DECL_INITIAL (current_function_decl);
773 /* Now fvars maps the old variable to incoming variable. Update
774 the expression and arguments to refer to the new names. */
775 fndecl = create_cilk_wrapper_body (exp, &wd);
776 *args_out = wd.arglist;
783 /* Transform *SPAWN_P, a spawned CALL_EXPR, to gimple. *SPAWN_P can be a
784 CALL_EXPR, INIT_EXPR or MODIFY_EXPR. Returns GS_OK if everything is fine,
785 and GS_UNHANDLED, otherwise. */
788 gimplify_cilk_spawn (tree *spawn_p)
790 tree expr = *spawn_p;
791 tree function, call1, call2, new_args;
792 tree ii_args = NULL_TREE;
793 int total_args = 0, ii = 0;
795 tree setjmp_cond_expr = NULL_TREE;
796 tree setjmp_expr, spawn_expr, setjmp_value = NULL_TREE;
798 cfun->calls_cilk_spawn = 1;
799 cfun->is_cilk_function = 1;
801 /* Remove CLEANUP_POINT_EXPR and EXPR_STMT from *spawn_p. */
802 while (TREE_CODE (expr) == CLEANUP_POINT_EXPR
803 || TREE_CODE (expr) == EXPR_STMT)
804 expr = TREE_OPERAND (expr, 0);
807 function = create_cilk_wrapper (expr, &new_args);
809 /* This should give the number of parameters. */
810 total_args = list_length (new_args);
812 arg_array = XNEWVEC (tree, total_args);
817 for (ii = 0; ii < total_args; ii++)
819 arg_array[ii] = TREE_VALUE (ii_args);
820 ii_args = TREE_CHAIN (ii_args);
823 TREE_USED (function) = 1;
824 rest_of_decl_compilation (function, 0, 0);
826 call1 = cilk_call_setjmp (cfun->cilk_frame_decl);
828 if (arg_array == NULL || *arg_array == NULL_TREE)
829 call2 = build_call_expr (function, 0);
831 call2 = build_call_expr_loc_array (EXPR_LOCATION (*spawn_p), function,
832 total_args, arg_array);
833 *spawn_p = alloc_stmt_list ();
834 tree f_ptr_type = build_pointer_type (TREE_TYPE (cfun->cilk_frame_decl));
835 tree frame_ptr = build1 (ADDR_EXPR, f_ptr_type, cfun->cilk_frame_decl);
836 tree save_fp = build_call_expr (cilk_save_fp_fndecl, 1, frame_ptr);
837 append_to_statement_list (save_fp, spawn_p);
838 setjmp_value = create_tmp_var (TREE_TYPE (call1));
839 setjmp_expr = fold_build2 (MODIFY_EXPR, void_type_node, setjmp_value, call1);
841 append_to_statement_list_force (setjmp_expr, spawn_p);
843 setjmp_cond_expr = fold_build2 (EQ_EXPR, TREE_TYPE (call1), setjmp_value,
844 build_int_cst (TREE_TYPE (call1), 0));
845 spawn_expr = fold_build3 (COND_EXPR, void_type_node, setjmp_cond_expr,
846 call2, build_empty_stmt (EXPR_LOCATION (call1)));
847 append_to_statement_list (spawn_expr, spawn_p);
852 /* Make the frames necessary for a spawn call. */
855 make_cilk_frame (tree fn)
857 struct function *f = DECL_STRUCT_FUNCTION (fn);
860 if (f->cilk_frame_decl)
861 return f->cilk_frame_decl;
863 decl = build_decl (EXPR_LOCATION (fn), VAR_DECL, NULL_TREE,
864 cilk_frame_type_decl);
865 DECL_CONTEXT (decl) = fn;
866 DECL_SEEN_IN_BIND_EXPR_P (decl) = 1;
867 f->cilk_frame_decl = decl;
871 /* Returns a STATEMENT_LIST with all the pedigree operations required for
872 install body with frame cleanup functions. FRAME_PTR is the pointer to
873 __cilkrts_stack_frame created by make_cilk_frame. */
876 cilk_install_body_pedigree_operations (tree frame_ptr)
878 tree body_list = alloc_stmt_list ();
879 tree enter_frame = build_call_expr (cilk_enter_fast_fndecl, 1, frame_ptr);
880 append_to_statement_list (enter_frame, &body_list);
882 tree parent = cilk_arrow (frame_ptr, CILK_TI_FRAME_PARENT, 0);
883 tree worker = cilk_arrow (frame_ptr, CILK_TI_FRAME_WORKER, 0);
885 tree pedigree = cilk_arrow (frame_ptr, CILK_TI_FRAME_PEDIGREE, 0);
886 tree pedigree_rank = cilk_dot (pedigree, CILK_TI_PEDIGREE_RANK, 0);
887 tree parent_pedigree = cilk_dot (pedigree, CILK_TI_PEDIGREE_PARENT, 0);
888 tree pedigree_parent = cilk_arrow (parent, CILK_TI_FRAME_PEDIGREE, 0);
889 tree pedigree_parent_rank = cilk_dot (pedigree_parent,
890 CILK_TI_PEDIGREE_RANK, 0);
891 tree pedigree_parent_parent = cilk_dot (pedigree_parent,
892 CILK_TI_PEDIGREE_PARENT, 0);
893 tree worker_pedigree = cilk_arrow (worker, CILK_TI_WORKER_PEDIGREE, 1);
894 tree w_pedigree_rank = cilk_dot (worker_pedigree, CILK_TI_PEDIGREE_RANK, 0);
895 tree w_pedigree_parent = cilk_dot (worker_pedigree,
896 CILK_TI_PEDIGREE_PARENT, 0);
898 /* sf.pedigree.rank = worker->pedigree.rank. */
899 tree exp1 = build2 (MODIFY_EXPR, void_type_node, pedigree_rank,
901 append_to_statement_list (exp1, &body_list);
903 /* sf.pedigree.parent = worker->pedigree.parent. */
904 exp1 = build2 (MODIFY_EXPR, void_type_node, parent_pedigree,
906 append_to_statement_list (exp1, &body_list);
908 /* sf.call_parent->pedigree.rank = worker->pedigree.rank. */
909 exp1 = build2 (MODIFY_EXPR, void_type_node, pedigree_parent_rank,
911 append_to_statement_list (exp1, &body_list);
913 /* sf.call_parent->pedigree.parent = worker->pedigree.parent. */
914 exp1 = build2 (MODIFY_EXPR, void_type_node, pedigree_parent_parent,
916 append_to_statement_list (exp1, &body_list);
918 /* sf->worker.pedigree.rank = 0. */
919 exp1 = build2 (MODIFY_EXPR, void_type_node, w_pedigree_rank,
920 build_zero_cst (uint64_type_node));
921 append_to_statement_list (exp1, &body_list);
923 /* sf->pedigree.parent = &sf->pedigree. */
924 exp1 = build2 (MODIFY_EXPR, void_type_node, w_pedigree_parent,
926 build_pointer_type (cilk_pedigree_type_decl),
928 append_to_statement_list (exp1, &body_list);
932 /* Add a new variable, VAR to a variable list in WD->DECL_MAP. HOW indicates
933 whether the variable is previously defined, currently defined, or a variable
934 that is being written to. */
937 add_variable (struct wrapper_data *wd, tree var, enum add_variable_type how)
939 tree *valp = wd->decl_map->get (var);
942 tree val = (tree) *valp;
943 /* If the variable is local, do nothing. */
944 if (val == error_mark_node)
946 /* If the variable was entered with itself as value,
947 meaning it belongs to an outer scope, do not alter
951 /* A statement expression may cause a variable to be
952 bound twice, once in BIND_EXPR and again in a
953 DECL_EXPR. That case caused a return in the
954 test above. Any other duplicate definition is
956 gcc_assert (how != ADD_BIND);
957 if (how != ADD_WRITE)
959 /* This variable might have been entered as read but is now written. */
966 tree val = NULL_TREE;
968 /* Nested function rewriting silently discards hard register
969 assignments for function scope variables, and they wouldn't
970 work anyway. Warn here. This misses one case: if the
971 register variable is used as the loop bound or increment it
972 has already been added to the map. */
973 if ((how != ADD_BIND) && (TREE_CODE (var) == VAR_DECL)
974 && !DECL_EXTERNAL (var) && DECL_HARD_REGISTER (var))
975 warning (0, "register assignment ignored for %qD used in Cilk block",
980 /* ADD_BIND means always make a fresh new variable. */
982 val = error_mark_node;
985 1. For cilk_for, refer to the outer scope definition as-is
986 2. For a spawned block, take a scalar in an rgument
987 and otherwise refer to the outer scope definition as-is.
988 3. For a spawned call, take a scalar in an argument. */
995 case CILK_BLOCK_SPAWN:
996 if (TREE_ADDRESSABLE (var))
1002 val = integer_zero_node;
1009 case CILK_BLOCK_FOR:
1013 case CILK_BLOCK_SPAWN:
1014 if (TREE_ADDRESSABLE (var))
1015 val = integer_one_node;
1024 wd->decl_map->put (var, val);
1028 /* Find the variables referenced in an expression T. This does not avoid
1029 duplicates because a variable may be read in one context and written in
1030 another. HOW describes the context in which the reference is seen. If
1031 NESTED is true a nested function is being generated and variables in the
1032 original context should not be remapped. */
1035 extract_free_variables (tree t, struct wrapper_data *wd,
1036 enum add_variable_type how)
1041 enum tree_code code = TREE_CODE (t);
1042 bool is_expr = IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code));
1045 extract_free_variables (TREE_TYPE (t), wd, ADD_READ);
1050 case IDENTIFIER_NODE:
1057 case PLACEHOLDER_EXPR:
1061 /* These do not contain variable references. */
1065 /* Currently we don't see SSA_NAME. */
1066 extract_free_variables (SSA_NAME_VAR (t), wd, how);
1070 /* This might be a reference to a label outside the Cilk block,
1071 which is an error, or a reference to a label in the Cilk block
1072 that we haven't seen yet. We can't tell. Ignore it. An
1073 invalid use will cause an error later in copy_decl_for_cilk. */
1077 if (wd->type != CILK_BLOCK_SPAWN)
1078 TREE_ADDRESSABLE (t) = 1;
1081 if (!TREE_STATIC (t) && !DECL_EXTERNAL (t))
1082 add_variable (wd, t, how);
1085 case NON_LVALUE_EXPR:
1088 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_READ);
1093 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_BIND);
1094 extract_free_variables (TREE_OPERAND (t, 1), wd, ADD_READ);
1098 case PREDECREMENT_EXPR:
1099 case PREINCREMENT_EXPR:
1100 case POSTDECREMENT_EXPR:
1101 case POSTINCREMENT_EXPR:
1102 /* These write their result. */
1103 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_WRITE);
1104 extract_free_variables (TREE_OPERAND (t, 1), wd, ADD_READ);
1108 /* This might modify its argument, and the value needs to be
1109 passed by reference in any case to preserve identity and
1110 type if is a promoting type. In the case of a nested loop
1111 just notice that we touch the variable. It will already
1112 be addressable, and marking it modified will cause a spurious
1113 warning about writing the control variable. */
1114 if (wd->type != CILK_BLOCK_SPAWN)
1115 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_READ);
1117 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_WRITE);
1121 /* Treating ARRAY_REF and BIT_FIELD_REF identically may
1122 mark the array as written but the end result is correct
1123 because the array is passed by pointer anyway. */
1125 /* Propagate the access type to the object part of which
1126 is being accessed here. As for ADDR_EXPR, don't do this
1127 in a nested loop, unless the access is to a fixed index. */
1128 if (wd->type != CILK_BLOCK_FOR || TREE_CONSTANT (TREE_OPERAND (t, 1)))
1129 extract_free_variables (TREE_OPERAND (t, 0), wd, how);
1131 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_READ);
1132 extract_free_variables (TREE_OPERAND (t, 1), wd, ADD_READ);
1133 extract_free_variables (TREE_OPERAND (t, 2), wd, ADD_READ);
1137 extract_free_variables (TREE_PURPOSE (t), wd, ADD_READ);
1138 extract_free_variables (TREE_VALUE (t), wd, ADD_READ);
1139 extract_free_variables (TREE_CHAIN (t), wd, ADD_READ);
1144 int len = TREE_VEC_LENGTH (t);
1146 for (i = 0; i < len; i++)
1147 extract_free_variables (TREE_VEC_ELT (t, i), wd, ADD_READ);
1154 for (ii = 0; ii < VECTOR_CST_NELTS (t); ii++)
1155 extract_free_variables (VECTOR_CST_ELT (t, ii), wd, ADD_READ);
1160 extract_free_variables (TREE_REALPART (t), wd, ADD_READ);
1161 extract_free_variables (TREE_IMAGPART (t), wd, ADD_READ);
1167 for (decl = BIND_EXPR_VARS (t); decl; decl = TREE_CHAIN (decl))
1169 add_variable (wd, decl, ADD_BIND);
1170 /* A self-referential initialization is no problem because
1171 we already entered the variable into the map as local. */
1172 extract_free_variables (DECL_INITIAL (decl), wd, ADD_READ);
1173 extract_free_variables (DECL_SIZE (decl), wd, ADD_READ);
1174 extract_free_variables (DECL_SIZE_UNIT (decl), wd, ADD_READ);
1176 extract_free_variables (BIND_EXPR_BODY (t), wd, ADD_READ);
1180 case STATEMENT_LIST:
1182 tree_stmt_iterator i;
1183 for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
1184 extract_free_variables (*tsi_stmt_ptr (i), wd, ADD_READ);
1190 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_BIND);
1191 extract_free_variables (TREE_OPERAND (t, 1), wd, ADD_READ);
1192 extract_free_variables (TREE_OPERAND (t, 2), wd, ADD_READ);
1193 if (TREE_OPERAND (t, 3) != TREE_OPERAND (t, 1))
1194 extract_free_variables (TREE_OPERAND (t, 3), wd, ADD_READ);
1199 if (TREE_NO_WARNING (t))
1201 gcc_assert (errorcount);
1207 if (TREE_CODE (DECL_EXPR_DECL (t)) != TYPE_DECL)
1208 extract_free_variables (DECL_EXPR_DECL (t), wd, ADD_BIND);
1214 extract_free_variables (TYPE_MIN_VALUE (t), wd, ADD_READ);
1215 extract_free_variables (TYPE_MAX_VALUE (t), wd, ADD_READ);
1219 extract_free_variables (TREE_TYPE (t), wd, ADD_READ);
1223 extract_free_variables (TREE_TYPE (t), wd, ADD_READ);
1224 extract_free_variables (TYPE_DOMAIN (t), wd, ADD_READ);
1228 extract_free_variables (TYPE_FIELDS (t), wd, ADD_READ);
1232 extract_free_variables (TYPE_ARG_TYPES (t), wd, ADD_READ);
1233 extract_free_variables (TYPE_METHOD_BASETYPE (t), wd, ADD_READ);
1236 case AGGR_INIT_EXPR:
1241 if (TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST)
1243 len = TREE_INT_CST_LOW (TREE_OPERAND (t, 0));
1245 for (ii = 0; ii < len; ii++)
1246 extract_free_variables (TREE_OPERAND (t, ii), wd, ADD_READ);
1247 extract_free_variables (TREE_TYPE (t), wd, ADD_READ);
1254 unsigned HOST_WIDE_INT idx = 0;
1255 constructor_elt *ce;
1256 for (idx = 0; vec_safe_iterate (CONSTRUCTOR_ELTS (t), idx, &ce); idx++)
1257 extract_free_variables (ce->value, wd, ADD_READ);
1266 /* Walk over all the sub-trees of this operand. */
1267 len = TREE_CODE_LENGTH (code);
1269 /* Go through the subtrees. We need to do this in forward order so
1270 that the scope of a FOR_EXPR is handled properly. */
1271 for (i = 0; i < len; ++i)
1272 extract_free_variables (TREE_OPERAND (t, i), wd, ADD_READ);
1277 /* Add appropriate frames needed for a Cilk spawned function call, FNDECL.
1278 Returns the __cilkrts_stack_frame * variable. */
1281 insert_cilk_frame (tree fndecl)
1283 tree addr, body, enter, out, orig_body;
1284 location_t loc = EXPR_LOCATION (fndecl);
1286 if (!cfun || cfun->decl != fndecl)
1287 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
1289 tree decl = cfun->cilk_frame_decl;
1292 tree *saved_tree = &DECL_SAVED_TREE (fndecl);
1293 decl = make_cilk_frame (fndecl);
1294 add_local_decl (cfun, decl);
1296 addr = build1 (ADDR_EXPR, cilk_frame_ptr_type_decl, decl);
1297 enter = build_call_expr (cilk_enter_fndecl, 1, addr);
1298 out = create_cilk_function_exit (cfun->cilk_frame_decl, false, true);
1300 /* The new body will be:
1301 __cilkrts_enter_frame_1 (&sf);
1306 __cilkrts_pop_frame (&sf);
1307 __cilkrts_leave_frame (&sf);
1310 body = alloc_stmt_list ();
1311 orig_body = *saved_tree;
1313 if (TREE_CODE (orig_body) == BIND_EXPR)
1314 orig_body = BIND_EXPR_BODY (orig_body);
1316 append_to_statement_list (enter, &body);
1317 append_to_statement_list (build_stmt (loc, TRY_FINALLY_EXPR, orig_body,
1319 if (TREE_CODE (*saved_tree) == BIND_EXPR)
1320 BIND_EXPR_BODY (*saved_tree) = body;
1327 /* Wraps CALL, a CALL_EXPR, into a CILK_SPAWN_STMT tree and returns it. */
1330 build_cilk_spawn (location_t loc, tree call)
1332 if (!cilk_set_spawn_marker (loc, call))
1333 return error_mark_node;
1334 tree spawn_stmt = build1 (CILK_SPAWN_STMT, TREE_TYPE (call), call);
1335 TREE_SIDE_EFFECTS (spawn_stmt) = 1;
1339 /* Returns a tree of type CILK_SYNC_STMT. */
1342 build_cilk_sync (void)
1344 tree sync = build0 (CILK_SYNC_STMT, void_type_node);
1345 TREE_SIDE_EFFECTS (sync) = 1;
1349 /* Helper for contains_cilk_spawn_stmt, callback for walk_tree. Return
1350 non-null tree if TP contains CILK_SPAWN_STMT. */
1353 contains_cilk_spawn_stmt_walker (tree *tp, int *, void *)
1355 if (TREE_CODE (*tp) == CILK_SPAWN_STMT)
1361 /* Returns true if EXPR or any of its subtrees contain CILK_SPAWN_STMT
1365 contains_cilk_spawn_stmt (tree expr)
1367 return walk_tree (&expr, contains_cilk_spawn_stmt_walker, NULL, NULL)
1371 /* Return a error location for EXPR if LOC is not set. */
1374 get_error_location (tree expr, location_t loc)
1376 if (loc == UNKNOWN_LOCATION)
1378 if (TREE_CODE (expr) == MODIFY_EXPR)
1379 expr = TREE_OPERAND (expr, 0);
1380 loc = EXPR_LOCATION (expr);
1385 /* Check that no array notation or spawn statement is in EXPR.
1386 If not true generate an error at LOC for ARRAY_GMSGID or
1390 check_no_cilk (tree expr, const char *array_msgid, const char *spawn_msgid,
1395 if (contains_array_notation_expr (expr))
1397 loc = get_error_location (expr, loc);
1398 error_at (loc, array_msgid);
1401 if (walk_tree (&expr, contains_cilk_spawn_stmt_walker, NULL, NULL))
1403 loc = get_error_location (expr, loc);
1404 error_at (loc, spawn_msgid);