libgcc/ChangeLog:
[official-gcc.git] / gcc / c-family / cilk.c
blob99d9c7e354d6a8aa5fe3ccdc596bb537e46b2e2a
1 /* This file is part of the Intel(R) Cilk(TM) Plus support
2 This file contains the CilkPlus Intrinsics
3 Copyright (C) 2013 Free Software Foundation, Inc.
4 Contributed by Balaji V. Iyer <balaji.v.iyer@intel.com>,
5 Intel Corporation
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)
12 any later version.
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/>. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tree.h"
27 #include "stringpool.h"
28 #include "calls.h"
29 #include "langhooks.h"
30 #include "pointer-set.h"
31 #include "gimple-expr.h"
32 #include "gimplify.h"
33 #include "tree-iterator.h"
34 #include "tree-inline.h"
35 #include "c-family/c-common.h"
36 #include "toplev.h"
37 #include "cgraph.h"
38 #include "diagnostic.h"
39 #include "cilk.h"
41 enum add_variable_type {
42 /* Reference to previously-defined variable. */
43 ADD_READ,
44 /* Definition of a new variable in inner-scope. */
45 ADD_BIND,
46 /* Write to possibly previously-defined variable. */
47 ADD_WRITE
50 enum cilk_block_type {
51 /* Indicates a _Cilk_spawn block. 30 was an arbitary number picked for
52 ease of debugging. */
53 CILK_BLOCK_SPAWN = 30,
54 /* Indicates _Cilk_for statement block. */
55 CILK_BLOCK_FOR
58 struct wrapper_data
60 /* Kind of function to be created. */
61 enum cilk_block_type type;
62 /* Signature of helper function. */
63 tree fntype;
64 /* Containing function. */
65 tree context;
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. */
69 bool nested;
70 /* Arguments to be passed to wrapper function, currently a list. */
71 tree arglist;
72 /* Argument types, a list. */
73 tree argtypes;
74 /* Incoming parameters. */
75 tree parms;
76 /* Outer BLOCK object. */
77 tree block;
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. */
88 inline bool
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");
94 return false;
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
99 it. */
100 return false;
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
104 '=' operator. */
105 && TREE_CODE (fcall) != TARGET_EXPR)
107 error_at (loc, "only function calls can be spawned");
108 return false;
110 else
112 cfun->calls_cilk_spawn = true;
113 return true;
117 /* This function will output the exit conditions for a spawn call. */
119 tree
120 create_cilk_function_exit (tree frame, bool detaches, bool needs_sync)
122 tree epi = alloc_stmt_list ();
124 if (needs_sync)
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);
135 if (!detaches)
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);
145 return epi;
148 /* Trying to get the correct cfun for the FUNCTION_DECL indicated by OUTER. */
150 static void
151 pop_cfun_to (tree outer)
153 pop_cfun ();
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. */
162 static void
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);
174 push_cfun (f);
175 cgraph_create_node (fndecl);
176 pop_cfun_to (outer);
179 /* Return true if this is a tree which is allowed to contain a spawn as
180 operand 0.
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
185 within.
186 A comparison to constant is simple enough to allow, and
187 is used to convert to bool. */
189 static bool
190 cilk_ignorable_spawn_rhs_op (tree exp)
192 enum tree_code code = TREE_CODE (exp);
193 switch (TREE_CODE_CLASS (code))
195 case tcc_expression:
196 return code == ADDR_EXPR;
197 case tcc_comparison:
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
200 to bool. */
201 return (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST);
202 case tcc_unary:
203 case tcc_reference:
204 return true;
205 default:
206 return false;
210 /* Helper function for walk_tree. If *TP is a CILK_SPAWN_STMT, then unwrap
211 this "wrapper." The function returns NULL_TREE regardless. */
213 static tree
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);
219 *walk_subtrees = 0;
221 return NULL_TREE;
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. */
227 static bool
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);
236 spawn_found = true;
238 return spawn_found;
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. */
248 bool
249 cilk_detect_spawn_and_unwrap (tree *exp0)
251 tree exp = *exp0;
253 if (!TREE_SIDE_EFFECTS (exp))
254 return false;
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)
274 return false;
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))
282 return true;
283 return false;
286 /* This function will build and return a FUNCTION_DECL using information
287 from *WD. */
289 static tree
290 create_cilk_helper_decl (struct wrapper_data *wd)
292 char name[20];
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++);
297 else
298 gcc_unreachable ();
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,
324 void_type_node);
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;
330 return fndecl;
333 /* A function used by walk tree to find wrapper parms. */
335 static bool
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;
341 tree parm;
343 if (val == error_mark_node || val == arg)
344 return true;
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 "
357 "spawn", arg);
358 arg = null_pointer_node;
360 else
361 arg = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg)), arg);
363 val = TREE_OPERAND (val, 0);
364 *val0 = val;
365 gcc_assert (TREE_CODE (val) == INDIRECT_REF);
366 parm = TREE_OPERAND (val, 0);
367 STRIP_NOPS (parm);
369 else
370 parm = val;
371 TREE_CHAIN (parm) = wd->parms;
372 wd->parms = parm;
373 wd->argtypes = tree_cons (NULL_TREE, TREE_TYPE (parm), wd->argtypes);
374 wd->arglist = tree_cons (NULL_TREE, arg, wd->arglist);
375 return true;
378 /* This function is used to build a wrapper of a certain type. */
380 static void
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. */
399 static tree
400 check_outlined_calls (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
401 void *data)
403 bool *throws = (bool *) data;
404 tree t = *tp;
405 int flags;
407 if (TREE_CODE (t) != CALL_EXPR)
408 return 0;
409 flags = call_expr_flags (t);
411 if (!(flags & ECF_NOTHROW) && flag_exceptions)
412 *throws = true;
413 if (flags & ECF_RETURNS_TWICE)
414 error_at (EXPR_LOCATION (t),
415 "cannot spawn call to function that returns twice");
416 return 0;
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
421 function.
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. */
427 static tree
428 copy_decl_for_cilk (tree decl, copy_body_data *id)
430 switch (TREE_CODE (decl))
432 case VAR_DECL:
433 return copy_decl_no_change (decl, id);
435 case LABEL_DECL:
436 error_at (EXPR_LOCATION (decl), "invalid use of label %q+D in "
437 "%<_Cilk_spawn%>",
438 decl);
439 return error_mark_node;
441 case RESULT_DECL:
442 case PARM_DECL:
443 /* RESULT_DECL and PARM_DECL has already been entered into the map. */
444 default:
445 gcc_unreachable ();
446 return error_mark_node;
450 /* Copy all local variables. */
452 static bool
453 for_local_cb (const void *k_v, void **vp, void *p)
455 tree k = *(tree *) &k_v;
456 tree v = (tree) *vp;
458 if (v == error_mark_node)
459 *vp = copy_decl_no_change (k, (copy_body_data *) p);
460 return true;
463 /* Copy all local declarations from a _Cilk_spawned function's body. */
465 static bool
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);
475 return true;
478 /* Alter a tree STMT from OUTER_FN to form the body of INNER_FN. */
480 static void
481 cilk_outline (tree inner_fn, tree *stmt_p, struct wrapper_data *wd)
483 const tree outer_fn = wd->context;
484 const bool nested = (wd->type == CILK_BLOCK_FOR);
485 copy_body_data id;
486 bool throws;
488 DECL_STATIC_CHAIN (outer_fn) = 1;
490 memset (&id, 0, sizeof (id));
491 /* Copy from the function containing the spawn... */
492 id.src_fn = outer_fn;
494 /* ...to the wrapper. */
495 id.dst_fn = inner_fn;
496 id.src_cfun = DECL_STRUCT_FUNCTION (outer_fn);
498 /* There shall be no RETURN in spawn helper. */
499 id.retvar = 0;
500 id.decl_map = wd->decl_map;
501 id.copy_decl = nested ? copy_decl_no_change : copy_decl_for_cilk;
502 id.block = DECL_INITIAL (inner_fn);
503 id.transform_lang_insert_block = NULL;
505 id.transform_new_cfg = true;
506 id.transform_call_graph_edges = CB_CGE_MOVE;
507 id.remap_var_for_cilk = true;
508 id.regimplify = true; /* unused? */
510 insert_decl_map (&id, wd->block, DECL_INITIAL (inner_fn));
512 /* We don't want the private variables any more. */
513 pointer_map_traverse (wd->decl_map, nested ? for_local_cb : wrapper_local_cb,
514 &id);
516 walk_tree (stmt_p, copy_tree_body_r, &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. */
521 throws = false ;
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. */
530 static tree
531 create_cilk_wrapper_body (tree stmt, struct wrapper_data *wd)
533 const tree outer = current_function_decl;
534 tree fndecl;
535 tree p;
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 cilk_outline (fndecl, &stmt, wd);
558 stmt = fold_build_cleanup_point_expr (void_type_node, stmt);
559 gcc_assert (!DECL_SAVED_TREE (fndecl));
560 lang_hooks.cilkplus.install_body_with_frame_cleanup (fndecl, stmt);
561 gcc_assert (DECL_SAVED_TREE (fndecl));
563 pop_cfun_to (outer);
565 /* Recognize the new function. */
566 call_graph_add_fn (fndecl);
567 return fndecl;
570 /* Initializes the wrapper data structure. */
572 static void
573 init_wd (struct wrapper_data *wd, enum cilk_block_type type)
575 wd->type = type;
576 wd->fntype = NULL_TREE;
577 wd->context = current_function_decl;
578 wd->decl_map = pointer_map_create ();
579 /* _Cilk_for bodies are always nested. Others start off as
580 normal functions. */
581 wd->nested = (type == CILK_BLOCK_FOR);
582 wd->arglist = NULL_TREE;
583 wd->argtypes = NULL_TREE;
584 wd->block = NULL_TREE;
587 /* Clears the wrapper data structure. */
589 static void
590 free_wd (struct wrapper_data *wd)
592 pointer_map_destroy (wd->decl_map);
593 wd->nested = false;
594 wd->arglist = NULL_TREE;
595 wd->argtypes = NULL_TREE;
596 wd->parms = NULL_TREE;
600 /* Given a variable in an expression to be extracted into
601 a helper function, declare the helper function parameter
602 to receive it.
604 On entry the value of the (key, value) pair may be
606 (*, error_mark_node) -- Variable is private to helper function,
607 do nothing.
609 (var, var) -- Reference to outer scope (function or global scope).
611 (var, integer 0) -- Capture by value, save newly-declared PARM_DECL
612 for value in value slot.
614 (var, integer 1) -- Capture by reference, declare pointer to type
615 as new PARM_DECL and store (spawn_stmt (indirect_ref (parm)).
617 (var, ???) -- Pure output argument, handled similarly to above.
620 static bool
621 declare_one_free_variable (const void *var0, void **map0,
622 void *data ATTRIBUTE_UNUSED)
624 const_tree var = (const_tree) var0;
625 tree map = (tree)*map0;
626 tree var_type = TREE_TYPE (var), arg_type;
627 bool by_reference;
628 tree parm;
630 gcc_assert (DECL_P (var));
632 /* Ignore truly local variables. */
633 if (map == error_mark_node)
634 return true;
635 /* Ignore references to the parent function. */
636 if (map == var)
637 return true;
639 gcc_assert (TREE_CODE (map) == INTEGER_CST);
641 /* A value is passed by reference if:
643 1. It is addressable, so that a copy may not be made.
644 2. It is modified in the spawned statement.
645 In the future this function may want to arrange
646 a warning if the spawned statement is a loop body
647 because an output argument would indicate a race.
648 Note: Earlier passes must have marked the variable addressable.
649 3. It is expensive to copy. */
650 by_reference =
651 (TREE_ADDRESSABLE (var_type)
652 /* Arrays must be passed by reference. This is required for C
653 semantics -- arrays are not first class objects. Other
654 aggregate types can and should be passed by reference if
655 they are not passed to the spawned function. We aren't yet
656 distinguishing safe uses in argument calculation from unsafe
657 uses as outgoing function arguments, so we make a copy to
658 stabilize the value. */
659 || TREE_CODE (var_type) == ARRAY_TYPE
660 || (tree) map == integer_one_node);
662 if (by_reference)
663 var_type = build_qualified_type (build_pointer_type (var_type),
664 TYPE_QUAL_RESTRICT);
665 gcc_assert (!TREE_ADDRESSABLE (var_type));
667 /* Maybe promote to int. */
668 if (INTEGRAL_TYPE_P (var_type) && COMPLETE_TYPE_P (var_type)
669 && INT_CST_LT_UNSIGNED (TYPE_SIZE (var_type),
670 TYPE_SIZE (integer_type_node)))
671 arg_type = integer_type_node;
672 else
673 arg_type = var_type;
675 parm = build_decl (UNKNOWN_LOCATION, PARM_DECL, NULL_TREE, var_type);
676 DECL_ARG_TYPE (parm) = arg_type;
677 DECL_ARTIFICIAL (parm) = 0;
678 TREE_READONLY (parm) = 1;
680 if (by_reference)
682 parm = build1 (INDIRECT_REF, TREE_TYPE (var_type), parm);
683 parm = build1 (PAREN_EXPR, void_type_node, parm);
685 *map0 = parm;
686 return true;
689 /* Returns a wrapper function for a _Cilk_spawn. */
691 static tree
692 create_cilk_wrapper (tree exp, tree *args_out)
694 struct wrapper_data wd;
695 tree fndecl;
697 init_wd (&wd, CILK_BLOCK_SPAWN);
699 if (TREE_CODE (exp) == CONVERT_EXPR)
700 exp = TREE_OPERAND (exp, 0);
702 /* Special handling for top level INIT_EXPR. Usually INIT_EXPR means the
703 variable is defined in the spawned expression and can be private to the
704 spawn helper. A top level INIT_EXPR defines a variable to be initialized
705 by spawn and the variable must remain in the outer function. */
706 if (TREE_CODE (exp) == INIT_EXPR)
708 extract_free_variables (TREE_OPERAND (exp, 0), &wd, ADD_WRITE);
709 extract_free_variables (TREE_OPERAND (exp, 1), &wd, ADD_READ);
710 /* TREE_TYPE should be void. Be defensive. */
711 if (TREE_TYPE (exp) != void_type_node)
712 extract_free_variables (TREE_TYPE (exp), &wd, ADD_READ);
714 else
715 extract_free_variables (exp, &wd, ADD_READ);
716 pointer_map_traverse (wd.decl_map, declare_one_free_variable, &wd);
717 wd.block = TREE_BLOCK (exp);
718 if (!wd.block)
719 wd.block = DECL_INITIAL (current_function_decl);
721 /* Now fvars maps the old variable to incoming variable. Update
722 the expression and arguments to refer to the new names. */
723 fndecl = create_cilk_wrapper_body (exp, &wd);
724 *args_out = wd.arglist;
726 free_wd (&wd);
728 return fndecl;
731 /* Transform *SPAWN_P, a spawned CALL_EXPR, to gimple. *SPAWN_P can be a
732 CALL_EXPR, INIT_EXPR or MODIFY_EXPR. Returns GS_OK if everything is fine,
733 and GS_UNHANDLED, otherwise. */
736 gimplify_cilk_spawn (tree *spawn_p, gimple_seq *before ATTRIBUTE_UNUSED,
737 gimple_seq *after ATTRIBUTE_UNUSED)
739 tree expr = *spawn_p;
740 tree function, call1, call2, new_args;
741 tree ii_args = NULL_TREE;
742 int total_args = 0, ii = 0;
743 tree *arg_array;
744 tree setjmp_cond_expr = NULL_TREE;
745 tree setjmp_expr, spawn_expr, setjmp_value = NULL_TREE;
747 cfun->calls_cilk_spawn = 1;
748 cfun->is_cilk_function = 1;
750 /* Remove CLEANUP_POINT_EXPR and EXPR_STMT from *spawn_p. */
751 while (TREE_CODE (expr) == CLEANUP_POINT_EXPR
752 || TREE_CODE (expr) == EXPR_STMT)
753 expr = TREE_OPERAND (expr, 0);
755 new_args = NULL;
756 function = create_cilk_wrapper (expr, &new_args);
758 /* This should give the number of parameters. */
759 total_args = list_length (new_args);
760 if (total_args)
761 arg_array = XNEWVEC (tree, total_args);
762 else
763 arg_array = NULL;
765 ii_args = new_args;
766 for (ii = 0; ii < total_args; ii++)
768 arg_array[ii] = TREE_VALUE (ii_args);
769 ii_args = TREE_CHAIN (ii_args);
772 TREE_USED (function) = 1;
773 rest_of_decl_compilation (function, 0, 0);
775 call1 = cilk_call_setjmp (cfun->cilk_frame_decl);
777 if (arg_array == NULL || *arg_array == NULL_TREE)
778 call2 = build_call_expr (function, 0);
779 else
780 call2 = build_call_expr_loc_array (EXPR_LOCATION (*spawn_p), function,
781 total_args, arg_array);
782 *spawn_p = alloc_stmt_list ();
783 tree f_ptr_type = build_pointer_type (TREE_TYPE (cfun->cilk_frame_decl));
784 tree frame_ptr = build1 (ADDR_EXPR, f_ptr_type, cfun->cilk_frame_decl);
785 tree save_fp = build_call_expr (cilk_save_fp_fndecl, 1, frame_ptr);
786 append_to_statement_list (save_fp, spawn_p);
787 setjmp_value = create_tmp_var (TREE_TYPE (call1), NULL);
788 setjmp_expr = fold_build2 (MODIFY_EXPR, void_type_node, setjmp_value, call1);
790 append_to_statement_list_force (setjmp_expr, spawn_p);
792 setjmp_cond_expr = fold_build2 (EQ_EXPR, TREE_TYPE (call1), setjmp_value,
793 build_int_cst (TREE_TYPE (call1), 0));
794 spawn_expr = fold_build3 (COND_EXPR, void_type_node, setjmp_cond_expr,
795 call2, build_empty_stmt (EXPR_LOCATION (call1)));
796 append_to_statement_list (spawn_expr, spawn_p);
798 return GS_OK;
801 /* Make the frames necessary for a spawn call. */
803 tree
804 make_cilk_frame (tree fn)
806 struct function *f = DECL_STRUCT_FUNCTION (fn);
807 tree decl;
809 if (f->cilk_frame_decl)
810 return f->cilk_frame_decl;
812 decl = build_decl (EXPR_LOCATION (fn), VAR_DECL, NULL_TREE,
813 cilk_frame_type_decl);
814 DECL_CONTEXT (decl) = fn;
815 DECL_SEEN_IN_BIND_EXPR_P (decl) = 1;
816 f->cilk_frame_decl = decl;
817 return decl;
820 /* Returns a STATEMENT_LIST with all the pedigree operations required for
821 install body with frame cleanup functions. FRAME_PTR is the pointer to
822 __cilkrts_stack_frame created by make_cilk_frame. */
824 tree
825 cilk_install_body_pedigree_operations (tree frame_ptr)
827 tree body_list = alloc_stmt_list ();
828 tree enter_frame = build_call_expr (cilk_enter_fast_fndecl, 1, frame_ptr);
829 append_to_statement_list (enter_frame, &body_list);
831 tree parent = cilk_arrow (frame_ptr, CILK_TI_FRAME_PARENT, 0);
832 tree worker = cilk_arrow (frame_ptr, CILK_TI_FRAME_WORKER, 0);
834 tree pedigree = cilk_arrow (frame_ptr, CILK_TI_FRAME_PEDIGREE, 0);
835 tree pedigree_rank = cilk_dot (pedigree, CILK_TI_PEDIGREE_RANK, 0);
836 tree parent_pedigree = cilk_dot (pedigree, CILK_TI_PEDIGREE_PARENT, 0);
837 tree pedigree_parent = cilk_arrow (parent, CILK_TI_FRAME_PEDIGREE, 0);
838 tree pedigree_parent_rank = cilk_dot (pedigree_parent,
839 CILK_TI_PEDIGREE_RANK, 0);
840 tree pedigree_parent_parent = cilk_dot (pedigree_parent,
841 CILK_TI_PEDIGREE_PARENT, 0);
842 tree worker_pedigree = cilk_arrow (worker, CILK_TI_WORKER_PEDIGREE, 1);
843 tree w_pedigree_rank = cilk_dot (worker_pedigree, CILK_TI_PEDIGREE_RANK, 0);
844 tree w_pedigree_parent = cilk_dot (worker_pedigree,
845 CILK_TI_PEDIGREE_PARENT, 0);
847 /* sf.pedigree.rank = worker->pedigree.rank. */
848 tree exp1 = build2 (MODIFY_EXPR, void_type_node, pedigree_rank,
849 w_pedigree_rank);
850 append_to_statement_list (exp1, &body_list);
852 /* sf.pedigree.parent = worker->pedigree.parent. */
853 exp1 = build2 (MODIFY_EXPR, void_type_node, parent_pedigree,
854 w_pedigree_parent);
855 append_to_statement_list (exp1, &body_list);
857 /* sf.call_parent->pedigree.rank = worker->pedigree.rank. */
858 exp1 = build2 (MODIFY_EXPR, void_type_node, pedigree_parent_rank,
859 w_pedigree_rank);
860 append_to_statement_list (exp1, &body_list);
862 /* sf.call_parent->pedigree.parent = worker->pedigree.parent. */
863 exp1 = build2 (MODIFY_EXPR, void_type_node, pedigree_parent_parent,
864 w_pedigree_parent);
865 append_to_statement_list (exp1, &body_list);
867 /* sf->worker.pedigree.rank = 0. */
868 exp1 = build2 (MODIFY_EXPR, void_type_node, w_pedigree_rank,
869 build_zero_cst (uint64_type_node));
870 append_to_statement_list (exp1, &body_list);
872 /* sf->pedigree.parent = &sf->pedigree. */
873 exp1 = build2 (MODIFY_EXPR, void_type_node, w_pedigree_parent,
874 build1 (ADDR_EXPR,
875 build_pointer_type (cilk_pedigree_type_decl),
876 pedigree));
877 append_to_statement_list (exp1, &body_list);
878 return body_list;
881 /* Inserts "cleanup" functions after the function-body of FNDECL. FNDECL is a
882 spawn-helper and BODY is the newly created body for FNDECL. */
884 void
885 c_cilk_install_body_w_frame_cleanup (tree fndecl, tree body)
887 tree list = alloc_stmt_list ();
888 tree frame = make_cilk_frame (fndecl);
889 tree dtor = create_cilk_function_exit (frame, false, true);
890 add_local_decl (cfun, frame);
892 DECL_SAVED_TREE (fndecl) = list;
893 tree frame_ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (frame)),
894 frame);
895 tree body_list = cilk_install_body_pedigree_operations (frame_ptr);
896 gcc_assert (TREE_CODE (body_list) == STATEMENT_LIST);
898 tree detach_expr = build_call_expr (cilk_detach_fndecl, 1, frame_ptr);
899 append_to_statement_list (detach_expr, &body_list);
900 append_to_statement_list (body, &body_list);
901 append_to_statement_list (build_stmt (EXPR_LOCATION (body), TRY_FINALLY_EXPR,
902 body_list, dtor), &list);
905 /* Add a new variable, VAR to a variable list in WD->DECL_MAP. HOW indicates
906 whether the variable is previously defined, currently defined, or a variable
907 that is being written to. */
909 static void
910 add_variable (struct wrapper_data *wd, tree var, enum add_variable_type how)
912 void **valp;
914 valp = pointer_map_contains (wd->decl_map, (void *) var);
915 if (valp)
917 tree val = (tree) *valp;
918 /* If the variable is local, do nothing. */
919 if (val == error_mark_node)
920 return;
921 /* If the variable was entered with itself as value,
922 meaning it belongs to an outer scope, do not alter
923 the value. */
924 if (val == var)
925 return;
926 /* A statement expression may cause a variable to be
927 bound twice, once in BIND_EXPR and again in a
928 DECL_EXPR. That case caused a return in the
929 test above. Any other duplicate definition is
930 an error. */
931 gcc_assert (how != ADD_BIND);
932 if (how != ADD_WRITE)
933 return;
934 /* This variable might have been entered as read but is now written. */
935 *valp = (void *) var;
936 wd->nested = true;
937 return;
939 else
941 tree val = NULL_TREE;
943 /* Nested function rewriting silently discards hard register
944 assignments for function scope variables, and they wouldn't
945 work anyway. Warn here. This misses one case: if the
946 register variable is used as the loop bound or increment it
947 has already been added to the map. */
948 if ((how != ADD_BIND) && (TREE_CODE (var) == VAR_DECL)
949 && !DECL_EXTERNAL (var) && DECL_HARD_REGISTER (var))
950 warning (0, "register assignment ignored for %qD used in Cilk block",
951 var);
953 switch (how)
955 /* ADD_BIND means always make a fresh new variable. */
956 case ADD_BIND:
957 val = error_mark_node;
958 break;
959 /* ADD_READ means
960 1. For cilk_for, refer to the outer scope definition as-is
961 2. For a spawned block, take a scalar in an rgument
962 and otherwise refer to the outer scope definition as-is.
963 3. For a spawned call, take a scalar in an argument. */
964 case ADD_READ:
965 switch (wd->type)
967 case CILK_BLOCK_FOR:
968 val = var;
969 break;
970 case CILK_BLOCK_SPAWN:
971 if (TREE_ADDRESSABLE (var))
973 val = var;
974 wd->nested = true;
975 break;
977 val = integer_zero_node;
978 break;
980 break;
981 case ADD_WRITE:
982 switch (wd->type)
984 case CILK_BLOCK_FOR:
985 val = var;
986 wd->nested = true;
987 break;
988 case CILK_BLOCK_SPAWN:
989 if (TREE_ADDRESSABLE (var))
990 val = integer_one_node;
991 else
993 val = var;
994 wd->nested = true;
996 break;
999 *pointer_map_insert (wd->decl_map, (void *) var) = val;
1003 /* Find the variables referenced in an expression T. This does not avoid
1004 duplicates because a variable may be read in one context and written in
1005 another. HOW describes the context in which the reference is seen. If
1006 NESTED is true a nested function is being generated and variables in the
1007 original context should not be remapped. */
1009 static void
1010 extract_free_variables (tree t, struct wrapper_data *wd,
1011 enum add_variable_type how)
1013 if (t == NULL_TREE)
1014 return;
1016 enum tree_code code = TREE_CODE (t);
1017 bool is_expr = IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code));
1019 if (is_expr)
1020 extract_free_variables (TREE_TYPE (t), wd, ADD_READ);
1022 switch (code)
1024 case ERROR_MARK:
1025 case IDENTIFIER_NODE:
1026 case INTEGER_CST:
1027 case REAL_CST:
1028 case FIXED_CST:
1029 case STRING_CST:
1030 case BLOCK:
1031 case PLACEHOLDER_EXPR:
1032 case FIELD_DECL:
1033 case VOID_TYPE:
1034 case REAL_TYPE:
1035 /* These do not contain variable references. */
1036 return;
1038 case SSA_NAME:
1039 /* Currently we don't see SSA_NAME. */
1040 extract_free_variables (SSA_NAME_VAR (t), wd, how);
1041 return;
1043 case LABEL_DECL:
1044 /* This might be a reference to a label outside the Cilk block,
1045 which is an error, or a reference to a label in the Cilk block
1046 that we haven't seen yet. We can't tell. Ignore it. An
1047 invalid use will cause an error later in copy_decl_for_cilk. */
1048 return;
1050 case RESULT_DECL:
1051 if (wd->type != CILK_BLOCK_SPAWN)
1052 TREE_ADDRESSABLE (t) = 1;
1053 case VAR_DECL:
1054 case PARM_DECL:
1055 if (!TREE_STATIC (t) && !DECL_EXTERNAL (t))
1056 add_variable (wd, t, how);
1057 return;
1059 case NON_LVALUE_EXPR:
1060 case CONVERT_EXPR:
1061 case NOP_EXPR:
1062 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_READ);
1063 return;
1065 case INIT_EXPR:
1066 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_BIND);
1067 extract_free_variables (TREE_OPERAND (t, 1), wd, ADD_READ);
1068 return;
1070 case MODIFY_EXPR:
1071 case PREDECREMENT_EXPR:
1072 case PREINCREMENT_EXPR:
1073 case POSTDECREMENT_EXPR:
1074 case POSTINCREMENT_EXPR:
1075 /* These write their result. */
1076 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_WRITE);
1077 extract_free_variables (TREE_OPERAND (t, 1), wd, ADD_READ);
1078 return;
1080 case ADDR_EXPR:
1081 /* This might modify its argument, and the value needs to be
1082 passed by reference in any case to preserve identity and
1083 type if is a promoting type. In the case of a nested loop
1084 just notice that we touch the variable. It will already
1085 be addressable, and marking it modified will cause a spurious
1086 warning about writing the control variable. */
1087 if (wd->type != CILK_BLOCK_SPAWN)
1088 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_READ);
1089 else
1090 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_WRITE);
1091 return;
1093 case ARRAY_REF:
1094 /* Treating ARRAY_REF and BIT_FIELD_REF identically may
1095 mark the array as written but the end result is correct
1096 because the array is passed by pointer anyway. */
1097 case BIT_FIELD_REF:
1098 /* Propagate the access type to the object part of which
1099 is being accessed here. As for ADDR_EXPR, don't do this
1100 in a nested loop, unless the access is to a fixed index. */
1101 if (wd->type != CILK_BLOCK_FOR || TREE_CONSTANT (TREE_OPERAND (t, 1)))
1102 extract_free_variables (TREE_OPERAND (t, 0), wd, how);
1103 else
1104 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_READ);
1105 extract_free_variables (TREE_OPERAND (t, 1), wd, ADD_READ);
1106 extract_free_variables (TREE_OPERAND (t, 2), wd, ADD_READ);
1107 return;
1109 case TREE_LIST:
1110 extract_free_variables (TREE_PURPOSE (t), wd, ADD_READ);
1111 extract_free_variables (TREE_VALUE (t), wd, ADD_READ);
1112 extract_free_variables (TREE_CHAIN (t), wd, ADD_READ);
1113 return;
1115 case TREE_VEC:
1117 int len = TREE_VEC_LENGTH (t);
1118 int i;
1119 for (i = 0; i < len; i++)
1120 extract_free_variables (TREE_VEC_ELT (t, i), wd, ADD_READ);
1121 return;
1124 case VECTOR_CST:
1126 unsigned ii = 0;
1127 for (ii = 0; ii < VECTOR_CST_NELTS (t); ii++)
1128 extract_free_variables (VECTOR_CST_ELT (t, ii), wd, ADD_READ);
1129 break;
1132 case COMPLEX_CST:
1133 extract_free_variables (TREE_REALPART (t), wd, ADD_READ);
1134 extract_free_variables (TREE_IMAGPART (t), wd, ADD_READ);
1135 return;
1137 case BIND_EXPR:
1139 tree decl;
1140 for (decl = BIND_EXPR_VARS (t); decl; decl = TREE_CHAIN (decl))
1142 add_variable (wd, decl, ADD_BIND);
1143 /* A self-referential initialization is no problem because
1144 we already entered the variable into the map as local. */
1145 extract_free_variables (DECL_INITIAL (decl), wd, ADD_READ);
1146 extract_free_variables (DECL_SIZE (decl), wd, ADD_READ);
1147 extract_free_variables (DECL_SIZE_UNIT (decl), wd, ADD_READ);
1149 extract_free_variables (BIND_EXPR_BODY (t), wd, ADD_READ);
1150 return;
1153 case STATEMENT_LIST:
1155 tree_stmt_iterator i;
1156 for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
1157 extract_free_variables (*tsi_stmt_ptr (i), wd, ADD_READ);
1158 return;
1161 case TARGET_EXPR:
1163 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_BIND);
1164 extract_free_variables (TREE_OPERAND (t, 1), wd, ADD_READ);
1165 extract_free_variables (TREE_OPERAND (t, 2), wd, ADD_READ);
1166 if (TREE_OPERAND (t, 3) != TREE_OPERAND (t, 1))
1167 extract_free_variables (TREE_OPERAND (t, 3), wd, ADD_READ);
1168 return;
1171 case RETURN_EXPR:
1172 if (TREE_NO_WARNING (t))
1174 gcc_assert (errorcount);
1175 return;
1177 return;
1179 case DECL_EXPR:
1180 if (TREE_CODE (DECL_EXPR_DECL (t)) != TYPE_DECL)
1181 extract_free_variables (DECL_EXPR_DECL (t), wd, ADD_BIND);
1182 return;
1184 case INTEGER_TYPE:
1185 case ENUMERAL_TYPE:
1186 case BOOLEAN_TYPE:
1187 extract_free_variables (TYPE_MIN_VALUE (t), wd, ADD_READ);
1188 extract_free_variables (TYPE_MAX_VALUE (t), wd, ADD_READ);
1189 return;
1191 case POINTER_TYPE:
1192 extract_free_variables (TREE_TYPE (t), wd, ADD_READ);
1193 break;
1195 case ARRAY_TYPE:
1196 extract_free_variables (TREE_TYPE (t), wd, ADD_READ);
1197 extract_free_variables (TYPE_DOMAIN (t), wd, ADD_READ);
1198 return;
1200 case RECORD_TYPE:
1201 extract_free_variables (TYPE_FIELDS (t), wd, ADD_READ);
1202 return;
1204 case METHOD_TYPE:
1205 extract_free_variables (TYPE_ARG_TYPES (t), wd, ADD_READ);
1206 extract_free_variables (TYPE_METHOD_BASETYPE (t), wd, ADD_READ);
1207 return;
1209 case AGGR_INIT_EXPR:
1210 case CALL_EXPR:
1212 int len = 0;
1213 int ii = 0;
1214 if (TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST)
1216 len = TREE_INT_CST_LOW (TREE_OPERAND (t, 0));
1218 for (ii = 0; ii < len; ii++)
1219 extract_free_variables (TREE_OPERAND (t, ii), wd, ADD_READ);
1220 extract_free_variables (TREE_TYPE (t), wd, ADD_READ);
1222 break;
1225 default:
1226 if (is_expr)
1228 int i, len;
1230 /* Walk over all the sub-trees of this operand. */
1231 len = TREE_CODE_LENGTH (code);
1233 /* Go through the subtrees. We need to do this in forward order so
1234 that the scope of a FOR_EXPR is handled properly. */
1235 for (i = 0; i < len; ++i)
1236 extract_free_variables (TREE_OPERAND (t, i), wd, ADD_READ);
1242 /* Add appropriate frames needed for a Cilk spawned function call, FNDECL.
1243 Returns the __cilkrts_stack_frame * variable. */
1245 tree
1246 insert_cilk_frame (tree fndecl)
1248 tree addr, body, enter, out, orig_body;
1249 location_t loc = EXPR_LOCATION (fndecl);
1251 if (!cfun || cfun->decl != fndecl)
1252 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
1254 tree decl = cfun->cilk_frame_decl;
1255 if (!decl)
1257 tree *saved_tree = &DECL_SAVED_TREE (fndecl);
1258 decl = make_cilk_frame (fndecl);
1259 add_local_decl (cfun, decl);
1261 addr = build1 (ADDR_EXPR, cilk_frame_ptr_type_decl, decl);
1262 enter = build_call_expr (cilk_enter_fndecl, 1, addr);
1263 out = create_cilk_function_exit (cfun->cilk_frame_decl, false, true);
1265 /* The new body will be:
1266 __cilkrts_enter_frame_1 (&sf);
1267 try {
1268 orig_body;
1270 finally {
1271 __cilkrts_pop_frame (&sf);
1272 __cilkrts_leave_frame (&sf);
1273 } */
1275 body = alloc_stmt_list ();
1276 orig_body = *saved_tree;
1278 if (TREE_CODE (orig_body) == BIND_EXPR)
1279 orig_body = BIND_EXPR_BODY (orig_body);
1281 append_to_statement_list (enter, &body);
1282 append_to_statement_list (build_stmt (loc, TRY_FINALLY_EXPR, orig_body,
1283 out), &body);
1284 if (TREE_CODE (*saved_tree) == BIND_EXPR)
1285 BIND_EXPR_BODY (*saved_tree) = body;
1286 else
1287 *saved_tree = body;
1289 return decl;
1292 /* Wraps CALL, a CALL_EXPR, into a CILK_SPAWN_STMT tree and returns it. */
1294 tree
1295 build_cilk_spawn (location_t loc, tree call)
1297 if (!cilk_set_spawn_marker (loc, call))
1298 return error_mark_node;
1299 tree spawn_stmt = build1 (CILK_SPAWN_STMT, TREE_TYPE (call), call);
1300 TREE_SIDE_EFFECTS (spawn_stmt) = 1;
1301 return spawn_stmt;
1304 /* Returns a tree of type CILK_SYNC_STMT. */
1306 tree
1307 build_cilk_sync (void)
1309 tree sync = build0 (CILK_SYNC_STMT, void_type_node);
1310 TREE_SIDE_EFFECTS (sync) = 1;
1311 return sync;