2013-11-21 Edward Smith-Rowland <3dw4rd@verizon.net>
[official-gcc.git] / gcc / c-family / cilk.c
blob894a35270c54c73dcb3db47746d38f2446a61f4b
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 "gimple.h"
31 #include "gimplify.h"
32 #include "tree-iterator.h"
33 #include "tree-inline.h"
34 #include "c-family/c-common.h"
35 #include "toplev.h"
36 #include "cgraph.h"
37 #include "diagnostic.h"
38 #include "cilk.h"
40 enum add_variable_type {
41 /* Reference to previously-defined variable. */
42 ADD_READ,
43 /* Definition of a new variable in inner-scope. */
44 ADD_BIND,
45 /* Write to possibly previously-defined variable. */
46 ADD_WRITE
49 enum cilk_block_type {
50 /* Indicates a _Cilk_spawn block. 30 was an arbitary number picked for
51 ease of debugging. */
52 CILK_BLOCK_SPAWN = 30,
53 /* Indicates _Cilk_for statement block. */
54 CILK_BLOCK_FOR
57 struct wrapper_data
59 /* Kind of function to be created. */
60 enum cilk_block_type type;
61 /* Signature of helper function. */
62 tree fntype;
63 /* Containing function. */
64 tree context;
65 /* Disposition of all variables in the inner statement. */
66 struct pointer_map_t *decl_map;
67 /* True if this function needs a static chain. */
68 bool nested;
69 /* Arguments to be passed to wrapper function, currently a list. */
70 tree arglist;
71 /* Argument types, a list. */
72 tree argtypes;
73 /* Incoming parameters. */
74 tree parms;
75 /* Outer BLOCK object. */
76 tree block;
79 static void extract_free_variables (tree, struct wrapper_data *,
80 enum add_variable_type);
81 static HOST_WIDE_INT cilk_wrapper_count;
83 /* Marks the CALL_EXPR or FUNCTION_DECL, FCALL, as a spawned function call
84 and the current function as a spawner. Emit error if the function call
85 is outside a function or if a non function-call is spawned. */
87 inline bool
88 cilk_set_spawn_marker (location_t loc, tree fcall)
90 if (!current_function_decl)
92 error_at (loc, "%<_Cilk_spawn%> may only be used inside a function");
93 return false;
95 else if (fcall == error_mark_node)
96 /* Error reporting here is not necessary here since if FCALL is an
97 error_mark_node, the function marking it as error would have reported
98 it. */
99 return false;
100 else if (TREE_CODE (fcall) != CALL_EXPR
101 && TREE_CODE (fcall) != FUNCTION_DECL
102 /* In C++, TARGET_EXPR is generated when we have an overloaded
103 '=' operator. */
104 && TREE_CODE (fcall) != TARGET_EXPR)
106 error_at (loc, "only function calls can be spawned");
107 return false;
109 else
111 cfun->calls_cilk_spawn = true;
112 return true;
116 /* This function will output the exit conditions for a spawn call. */
118 tree
119 create_cilk_function_exit (tree frame, bool detaches, bool needs_sync)
121 tree epi = alloc_stmt_list ();
123 if (needs_sync)
124 append_to_statement_list (build_cilk_sync (), &epi);
125 tree func_ptr = build1 (ADDR_EXPR, cilk_frame_ptr_type_decl, frame);
126 tree pop_frame = build_call_expr (cilk_pop_fndecl, 1, func_ptr);
127 tree worker = cilk_dot (frame, CILK_TI_FRAME_WORKER, 0);
128 tree current = cilk_arrow (worker, CILK_TI_WORKER_CUR, 0);
129 tree parent = cilk_dot (frame, CILK_TI_FRAME_PARENT, 0);
130 tree set_current = build2 (MODIFY_EXPR, void_type_node, current, parent);
131 append_to_statement_list (set_current, &epi);
132 append_to_statement_list (pop_frame, &epi);
133 tree call = build_call_expr (cilk_leave_fndecl, 1, func_ptr);
134 if (!detaches)
136 tree flags = cilk_dot (frame, CILK_TI_FRAME_FLAGS, false);
137 tree flags_cmp_expr = fold_build2 (NE_EXPR, TREE_TYPE (flags), flags,
138 build_int_cst (TREE_TYPE (flags),
139 CILK_FRAME_VERSION));
140 call = fold_build3 (COND_EXPR, void_type_node, flags_cmp_expr,
141 call, build_empty_stmt (EXPR_LOCATION (flags)));
143 append_to_statement_list (call, &epi);
144 return epi;
147 /* Trying to get the correct cfun for the FUNCTION_DECL indicated by OUTER. */
149 static void
150 pop_cfun_to (tree outer)
152 pop_cfun ();
153 current_function_decl = outer;
154 gcc_assert (cfun == DECL_STRUCT_FUNCTION (current_function_decl));
155 gcc_assert (cfun->decl == current_function_decl);
158 /* This function does whatever is necessary to make the compiler emit a newly
159 generated function, FNDECL. */
161 static void
162 call_graph_add_fn (tree fndecl)
164 const tree outer = current_function_decl;
165 struct function *f = DECL_STRUCT_FUNCTION (fndecl);
166 gcc_assert (TREE_CODE (fndecl) == FUNCTION_DECL);
168 f->is_cilk_function = 1;
169 f->curr_properties = cfun->curr_properties;
170 gcc_assert (cfun == DECL_STRUCT_FUNCTION (outer));
171 gcc_assert (cfun->decl == outer);
173 push_cfun (f);
174 cgraph_create_node (fndecl);
175 pop_cfun_to (outer);
178 /* Return true if this is a tree which is allowed to contain a spawn as
179 operand 0.
180 A spawn call may be wrapped in a series of unary operations such
181 as conversions. These conversions need not be "useless"
182 to be disregarded because they are retained in the spawned
183 statement. They are bypassed only to look for a spawn
184 within.
185 A comparison to constant is simple enough to allow, and
186 is used to convert to bool. */
188 static bool
189 cilk_ignorable_spawn_rhs_op (tree exp)
191 enum tree_code code = TREE_CODE (exp);
192 switch (TREE_CODE_CLASS (code))
194 case tcc_expression:
195 return code == ADDR_EXPR;
196 case tcc_comparison:
197 /* We need the spawn as operand 0 for now. That's where it
198 appears in the only case we really care about, conversion
199 to bool. */
200 return (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST);
201 case tcc_unary:
202 case tcc_reference:
203 return true;
204 default:
205 return false;
209 /* Helper function for walk_tree. If *TP is a CILK_SPAWN_STMT, then unwrap
210 this "wrapper." The function returns NULL_TREE regardless. */
212 static tree
213 unwrap_cilk_spawn_stmt (tree *tp, int *walk_subtrees, void *)
215 if (TREE_CODE (*tp) == CILK_SPAWN_STMT)
217 *tp = CILK_SPAWN_FN (*tp);
218 *walk_subtrees = 0;
220 return NULL_TREE;
223 /* Returns true when EXP is a CALL_EXPR with _Cilk_spawn in front. Unwraps
224 CILK_SPAWN_STMT wrapper from the CALL_EXPR in *EXP0 statement. */
226 static bool
227 recognize_spawn (tree exp, tree *exp0)
229 bool spawn_found = false;
230 if (TREE_CODE (exp) == CILK_SPAWN_STMT)
232 /* Remove the CALL_EXPR from CILK_SPAWN_STMT wrapper. */
233 exp = CILK_SPAWN_FN (exp);
234 walk_tree (exp0, unwrap_cilk_spawn_stmt, NULL, NULL);
235 spawn_found = true;
237 return spawn_found;
240 /* Returns true if *EXP0 is a recognized form of spawn. Recognized forms are,
241 after conversion to void, a call expression at outer level or an assignment
242 at outer level with the right hand side being a spawned call.
243 In addition to this, it also unwraps the CILK_SPAWN_STMT cover from the
244 CALL_EXPR that is being spawned.
245 Note that `=' in C++ may turn into a CALL_EXPR rather than a MODIFY_EXPR. */
247 bool
248 cilk_detect_spawn_and_unwrap (tree *exp0)
250 tree exp = *exp0;
252 if (!TREE_SIDE_EFFECTS (exp))
253 return false;
255 /* Strip off any conversion to void. It does not affect whether spawn
256 is supported here. */
257 if (TREE_CODE (exp) == CONVERT_EXPR && VOID_TYPE_P (TREE_TYPE (exp)))
258 exp = TREE_OPERAND (exp, 0);
260 if (TREE_CODE (exp) == MODIFY_EXPR || TREE_CODE (exp) == INIT_EXPR)
261 exp = TREE_OPERAND (exp, 1);
263 while (cilk_ignorable_spawn_rhs_op (exp))
264 exp = TREE_OPERAND (exp, 0);
266 if (TREE_CODE (exp) == TARGET_EXPR)
267 if (TARGET_EXPR_INITIAL (exp)
268 && TREE_CODE (TARGET_EXPR_INITIAL (exp)) != AGGR_INIT_EXPR)
269 exp = TARGET_EXPR_INITIAL (exp);
271 /* Happens with C++ TARGET_EXPR. */
272 if (exp == NULL_TREE)
273 return false;
275 while (TREE_CODE (exp) == CLEANUP_POINT_EXPR || TREE_CODE (exp) == EXPR_STMT)
276 exp = TREE_OPERAND (exp, 0);
278 /* Now we should have a CALL_EXPR with a CILK_SPAWN_STMT wrapper around
279 it, or return false. */
280 if (recognize_spawn (exp, exp0))
281 return true;
282 return false;
285 /* This function will build and return a FUNCTION_DECL using information
286 from *WD. */
288 static tree
289 create_cilk_helper_decl (struct wrapper_data *wd)
291 char name[20];
292 if (wd->type == CILK_BLOCK_FOR)
293 sprintf (name, "_cilk_for_" HOST_WIDE_INT_PRINT_DEC, cilk_wrapper_count++);
294 else if (wd->type == CILK_BLOCK_SPAWN)
295 sprintf (name, "_cilk_spn_" HOST_WIDE_INT_PRINT_DEC, cilk_wrapper_count++);
296 else
297 gcc_unreachable ();
299 clean_symbol_name (name);
300 tree fndecl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
301 get_identifier (name), wd->fntype);
303 TREE_PUBLIC (fndecl) = 0;
304 TREE_STATIC (fndecl) = 1;
305 TREE_USED (fndecl) = 1;
306 DECL_ARTIFICIAL (fndecl) = 0;
307 DECL_IGNORED_P (fndecl) = 0;
308 DECL_EXTERNAL (fndecl) = 0;
310 DECL_CONTEXT (fndecl) = wd->context;
311 tree block = make_node (BLOCK);
312 DECL_INITIAL (fndecl) = block;
313 TREE_USED (block) = 1;
314 gcc_assert (!DECL_SAVED_TREE (fndecl));
316 /* Inlining would defeat the purpose of this wrapper.
317 Either it secretly switches stack frames or it allocates
318 a stable stack frame to hold function arguments even if
319 the parent stack frame is stolen. */
320 DECL_UNINLINABLE (fndecl) = 1;
322 tree result_decl = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE,
323 void_type_node);
324 DECL_ARTIFICIAL (result_decl) = 0;
325 DECL_IGNORED_P (result_decl) = 1;
326 DECL_CONTEXT (result_decl) = fndecl;
327 DECL_RESULT (fndecl) = result_decl;
329 return fndecl;
332 /* A function used by walk tree to find wrapper parms. */
334 static bool
335 wrapper_parm_cb (const void *key0, void **val0, void *data)
337 struct wrapper_data *wd = (struct wrapper_data *) data;
338 tree arg = * (tree *)&key0;
339 tree val = (tree)*val0;
340 tree parm;
342 if (val == error_mark_node || val == arg)
343 return true;
345 if (TREE_CODE (val) == PAREN_EXPR)
347 /* We should not reach here with a register receiver.
348 We may see a register variable modified in the
349 argument list. Because register variables are
350 worker-local we don't need to work hard to support
351 them in code that spawns. */
352 if ((TREE_CODE (arg) == VAR_DECL) && DECL_HARD_REGISTER (arg))
354 error_at (EXPR_LOCATION (arg),
355 "explicit register variable %qD may not be modified in "
356 "spawn", arg);
357 arg = null_pointer_node;
359 else
360 arg = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg)), arg);
362 val = TREE_OPERAND (val, 0);
363 *val0 = val;
364 gcc_assert (TREE_CODE (val) == INDIRECT_REF);
365 parm = TREE_OPERAND (val, 0);
366 STRIP_NOPS (parm);
368 else
369 parm = val;
370 TREE_CHAIN (parm) = wd->parms;
371 wd->parms = parm;
372 wd->argtypes = tree_cons (NULL_TREE, TREE_TYPE (parm), wd->argtypes);
373 wd->arglist = tree_cons (NULL_TREE, arg, wd->arglist);
374 return true;
377 /* This function is used to build a wrapper of a certain type. */
379 static void
380 build_wrapper_type (struct wrapper_data *wd)
382 wd->arglist = NULL_TREE;
383 wd->parms = NULL_TREE;
384 wd->argtypes = void_list_node;
386 pointer_map_traverse (wd->decl_map, wrapper_parm_cb, wd);
387 gcc_assert (wd->type != CILK_BLOCK_FOR);
389 /* Now build a function.
390 Its return type is void (all side effects are via explicit parameters).
391 Its parameters are WRAPPER_PARMS with type WRAPPER_TYPES.
392 Actual arguments in the caller are WRAPPER_ARGS. */
393 wd->fntype = build_function_type (void_type_node, wd->argtypes);
396 /* This function checks all the CALL_EXPRs in *TP found by cilk_outline. */
398 static tree
399 check_outlined_calls (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
400 void *data)
402 bool *throws = (bool *) data;
403 tree t = *tp;
404 int flags;
406 if (TREE_CODE (t) != CALL_EXPR)
407 return 0;
408 flags = call_expr_flags (t);
410 if (!(flags & ECF_NOTHROW) && flag_exceptions)
411 *throws = true;
412 if (flags & ECF_RETURNS_TWICE)
413 error_at (EXPR_LOCATION (t),
414 "cannot spawn call to function that returns twice");
415 return 0;
418 /* Each DECL in the source code (spawned statement) is passed to this function
419 once. Each instance of the DECL is replaced with the result of this
420 function.
422 The parameters of the wrapper should have been entered into the map already.
423 This function only deals with variables with scope limited to the
424 spawned expression. */
426 static tree
427 copy_decl_for_cilk (tree decl, copy_body_data *id)
429 switch (TREE_CODE (decl))
431 case VAR_DECL:
432 return copy_decl_no_change (decl, id);
434 case LABEL_DECL:
435 error_at (EXPR_LOCATION (decl), "invalid use of label %q+D in "
436 "%<_Cilk_spawn%>",
437 decl);
438 return error_mark_node;
440 case RESULT_DECL:
441 case PARM_DECL:
442 /* RESULT_DECL and PARM_DECL has already been entered into the map. */
443 default:
444 gcc_unreachable ();
445 return error_mark_node;
449 /* Copy all local variables. */
451 static bool
452 for_local_cb (const void *k_v, void **vp, void *p)
454 tree k = *(tree *) &k_v;
455 tree v = (tree) *vp;
457 if (v == error_mark_node)
458 *vp = copy_decl_no_change (k, (copy_body_data *) p);
459 return true;
462 /* Copy all local declarations from a _Cilk_spawned function's body. */
464 static bool
465 wrapper_local_cb (const void *k_v, void **vp, void *data)
467 copy_body_data *id = (copy_body_data *) data;
468 tree key = *(tree *) &k_v;
469 tree val = (tree) *vp;
471 if (val == error_mark_node)
472 *vp = copy_decl_for_cilk (key, id);
474 return true;
477 /* Alter a tree STMT from OUTER_FN to form the body of INNER_FN. */
479 static void
480 cilk_outline (tree inner_fn, tree *stmt_p, struct wrapper_data *wd)
482 const tree outer_fn = wd->context;
483 const bool nested = (wd->type == CILK_BLOCK_FOR);
484 copy_body_data id;
485 bool throws;
487 DECL_STATIC_CHAIN (outer_fn) = 1;
489 memset (&id, 0, sizeof (id));
490 /* Copy from the function containing the spawn... */
491 id.src_fn = outer_fn;
493 /* ...to the wrapper. */
494 id.dst_fn = inner_fn;
495 id.src_cfun = DECL_STRUCT_FUNCTION (outer_fn);
497 /* There shall be no RETURN in spawn helper. */
498 id.retvar = 0;
499 id.decl_map = wd->decl_map;
500 id.copy_decl = nested ? copy_decl_no_change : copy_decl_for_cilk;
501 id.block = DECL_INITIAL (inner_fn);
502 id.transform_lang_insert_block = NULL;
504 id.transform_new_cfg = true;
505 id.transform_call_graph_edges = CB_CGE_MOVE;
506 id.remap_var_for_cilk = true;
507 id.regimplify = true; /* unused? */
509 insert_decl_map (&id, wd->block, DECL_INITIAL (inner_fn));
511 /* We don't want the private variables any more. */
512 pointer_map_traverse (wd->decl_map, nested ? for_local_cb : wrapper_local_cb,
513 &id);
515 walk_tree (stmt_p, copy_tree_body_r, &id, NULL);
517 /* See if this function can throw or calls something that should
518 not be spawned. The exception part is only necessary if
519 flag_exceptions && !flag_non_call_exceptions. */
520 throws = false ;
521 (void) walk_tree_without_duplicates (stmt_p, check_outlined_calls, &throws);
524 /* Generate the body of a wrapper function that assigns the
525 result of the expression RHS into RECEIVER. RECEIVER must
526 be NULL if this is not a spawn -- the wrapper will return
527 a value. If this is a spawn, the wrapper will return void. */
529 static tree
530 create_cilk_wrapper_body (tree stmt, struct wrapper_data *wd)
532 const tree outer = current_function_decl;
533 tree fndecl;
534 tree p;
536 /* Build the type of the wrapper and its argument list from the
537 variables that it requires. */
538 build_wrapper_type (wd);
540 /* Emit a function that takes WRAPPER_PARMS incoming and applies ARGS
541 (modified) to the wrapped function. Return the wrapper and modified ARGS
542 to the caller to generate a function call. */
543 fndecl = create_cilk_helper_decl (wd);
544 push_struct_function (fndecl);
545 if (wd->nested && (wd->type == CILK_BLOCK_FOR))
547 gcc_assert (TREE_VALUE (wd->arglist) == NULL_TREE);
548 TREE_VALUE (wd->arglist) = build2 (FDESC_EXPR, ptr_type_node,
549 fndecl, integer_one_node);
551 DECL_ARGUMENTS (fndecl) = wd->parms;
553 for (p = wd->parms; p; p = TREE_CHAIN (p))
554 DECL_CONTEXT (p) = fndecl;
556 cilk_outline (fndecl, &stmt, wd);
557 stmt = fold_build_cleanup_point_expr (void_type_node, stmt);
558 gcc_assert (!DECL_SAVED_TREE (fndecl));
559 lang_hooks.cilkplus.install_body_with_frame_cleanup (fndecl, stmt);
560 gcc_assert (DECL_SAVED_TREE (fndecl));
562 pop_cfun_to (outer);
564 /* Recognize the new function. */
565 call_graph_add_fn (fndecl);
566 return fndecl;
569 /* Initializes the wrapper data structure. */
571 static void
572 init_wd (struct wrapper_data *wd, enum cilk_block_type type)
574 wd->type = type;
575 wd->fntype = NULL_TREE;
576 wd->context = current_function_decl;
577 wd->decl_map = pointer_map_create ();
578 /* _Cilk_for bodies are always nested. Others start off as
579 normal functions. */
580 wd->nested = (type == CILK_BLOCK_FOR);
581 wd->arglist = NULL_TREE;
582 wd->argtypes = NULL_TREE;
583 wd->block = NULL_TREE;
586 /* Clears the wrapper data structure. */
588 static void
589 free_wd (struct wrapper_data *wd)
591 pointer_map_destroy (wd->decl_map);
592 wd->nested = false;
593 wd->arglist = NULL_TREE;
594 wd->argtypes = NULL_TREE;
595 wd->parms = NULL_TREE;
599 /* Given a variable in an expression to be extracted into
600 a helper function, declare the helper function parameter
601 to receive it.
603 On entry the value of the (key, value) pair may be
605 (*, error_mark_node) -- Variable is private to helper function,
606 do nothing.
608 (var, var) -- Reference to outer scope (function or global scope).
610 (var, integer 0) -- Capture by value, save newly-declared PARM_DECL
611 for value in value slot.
613 (var, integer 1) -- Capture by reference, declare pointer to type
614 as new PARM_DECL and store (spawn_stmt (indirect_ref (parm)).
616 (var, ???) -- Pure output argument, handled similarly to above.
619 static bool
620 declare_one_free_variable (const void *var0, void **map0,
621 void *data ATTRIBUTE_UNUSED)
623 const_tree var = (const_tree) var0;
624 tree map = (tree)*map0;
625 tree var_type = TREE_TYPE (var), arg_type;
626 bool by_reference;
627 tree parm;
629 gcc_assert (DECL_P (var));
631 /* Ignore truly local variables. */
632 if (map == error_mark_node)
633 return true;
634 /* Ignore references to the parent function. */
635 if (map == var)
636 return true;
638 gcc_assert (TREE_CODE (map) == INTEGER_CST);
640 /* A value is passed by reference if:
642 1. It is addressable, so that a copy may not be made.
643 2. It is modified in the spawned statement.
644 In the future this function may want to arrange
645 a warning if the spawned statement is a loop body
646 because an output argument would indicate a race.
647 Note: Earlier passes must have marked the variable addressable.
648 3. It is expensive to copy. */
649 by_reference =
650 (TREE_ADDRESSABLE (var_type)
651 /* Arrays must be passed by reference. This is required for C
652 semantics -- arrays are not first class objects. Other
653 aggregate types can and should be passed by reference if
654 they are not passed to the spawned function. We aren't yet
655 distinguishing safe uses in argument calculation from unsafe
656 uses as outgoing function arguments, so we make a copy to
657 stabilize the value. */
658 || TREE_CODE (var_type) == ARRAY_TYPE
659 || (tree) map == integer_one_node);
661 if (by_reference)
662 var_type = build_qualified_type (build_pointer_type (var_type),
663 TYPE_QUAL_RESTRICT);
664 gcc_assert (!TREE_ADDRESSABLE (var_type));
666 /* Maybe promote to int. */
667 if (INTEGRAL_TYPE_P (var_type) && COMPLETE_TYPE_P (var_type)
668 && INT_CST_LT_UNSIGNED (TYPE_SIZE (var_type),
669 TYPE_SIZE (integer_type_node)))
670 arg_type = integer_type_node;
671 else
672 arg_type = var_type;
674 parm = build_decl (UNKNOWN_LOCATION, PARM_DECL, NULL_TREE, var_type);
675 DECL_ARG_TYPE (parm) = arg_type;
676 DECL_ARTIFICIAL (parm) = 0;
677 TREE_READONLY (parm) = 1;
679 if (by_reference)
681 parm = build1 (INDIRECT_REF, TREE_TYPE (var_type), parm);
682 parm = build1 (PAREN_EXPR, void_type_node, parm);
684 *map0 = parm;
685 return true;
688 /* Returns a wrapper function for a _Cilk_spawn. */
690 static tree
691 create_cilk_wrapper (tree exp, tree *args_out)
693 struct wrapper_data wd;
694 tree fndecl;
696 init_wd (&wd, CILK_BLOCK_SPAWN);
698 if (TREE_CODE (exp) == CONVERT_EXPR)
699 exp = TREE_OPERAND (exp, 0);
701 /* Special handling for top level INIT_EXPR. Usually INIT_EXPR means the
702 variable is defined in the spawned expression and can be private to the
703 spawn helper. A top level INIT_EXPR defines a variable to be initialized
704 by spawn and the variable must remain in the outer function. */
705 if (TREE_CODE (exp) == INIT_EXPR)
707 extract_free_variables (TREE_OPERAND (exp, 0), &wd, ADD_WRITE);
708 extract_free_variables (TREE_OPERAND (exp, 1), &wd, ADD_READ);
709 /* TREE_TYPE should be void. Be defensive. */
710 if (TREE_TYPE (exp) != void_type_node)
711 extract_free_variables (TREE_TYPE (exp), &wd, ADD_READ);
713 else
714 extract_free_variables (exp, &wd, ADD_READ);
715 pointer_map_traverse (wd.decl_map, declare_one_free_variable, &wd);
716 wd.block = TREE_BLOCK (exp);
717 if (!wd.block)
718 wd.block = DECL_INITIAL (current_function_decl);
720 /* Now fvars maps the old variable to incoming variable. Update
721 the expression and arguments to refer to the new names. */
722 fndecl = create_cilk_wrapper_body (exp, &wd);
723 *args_out = wd.arglist;
725 free_wd (&wd);
727 return fndecl;
730 /* Transform *SPAWN_P, a spawned CALL_EXPR, to gimple. *SPAWN_P can be a
731 CALL_EXPR, INIT_EXPR or MODIFY_EXPR. Returns GS_OK if everything is fine,
732 and GS_UNHANDLED, otherwise. */
735 gimplify_cilk_spawn (tree *spawn_p, gimple_seq *before ATTRIBUTE_UNUSED,
736 gimple_seq *after ATTRIBUTE_UNUSED)
738 tree expr = *spawn_p;
739 tree function, call1, call2, new_args;
740 tree ii_args = NULL_TREE;
741 int total_args = 0, ii = 0;
742 tree *arg_array;
743 tree setjmp_cond_expr = NULL_TREE;
744 tree setjmp_expr, spawn_expr, setjmp_value = NULL_TREE;
746 cfun->calls_cilk_spawn = 1;
747 cfun->is_cilk_function = 1;
749 /* Remove CLEANUP_POINT_EXPR and EXPR_STMT from *spawn_p. */
750 while (TREE_CODE (expr) == CLEANUP_POINT_EXPR
751 || TREE_CODE (expr) == EXPR_STMT)
752 expr = TREE_OPERAND (expr, 0);
754 new_args = NULL;
755 function = create_cilk_wrapper (expr, &new_args);
757 /* This should give the number of parameters. */
758 total_args = list_length (new_args);
759 arg_array = XNEWVEC (tree, total_args);
761 ii_args = new_args;
762 for (ii = 0; ii < total_args; ii++)
764 arg_array[ii] = TREE_VALUE (ii_args);
765 ii_args = TREE_CHAIN (ii_args);
768 TREE_USED (function) = 1;
769 rest_of_decl_compilation (function, 0, 0);
771 call1 = cilk_call_setjmp (cfun->cilk_frame_decl);
773 if (*arg_array == NULL_TREE)
774 call2 = build_call_expr (function, 0);
775 else
776 call2 = build_call_expr_loc_array (EXPR_LOCATION (*spawn_p), function,
777 total_args, arg_array);
778 *spawn_p = alloc_stmt_list ();
779 tree f_ptr_type = build_pointer_type (TREE_TYPE (cfun->cilk_frame_decl));
780 tree frame_ptr = build1 (ADDR_EXPR, f_ptr_type, cfun->cilk_frame_decl);
781 tree save_fp = build_call_expr (cilk_save_fp_fndecl, 1, frame_ptr);
782 append_to_statement_list (save_fp, spawn_p);
783 setjmp_value = create_tmp_var (TREE_TYPE (call1), NULL);
784 setjmp_expr = fold_build2 (MODIFY_EXPR, void_type_node, setjmp_value, call1);
786 append_to_statement_list_force (setjmp_expr, spawn_p);
788 setjmp_cond_expr = fold_build2 (EQ_EXPR, TREE_TYPE (call1), setjmp_value,
789 build_int_cst (TREE_TYPE (call1), 0));
790 spawn_expr = fold_build3 (COND_EXPR, void_type_node, setjmp_cond_expr,
791 call2, build_empty_stmt (EXPR_LOCATION (call1)));
792 append_to_statement_list (spawn_expr, spawn_p);
794 return GS_OK;
797 /* Make the frames necessary for a spawn call. */
799 tree
800 make_cilk_frame (tree fn)
802 struct function *f = DECL_STRUCT_FUNCTION (fn);
803 tree decl;
805 if (f->cilk_frame_decl)
806 return f->cilk_frame_decl;
808 decl = build_decl (EXPR_LOCATION (fn), VAR_DECL, NULL_TREE,
809 cilk_frame_type_decl);
810 DECL_CONTEXT (decl) = fn;
811 DECL_SEEN_IN_BIND_EXPR_P (decl) = 1;
812 f->cilk_frame_decl = decl;
813 return decl;
816 /* Returns a STATEMENT_LIST with all the pedigree operations required for
817 install body with frame cleanup functions. FRAME_PTR is the pointer to
818 __cilkrts_stack_frame created by make_cilk_frame. */
820 tree
821 cilk_install_body_pedigree_operations (tree frame_ptr)
823 tree body_list = alloc_stmt_list ();
824 tree enter_frame = build_call_expr (cilk_enter_fast_fndecl, 1, frame_ptr);
825 append_to_statement_list (enter_frame, &body_list);
827 tree parent = cilk_arrow (frame_ptr, CILK_TI_FRAME_PARENT, 0);
828 tree worker = cilk_arrow (frame_ptr, CILK_TI_FRAME_WORKER, 0);
830 tree pedigree = cilk_arrow (frame_ptr, CILK_TI_FRAME_PEDIGREE, 0);
831 tree pedigree_rank = cilk_dot (pedigree, CILK_TI_PEDIGREE_RANK, 0);
832 tree parent_pedigree = cilk_dot (pedigree, CILK_TI_PEDIGREE_PARENT, 0);
833 tree pedigree_parent = cilk_arrow (parent, CILK_TI_FRAME_PEDIGREE, 0);
834 tree pedigree_parent_rank = cilk_dot (pedigree_parent,
835 CILK_TI_PEDIGREE_RANK, 0);
836 tree pedigree_parent_parent = cilk_dot (pedigree_parent,
837 CILK_TI_PEDIGREE_PARENT, 0);
838 tree worker_pedigree = cilk_arrow (worker, CILK_TI_WORKER_PEDIGREE, 1);
839 tree w_pedigree_rank = cilk_dot (worker_pedigree, CILK_TI_PEDIGREE_RANK, 0);
840 tree w_pedigree_parent = cilk_dot (worker_pedigree,
841 CILK_TI_PEDIGREE_PARENT, 0);
843 /* sf.pedigree.rank = worker->pedigree.rank. */
844 tree exp1 = build2 (MODIFY_EXPR, void_type_node, pedigree_rank,
845 w_pedigree_rank);
846 append_to_statement_list (exp1, &body_list);
848 /* sf.pedigree.parent = worker->pedigree.parent. */
849 exp1 = build2 (MODIFY_EXPR, void_type_node, parent_pedigree,
850 w_pedigree_parent);
851 append_to_statement_list (exp1, &body_list);
853 /* sf.call_parent->pedigree.rank = worker->pedigree.rank. */
854 exp1 = build2 (MODIFY_EXPR, void_type_node, pedigree_parent_rank,
855 w_pedigree_rank);
856 append_to_statement_list (exp1, &body_list);
858 /* sf.call_parent->pedigree.parent = worker->pedigree.parent. */
859 exp1 = build2 (MODIFY_EXPR, void_type_node, pedigree_parent_parent,
860 w_pedigree_parent);
861 append_to_statement_list (exp1, &body_list);
863 /* sf->worker.pedigree.rank = 0. */
864 exp1 = build2 (MODIFY_EXPR, void_type_node, w_pedigree_rank,
865 build_zero_cst (uint64_type_node));
866 append_to_statement_list (exp1, &body_list);
868 /* sf->pedigree.parent = &sf->pedigree. */
869 exp1 = build2 (MODIFY_EXPR, void_type_node, w_pedigree_parent,
870 build1 (ADDR_EXPR,
871 build_pointer_type (cilk_pedigree_type_decl),
872 pedigree));
873 append_to_statement_list (exp1, &body_list);
874 return body_list;
877 /* Inserts "cleanup" functions after the function-body of FNDECL. FNDECL is a
878 spawn-helper and BODY is the newly created body for FNDECL. */
880 void
881 c_cilk_install_body_w_frame_cleanup (tree fndecl, tree body)
883 tree list = alloc_stmt_list ();
884 tree frame = make_cilk_frame (fndecl);
885 tree dtor = create_cilk_function_exit (frame, false, true);
886 add_local_decl (cfun, frame);
888 DECL_SAVED_TREE (fndecl) = list;
889 tree frame_ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (frame)),
890 frame);
891 tree body_list = cilk_install_body_pedigree_operations (frame_ptr);
892 gcc_assert (TREE_CODE (body_list) == STATEMENT_LIST);
894 tree detach_expr = build_call_expr (cilk_detach_fndecl, 1, frame_ptr);
895 append_to_statement_list (detach_expr, &body_list);
896 append_to_statement_list (body, &body_list);
897 append_to_statement_list (build_stmt (EXPR_LOCATION (body), TRY_FINALLY_EXPR,
898 body_list, dtor), &list);
901 /* Add a new variable, VAR to a variable list in WD->DECL_MAP. HOW indicates
902 whether the variable is previously defined, currently defined, or a variable
903 that is being written to. */
905 static void
906 add_variable (struct wrapper_data *wd, tree var, enum add_variable_type how)
908 void **valp;
910 valp = pointer_map_contains (wd->decl_map, (void *) var);
911 if (valp)
913 tree val = (tree) *valp;
914 /* If the variable is local, do nothing. */
915 if (val == error_mark_node)
916 return;
917 /* If the variable was entered with itself as value,
918 meaning it belongs to an outer scope, do not alter
919 the value. */
920 if (val == var)
921 return;
922 /* A statement expression may cause a variable to be
923 bound twice, once in BIND_EXPR and again in a
924 DECL_EXPR. That case caused a return in the
925 test above. Any other duplicate definition is
926 an error. */
927 gcc_assert (how != ADD_BIND);
928 if (how != ADD_WRITE)
929 return;
930 /* This variable might have been entered as read but is now written. */
931 *valp = (void *) var;
932 wd->nested = true;
933 return;
935 else
937 tree val = NULL_TREE;
939 /* Nested function rewriting silently discards hard register
940 assignments for function scope variables, and they wouldn't
941 work anyway. Warn here. This misses one case: if the
942 register variable is used as the loop bound or increment it
943 has already been added to the map. */
944 if ((how != ADD_BIND) && (TREE_CODE (var) == VAR_DECL)
945 && !DECL_EXTERNAL (var) && DECL_HARD_REGISTER (var))
946 warning (0, "register assignment ignored for %qD used in Cilk block",
947 var);
949 switch (how)
951 /* ADD_BIND means always make a fresh new variable. */
952 case ADD_BIND:
953 val = error_mark_node;
954 break;
955 /* ADD_READ means
956 1. For cilk_for, refer to the outer scope definition as-is
957 2. For a spawned block, take a scalar in an rgument
958 and otherwise refer to the outer scope definition as-is.
959 3. For a spawned call, take a scalar in an argument. */
960 case ADD_READ:
961 switch (wd->type)
963 case CILK_BLOCK_FOR:
964 val = var;
965 break;
966 case CILK_BLOCK_SPAWN:
967 if (TREE_ADDRESSABLE (var))
969 val = var;
970 wd->nested = true;
971 break;
973 val = integer_zero_node;
974 break;
976 break;
977 case ADD_WRITE:
978 switch (wd->type)
980 case CILK_BLOCK_FOR:
981 val = var;
982 wd->nested = true;
983 break;
984 case CILK_BLOCK_SPAWN:
985 if (TREE_ADDRESSABLE (var))
986 val = integer_one_node;
987 else
989 val = var;
990 wd->nested = true;
992 break;
995 *pointer_map_insert (wd->decl_map, (void *) var) = val;
999 /* Find the variables referenced in an expression T. This does not avoid
1000 duplicates because a variable may be read in one context and written in
1001 another. HOW describes the context in which the reference is seen. If
1002 NESTED is true a nested function is being generated and variables in the
1003 original context should not be remapped. */
1005 static void
1006 extract_free_variables (tree t, struct wrapper_data *wd,
1007 enum add_variable_type how)
1009 if (t == NULL_TREE)
1010 return;
1012 enum tree_code code = TREE_CODE (t);
1013 bool is_expr = IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code));
1015 if (is_expr)
1016 extract_free_variables (TREE_TYPE (t), wd, ADD_READ);
1018 switch (code)
1020 case ERROR_MARK:
1021 case IDENTIFIER_NODE:
1022 case INTEGER_CST:
1023 case REAL_CST:
1024 case FIXED_CST:
1025 case STRING_CST:
1026 case BLOCK:
1027 case PLACEHOLDER_EXPR:
1028 case FIELD_DECL:
1029 case VOID_TYPE:
1030 case REAL_TYPE:
1031 /* These do not contain variable references. */
1032 return;
1034 case SSA_NAME:
1035 /* Currently we don't see SSA_NAME. */
1036 extract_free_variables (SSA_NAME_VAR (t), wd, how);
1037 return;
1039 case LABEL_DECL:
1040 /* This might be a reference to a label outside the Cilk block,
1041 which is an error, or a reference to a label in the Cilk block
1042 that we haven't seen yet. We can't tell. Ignore it. An
1043 invalid use will cause an error later in copy_decl_for_cilk. */
1044 return;
1046 case RESULT_DECL:
1047 if (wd->type != CILK_BLOCK_SPAWN)
1048 TREE_ADDRESSABLE (t) = 1;
1049 case VAR_DECL:
1050 case PARM_DECL:
1051 if (!TREE_STATIC (t) && !DECL_EXTERNAL (t))
1052 add_variable (wd, t, how);
1053 return;
1055 case NON_LVALUE_EXPR:
1056 case CONVERT_EXPR:
1057 case NOP_EXPR:
1058 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_READ);
1059 return;
1061 case INIT_EXPR:
1062 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_BIND);
1063 extract_free_variables (TREE_OPERAND (t, 1), wd, ADD_READ);
1064 return;
1066 case MODIFY_EXPR:
1067 case PREDECREMENT_EXPR:
1068 case PREINCREMENT_EXPR:
1069 case POSTDECREMENT_EXPR:
1070 case POSTINCREMENT_EXPR:
1071 /* These write their result. */
1072 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_WRITE);
1073 extract_free_variables (TREE_OPERAND (t, 1), wd, ADD_READ);
1074 return;
1076 case ADDR_EXPR:
1077 /* This might modify its argument, and the value needs to be
1078 passed by reference in any case to preserve identity and
1079 type if is a promoting type. In the case of a nested loop
1080 just notice that we touch the variable. It will already
1081 be addressable, and marking it modified will cause a spurious
1082 warning about writing the control variable. */
1083 if (wd->type != CILK_BLOCK_SPAWN)
1084 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_READ);
1085 else
1086 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_WRITE);
1087 return;
1089 case ARRAY_REF:
1090 /* Treating ARRAY_REF and BIT_FIELD_REF identically may
1091 mark the array as written but the end result is correct
1092 because the array is passed by pointer anyway. */
1093 case BIT_FIELD_REF:
1094 /* Propagate the access type to the object part of which
1095 is being accessed here. As for ADDR_EXPR, don't do this
1096 in a nested loop, unless the access is to a fixed index. */
1097 if (wd->type != CILK_BLOCK_FOR || TREE_CONSTANT (TREE_OPERAND (t, 1)))
1098 extract_free_variables (TREE_OPERAND (t, 0), wd, how);
1099 else
1100 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_READ);
1101 extract_free_variables (TREE_OPERAND (t, 1), wd, ADD_READ);
1102 extract_free_variables (TREE_OPERAND (t, 2), wd, ADD_READ);
1103 return;
1105 case TREE_LIST:
1106 extract_free_variables (TREE_PURPOSE (t), wd, ADD_READ);
1107 extract_free_variables (TREE_VALUE (t), wd, ADD_READ);
1108 extract_free_variables (TREE_CHAIN (t), wd, ADD_READ);
1109 return;
1111 case TREE_VEC:
1113 int len = TREE_VEC_LENGTH (t);
1114 int i;
1115 for (i = 0; i < len; i++)
1116 extract_free_variables (TREE_VEC_ELT (t, i), wd, ADD_READ);
1117 return;
1120 case VECTOR_CST:
1122 unsigned ii = 0;
1123 for (ii = 0; ii < VECTOR_CST_NELTS (t); ii++)
1124 extract_free_variables (VECTOR_CST_ELT (t, ii), wd, ADD_READ);
1125 break;
1128 case COMPLEX_CST:
1129 extract_free_variables (TREE_REALPART (t), wd, ADD_READ);
1130 extract_free_variables (TREE_IMAGPART (t), wd, ADD_READ);
1131 return;
1133 case BIND_EXPR:
1135 tree decl;
1136 for (decl = BIND_EXPR_VARS (t); decl; decl = TREE_CHAIN (decl))
1138 add_variable (wd, decl, ADD_BIND);
1139 /* A self-referential initialization is no problem because
1140 we already entered the variable into the map as local. */
1141 extract_free_variables (DECL_INITIAL (decl), wd, ADD_READ);
1142 extract_free_variables (DECL_SIZE (decl), wd, ADD_READ);
1143 extract_free_variables (DECL_SIZE_UNIT (decl), wd, ADD_READ);
1145 extract_free_variables (BIND_EXPR_BODY (t), wd, ADD_READ);
1146 return;
1149 case STATEMENT_LIST:
1151 tree_stmt_iterator i;
1152 for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
1153 extract_free_variables (*tsi_stmt_ptr (i), wd, ADD_READ);
1154 return;
1157 case TARGET_EXPR:
1159 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_BIND);
1160 extract_free_variables (TREE_OPERAND (t, 1), wd, ADD_READ);
1161 extract_free_variables (TREE_OPERAND (t, 2), wd, ADD_READ);
1162 if (TREE_OPERAND (t, 3) != TREE_OPERAND (t, 1))
1163 extract_free_variables (TREE_OPERAND (t, 3), wd, ADD_READ);
1164 return;
1167 case RETURN_EXPR:
1168 if (TREE_NO_WARNING (t))
1170 gcc_assert (errorcount);
1171 return;
1173 return;
1175 case DECL_EXPR:
1176 if (TREE_CODE (DECL_EXPR_DECL (t)) != TYPE_DECL)
1177 extract_free_variables (DECL_EXPR_DECL (t), wd, ADD_BIND);
1178 return;
1180 case INTEGER_TYPE:
1181 case ENUMERAL_TYPE:
1182 case BOOLEAN_TYPE:
1183 extract_free_variables (TYPE_MIN_VALUE (t), wd, ADD_READ);
1184 extract_free_variables (TYPE_MAX_VALUE (t), wd, ADD_READ);
1185 return;
1187 case POINTER_TYPE:
1188 extract_free_variables (TREE_TYPE (t), wd, ADD_READ);
1189 break;
1191 case ARRAY_TYPE:
1192 extract_free_variables (TREE_TYPE (t), wd, ADD_READ);
1193 extract_free_variables (TYPE_DOMAIN (t), wd, ADD_READ);
1194 return;
1196 case RECORD_TYPE:
1197 extract_free_variables (TYPE_FIELDS (t), wd, ADD_READ);
1198 return;
1200 case METHOD_TYPE:
1201 extract_free_variables (TYPE_ARG_TYPES (t), wd, ADD_READ);
1202 extract_free_variables (TYPE_METHOD_BASETYPE (t), wd, ADD_READ);
1203 return;
1205 case AGGR_INIT_EXPR:
1206 case CALL_EXPR:
1208 int len = 0;
1209 int ii = 0;
1210 if (TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST)
1212 len = TREE_INT_CST_LOW (TREE_OPERAND (t, 0));
1214 for (ii = 0; ii < len; ii++)
1215 extract_free_variables (TREE_OPERAND (t, ii), wd, ADD_READ);
1216 extract_free_variables (TREE_TYPE (t), wd, ADD_READ);
1218 break;
1221 default:
1222 if (is_expr)
1224 int i, len;
1226 /* Walk over all the sub-trees of this operand. */
1227 len = TREE_CODE_LENGTH (code);
1229 /* Go through the subtrees. We need to do this in forward order so
1230 that the scope of a FOR_EXPR is handled properly. */
1231 for (i = 0; i < len; ++i)
1232 extract_free_variables (TREE_OPERAND (t, i), wd, ADD_READ);
1238 /* Add appropriate frames needed for a Cilk spawned function call, FNDECL.
1239 Returns the __cilkrts_stack_frame * variable. */
1241 tree
1242 insert_cilk_frame (tree fndecl)
1244 tree addr, body, enter, out, orig_body;
1245 location_t loc = EXPR_LOCATION (fndecl);
1247 if (!cfun || cfun->decl != fndecl)
1248 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
1250 tree decl = cfun->cilk_frame_decl;
1251 if (!decl)
1253 tree *saved_tree = &DECL_SAVED_TREE (fndecl);
1254 decl = make_cilk_frame (fndecl);
1255 add_local_decl (cfun, decl);
1257 addr = build1 (ADDR_EXPR, cilk_frame_ptr_type_decl, decl);
1258 enter = build_call_expr (cilk_enter_fndecl, 1, addr);
1259 out = create_cilk_function_exit (cfun->cilk_frame_decl, false, true);
1261 /* The new body will be:
1262 __cilkrts_enter_frame_1 (&sf);
1263 try {
1264 orig_body;
1266 finally {
1267 __cilkrts_pop_frame (&sf);
1268 __cilkrts_leave_frame (&sf);
1269 } */
1271 body = alloc_stmt_list ();
1272 orig_body = *saved_tree;
1274 if (TREE_CODE (orig_body) == BIND_EXPR)
1275 orig_body = BIND_EXPR_BODY (orig_body);
1277 append_to_statement_list (enter, &body);
1278 append_to_statement_list (build_stmt (loc, TRY_FINALLY_EXPR, orig_body,
1279 out), &body);
1280 if (TREE_CODE (*saved_tree) == BIND_EXPR)
1281 BIND_EXPR_BODY (*saved_tree) = body;
1282 else
1283 *saved_tree = body;
1285 return decl;
1288 /* Wraps CALL, a CALL_EXPR, into a CILK_SPAWN_STMT tree and returns it. */
1290 tree
1291 build_cilk_spawn (location_t loc, tree call)
1293 if (!cilk_set_spawn_marker (loc, call))
1294 return error_mark_node;
1295 tree spawn_stmt = build1 (CILK_SPAWN_STMT, TREE_TYPE (call), call);
1296 TREE_SIDE_EFFECTS (spawn_stmt) = 1;
1297 return spawn_stmt;
1300 /* Returns a tree of type CILK_SYNC_STMT. */
1302 tree
1303 build_cilk_sync (void)
1305 tree sync = build0 (CILK_SYNC_STMT, void_type_node);
1306 TREE_SIDE_EFFECTS (sync) = 1;
1307 return sync;