* sv.po: Update.
[official-gcc.git] / gcc / cp / cp-cilkplus.c
blob3b6cda2bcd07703bd29a021b305a53832eb739a8
1 /* This file is part of the Intel(R) Cilk(TM) Plus support
2 This file contains routines to handle Cilk Plus specific
3 routines for the C++ Compiler.
4 Copyright (C) 2013-2016 Free Software Foundation, Inc.
5 Contributed by Aldy Hernandez <aldyh@redhat.com>.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
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 "cp-tree.h"
27 #include "tree-iterator.h"
28 #include "cilk.h"
30 /* Callback for cp_walk_tree to validate the body of a pragma simd loop
31 or _cilk_for loop.
33 This function is passed in as a function pointer to walk_tree. *TP is
34 the current tree pointer, *WALK_SUBTREES is set to 0 by this function if
35 recursing into TP's subtrees is unnecessary. *DATA is a bool variable that
36 is set to false if an error has occured. */
38 static tree
39 cpp_validate_cilk_plus_loop_aux (tree *tp, int *walk_subtrees, void *data)
41 bool *valid = (bool *) data;
43 if (!tp || !*tp)
44 return NULL_TREE;
46 location_t loc = EXPR_LOCATION (*tp);
47 if (TREE_CODE (*tp) == THROW_EXPR)
49 error_at (loc, "throw expressions are not allowed inside loops "
50 "marked with pragma simd");
51 *walk_subtrees = 0;
52 *valid = false;
54 else if (TREE_CODE (*tp) == TRY_BLOCK)
56 error_at (loc, "try statements are not allowed inside loops marked "
57 "with #pragma simd");
58 *valid = false;
59 *walk_subtrees = 0;
61 return NULL_TREE;
65 /* Walks through all the subtrees of BODY using walk_tree to make sure
66 invalid statements/expressions are not found inside BODY. Returns
67 false if any invalid statements are found. */
69 bool
70 cpp_validate_cilk_plus_loop (tree body)
72 bool valid = true;
73 cp_walk_tree (&body, cpp_validate_cilk_plus_loop_aux,
74 (void *) &valid, NULL);
75 return valid;
78 /* Sets the EXCEPTION bit (0x10) in the FRAME.flags field. */
80 static tree
81 set_cilk_except_flag (tree frame)
83 tree flags = cilk_dot (frame, CILK_TI_FRAME_FLAGS, 0);
85 flags = build2 (MODIFY_EXPR, void_type_node, flags,
86 build2 (BIT_IOR_EXPR, TREE_TYPE (flags), flags,
87 build_int_cst (TREE_TYPE (flags),
88 CILK_FRAME_EXCEPTING)));
89 return flags;
92 /* Sets the frame.EXCEPT_DATA field to the head of the exception pointer. */
94 static tree
95 set_cilk_except_data (tree frame)
97 tree except_data = cilk_dot (frame, CILK_TI_FRAME_EXCEPTION, 0);
98 tree uresume_fn = builtin_decl_implicit (BUILT_IN_EH_POINTER);
99 tree ret_expr;
100 uresume_fn = build_call_expr (uresume_fn, 1,
101 build_int_cst (integer_type_node, 0));
102 ret_expr = build2 (MODIFY_EXPR, void_type_node, except_data, uresume_fn);
103 return ret_expr;
106 /* Installs BODY into function FNDECL with appropriate exception handling
107 code. WD holds information of wrapper function used to pass into the
108 outlining function, cilk_outline. */
110 void
111 cilk_install_body_with_frame_cleanup (tree fndecl, tree orig_body, void *wd)
113 tree frame = make_cilk_frame (fndecl);
114 tree dtor = create_cilk_function_exit (frame, false, false);
115 add_local_decl (cfun, frame);
117 cfun->language = ggc_cleared_alloc<language_function> ();
119 location_t loc = EXPR_LOCATION (orig_body);
120 tree list = alloc_stmt_list ();
121 DECL_SAVED_TREE (fndecl) = list;
122 tree fptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (frame)), frame);
123 tree body = cilk_install_body_pedigree_operations (fptr);
124 gcc_assert (TREE_CODE (body) == STATEMENT_LIST);
125 tree detach_expr = build_call_expr (cilk_detach_fndecl, 1, fptr);
126 append_to_statement_list (detach_expr, &body);
127 cilk_outline (fndecl, &orig_body, (struct wrapper_data *) wd);
128 append_to_statement_list (orig_body, &body);
129 if (flag_exceptions)
131 tree except_flag = set_cilk_except_flag (frame);
132 tree except_data = set_cilk_except_data (frame);
133 tree catch_list = alloc_stmt_list ();
134 append_to_statement_list (except_flag, &catch_list);
135 append_to_statement_list (except_data, &catch_list);
136 body = create_try_catch_expr (body, catch_list);
138 append_to_statement_list (build_stmt (loc, TRY_FINALLY_EXPR, body, dtor),
139 &list);