PR middle-end/59175
[official-gcc.git] / gcc / c-family / cilk.c
blob165348f124cfacb7ed5b5026a8715995b39d6d52
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 "langhooks.h"
28 #include "gimple.h"
29 #include "gimplify.h"
30 #include "tree-iterator.h"
31 #include "tree-inline.h"
32 #include "c-family/c-common.h"
33 #include "toplev.h"
34 #include "cgraph.h"
35 #include "diagnostic.h"
36 #include "cilk.h"
38 enum add_variable_type {
39 /* Reference to previously-defined variable. */
40 ADD_READ,
41 /* Definition of a new variable in inner-scope. */
42 ADD_BIND,
43 /* Write to possibly previously-defined variable. */
44 ADD_WRITE
47 enum cilk_block_type {
48 /* Indicates a _Cilk_spawn block. 30 was an arbitary number picked for
49 ease of debugging. */
50 CILK_BLOCK_SPAWN = 30,
51 /* Indicates _Cilk_for statement block. */
52 CILK_BLOCK_FOR
55 struct wrapper_data
57 /* Kind of function to be created. */
58 enum cilk_block_type type;
59 /* Signature of helper function. */
60 tree fntype;
61 /* Containing function. */
62 tree context;
63 /* Disposition of all variables in the inner statement. */
64 struct pointer_map_t *decl_map;
65 /* True if this function needs a static chain. */
66 bool nested;
67 /* Arguments to be passed to wrapper function, currently a list. */
68 tree arglist;
69 /* Argument types, a list. */
70 tree argtypes;
71 /* Incoming parameters. */
72 tree parms;
73 /* Outer BLOCK object. */
74 tree block;
77 static void extract_free_variables (tree, struct wrapper_data *,
78 enum add_variable_type);
79 static HOST_WIDE_INT cilk_wrapper_count;
81 /* Marks the CALL_EXPR or FUNCTION_DECL, FCALL, as a spawned function call
82 and the current function as a spawner. Emit error if the function call
83 is outside a function or if a non function-call is spawned. */
85 inline bool
86 cilk_set_spawn_marker (location_t loc, tree fcall)
88 if (!current_function_decl)
90 error_at (loc, "%<_Cilk_spawn%> may only be used inside a function");
91 return false;
93 else if (fcall == error_mark_node)
94 /* Error reporting here is not necessary here since if FCALL is an
95 error_mark_node, the function marking it as error would have reported
96 it. */
97 return false;
98 else if (TREE_CODE (fcall) != CALL_EXPR
99 && TREE_CODE (fcall) != FUNCTION_DECL
100 /* In C++, TARGET_EXPR is generated when we have an overloaded
101 '=' operator. */
102 && TREE_CODE (fcall) != TARGET_EXPR)
104 error_at (loc, "only function calls can be spawned");
105 return false;
107 else
109 cfun->calls_cilk_spawn = true;
110 return true;
114 /* This function will output the exit conditions for a spawn call. */
116 tree
117 create_cilk_function_exit (tree frame, bool detaches, bool needs_sync)
119 tree epi = alloc_stmt_list ();
121 if (needs_sync)
122 append_to_statement_list (build_cilk_sync (), &epi);
123 tree func_ptr = build1 (ADDR_EXPR, cilk_frame_ptr_type_decl, frame);
124 tree pop_frame = build_call_expr (cilk_pop_fndecl, 1, func_ptr);
125 tree worker = cilk_dot (frame, CILK_TI_FRAME_WORKER, 0);
126 tree current = cilk_arrow (worker, CILK_TI_WORKER_CUR, 0);
127 tree parent = cilk_dot (frame, CILK_TI_FRAME_PARENT, 0);
128 tree set_current = build2 (MODIFY_EXPR, void_type_node, current, parent);
129 append_to_statement_list (set_current, &epi);
130 append_to_statement_list (pop_frame, &epi);
131 tree call = build_call_expr (cilk_leave_fndecl, 1, func_ptr);
132 if (!detaches)
134 tree flags = cilk_dot (frame, CILK_TI_FRAME_FLAGS, false);
135 tree flags_cmp_expr = fold_build2 (NE_EXPR, TREE_TYPE (flags), flags,
136 build_int_cst (TREE_TYPE (flags),
137 CILK_FRAME_VERSION));
138 call = fold_build3 (COND_EXPR, void_type_node, flags_cmp_expr,
139 call, build_empty_stmt (EXPR_LOCATION (flags)));
141 append_to_statement_list (call, &epi);
142 return epi;
145 /* Trying to get the correct cfun for the FUNCTION_DECL indicated by OUTER. */
147 static void
148 pop_cfun_to (tree outer)
150 pop_cfun ();
151 current_function_decl = outer;
152 gcc_assert (cfun == DECL_STRUCT_FUNCTION (current_function_decl));
153 gcc_assert (cfun->decl == current_function_decl);
156 /* This function does whatever is necessary to make the compiler emit a newly
157 generated function, FNDECL. */
159 static void
160 call_graph_add_fn (tree fndecl)
162 const tree outer = current_function_decl;
163 struct function *f = DECL_STRUCT_FUNCTION (fndecl);
164 gcc_assert (TREE_CODE (fndecl) == FUNCTION_DECL);
166 f->is_cilk_function = 1;
167 f->curr_properties = cfun->curr_properties;
168 gcc_assert (cfun == DECL_STRUCT_FUNCTION (outer));
169 gcc_assert (cfun->decl == outer);
171 push_cfun (f);
172 cgraph_create_node (fndecl);
173 pop_cfun_to (outer);
176 /* Return true if this is a tree which is allowed to contain a spawn as
177 operand 0.
178 A spawn call may be wrapped in a series of unary operations such
179 as conversions. These conversions need not be "useless"
180 to be disregarded because they are retained in the spawned
181 statement. They are bypassed only to look for a spawn
182 within.
183 A comparison to constant is simple enough to allow, and
184 is used to convert to bool. */
186 static bool
187 cilk_ignorable_spawn_rhs_op (tree exp)
189 enum tree_code code = TREE_CODE (exp);
190 switch (TREE_CODE_CLASS (code))
192 case tcc_expression:
193 return code == ADDR_EXPR;
194 case tcc_comparison:
195 /* We need the spawn as operand 0 for now. That's where it
196 appears in the only case we really care about, conversion
197 to bool. */
198 return (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST);
199 case tcc_unary:
200 case tcc_reference:
201 return true;
202 default:
203 return false;
207 /* Helper function for walk_tree. If *TP is a CILK_SPAWN_STMT, then unwrap
208 this "wrapper." The function returns NULL_TREE regardless. */
210 static tree
211 unwrap_cilk_spawn_stmt (tree *tp, int *walk_subtrees, void *)
213 if (TREE_CODE (*tp) == CILK_SPAWN_STMT)
215 *tp = CILK_SPAWN_FN (*tp);
216 *walk_subtrees = 0;
218 return NULL_TREE;
221 /* Returns true when EXP is a CALL_EXPR with _Cilk_spawn in front. Unwraps
222 CILK_SPAWN_STMT wrapper from the CALL_EXPR in *EXP0 statement. */
224 static bool
225 recognize_spawn (tree exp, tree *exp0)
227 bool spawn_found = false;
228 if (TREE_CODE (exp) == CILK_SPAWN_STMT)
230 /* Remove the CALL_EXPR from CILK_SPAWN_STMT wrapper. */
231 exp = CILK_SPAWN_FN (exp);
232 walk_tree (exp0, unwrap_cilk_spawn_stmt, NULL, NULL);
233 spawn_found = true;
235 return spawn_found;
238 /* Returns true if *EXP0 is a recognized form of spawn. Recognized forms are,
239 after conversion to void, a call expression at outer level or an assignment
240 at outer level with the right hand side being a spawned call.
241 In addition to this, it also unwraps the CILK_SPAWN_STMT cover from the
242 CALL_EXPR that is being spawned.
243 Note that `=' in C++ may turn into a CALL_EXPR rather than a MODIFY_EXPR. */
245 bool
246 cilk_detect_spawn_and_unwrap (tree *exp0)
248 tree exp = *exp0;
250 if (!TREE_SIDE_EFFECTS (exp))
251 return false;
253 /* Strip off any conversion to void. It does not affect whether spawn
254 is supported here. */
255 if (TREE_CODE (exp) == CONVERT_EXPR && VOID_TYPE_P (TREE_TYPE (exp)))
256 exp = TREE_OPERAND (exp, 0);
258 if (TREE_CODE (exp) == MODIFY_EXPR || TREE_CODE (exp) == INIT_EXPR)
259 exp = TREE_OPERAND (exp, 1);
261 while (cilk_ignorable_spawn_rhs_op (exp))
262 exp = TREE_OPERAND (exp, 0);
264 if (TREE_CODE (exp) == TARGET_EXPR)
265 if (TARGET_EXPR_INITIAL (exp)
266 && TREE_CODE (TARGET_EXPR_INITIAL (exp)) != AGGR_INIT_EXPR)
267 exp = TARGET_EXPR_INITIAL (exp);
269 /* Happens with C++ TARGET_EXPR. */
270 if (exp == NULL_TREE)
271 return false;
273 while (TREE_CODE (exp) == CLEANUP_POINT_EXPR || TREE_CODE (exp) == EXPR_STMT)
274 exp = TREE_OPERAND (exp, 0);
276 /* Now we should have a CALL_EXPR with a CILK_SPAWN_STMT wrapper around
277 it, or return false. */
278 if (recognize_spawn (exp, exp0))
279 return true;
280 return false;
283 /* This function will build and return a FUNCTION_DECL using information
284 from *WD. */
286 static tree
287 create_cilk_helper_decl (struct wrapper_data *wd)
289 char name[20];
290 if (wd->type == CILK_BLOCK_FOR)
291 sprintf (name, "_cilk_for_" HOST_WIDE_INT_PRINT_DEC, cilk_wrapper_count++);
292 else if (wd->type == CILK_BLOCK_SPAWN)
293 sprintf (name, "_cilk_spn_" HOST_WIDE_INT_PRINT_DEC, cilk_wrapper_count++);
294 else
295 gcc_unreachable ();
297 clean_symbol_name (name);
298 tree fndecl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
299 get_identifier (name), wd->fntype);
301 TREE_PUBLIC (fndecl) = 0;
302 TREE_STATIC (fndecl) = 1;
303 TREE_USED (fndecl) = 1;
304 DECL_ARTIFICIAL (fndecl) = 0;
305 DECL_IGNORED_P (fndecl) = 0;
306 DECL_EXTERNAL (fndecl) = 0;
308 DECL_CONTEXT (fndecl) = wd->context;
309 tree block = make_node (BLOCK);
310 DECL_INITIAL (fndecl) = block;
311 TREE_USED (block) = 1;
312 gcc_assert (!DECL_SAVED_TREE (fndecl));
314 /* Inlining would defeat the purpose of this wrapper.
315 Either it secretly switches stack frames or it allocates
316 a stable stack frame to hold function arguments even if
317 the parent stack frame is stolen. */
318 DECL_UNINLINABLE (fndecl) = 1;
320 tree result_decl = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE,
321 void_type_node);
322 DECL_ARTIFICIAL (result_decl) = 0;
323 DECL_IGNORED_P (result_decl) = 1;
324 DECL_CONTEXT (result_decl) = fndecl;
325 DECL_RESULT (fndecl) = result_decl;
327 return fndecl;
330 /* A function used by walk tree to find wrapper parms. */
332 static bool
333 wrapper_parm_cb (const void *key0, void **val0, void *data)
335 struct wrapper_data *wd = (struct wrapper_data *) data;
336 tree arg = * (tree *)&key0;
337 tree val = (tree)*val0;
338 tree parm;
340 if (val == error_mark_node || val == arg)
341 return true;
343 if (TREE_CODE (val) == PAREN_EXPR)
345 /* We should not reach here with a register receiver.
346 We may see a register variable modified in the
347 argument list. Because register variables are
348 worker-local we don't need to work hard to support
349 them in code that spawns. */
350 if ((TREE_CODE (arg) == VAR_DECL) && DECL_HARD_REGISTER (arg))
352 error_at (EXPR_LOCATION (arg),
353 "explicit register variable %qD may not be modified in "
354 "spawn", arg);
355 arg = null_pointer_node;
357 else
358 arg = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg)), arg);
360 val = TREE_OPERAND (val, 0);
361 *val0 = val;
362 gcc_assert (TREE_CODE (val) == INDIRECT_REF);
363 parm = TREE_OPERAND (val, 0);
364 STRIP_NOPS (parm);
366 else
367 parm = val;
368 TREE_CHAIN (parm) = wd->parms;
369 wd->parms = parm;
370 wd->argtypes = tree_cons (NULL_TREE, TREE_TYPE (parm), wd->argtypes);
371 wd->arglist = tree_cons (NULL_TREE, arg, wd->arglist);
372 return true;
375 /* This function is used to build a wrapper of a certain type. */
377 static void
378 build_wrapper_type (struct wrapper_data *wd)
380 wd->arglist = NULL_TREE;
381 wd->parms = NULL_TREE;
382 wd->argtypes = void_list_node;
384 pointer_map_traverse (wd->decl_map, wrapper_parm_cb, wd);
385 gcc_assert (wd->type != CILK_BLOCK_FOR);
387 /* Now build a function.
388 Its return type is void (all side effects are via explicit parameters).
389 Its parameters are WRAPPER_PARMS with type WRAPPER_TYPES.
390 Actual arguments in the caller are WRAPPER_ARGS. */
391 wd->fntype = build_function_type (void_type_node, wd->argtypes);
394 /* This function checks all the CALL_EXPRs in *TP found by cilk_outline. */
396 static tree
397 check_outlined_calls (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
398 void *data)
400 bool *throws = (bool *) data;
401 tree t = *tp;
402 int flags;
404 if (TREE_CODE (t) != CALL_EXPR)
405 return 0;
406 flags = call_expr_flags (t);
408 if (!(flags & ECF_NOTHROW) && flag_exceptions)
409 *throws = true;
410 if (flags & ECF_RETURNS_TWICE)
411 error_at (EXPR_LOCATION (t),
412 "cannot spawn call to function that returns twice");
413 return 0;
416 /* Each DECL in the source code (spawned statement) is passed to this function
417 once. Each instance of the DECL is replaced with the result of this
418 function.
420 The parameters of the wrapper should have been entered into the map already.
421 This function only deals with variables with scope limited to the
422 spawned expression. */
424 static tree
425 copy_decl_for_cilk (tree decl, copy_body_data *id)
427 switch (TREE_CODE (decl))
429 case VAR_DECL:
430 return copy_decl_no_change (decl, id);
432 case LABEL_DECL:
433 error_at (EXPR_LOCATION (decl), "invalid use of label %q+D in "
434 "%<_Cilk_spawn%>",
435 decl);
436 return error_mark_node;
438 case RESULT_DECL:
439 case PARM_DECL:
440 /* RESULT_DECL and PARM_DECL has already been entered into the map. */
441 default:
442 gcc_unreachable ();
443 return error_mark_node;
447 /* Copy all local variables. */
449 static bool
450 for_local_cb (const void *k_v, void **vp, void *p)
452 tree k = *(tree *) &k_v;
453 tree v = (tree) *vp;
455 if (v == error_mark_node)
456 *vp = copy_decl_no_change (k, (copy_body_data *) p);
457 return true;
460 /* Copy all local declarations from a _Cilk_spawned function's body. */
462 static bool
463 wrapper_local_cb (const void *k_v, void **vp, void *data)
465 copy_body_data *id = (copy_body_data *) data;
466 tree key = *(tree *) &k_v;
467 tree val = (tree) *vp;
469 if (val == error_mark_node)
470 *vp = copy_decl_for_cilk (key, id);
472 return true;
475 /* Alter a tree STMT from OUTER_FN to form the body of INNER_FN. */
477 static void
478 cilk_outline (tree inner_fn, tree *stmt_p, struct wrapper_data *wd)
480 const tree outer_fn = wd->context;
481 const bool nested = (wd->type == CILK_BLOCK_FOR);
482 copy_body_data id;
483 bool throws;
485 DECL_STATIC_CHAIN (outer_fn) = 1;
487 memset (&id, 0, sizeof (id));
488 /* Copy from the function containing the spawn... */
489 id.src_fn = outer_fn;
491 /* ...to the wrapper. */
492 id.dst_fn = inner_fn;
493 id.src_cfun = DECL_STRUCT_FUNCTION (outer_fn);
495 /* There shall be no RETURN in spawn helper. */
496 id.retvar = 0;
497 id.decl_map = wd->decl_map;
498 id.copy_decl = nested ? copy_decl_no_change : copy_decl_for_cilk;
499 id.block = DECL_INITIAL (inner_fn);
500 id.transform_lang_insert_block = NULL;
502 id.transform_new_cfg = true;
503 id.transform_call_graph_edges = CB_CGE_MOVE;
504 id.remap_var_for_cilk = true;
505 id.regimplify = true; /* unused? */
507 insert_decl_map (&id, wd->block, DECL_INITIAL (inner_fn));
509 /* We don't want the private variables any more. */
510 pointer_map_traverse (wd->decl_map, nested ? for_local_cb : wrapper_local_cb,
511 &id);
513 walk_tree (stmt_p, copy_tree_body_r, &id, NULL);
515 /* See if this function can throw or calls something that should
516 not be spawned. The exception part is only necessary if
517 flag_exceptions && !flag_non_call_exceptions. */
518 throws = false ;
519 (void) walk_tree_without_duplicates (stmt_p, check_outlined_calls, &throws);
522 /* Generate the body of a wrapper function that assigns the
523 result of the expression RHS into RECEIVER. RECEIVER must
524 be NULL if this is not a spawn -- the wrapper will return
525 a value. If this is a spawn, the wrapper will return void. */
527 static tree
528 create_cilk_wrapper_body (tree stmt, struct wrapper_data *wd)
530 const tree outer = current_function_decl;
531 tree fndecl;
532 tree p;
534 /* Build the type of the wrapper and its argument list from the
535 variables that it requires. */
536 build_wrapper_type (wd);
538 /* Emit a function that takes WRAPPER_PARMS incoming and applies ARGS
539 (modified) to the wrapped function. Return the wrapper and modified ARGS
540 to the caller to generate a function call. */
541 fndecl = create_cilk_helper_decl (wd);
542 push_struct_function (fndecl);
543 if (wd->nested && (wd->type == CILK_BLOCK_FOR))
545 gcc_assert (TREE_VALUE (wd->arglist) == NULL_TREE);
546 TREE_VALUE (wd->arglist) = build2 (FDESC_EXPR, ptr_type_node,
547 fndecl, integer_one_node);
549 DECL_ARGUMENTS (fndecl) = wd->parms;
551 for (p = wd->parms; p; p = TREE_CHAIN (p))
552 DECL_CONTEXT (p) = fndecl;
554 cilk_outline (fndecl, &stmt, wd);
555 stmt = fold_build_cleanup_point_expr (void_type_node, stmt);
556 gcc_assert (!DECL_SAVED_TREE (fndecl));
557 lang_hooks.cilkplus.install_body_with_frame_cleanup (fndecl, stmt);
558 gcc_assert (DECL_SAVED_TREE (fndecl));
560 pop_cfun_to (outer);
562 /* Recognize the new function. */
563 call_graph_add_fn (fndecl);
564 return fndecl;
567 /* Initializes the wrapper data structure. */
569 static void
570 init_wd (struct wrapper_data *wd, enum cilk_block_type type)
572 wd->type = type;
573 wd->fntype = NULL_TREE;
574 wd->context = current_function_decl;
575 wd->decl_map = pointer_map_create ();
576 /* _Cilk_for bodies are always nested. Others start off as
577 normal functions. */
578 wd->nested = (type == CILK_BLOCK_FOR);
579 wd->arglist = NULL_TREE;
580 wd->argtypes = NULL_TREE;
581 wd->block = NULL_TREE;
584 /* Clears the wrapper data structure. */
586 static void
587 free_wd (struct wrapper_data *wd)
589 pointer_map_destroy (wd->decl_map);
590 wd->nested = false;
591 wd->arglist = NULL_TREE;
592 wd->argtypes = NULL_TREE;
593 wd->parms = NULL_TREE;
597 /* Given a variable in an expression to be extracted into
598 a helper function, declare the helper function parameter
599 to receive it.
601 On entry the value of the (key, value) pair may be
603 (*, error_mark_node) -- Variable is private to helper function,
604 do nothing.
606 (var, var) -- Reference to outer scope (function or global scope).
608 (var, integer 0) -- Capture by value, save newly-declared PARM_DECL
609 for value in value slot.
611 (var, integer 1) -- Capture by reference, declare pointer to type
612 as new PARM_DECL and store (spawn_stmt (indirect_ref (parm)).
614 (var, ???) -- Pure output argument, handled similarly to above.
617 static bool
618 declare_one_free_variable (const void *var0, void **map0,
619 void *data ATTRIBUTE_UNUSED)
621 const_tree var = (const_tree) var0;
622 tree map = (tree)*map0;
623 tree var_type = TREE_TYPE (var), arg_type;
624 bool by_reference;
625 tree parm;
627 gcc_assert (DECL_P (var));
629 /* Ignore truly local variables. */
630 if (map == error_mark_node)
631 return true;
632 /* Ignore references to the parent function. */
633 if (map == var)
634 return true;
636 gcc_assert (TREE_CODE (map) == INTEGER_CST);
638 /* A value is passed by reference if:
640 1. It is addressable, so that a copy may not be made.
641 2. It is modified in the spawned statement.
642 In the future this function may want to arrange
643 a warning if the spawned statement is a loop body
644 because an output argument would indicate a race.
645 Note: Earlier passes must have marked the variable addressable.
646 3. It is expensive to copy. */
647 by_reference =
648 (TREE_ADDRESSABLE (var_type)
649 /* Arrays must be passed by reference. This is required for C
650 semantics -- arrays are not first class objects. Other
651 aggregate types can and should be passed by reference if
652 they are not passed to the spawned function. We aren't yet
653 distinguishing safe uses in argument calculation from unsafe
654 uses as outgoing function arguments, so we make a copy to
655 stabilize the value. */
656 || TREE_CODE (var_type) == ARRAY_TYPE
657 || (tree) map == integer_one_node);
659 if (by_reference)
660 var_type = build_qualified_type (build_pointer_type (var_type),
661 TYPE_QUAL_RESTRICT);
662 gcc_assert (!TREE_ADDRESSABLE (var_type));
664 /* Maybe promote to int. */
665 if (INTEGRAL_TYPE_P (var_type) && COMPLETE_TYPE_P (var_type)
666 && INT_CST_LT_UNSIGNED (TYPE_SIZE (var_type),
667 TYPE_SIZE (integer_type_node)))
668 arg_type = integer_type_node;
669 else
670 arg_type = var_type;
672 parm = build_decl (UNKNOWN_LOCATION, PARM_DECL, NULL_TREE, var_type);
673 DECL_ARG_TYPE (parm) = arg_type;
674 DECL_ARTIFICIAL (parm) = 0;
675 TREE_READONLY (parm) = 1;
677 if (by_reference)
679 parm = build1 (INDIRECT_REF, TREE_TYPE (var_type), parm);
680 parm = build1 (PAREN_EXPR, void_type_node, parm);
682 *map0 = parm;
683 return true;
686 /* Returns a wrapper function for a _Cilk_spawn. */
688 static tree
689 create_cilk_wrapper (tree exp, tree *args_out)
691 struct wrapper_data wd;
692 tree fndecl;
694 init_wd (&wd, CILK_BLOCK_SPAWN);
696 if (TREE_CODE (exp) == CONVERT_EXPR)
697 exp = TREE_OPERAND (exp, 0);
699 /* Special handling for top level INIT_EXPR. Usually INIT_EXPR means the
700 variable is defined in the spawned expression and can be private to the
701 spawn helper. A top level INIT_EXPR defines a variable to be initialized
702 by spawn and the variable must remain in the outer function. */
703 if (TREE_CODE (exp) == INIT_EXPR)
705 extract_free_variables (TREE_OPERAND (exp, 0), &wd, ADD_WRITE);
706 extract_free_variables (TREE_OPERAND (exp, 1), &wd, ADD_READ);
707 /* TREE_TYPE should be void. Be defensive. */
708 if (TREE_TYPE (exp) != void_type_node)
709 extract_free_variables (TREE_TYPE (exp), &wd, ADD_READ);
711 else
712 extract_free_variables (exp, &wd, ADD_READ);
713 pointer_map_traverse (wd.decl_map, declare_one_free_variable, &wd);
714 wd.block = TREE_BLOCK (exp);
715 if (!wd.block)
716 wd.block = DECL_INITIAL (current_function_decl);
718 /* Now fvars maps the old variable to incoming variable. Update
719 the expression and arguments to refer to the new names. */
720 fndecl = create_cilk_wrapper_body (exp, &wd);
721 *args_out = wd.arglist;
723 free_wd (&wd);
725 return fndecl;
728 /* Transform *SPAWN_P, a spawned CALL_EXPR, to gimple. *SPAWN_P can be a
729 CALL_EXPR, INIT_EXPR or MODIFY_EXPR. Returns GS_OK if everything is fine,
730 and GS_UNHANDLED, otherwise. */
733 gimplify_cilk_spawn (tree *spawn_p, gimple_seq *before ATTRIBUTE_UNUSED,
734 gimple_seq *after ATTRIBUTE_UNUSED)
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;
740 tree *arg_array;
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);
752 new_args = NULL;
753 function = create_cilk_wrapper (expr, &new_args);
755 /* This should give the number of parameters. */
756 total_args = list_length (new_args);
757 arg_array = XNEWVEC (tree, total_args);
759 ii_args = new_args;
760 for (ii = 0; ii < total_args; ii++)
762 arg_array[ii] = TREE_VALUE (ii_args);
763 ii_args = TREE_CHAIN (ii_args);
766 TREE_USED (function) = 1;
767 rest_of_decl_compilation (function, 0, 0);
769 call1 = cilk_call_setjmp (cfun->cilk_frame_decl);
771 if (*arg_array == NULL_TREE)
772 call2 = build_call_expr (function, 0);
773 else
774 call2 = build_call_expr_loc_array (EXPR_LOCATION (*spawn_p), function,
775 total_args, arg_array);
776 *spawn_p = alloc_stmt_list ();
777 tree f_ptr_type = build_pointer_type (TREE_TYPE (cfun->cilk_frame_decl));
778 tree frame_ptr = build1 (ADDR_EXPR, f_ptr_type, cfun->cilk_frame_decl);
779 tree save_fp = build_call_expr (cilk_save_fp_fndecl, 1, frame_ptr);
780 append_to_statement_list (save_fp, spawn_p);
781 setjmp_value = create_tmp_var (TREE_TYPE (call1), NULL);
782 setjmp_expr = fold_build2 (MODIFY_EXPR, void_type_node, setjmp_value, call1);
784 append_to_statement_list_force (setjmp_expr, spawn_p);
786 setjmp_cond_expr = fold_build2 (EQ_EXPR, TREE_TYPE (call1), setjmp_value,
787 build_int_cst (TREE_TYPE (call1), 0));
788 spawn_expr = fold_build3 (COND_EXPR, void_type_node, setjmp_cond_expr,
789 call2, build_empty_stmt (EXPR_LOCATION (call1)));
790 append_to_statement_list (spawn_expr, spawn_p);
792 return GS_OK;
795 /* Make the frames necessary for a spawn call. */
797 tree
798 make_cilk_frame (tree fn)
800 struct function *f = DECL_STRUCT_FUNCTION (fn);
801 tree decl;
803 if (f->cilk_frame_decl)
804 return f->cilk_frame_decl;
806 decl = build_decl (EXPR_LOCATION (fn), VAR_DECL, NULL_TREE,
807 cilk_frame_type_decl);
808 DECL_CONTEXT (decl) = fn;
809 DECL_SEEN_IN_BIND_EXPR_P (decl) = 1;
810 f->cilk_frame_decl = decl;
811 return decl;
814 /* Returns a STATEMENT_LIST with all the pedigree operations required for
815 install body with frame cleanup functions. FRAME_PTR is the pointer to
816 __cilkrts_stack_frame created by make_cilk_frame. */
818 tree
819 cilk_install_body_pedigree_operations (tree frame_ptr)
821 tree body_list = alloc_stmt_list ();
822 tree enter_frame = build_call_expr (cilk_enter_fast_fndecl, 1, frame_ptr);
823 append_to_statement_list (enter_frame, &body_list);
825 tree parent = cilk_arrow (frame_ptr, CILK_TI_FRAME_PARENT, 0);
826 tree worker = cilk_arrow (frame_ptr, CILK_TI_FRAME_WORKER, 0);
828 tree pedigree = cilk_arrow (frame_ptr, CILK_TI_FRAME_PEDIGREE, 0);
829 tree pedigree_rank = cilk_dot (pedigree, CILK_TI_PEDIGREE_RANK, 0);
830 tree parent_pedigree = cilk_dot (pedigree, CILK_TI_PEDIGREE_PARENT, 0);
831 tree pedigree_parent = cilk_arrow (parent, CILK_TI_FRAME_PEDIGREE, 0);
832 tree pedigree_parent_rank = cilk_dot (pedigree_parent,
833 CILK_TI_PEDIGREE_RANK, 0);
834 tree pedigree_parent_parent = cilk_dot (pedigree_parent,
835 CILK_TI_PEDIGREE_PARENT, 0);
836 tree worker_pedigree = cilk_arrow (worker, CILK_TI_WORKER_PEDIGREE, 1);
837 tree w_pedigree_rank = cilk_dot (worker_pedigree, CILK_TI_PEDIGREE_RANK, 0);
838 tree w_pedigree_parent = cilk_dot (worker_pedigree,
839 CILK_TI_PEDIGREE_PARENT, 0);
841 /* sf.pedigree.rank = worker->pedigree.rank. */
842 tree exp1 = build2 (MODIFY_EXPR, void_type_node, pedigree_rank,
843 w_pedigree_rank);
844 append_to_statement_list (exp1, &body_list);
846 /* sf.pedigree.parent = worker->pedigree.parent. */
847 exp1 = build2 (MODIFY_EXPR, void_type_node, parent_pedigree,
848 w_pedigree_parent);
849 append_to_statement_list (exp1, &body_list);
851 /* sf.call_parent->pedigree.rank = worker->pedigree.rank. */
852 exp1 = build2 (MODIFY_EXPR, void_type_node, pedigree_parent_rank,
853 w_pedigree_rank);
854 append_to_statement_list (exp1, &body_list);
856 /* sf.call_parent->pedigree.parent = worker->pedigree.parent. */
857 exp1 = build2 (MODIFY_EXPR, void_type_node, pedigree_parent_parent,
858 w_pedigree_parent);
859 append_to_statement_list (exp1, &body_list);
861 /* sf->worker.pedigree.rank = 0. */
862 exp1 = build2 (MODIFY_EXPR, void_type_node, w_pedigree_rank,
863 build_zero_cst (uint64_type_node));
864 append_to_statement_list (exp1, &body_list);
866 /* sf->pedigree.parent = &sf->pedigree. */
867 exp1 = build2 (MODIFY_EXPR, void_type_node, w_pedigree_parent,
868 build1 (ADDR_EXPR,
869 build_pointer_type (cilk_pedigree_type_decl),
870 pedigree));
871 append_to_statement_list (exp1, &body_list);
872 return body_list;
875 /* Inserts "cleanup" functions after the function-body of FNDECL. FNDECL is a
876 spawn-helper and BODY is the newly created body for FNDECL. */
878 void
879 c_cilk_install_body_w_frame_cleanup (tree fndecl, tree body)
881 tree list = alloc_stmt_list ();
882 tree frame = make_cilk_frame (fndecl);
883 tree dtor = create_cilk_function_exit (frame, false, true);
884 add_local_decl (cfun, frame);
886 DECL_SAVED_TREE (fndecl) = list;
887 tree frame_ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (frame)),
888 frame);
889 tree body_list = cilk_install_body_pedigree_operations (frame_ptr);
890 gcc_assert (TREE_CODE (body_list) == STATEMENT_LIST);
892 tree detach_expr = build_call_expr (cilk_detach_fndecl, 1, frame_ptr);
893 append_to_statement_list (detach_expr, &body_list);
894 append_to_statement_list (body, &body_list);
895 append_to_statement_list (build_stmt (EXPR_LOCATION (body), TRY_FINALLY_EXPR,
896 body_list, dtor), &list);
899 /* Add a new variable, VAR to a variable list in WD->DECL_MAP. HOW indicates
900 whether the variable is previously defined, currently defined, or a variable
901 that is being written to. */
903 static void
904 add_variable (struct wrapper_data *wd, tree var, enum add_variable_type how)
906 void **valp;
908 valp = pointer_map_contains (wd->decl_map, (void *) var);
909 if (valp)
911 tree val = (tree) *valp;
912 /* If the variable is local, do nothing. */
913 if (val == error_mark_node)
914 return;
915 /* If the variable was entered with itself as value,
916 meaning it belongs to an outer scope, do not alter
917 the value. */
918 if (val == var)
919 return;
920 /* A statement expression may cause a variable to be
921 bound twice, once in BIND_EXPR and again in a
922 DECL_EXPR. That case caused a return in the
923 test above. Any other duplicate definition is
924 an error. */
925 gcc_assert (how != ADD_BIND);
926 if (how != ADD_WRITE)
927 return;
928 /* This variable might have been entered as read but is now written. */
929 *valp = (void *) var;
930 wd->nested = true;
931 return;
933 else
935 tree val = NULL_TREE;
937 /* Nested function rewriting silently discards hard register
938 assignments for function scope variables, and they wouldn't
939 work anyway. Warn here. This misses one case: if the
940 register variable is used as the loop bound or increment it
941 has already been added to the map. */
942 if ((how != ADD_BIND) && (TREE_CODE (var) == VAR_DECL)
943 && !DECL_EXTERNAL (var) && DECL_HARD_REGISTER (var))
944 warning (0, "register assignment ignored for %qD used in Cilk block",
945 var);
947 switch (how)
949 /* ADD_BIND means always make a fresh new variable. */
950 case ADD_BIND:
951 val = error_mark_node;
952 break;
953 /* ADD_READ means
954 1. For cilk_for, refer to the outer scope definition as-is
955 2. For a spawned block, take a scalar in an rgument
956 and otherwise refer to the outer scope definition as-is.
957 3. For a spawned call, take a scalar in an argument. */
958 case ADD_READ:
959 switch (wd->type)
961 case CILK_BLOCK_FOR:
962 val = var;
963 break;
964 case CILK_BLOCK_SPAWN:
965 if (TREE_ADDRESSABLE (var))
967 val = var;
968 wd->nested = true;
969 break;
971 val = integer_zero_node;
972 break;
974 break;
975 case ADD_WRITE:
976 switch (wd->type)
978 case CILK_BLOCK_FOR:
979 val = var;
980 wd->nested = true;
981 break;
982 case CILK_BLOCK_SPAWN:
983 if (TREE_ADDRESSABLE (var))
984 val = integer_one_node;
985 else
987 val = var;
988 wd->nested = true;
990 break;
993 *pointer_map_insert (wd->decl_map, (void *) var) = val;
997 /* Find the variables referenced in an expression T. This does not avoid
998 duplicates because a variable may be read in one context and written in
999 another. HOW describes the context in which the reference is seen. If
1000 NESTED is true a nested function is being generated and variables in the
1001 original context should not be remapped. */
1003 static void
1004 extract_free_variables (tree t, struct wrapper_data *wd,
1005 enum add_variable_type how)
1007 if (t == NULL_TREE)
1008 return;
1010 enum tree_code code = TREE_CODE (t);
1011 bool is_expr = IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code));
1013 if (is_expr)
1014 extract_free_variables (TREE_TYPE (t), wd, ADD_READ);
1016 switch (code)
1018 case ERROR_MARK:
1019 case IDENTIFIER_NODE:
1020 case INTEGER_CST:
1021 case REAL_CST:
1022 case FIXED_CST:
1023 case STRING_CST:
1024 case BLOCK:
1025 case PLACEHOLDER_EXPR:
1026 case FIELD_DECL:
1027 case VOID_TYPE:
1028 case REAL_TYPE:
1029 /* These do not contain variable references. */
1030 return;
1032 case SSA_NAME:
1033 /* Currently we don't see SSA_NAME. */
1034 extract_free_variables (SSA_NAME_VAR (t), wd, how);
1035 return;
1037 case LABEL_DECL:
1038 /* This might be a reference to a label outside the Cilk block,
1039 which is an error, or a reference to a label in the Cilk block
1040 that we haven't seen yet. We can't tell. Ignore it. An
1041 invalid use will cause an error later in copy_decl_for_cilk. */
1042 return;
1044 case RESULT_DECL:
1045 if (wd->type != CILK_BLOCK_SPAWN)
1046 TREE_ADDRESSABLE (t) = 1;
1047 case VAR_DECL:
1048 case PARM_DECL:
1049 if (!TREE_STATIC (t) && !DECL_EXTERNAL (t))
1050 add_variable (wd, t, how);
1051 return;
1053 case NON_LVALUE_EXPR:
1054 case CONVERT_EXPR:
1055 case NOP_EXPR:
1056 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_READ);
1057 return;
1059 case INIT_EXPR:
1060 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_BIND);
1061 extract_free_variables (TREE_OPERAND (t, 1), wd, ADD_READ);
1062 return;
1064 case MODIFY_EXPR:
1065 case PREDECREMENT_EXPR:
1066 case PREINCREMENT_EXPR:
1067 case POSTDECREMENT_EXPR:
1068 case POSTINCREMENT_EXPR:
1069 /* These write their result. */
1070 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_WRITE);
1071 extract_free_variables (TREE_OPERAND (t, 1), wd, ADD_READ);
1072 return;
1074 case ADDR_EXPR:
1075 /* This might modify its argument, and the value needs to be
1076 passed by reference in any case to preserve identity and
1077 type if is a promoting type. In the case of a nested loop
1078 just notice that we touch the variable. It will already
1079 be addressable, and marking it modified will cause a spurious
1080 warning about writing the control variable. */
1081 if (wd->type != CILK_BLOCK_SPAWN)
1082 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_READ);
1083 else
1084 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_WRITE);
1085 return;
1087 case ARRAY_REF:
1088 /* Treating ARRAY_REF and BIT_FIELD_REF identically may
1089 mark the array as written but the end result is correct
1090 because the array is passed by pointer anyway. */
1091 case BIT_FIELD_REF:
1092 /* Propagate the access type to the object part of which
1093 is being accessed here. As for ADDR_EXPR, don't do this
1094 in a nested loop, unless the access is to a fixed index. */
1095 if (wd->type != CILK_BLOCK_FOR || TREE_CONSTANT (TREE_OPERAND (t, 1)))
1096 extract_free_variables (TREE_OPERAND (t, 0), wd, how);
1097 else
1098 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_READ);
1099 extract_free_variables (TREE_OPERAND (t, 1), wd, ADD_READ);
1100 extract_free_variables (TREE_OPERAND (t, 2), wd, ADD_READ);
1101 return;
1103 case TREE_LIST:
1104 extract_free_variables (TREE_PURPOSE (t), wd, ADD_READ);
1105 extract_free_variables (TREE_VALUE (t), wd, ADD_READ);
1106 extract_free_variables (TREE_CHAIN (t), wd, ADD_READ);
1107 return;
1109 case TREE_VEC:
1111 int len = TREE_VEC_LENGTH (t);
1112 int i;
1113 for (i = 0; i < len; i++)
1114 extract_free_variables (TREE_VEC_ELT (t, i), wd, ADD_READ);
1115 return;
1118 case VECTOR_CST:
1120 unsigned ii = 0;
1121 for (ii = 0; ii < VECTOR_CST_NELTS (t); ii++)
1122 extract_free_variables (VECTOR_CST_ELT (t, ii), wd, ADD_READ);
1123 break;
1126 case COMPLEX_CST:
1127 extract_free_variables (TREE_REALPART (t), wd, ADD_READ);
1128 extract_free_variables (TREE_IMAGPART (t), wd, ADD_READ);
1129 return;
1131 case BIND_EXPR:
1133 tree decl;
1134 for (decl = BIND_EXPR_VARS (t); decl; decl = TREE_CHAIN (decl))
1136 add_variable (wd, decl, ADD_BIND);
1137 /* A self-referential initialization is no problem because
1138 we already entered the variable into the map as local. */
1139 extract_free_variables (DECL_INITIAL (decl), wd, ADD_READ);
1140 extract_free_variables (DECL_SIZE (decl), wd, ADD_READ);
1141 extract_free_variables (DECL_SIZE_UNIT (decl), wd, ADD_READ);
1143 extract_free_variables (BIND_EXPR_BODY (t), wd, ADD_READ);
1144 return;
1147 case STATEMENT_LIST:
1149 tree_stmt_iterator i;
1150 for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
1151 extract_free_variables (*tsi_stmt_ptr (i), wd, ADD_READ);
1152 return;
1155 case TARGET_EXPR:
1157 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_BIND);
1158 extract_free_variables (TREE_OPERAND (t, 1), wd, ADD_READ);
1159 extract_free_variables (TREE_OPERAND (t, 2), wd, ADD_READ);
1160 if (TREE_OPERAND (t, 3) != TREE_OPERAND (t, 1))
1161 extract_free_variables (TREE_OPERAND (t, 3), wd, ADD_READ);
1162 return;
1165 case RETURN_EXPR:
1166 if (TREE_NO_WARNING (t))
1168 gcc_assert (errorcount);
1169 return;
1171 return;
1173 case DECL_EXPR:
1174 if (TREE_CODE (DECL_EXPR_DECL (t)) != TYPE_DECL)
1175 extract_free_variables (DECL_EXPR_DECL (t), wd, ADD_BIND);
1176 return;
1178 case INTEGER_TYPE:
1179 case ENUMERAL_TYPE:
1180 case BOOLEAN_TYPE:
1181 extract_free_variables (TYPE_MIN_VALUE (t), wd, ADD_READ);
1182 extract_free_variables (TYPE_MAX_VALUE (t), wd, ADD_READ);
1183 return;
1185 case POINTER_TYPE:
1186 extract_free_variables (TREE_TYPE (t), wd, ADD_READ);
1187 break;
1189 case ARRAY_TYPE:
1190 extract_free_variables (TREE_TYPE (t), wd, ADD_READ);
1191 extract_free_variables (TYPE_DOMAIN (t), wd, ADD_READ);
1192 return;
1194 case RECORD_TYPE:
1195 extract_free_variables (TYPE_FIELDS (t), wd, ADD_READ);
1196 return;
1198 case METHOD_TYPE:
1199 extract_free_variables (TYPE_ARG_TYPES (t), wd, ADD_READ);
1200 extract_free_variables (TYPE_METHOD_BASETYPE (t), wd, ADD_READ);
1201 return;
1203 case AGGR_INIT_EXPR:
1204 case CALL_EXPR:
1206 int len = 0;
1207 int ii = 0;
1208 if (TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST)
1210 len = TREE_INT_CST_LOW (TREE_OPERAND (t, 0));
1212 for (ii = 0; ii < len; ii++)
1213 extract_free_variables (TREE_OPERAND (t, ii), wd, ADD_READ);
1214 extract_free_variables (TREE_TYPE (t), wd, ADD_READ);
1216 break;
1219 default:
1220 if (is_expr)
1222 int i, len;
1224 /* Walk over all the sub-trees of this operand. */
1225 len = TREE_CODE_LENGTH (code);
1227 /* Go through the subtrees. We need to do this in forward order so
1228 that the scope of a FOR_EXPR is handled properly. */
1229 for (i = 0; i < len; ++i)
1230 extract_free_variables (TREE_OPERAND (t, i), wd, ADD_READ);
1236 /* Add appropriate frames needed for a Cilk spawned function call, FNDECL.
1237 Returns the __cilkrts_stack_frame * variable. */
1239 tree
1240 insert_cilk_frame (tree fndecl)
1242 tree addr, body, enter, out, orig_body;
1243 location_t loc = EXPR_LOCATION (fndecl);
1245 if (!cfun || cfun->decl != fndecl)
1246 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
1248 tree decl = cfun->cilk_frame_decl;
1249 if (!decl)
1251 tree *saved_tree = &DECL_SAVED_TREE (fndecl);
1252 decl = make_cilk_frame (fndecl);
1253 add_local_decl (cfun, decl);
1255 addr = build1 (ADDR_EXPR, cilk_frame_ptr_type_decl, decl);
1256 enter = build_call_expr (cilk_enter_fndecl, 1, addr);
1257 out = create_cilk_function_exit (cfun->cilk_frame_decl, false, true);
1259 /* The new body will be:
1260 __cilkrts_enter_frame_1 (&sf);
1261 try {
1262 orig_body;
1264 finally {
1265 __cilkrts_pop_frame (&sf);
1266 __cilkrts_leave_frame (&sf);
1267 } */
1269 body = alloc_stmt_list ();
1270 orig_body = *saved_tree;
1272 if (TREE_CODE (orig_body) == BIND_EXPR)
1273 orig_body = BIND_EXPR_BODY (orig_body);
1275 append_to_statement_list (enter, &body);
1276 append_to_statement_list (build_stmt (loc, TRY_FINALLY_EXPR, orig_body,
1277 out), &body);
1278 if (TREE_CODE (*saved_tree) == BIND_EXPR)
1279 BIND_EXPR_BODY (*saved_tree) = body;
1280 else
1281 *saved_tree = body;
1283 return decl;
1286 /* Wraps CALL, a CALL_EXPR, into a CILK_SPAWN_STMT tree and returns it. */
1288 tree
1289 build_cilk_spawn (location_t loc, tree call)
1291 if (!cilk_set_spawn_marker (loc, call))
1292 return error_mark_node;
1293 tree spawn_stmt = build1 (CILK_SPAWN_STMT, TREE_TYPE (call), call);
1294 TREE_SIDE_EFFECTS (spawn_stmt) = 1;
1295 return spawn_stmt;
1298 /* Returns a tree of type CILK_SYNC_STMT. */
1300 tree
1301 build_cilk_sync (void)
1303 tree sync = build0 (CILK_SYNC_STMT, void_type_node);
1304 TREE_SIDE_EFFECTS (sync) = 1;
1305 return sync;