Fix date
[official-gcc.git] / gcc / c-family / cilk.c
blobe6df498e471a05d623d579e97e376720ce4808c1
1 /* This file is part of the Intel(R) Cilk(TM) Plus support
2 This file contains the CilkPlus Intrinsics
3 Copyright (C) 2013-2017 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 "tm.h"
27 #include "function.h"
28 #include "c-family/c-common.h"
29 #include "gimple-expr.h"
30 #include "stringpool.h"
31 #include "cgraph.h"
32 #include "diagnostic.h"
33 #include "gimplify.h"
34 #include "tree-iterator.h"
35 #include "tree-inline.h"
36 #include "toplev.h"
37 #include "calls.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 hash_map<tree, tree> *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 tree contains_cilk_spawn_stmt_walker (tree *tp, int *, void *);
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 /* 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 if (TREE_CODE (fcall) == CALL_EXPR)
113 EXPR_CILK_SPAWN (fcall) = 1;
114 else /* TREE_CODE (fcall) == TARGET_EXPR */
115 EXPR_CILK_SPAWN (TREE_OPERAND (fcall, 1)) = 1;
116 return true;
120 /* This function will output the exit conditions for a spawn call. */
122 tree
123 create_cilk_function_exit (tree frame, bool detaches, bool needs_sync)
125 tree epi = alloc_stmt_list ();
127 if (needs_sync)
128 append_to_statement_list (build_cilk_sync (), &epi);
129 tree func_ptr = build1 (ADDR_EXPR, cilk_frame_ptr_type_decl, frame);
130 tree pop_frame = build_call_expr (cilk_pop_fndecl, 1, func_ptr);
131 tree worker = cilk_dot (frame, CILK_TI_FRAME_WORKER, 0);
132 tree current = cilk_arrow (worker, CILK_TI_WORKER_CUR, 0);
133 tree parent = cilk_dot (frame, CILK_TI_FRAME_PARENT, 0);
134 tree set_current = build2 (MODIFY_EXPR, void_type_node, current, parent);
135 append_to_statement_list (set_current, &epi);
136 append_to_statement_list (pop_frame, &epi);
137 tree call = build_call_expr (cilk_leave_fndecl, 1, func_ptr);
138 if (!detaches)
140 tree flags = cilk_dot (frame, CILK_TI_FRAME_FLAGS, false);
141 tree flags_cmp_expr = fold_build2 (NE_EXPR, TREE_TYPE (flags), flags,
142 build_int_cst (TREE_TYPE (flags),
143 CILK_FRAME_VERSION));
144 call = fold_build3 (COND_EXPR, void_type_node, flags_cmp_expr,
145 call, build_empty_stmt (EXPR_LOCATION (flags)));
147 append_to_statement_list (call, &epi);
148 return epi;
151 /* Trying to get the correct cfun for the FUNCTION_DECL indicated by OUTER. */
153 static void
154 pop_cfun_to (tree outer)
156 pop_cfun ();
157 current_function_decl = outer;
158 gcc_assert (cfun == DECL_STRUCT_FUNCTION (current_function_decl));
159 gcc_assert (cfun->decl == current_function_decl);
162 /* This function does whatever is necessary to make the compiler emit a newly
163 generated function, FNDECL. */
165 static void
166 call_graph_add_fn (tree fndecl)
168 const tree outer = current_function_decl;
169 struct function *f = DECL_STRUCT_FUNCTION (fndecl);
170 gcc_assert (TREE_CODE (fndecl) == FUNCTION_DECL);
172 f->is_cilk_function = 1;
173 f->curr_properties = cfun->curr_properties;
174 gcc_assert (cfun == DECL_STRUCT_FUNCTION (outer));
175 gcc_assert (cfun->decl == outer);
177 push_cfun (f);
178 cgraph_node::create (fndecl);
179 pop_cfun_to (outer);
182 /* Return true if this is a tree which is allowed to contain a spawn as
183 operand 0.
184 A spawn call may be wrapped in a series of unary operations such
185 as conversions. These conversions need not be "useless"
186 to be disregarded because they are retained in the spawned
187 statement. They are bypassed only to look for a spawn
188 within.
189 A comparison to constant is simple enough to allow, and
190 is used to convert to bool. */
192 bool
193 cilk_ignorable_spawn_rhs_op (tree exp)
195 enum tree_code code = TREE_CODE (exp);
196 switch (TREE_CODE_CLASS (code))
198 case tcc_expression:
199 return code == ADDR_EXPR;
200 case tcc_comparison:
201 /* We need the spawn as operand 0 for now. That's where it
202 appears in the only case we really care about, conversion
203 to bool. */
204 return (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST);
205 case tcc_unary:
206 case tcc_reference:
207 return true;
208 default:
209 return false;
213 /* Helper function for walk_tree. If *TP is a CILK_SPAWN_STMT, then unwrap
214 this "wrapper." The function returns NULL_TREE regardless. */
216 static tree
217 unwrap_cilk_spawn_stmt (tree *tp, int *walk_subtrees, void *)
219 if (TREE_CODE (*tp) == CILK_SPAWN_STMT)
221 *tp = CILK_SPAWN_FN (*tp);
222 *walk_subtrees = 0;
224 return NULL_TREE;
227 /* Returns true when EXP is a CALL_EXPR with _Cilk_spawn in front. Unwraps
228 CILK_SPAWN_STMT wrapper from the CALL_EXPR in *EXP0 statement. */
230 bool
231 cilk_recognize_spawn (tree exp, tree *exp0)
233 bool spawn_found = false;
234 if (TREE_CODE (exp) == CILK_SPAWN_STMT)
236 /* Remove the CALL_EXPR from CILK_SPAWN_STMT wrapper. */
237 exp = CILK_SPAWN_FN (exp);
238 walk_tree (exp0, unwrap_cilk_spawn_stmt, NULL, NULL);
239 spawn_found = true;
241 /* _Cilk_spawn can't be wrapped in expression such as PLUS_EXPR. */
242 else if (contains_cilk_spawn_stmt (exp))
244 location_t loc = EXPR_LOCATION (exp);
245 if (loc == UNKNOWN_LOCATION)
247 tree stmt = walk_tree (&exp,
248 contains_cilk_spawn_stmt_walker,
249 NULL,
250 NULL);
251 gcc_assert (stmt != NULL_TREE);
252 loc = EXPR_LOCATION (stmt);
254 error_at (loc, "invalid use of %<_Cilk_spawn%>");
256 return spawn_found;
259 /* Returns true if *EXP0 is a recognized form of spawn. Recognized forms are,
260 after conversion to void, a call expression at outer level or an assignment
261 at outer level with the right hand side being a spawned call.
262 In addition to this, it also unwraps the CILK_SPAWN_STMT cover from the
263 CALL_EXPR that is being spawned.
264 Note that `=' in C++ may turn into a CALL_EXPR rather than a MODIFY_EXPR. */
266 bool
267 cilk_detect_spawn_and_unwrap (tree *exp0)
269 tree exp = *exp0;
271 if (!TREE_SIDE_EFFECTS (exp))
272 return false;
274 /* Strip off any conversion to void. It does not affect whether spawn
275 is supported here. */
276 if (TREE_CODE (exp) == CONVERT_EXPR && VOID_TYPE_P (TREE_TYPE (exp)))
277 exp = TREE_OPERAND (exp, 0);
279 if (TREE_CODE (exp) == MODIFY_EXPR || TREE_CODE (exp) == INIT_EXPR)
280 exp = TREE_OPERAND (exp, 1);
282 while (cilk_ignorable_spawn_rhs_op (exp))
283 exp = TREE_OPERAND (exp, 0);
285 if (TREE_CODE (exp) == TARGET_EXPR)
286 if (TARGET_EXPR_INITIAL (exp)
287 && TREE_CODE (TARGET_EXPR_INITIAL (exp)) != AGGR_INIT_EXPR)
288 exp = TARGET_EXPR_INITIAL (exp);
290 /* Happens with C++ TARGET_EXPR. */
291 if (exp == NULL_TREE)
292 return false;
294 while (TREE_CODE (exp) == CLEANUP_POINT_EXPR || TREE_CODE (exp) == EXPR_STMT)
295 exp = TREE_OPERAND (exp, 0);
297 /* Now we should have a CALL_EXPR with a CILK_SPAWN_STMT wrapper around
298 it, or return false. */
299 if (cilk_recognize_spawn (exp, exp0))
300 return true;
301 return false;
304 /* This function will build and return a FUNCTION_DECL using information
305 from *WD. */
307 static tree
308 create_cilk_helper_decl (struct wrapper_data *wd)
310 char name[20];
311 if (wd->type == CILK_BLOCK_FOR)
312 sprintf (name, "_cilk_for_" HOST_WIDE_INT_PRINT_DEC, cilk_wrapper_count++);
313 else if (wd->type == CILK_BLOCK_SPAWN)
314 sprintf (name, "_cilk_spn_" HOST_WIDE_INT_PRINT_DEC, cilk_wrapper_count++);
315 else
316 gcc_unreachable ();
318 clean_symbol_name (name);
320 tree fndecl = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
321 FUNCTION_DECL, get_identifier (name), wd->fntype);
323 TREE_PUBLIC (fndecl) = 0;
324 TREE_STATIC (fndecl) = 1;
325 TREE_USED (fndecl) = 1;
326 DECL_ARTIFICIAL (fndecl) = 0;
327 DECL_IGNORED_P (fndecl) = 0;
328 DECL_EXTERNAL (fndecl) = 0;
330 DECL_CONTEXT (fndecl) = wd->context;
331 tree block = make_node (BLOCK);
332 DECL_INITIAL (fndecl) = block;
333 TREE_USED (block) = 1;
334 BLOCK_SUPERCONTEXT (block) = fndecl;
335 gcc_assert (!DECL_SAVED_TREE (fndecl));
337 /* Inlining would defeat the purpose of this wrapper.
338 Either it secretly switches stack frames or it allocates
339 a stable stack frame to hold function arguments even if
340 the parent stack frame is stolen. */
341 DECL_UNINLINABLE (fndecl) = 1;
343 tree result_decl = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE,
344 void_type_node);
345 DECL_ARTIFICIAL (result_decl) = 0;
346 DECL_IGNORED_P (result_decl) = 1;
347 DECL_CONTEXT (result_decl) = fndecl;
348 DECL_RESULT (fndecl) = result_decl;
350 return fndecl;
353 struct cilk_decls
355 tree key;
356 tree *val;
359 /* A function used by traversal to fill vector of decls for further work. */
361 bool
362 fill_decls_vec (tree const &key0, tree *val0, auto_vec<struct cilk_decls> *v)
364 tree t1 = key0;
365 struct cilk_decls dp;
367 if (DECL_P (t1))
369 dp.key = t1;
370 dp.val = val0;
371 v->safe_push (dp);
373 return true;
376 /* Function that actually creates necessary parm lists. */
378 static void
379 create_parm_list (struct wrapper_data *wd, tree *val0, tree arg)
381 tree val = *val0;
382 tree parm;
384 if (val == error_mark_node || val == arg)
385 return;
387 if (TREE_CODE (val) == PAREN_EXPR)
389 /* We should not reach here with a register receiver.
390 We may see a register variable modified in the
391 argument list. Because register variables are
392 worker-local we don't need to work hard to support
393 them in code that spawns. */
394 if (VAR_P (arg) && DECL_HARD_REGISTER (arg))
396 error_at (EXPR_LOCATION (arg),
397 "explicit register variable %qD may not be modified in "
398 "spawn", arg);
399 arg = null_pointer_node;
401 else
402 arg = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg)), arg);
404 val = TREE_OPERAND (val, 0);
405 *val0 = val;
406 gcc_assert (INDIRECT_REF_P (val));
407 parm = TREE_OPERAND (val, 0);
408 STRIP_NOPS (parm);
410 else
411 parm = val;
412 TREE_CHAIN (parm) = wd->parms;
413 wd->parms = parm;
414 wd->argtypes = tree_cons (NULL_TREE, TREE_TYPE (parm), wd->argtypes);
415 wd->arglist = tree_cons (NULL_TREE, arg, wd->arglist);
418 /* Sorting decls in a vector. */
420 static int
421 compare_decls (const void *a, const void *b)
423 const struct cilk_decls *t1 = (const struct cilk_decls *) a;
424 const struct cilk_decls *t2 = (const struct cilk_decls *) b;
426 if (DECL_UID (t1->key) > DECL_UID (t2->key))
427 return 1;
428 else if (DECL_UID (t1->key) < DECL_UID (t2->key))
429 return -1;
430 else
431 return 0;
434 /* This function is used to build a wrapper of a certain type. */
436 static void
437 build_wrapper_type (struct wrapper_data *wd)
439 unsigned int j;
440 struct cilk_decls * c;
441 auto_vec<struct cilk_decls> vd;
442 wd->arglist = NULL_TREE;
443 wd->parms = NULL_TREE;
444 wd->argtypes = void_list_node;
446 gcc_assert (wd->type != CILK_BLOCK_FOR);
447 wd->decl_map->traverse<auto_vec<struct cilk_decls> *, fill_decls_vec> (&vd);
448 vd.qsort (compare_decls);
450 FOR_EACH_VEC_ELT (vd, j, c)
451 create_parm_list (wd, c->val, c->key);
453 /* Now build a function.
454 Its return type is void (all side effects are via explicit parameters).
455 Its parameters are WRAPPER_PARMS with type WRAPPER_TYPES.
456 Actual arguments in the caller are WRAPPER_ARGS. */
457 wd->fntype = build_function_type (void_type_node, wd->argtypes);
460 /* This function checks all the CALL_EXPRs in *TP found by cilk_outline. */
462 static tree
463 check_outlined_calls (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
464 void *data)
466 bool *throws = (bool *) data;
467 tree t = *tp;
468 int flags;
470 if (TREE_CODE (t) != CALL_EXPR)
471 return 0;
472 flags = call_expr_flags (t);
474 if (!(flags & ECF_NOTHROW) && flag_exceptions)
475 *throws = true;
476 if (flags & ECF_RETURNS_TWICE)
477 error_at (EXPR_LOCATION (t),
478 "cannot spawn call to function that returns twice");
479 return 0;
482 /* Each DECL in the source code (spawned statement) is passed to this function
483 once. Each instance of the DECL is replaced with the result of this
484 function.
486 The parameters of the wrapper should have been entered into the map already.
487 This function only deals with variables with scope limited to the
488 spawned expression. */
490 static tree
491 copy_decl_for_cilk (tree decl, copy_body_data *id)
493 switch (TREE_CODE (decl))
495 case VAR_DECL:
496 return copy_decl_no_change (decl, id);
498 case LABEL_DECL:
499 error_at (EXPR_LOCATION (decl), "invalid use of label %q+D in "
500 "%<_Cilk_spawn%>",
501 decl);
502 return error_mark_node;
504 case RESULT_DECL:
505 case PARM_DECL:
506 /* RESULT_DECL and PARM_DECL has already been entered into the map. */
507 default:
508 gcc_unreachable ();
509 return error_mark_node;
513 /* Alter a tree STMT from OUTER_FN to form the body of INNER_FN. */
515 void
516 cilk_outline (tree inner_fn, tree *stmt_p, void *w)
518 struct wrapper_data *wd = (struct wrapper_data *) w;
519 const tree outer_fn = wd->context;
520 const bool nested = (wd->type == CILK_BLOCK_FOR);
521 copy_body_data id;
522 bool throws;
523 auto_vec<struct cilk_decls> vd;
524 unsigned int j;
525 struct cilk_decls * c;
527 DECL_STATIC_CHAIN (outer_fn) = 1;
529 memset (&id, 0, sizeof (id));
530 /* Copy from the function containing the spawn... */
531 id.src_fn = outer_fn;
533 /* ...to the wrapper. */
534 id.dst_fn = inner_fn;
535 id.src_cfun = DECL_STRUCT_FUNCTION (outer_fn);
537 /* There shall be no RETURN in spawn helper. */
538 id.retvar = 0;
539 id.decl_map = wd->decl_map;
540 id.copy_decl = nested ? copy_decl_no_change : copy_decl_for_cilk;
541 id.block = DECL_INITIAL (inner_fn);
542 id.transform_lang_insert_block = NULL;
544 id.transform_new_cfg = true;
545 id.transform_call_graph_edges = CB_CGE_MOVE;
546 id.remap_var_for_cilk = true;
547 id.regimplify = true; /* unused? */
549 insert_decl_map (&id, wd->block, DECL_INITIAL (inner_fn));
551 wd->decl_map->traverse<auto_vec<struct cilk_decls> *, fill_decls_vec> (&vd);
552 vd.qsort (compare_decls);
553 /* We don't want the private variables any more. */
554 FOR_EACH_VEC_ELT (vd, j, c)
555 if (*(c->val) == error_mark_node)
556 *(c->val) = nested ? copy_decl_no_change (c->key, &id)
557 : copy_decl_for_cilk (c->key, &id);
559 walk_tree (stmt_p, copy_tree_body_r, (void *) &id, NULL);
561 /* See if this function can throw or calls something that should
562 not be spawned. The exception part is only necessary if
563 flag_exceptions && !flag_non_call_exceptions. */
564 throws = false ;
565 (void) walk_tree_without_duplicates (stmt_p, check_outlined_calls, &throws);
568 /* Generate the body of a wrapper function that assigns the
569 result of the expression RHS into RECEIVER. RECEIVER must
570 be NULL if this is not a spawn -- the wrapper will return
571 a value. If this is a spawn, the wrapper will return void. */
573 static tree
574 create_cilk_wrapper_body (tree stmt, struct wrapper_data *wd)
576 const tree outer = current_function_decl;
577 tree fndecl;
578 tree p;
580 /* Build the type of the wrapper and its argument list from the
581 variables that it requires. */
582 build_wrapper_type (wd);
584 /* Emit a function that takes WRAPPER_PARMS incoming and applies ARGS
585 (modified) to the wrapped function. Return the wrapper and modified ARGS
586 to the caller to generate a function call. */
587 fndecl = create_cilk_helper_decl (wd);
588 push_struct_function (fndecl);
589 if (wd->nested && (wd->type == CILK_BLOCK_FOR))
591 gcc_assert (TREE_VALUE (wd->arglist) == NULL_TREE);
592 TREE_VALUE (wd->arglist) = build2 (FDESC_EXPR, ptr_type_node,
593 fndecl, integer_one_node);
595 DECL_ARGUMENTS (fndecl) = wd->parms;
597 for (p = wd->parms; p; p = TREE_CHAIN (p))
598 DECL_CONTEXT (p) = fndecl;
600 /* The statement containing the spawn expression might create temporaries with
601 destructors defined; if so we need to add a CLEANUP_POINT_EXPR to ensure
602 the expression is properly gimplified. */
603 stmt = fold_build_cleanup_point_expr (void_type_node, stmt);
605 gcc_assert (!DECL_SAVED_TREE (fndecl));
606 cilk_install_body_with_frame_cleanup (fndecl, stmt, (void *) wd);
607 gcc_assert (DECL_SAVED_TREE (fndecl));
609 pop_cfun_to (outer);
611 /* Recognize the new function. */
612 call_graph_add_fn (fndecl);
613 return fndecl;
616 /* Initializes the wrapper data structure. */
618 static void
619 init_wd (struct wrapper_data *wd, enum cilk_block_type type)
621 wd->type = type;
622 wd->fntype = NULL_TREE;
623 wd->context = current_function_decl;
624 wd->decl_map = new hash_map<tree, tree>;
625 /* _Cilk_for bodies are always nested. Others start off as
626 normal functions. */
627 wd->nested = (type == CILK_BLOCK_FOR);
628 wd->arglist = NULL_TREE;
629 wd->argtypes = NULL_TREE;
630 wd->block = NULL_TREE;
633 /* Clears the wrapper data structure. */
635 static void
636 free_wd (struct wrapper_data *wd)
638 delete wd->decl_map;
639 wd->nested = false;
640 wd->arglist = NULL_TREE;
641 wd->argtypes = NULL_TREE;
642 wd->parms = NULL_TREE;
646 /* Given a variable in an expression to be extracted into
647 a helper function, declare the helper function parameter
648 to receive it.
650 On entry the value of the (key, value) pair may be
652 (*, error_mark_node) -- Variable is private to helper function,
653 do nothing.
655 (var, var) -- Reference to outer scope (function or global scope).
657 (var, integer 0) -- Capture by value, save newly-declared PARM_DECL
658 for value in value slot.
660 (var, integer 1) -- Capture by reference, declare pointer to type
661 as new PARM_DECL and store (spawn_stmt (indirect_ref (parm)).
663 (var, ???) -- Pure output argument, handled similarly to above.
666 bool
667 declare_one_free_variable (tree var0, tree *map0)
669 const_tree var = var0;
670 tree map = *map0;
671 tree var_type = TREE_TYPE (var), arg_type;
672 bool by_reference;
673 tree parm;
675 gcc_assert (DECL_P (var));
677 /* Ignore truly local variables. */
678 if (map == error_mark_node)
679 return true;
680 /* Ignore references to the parent function. */
681 if (map == var)
682 return true;
684 gcc_assert (TREE_CODE (map) == INTEGER_CST);
686 /* A value is passed by reference if:
688 1. It is addressable, so that a copy may not be made.
689 2. It is modified in the spawned statement.
690 In the future this function may want to arrange
691 a warning if the spawned statement is a loop body
692 because an output argument would indicate a race.
693 Note: Earlier passes must have marked the variable addressable.
694 3. It is expensive to copy. */
695 by_reference =
696 (TREE_ADDRESSABLE (var_type)
697 /* Arrays must be passed by reference. This is required for C
698 semantics -- arrays are not first class objects. Other
699 aggregate types can and should be passed by reference if
700 they are not passed to the spawned function. We aren't yet
701 distinguishing safe uses in argument calculation from unsafe
702 uses as outgoing function arguments, so we make a copy to
703 stabilize the value. */
704 || TREE_CODE (var_type) == ARRAY_TYPE
705 || (tree) map == integer_one_node);
707 if (by_reference)
708 var_type = build_qualified_type (build_pointer_type (var_type),
709 TYPE_QUAL_RESTRICT);
710 gcc_assert (!TREE_ADDRESSABLE (var_type));
712 /* Maybe promote to int. */
713 if (INTEGRAL_TYPE_P (var_type) && COMPLETE_TYPE_P (var_type)
714 && tree_int_cst_lt (TYPE_SIZE (var_type), TYPE_SIZE (integer_type_node)))
715 arg_type = integer_type_node;
716 else
717 arg_type = var_type;
719 parm = build_decl (UNKNOWN_LOCATION, PARM_DECL, NULL_TREE, var_type);
720 DECL_ARG_TYPE (parm) = arg_type;
721 DECL_ARTIFICIAL (parm) = 0;
722 TREE_READONLY (parm) = 1;
724 if (by_reference)
726 parm = build1 (INDIRECT_REF, TREE_TYPE (var_type), parm);
727 parm = build1 (PAREN_EXPR, void_type_node, parm);
729 *map0 = parm;
730 return true;
733 /* Returns a wrapper function for a _Cilk_spawn. */
735 static tree
736 create_cilk_wrapper (tree exp, tree *args_out)
738 struct wrapper_data wd;
739 tree fndecl;
740 unsigned int j;
741 struct cilk_decls * c;
742 auto_vec<struct cilk_decls> vd;
744 init_wd (&wd, CILK_BLOCK_SPAWN);
746 if (TREE_CODE (exp) == CONVERT_EXPR)
747 exp = TREE_OPERAND (exp, 0);
749 /* Special handling for top level INIT_EXPR. Usually INIT_EXPR means the
750 variable is defined in the spawned expression and can be private to the
751 spawn helper. A top level INIT_EXPR defines a variable to be initialized
752 by spawn and the variable must remain in the outer function. */
753 if (TREE_CODE (exp) == INIT_EXPR)
755 extract_free_variables (TREE_OPERAND (exp, 0), &wd, ADD_WRITE);
756 extract_free_variables (TREE_OPERAND (exp, 1), &wd, ADD_READ);
757 /* TREE_TYPE should be void. Be defensive. */
758 if (TREE_TYPE (exp) != void_type_node)
759 extract_free_variables (TREE_TYPE (exp), &wd, ADD_READ);
761 else
762 extract_free_variables (exp, &wd, ADD_READ);
763 wd.decl_map->traverse<auto_vec<struct cilk_decls> *, fill_decls_vec> (&vd);
764 vd.qsort (compare_decls);
765 FOR_EACH_VEC_ELT (vd, j, c)
766 declare_one_free_variable (c->key, c->val);
768 wd.block = TREE_BLOCK (exp);
769 if (!wd.block)
770 wd.block = DECL_INITIAL (current_function_decl);
772 /* Now fvars maps the old variable to incoming variable. Update
773 the expression and arguments to refer to the new names. */
774 fndecl = create_cilk_wrapper_body (exp, &wd);
775 *args_out = wd.arglist;
777 free_wd (&wd);
779 return fndecl;
782 /* Transform *SPAWN_P, a spawned CALL_EXPR, to gimple. *SPAWN_P can be a
783 CALL_EXPR, INIT_EXPR or MODIFY_EXPR. Returns GS_OK if everything is fine,
784 and GS_UNHANDLED, otherwise. */
787 gimplify_cilk_spawn (tree *spawn_p)
789 tree expr = *spawn_p;
790 tree function, call1, call2, new_args;
791 tree ii_args = NULL_TREE;
792 int total_args = 0, ii = 0;
793 tree *arg_array;
794 tree setjmp_cond_expr = NULL_TREE;
795 tree setjmp_expr, spawn_expr, setjmp_value = NULL_TREE;
797 cfun->calls_cilk_spawn = 1;
798 cfun->is_cilk_function = 1;
800 /* Remove CLEANUP_POINT_EXPR and EXPR_STMT from *spawn_p. */
801 while (TREE_CODE (expr) == CLEANUP_POINT_EXPR
802 || TREE_CODE (expr) == EXPR_STMT)
803 expr = TREE_OPERAND (expr, 0);
805 new_args = NULL;
806 function = create_cilk_wrapper (expr, &new_args);
808 /* This should give the number of parameters. */
809 total_args = list_length (new_args);
810 if (total_args)
811 arg_array = XNEWVEC (tree, total_args);
812 else
813 arg_array = NULL;
815 ii_args = new_args;
816 for (ii = 0; ii < total_args; ii++)
818 arg_array[ii] = TREE_VALUE (ii_args);
819 ii_args = TREE_CHAIN (ii_args);
822 TREE_USED (function) = 1;
823 rest_of_decl_compilation (function, 0, 0);
825 call1 = cilk_call_setjmp (cfun->cilk_frame_decl);
827 if (arg_array == NULL || *arg_array == NULL_TREE)
828 call2 = build_call_expr (function, 0);
829 else
830 call2 = build_call_expr_loc_array (EXPR_LOCATION (*spawn_p), function,
831 total_args, arg_array);
832 *spawn_p = alloc_stmt_list ();
833 tree f_ptr_type = build_pointer_type (TREE_TYPE (cfun->cilk_frame_decl));
834 tree frame_ptr = build1 (ADDR_EXPR, f_ptr_type, cfun->cilk_frame_decl);
835 tree save_fp = build_call_expr (cilk_save_fp_fndecl, 1, frame_ptr);
836 append_to_statement_list (save_fp, spawn_p);
837 setjmp_value = create_tmp_var (TREE_TYPE (call1));
838 setjmp_expr = fold_build2 (MODIFY_EXPR, void_type_node, setjmp_value, call1);
840 append_to_statement_list_force (setjmp_expr, spawn_p);
842 setjmp_cond_expr = fold_build2 (EQ_EXPR, TREE_TYPE (call1), setjmp_value,
843 build_int_cst (TREE_TYPE (call1), 0));
844 spawn_expr = fold_build3 (COND_EXPR, void_type_node, setjmp_cond_expr,
845 call2, build_empty_stmt (EXPR_LOCATION (call1)));
846 append_to_statement_list (spawn_expr, spawn_p);
848 free (arg_array);
849 return GS_OK;
852 /* Make the frames necessary for a spawn call. */
854 tree
855 make_cilk_frame (tree fn)
857 struct function *f = DECL_STRUCT_FUNCTION (fn);
858 tree decl;
860 if (f->cilk_frame_decl)
861 return f->cilk_frame_decl;
863 decl = build_decl (EXPR_LOCATION (fn), VAR_DECL, NULL_TREE,
864 cilk_frame_type_decl);
865 DECL_CONTEXT (decl) = fn;
866 DECL_SEEN_IN_BIND_EXPR_P (decl) = 1;
867 f->cilk_frame_decl = decl;
868 return decl;
871 /* Add a new variable, VAR to a variable list in WD->DECL_MAP. HOW indicates
872 whether the variable is previously defined, currently defined, or a variable
873 that is being written to. */
875 static void
876 add_variable (struct wrapper_data *wd, tree var, enum add_variable_type how)
878 tree *valp = wd->decl_map->get (var);
879 if (valp)
881 tree val = (tree) *valp;
882 /* If the variable is local, do nothing. */
883 if (val == error_mark_node)
884 return;
885 /* If the variable was entered with itself as value,
886 meaning it belongs to an outer scope, do not alter
887 the value. */
888 if (val == var)
889 return;
890 /* A statement expression may cause a variable to be
891 bound twice, once in BIND_EXPR and again in a
892 DECL_EXPR. That case caused a return in the
893 test above. Any other duplicate definition is
894 an error. */
895 gcc_assert (how != ADD_BIND);
896 if (how != ADD_WRITE)
897 return;
898 /* This variable might have been entered as read but is now written. */
899 *valp = var;
900 wd->nested = true;
901 return;
903 else
905 tree val = NULL_TREE;
907 /* Nested function rewriting silently discards hard register
908 assignments for function scope variables, and they wouldn't
909 work anyway. Warn here. This misses one case: if the
910 register variable is used as the loop bound or increment it
911 has already been added to the map. */
912 if ((how != ADD_BIND) && VAR_P (var)
913 && !DECL_EXTERNAL (var) && DECL_HARD_REGISTER (var))
914 warning (0, "register assignment ignored for %qD used in Cilk block",
915 var);
917 switch (how)
919 /* ADD_BIND means always make a fresh new variable. */
920 case ADD_BIND:
921 val = error_mark_node;
922 break;
923 /* ADD_READ means
924 1. For cilk_for, refer to the outer scope definition as-is
925 2. For a spawned block, take a scalar in an rgument
926 and otherwise refer to the outer scope definition as-is.
927 3. For a spawned call, take a scalar in an argument. */
928 case ADD_READ:
929 switch (wd->type)
931 case CILK_BLOCK_FOR:
932 val = var;
933 break;
934 case CILK_BLOCK_SPAWN:
935 if (TREE_ADDRESSABLE (var))
937 val = var;
938 wd->nested = true;
939 break;
941 val = integer_zero_node;
942 break;
944 break;
945 case ADD_WRITE:
946 switch (wd->type)
948 case CILK_BLOCK_FOR:
949 val = var;
950 wd->nested = true;
951 break;
952 case CILK_BLOCK_SPAWN:
953 if (TREE_ADDRESSABLE (var))
954 val = integer_one_node;
955 else
957 val = var;
958 wd->nested = true;
960 break;
963 wd->decl_map->put (var, val);
967 /* Find the variables referenced in an expression T. This does not avoid
968 duplicates because a variable may be read in one context and written in
969 another. HOW describes the context in which the reference is seen. If
970 NESTED is true a nested function is being generated and variables in the
971 original context should not be remapped. */
973 static void
974 extract_free_variables (tree t, struct wrapper_data *wd,
975 enum add_variable_type how)
977 if (t == NULL_TREE)
978 return;
980 enum tree_code code = TREE_CODE (t);
981 bool is_expr = IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code));
983 if (is_expr)
984 extract_free_variables (TREE_TYPE (t), wd, ADD_READ);
986 switch (code)
988 case ERROR_MARK:
989 case IDENTIFIER_NODE:
990 case VOID_CST:
991 case INTEGER_CST:
992 case REAL_CST:
993 case FIXED_CST:
994 case STRING_CST:
995 case BLOCK:
996 case PLACEHOLDER_EXPR:
997 case FIELD_DECL:
998 case VOID_TYPE:
999 case REAL_TYPE:
1000 /* These do not contain variable references. */
1001 return;
1003 case SSA_NAME:
1004 /* Currently we don't see SSA_NAME. */
1005 extract_free_variables (SSA_NAME_VAR (t), wd, how);
1006 return;
1008 case LABEL_DECL:
1009 /* This might be a reference to a label outside the Cilk block,
1010 which is an error, or a reference to a label in the Cilk block
1011 that we haven't seen yet. We can't tell. Ignore it. An
1012 invalid use will cause an error later in copy_decl_for_cilk. */
1013 return;
1015 case RESULT_DECL:
1016 if (wd->type != CILK_BLOCK_SPAWN)
1017 TREE_ADDRESSABLE (t) = 1;
1018 /* FALLTHRU */
1019 case VAR_DECL:
1020 case PARM_DECL:
1021 if (!is_global_var (t))
1022 add_variable (wd, t, how);
1023 return;
1025 case NON_LVALUE_EXPR:
1026 case CONVERT_EXPR:
1027 case NOP_EXPR:
1028 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_READ);
1029 return;
1031 case VEC_INIT_EXPR:
1032 case INIT_EXPR:
1033 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_BIND);
1034 extract_free_variables (TREE_OPERAND (t, 1), wd, ADD_READ);
1035 return;
1037 case MODIFY_EXPR:
1038 case PREDECREMENT_EXPR:
1039 case PREINCREMENT_EXPR:
1040 case POSTDECREMENT_EXPR:
1041 case POSTINCREMENT_EXPR:
1042 /* These write their result. */
1043 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_WRITE);
1044 extract_free_variables (TREE_OPERAND (t, 1), wd, ADD_READ);
1045 return;
1047 case ADDR_EXPR:
1048 /* This might modify its argument, and the value needs to be
1049 passed by reference in any case to preserve identity and
1050 type if is a promoting type. In the case of a nested loop
1051 just notice that we touch the variable. It will already
1052 be addressable, and marking it modified will cause a spurious
1053 warning about writing the control variable. */
1054 if (wd->type != CILK_BLOCK_SPAWN)
1055 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_READ);
1056 else
1057 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_WRITE);
1058 return;
1060 case ARRAY_REF:
1061 /* Treating ARRAY_REF and BIT_FIELD_REF identically may
1062 mark the array as written but the end result is correct
1063 because the array is passed by pointer anyway. */
1064 case BIT_FIELD_REF:
1065 /* Propagate the access type to the object part of which
1066 is being accessed here. As for ADDR_EXPR, don't do this
1067 in a nested loop, unless the access is to a fixed index. */
1068 if (wd->type != CILK_BLOCK_FOR || TREE_CONSTANT (TREE_OPERAND (t, 1)))
1069 extract_free_variables (TREE_OPERAND (t, 0), wd, how);
1070 else
1071 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_READ);
1072 extract_free_variables (TREE_OPERAND (t, 1), wd, ADD_READ);
1073 extract_free_variables (TREE_OPERAND (t, 2), wd, ADD_READ);
1074 return;
1076 case TREE_LIST:
1077 extract_free_variables (TREE_PURPOSE (t), wd, ADD_READ);
1078 extract_free_variables (TREE_VALUE (t), wd, ADD_READ);
1079 extract_free_variables (TREE_CHAIN (t), wd, ADD_READ);
1080 return;
1082 case TREE_VEC:
1084 int len = TREE_VEC_LENGTH (t);
1085 int i;
1086 for (i = 0; i < len; i++)
1087 extract_free_variables (TREE_VEC_ELT (t, i), wd, ADD_READ);
1088 return;
1091 case VECTOR_CST:
1093 unsigned ii = 0;
1094 for (ii = 0; ii < VECTOR_CST_NELTS (t); ii++)
1095 extract_free_variables (VECTOR_CST_ELT (t, ii), wd, ADD_READ);
1096 break;
1099 case COMPLEX_CST:
1100 extract_free_variables (TREE_REALPART (t), wd, ADD_READ);
1101 extract_free_variables (TREE_IMAGPART (t), wd, ADD_READ);
1102 return;
1104 case BIND_EXPR:
1106 tree decl;
1107 for (decl = BIND_EXPR_VARS (t); decl; decl = TREE_CHAIN (decl))
1109 add_variable (wd, decl, ADD_BIND);
1110 /* A self-referential initialization is no problem because
1111 we already entered the variable into the map as local. */
1112 extract_free_variables (DECL_INITIAL (decl), wd, ADD_READ);
1113 extract_free_variables (DECL_SIZE (decl), wd, ADD_READ);
1114 extract_free_variables (DECL_SIZE_UNIT (decl), wd, ADD_READ);
1116 extract_free_variables (BIND_EXPR_BODY (t), wd, ADD_READ);
1117 return;
1120 case STATEMENT_LIST:
1122 tree_stmt_iterator i;
1123 for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
1124 extract_free_variables (*tsi_stmt_ptr (i), wd, ADD_READ);
1125 return;
1128 case TARGET_EXPR:
1130 extract_free_variables (TREE_OPERAND (t, 0), wd, ADD_BIND);
1131 extract_free_variables (TREE_OPERAND (t, 1), wd, ADD_READ);
1132 extract_free_variables (TREE_OPERAND (t, 2), wd, ADD_READ);
1133 if (TREE_OPERAND (t, 3) != TREE_OPERAND (t, 1))
1134 extract_free_variables (TREE_OPERAND (t, 3), wd, ADD_READ);
1135 return;
1138 case RETURN_EXPR:
1139 if (TREE_NO_WARNING (t))
1141 gcc_assert (errorcount);
1142 return;
1144 return;
1146 case DECL_EXPR:
1147 if (TREE_CODE (DECL_EXPR_DECL (t)) != TYPE_DECL)
1148 extract_free_variables (DECL_EXPR_DECL (t), wd, ADD_BIND);
1149 return;
1151 case INTEGER_TYPE:
1152 case ENUMERAL_TYPE:
1153 case BOOLEAN_TYPE:
1154 extract_free_variables (TYPE_MIN_VALUE (t), wd, ADD_READ);
1155 extract_free_variables (TYPE_MAX_VALUE (t), wd, ADD_READ);
1156 return;
1158 case POINTER_TYPE:
1159 extract_free_variables (TREE_TYPE (t), wd, ADD_READ);
1160 break;
1162 case ARRAY_TYPE:
1163 extract_free_variables (TREE_TYPE (t), wd, ADD_READ);
1164 extract_free_variables (TYPE_DOMAIN (t), wd, ADD_READ);
1165 return;
1167 case RECORD_TYPE:
1168 extract_free_variables (TYPE_FIELDS (t), wd, ADD_READ);
1169 return;
1171 case METHOD_TYPE:
1172 extract_free_variables (TYPE_ARG_TYPES (t), wd, ADD_READ);
1173 extract_free_variables (TYPE_METHOD_BASETYPE (t), wd, ADD_READ);
1174 return;
1176 case AGGR_INIT_EXPR:
1178 int len = 0;
1179 int ii = 0;
1180 extract_free_variables (TREE_OPERAND (t, 1), wd, ADD_READ);
1181 if (TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST)
1183 len = TREE_INT_CST_LOW (TREE_OPERAND (t, 0));
1185 for (ii = 3; ii < len; ii++)
1186 extract_free_variables (TREE_OPERAND (t, ii), wd, ADD_READ);
1187 extract_free_variables (TREE_TYPE (t), wd, ADD_READ);
1189 break;
1192 case CALL_EXPR:
1194 int len = 0;
1195 int ii = 0;
1196 if (TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST)
1198 len = TREE_INT_CST_LOW (TREE_OPERAND (t, 0));
1200 for (ii = 0; ii < len; ii++)
1201 extract_free_variables (TREE_OPERAND (t, ii), wd, ADD_READ);
1202 extract_free_variables (TREE_TYPE (t), wd, ADD_READ);
1204 break;
1207 case CONSTRUCTOR:
1209 unsigned HOST_WIDE_INT idx = 0;
1210 constructor_elt *ce;
1211 for (idx = 0; vec_safe_iterate (CONSTRUCTOR_ELTS (t), idx, &ce); idx++)
1212 extract_free_variables (ce->value, wd, ADD_READ);
1213 break;
1216 default:
1217 if (is_expr)
1219 int i, len;
1221 /* Walk over all the sub-trees of this operand. */
1222 len = TREE_CODE_LENGTH (code);
1224 /* Go through the subtrees. We need to do this in forward order so
1225 that the scope of a FOR_EXPR is handled properly. */
1226 for (i = 0; i < len; ++i)
1227 extract_free_variables (TREE_OPERAND (t, i), wd, ADD_READ);
1232 /* Add appropriate frames needed for a Cilk spawned function call, FNDECL.
1233 Returns the __cilkrts_stack_frame * variable. */
1235 tree
1236 insert_cilk_frame (tree fndecl)
1238 tree addr, body, enter, out, orig_body;
1239 location_t loc = EXPR_LOCATION (fndecl);
1241 if (!cfun || cfun->decl != fndecl)
1242 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
1244 tree decl = cfun->cilk_frame_decl;
1245 if (!decl)
1247 tree *saved_tree = &DECL_SAVED_TREE (fndecl);
1248 decl = make_cilk_frame (fndecl);
1249 add_local_decl (cfun, decl);
1251 addr = build1 (ADDR_EXPR, cilk_frame_ptr_type_decl, decl);
1252 enter = build_call_expr (cilk_enter_fndecl, 1, addr);
1253 out = create_cilk_function_exit (cfun->cilk_frame_decl, false, true);
1255 /* The new body will be:
1256 __cilkrts_enter_frame_1 (&sf);
1257 try {
1258 orig_body;
1260 finally {
1261 __cilkrts_pop_frame (&sf);
1262 __cilkrts_leave_frame (&sf);
1263 } */
1265 body = alloc_stmt_list ();
1266 orig_body = *saved_tree;
1268 if (TREE_CODE (orig_body) == BIND_EXPR)
1269 orig_body = BIND_EXPR_BODY (orig_body);
1271 append_to_statement_list (enter, &body);
1272 append_to_statement_list (build_stmt (loc, TRY_FINALLY_EXPR, orig_body,
1273 out), &body);
1274 if (TREE_CODE (*saved_tree) == BIND_EXPR)
1275 BIND_EXPR_BODY (*saved_tree) = body;
1276 else
1277 *saved_tree = body;
1279 return decl;
1282 /* Wraps CALL, a CALL_EXPR, into a CILK_SPAWN_STMT tree and returns it. */
1284 tree
1285 build_cilk_spawn (location_t loc, tree call)
1287 if (!cilk_set_spawn_marker (loc, call))
1288 return error_mark_node;
1289 tree spawn_stmt = build1 (CILK_SPAWN_STMT, TREE_TYPE (call), call);
1290 TREE_SIDE_EFFECTS (spawn_stmt) = 1;
1291 return spawn_stmt;
1294 /* Returns a tree of type CILK_SYNC_STMT. */
1296 tree
1297 build_cilk_sync (void)
1299 tree sync = build0 (CILK_SYNC_STMT, void_type_node);
1300 TREE_SIDE_EFFECTS (sync) = 1;
1301 return sync;
1304 /* Helper for contains_cilk_spawn_stmt, callback for walk_tree. Return
1305 non-null tree if TP contains CILK_SPAWN_STMT. */
1307 static tree
1308 contains_cilk_spawn_stmt_walker (tree *tp, int *, void *)
1310 if (TREE_CODE (*tp) == CILK_SPAWN_STMT)
1311 return *tp;
1312 else
1313 return NULL_TREE;
1316 /* Returns true if EXPR or any of its subtrees contain CILK_SPAWN_STMT
1317 node. */
1319 bool
1320 contains_cilk_spawn_stmt (tree expr)
1322 return walk_tree (&expr, contains_cilk_spawn_stmt_walker, NULL, NULL)
1323 != NULL_TREE;
1326 /* Return a error location for EXPR if LOC is not set. */
1328 static location_t
1329 get_error_location (tree expr, location_t loc)
1331 if (loc == UNKNOWN_LOCATION)
1333 if (TREE_CODE (expr) == MODIFY_EXPR)
1334 expr = TREE_OPERAND (expr, 0);
1335 loc = EXPR_LOCATION (expr);
1337 return loc;
1340 /* Check that no array notation or spawn statement is in EXPR.
1341 If not true generate an error at LOC for ARRAY_GMSGID or
1342 SPAWN_MSGID. */
1344 bool
1345 check_no_cilk (tree expr, const char *array_msgid, const char *spawn_msgid,
1346 location_t loc)
1348 if (!flag_cilkplus)
1349 return false;
1350 if (contains_array_notation_expr (expr))
1352 loc = get_error_location (expr, loc);
1353 error_at (loc, array_msgid);
1354 return true;
1356 if (walk_tree (&expr, contains_cilk_spawn_stmt_walker, NULL, NULL))
1358 loc = get_error_location (expr, loc);
1359 error_at (loc, spawn_msgid);
1360 return true;
1362 return false;