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-2014 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)
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/>. */
25 #include "coretypes.h"
27 #include "diagnostic-core.h"
28 #include "tree-iterator.h"
29 #include "tree-inline.h" /* for copy_tree_body_r. */
33 /* Callback for cp_walk_tree to validate the body of a pragma simd loop
36 This function is passed in as a function pointer to walk_tree. *TP is
37 the current tree pointer, *WALK_SUBTREES is set to 0 by this function if
38 recursing into TP's subtrees is unnecessary. *DATA is a bool variable that
39 is set to false if an error has occured. */
42 cpp_validate_cilk_plus_loop_aux (tree
*tp
, int *walk_subtrees
, void *data
)
44 bool *valid
= (bool *) data
;
45 location_t loc
= EXPR_HAS_LOCATION (*tp
) ? EXPR_LOCATION (*tp
) :
51 if (TREE_CODE (*tp
) == THROW_EXPR
)
53 error_at (loc
, "throw expressions are not allowed inside loops "
54 "marked with pragma simd");
58 else if (TREE_CODE (*tp
) == TRY_BLOCK
)
60 error_at (loc
, "try statements are not allowed inside loops marked "
69 /* Walks through all the subtrees of BODY using walk_tree to make sure
70 invalid statements/expressions are not found inside BODY. Returns
71 false if any invalid statements are found. */
74 cpp_validate_cilk_plus_loop (tree body
)
77 cp_walk_tree (&body
, cpp_validate_cilk_plus_loop_aux
,
78 (void *) &valid
, NULL
);
82 /* Sets the EXCEPTION bit (0x10) in the FRAME.flags field. */
85 set_cilk_except_flag (tree frame
)
87 tree flags
= cilk_dot (frame
, CILK_TI_FRAME_FLAGS
, 0);
89 flags
= build2 (MODIFY_EXPR
, void_type_node
, flags
,
90 build2 (BIT_IOR_EXPR
, TREE_TYPE (flags
), flags
,
91 build_int_cst (TREE_TYPE (flags
),
92 CILK_FRAME_EXCEPTING
)));
96 /* Sets the frame.EXCEPT_DATA field to the head of the exception pointer. */
99 set_cilk_except_data (tree frame
)
101 tree except_data
= cilk_dot (frame
, CILK_TI_FRAME_EXCEPTION
, 0);
102 tree uresume_fn
= builtin_decl_implicit (BUILT_IN_EH_POINTER
);
104 uresume_fn
= build_call_expr (uresume_fn
, 1,
105 build_int_cst (integer_type_node
, 0));
106 ret_expr
= build2 (MODIFY_EXPR
, void_type_node
, except_data
, uresume_fn
);
110 /* Installs BODY into function FNDECL with appropriate exception handling
111 code. WD holds information of wrapper function used to pass into the
112 outlining function, cilk_outline. */
115 cilk_install_body_with_frame_cleanup (tree fndecl
, tree orig_body
, void *wd
)
117 tree frame
= make_cilk_frame (fndecl
);
118 tree dtor
= create_cilk_function_exit (frame
, false, false);
119 add_local_decl (cfun
, frame
);
121 cfun
->language
= ggc_cleared_alloc
<language_function
> ();
123 location_t loc
= EXPR_LOCATION (orig_body
);
124 tree list
= alloc_stmt_list ();
125 DECL_SAVED_TREE (fndecl
) = list
;
126 tree fptr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (frame
)), frame
);
127 tree body
= cilk_install_body_pedigree_operations (fptr
);
128 gcc_assert (TREE_CODE (body
) == STATEMENT_LIST
);
129 tree detach_expr
= build_call_expr (cilk_detach_fndecl
, 1, fptr
);
130 append_to_statement_list (detach_expr
, &body
);
131 cilk_outline (fndecl
, &orig_body
, (struct wrapper_data
*) wd
);
132 append_to_statement_list (orig_body
, &body
);
135 tree except_flag
= set_cilk_except_flag (frame
);
136 tree except_data
= set_cilk_except_data (frame
);
137 tree catch_list
= alloc_stmt_list ();
138 append_to_statement_list (except_flag
, &catch_list
);
139 append_to_statement_list (except_data
, &catch_list
);
140 body
= create_try_catch_expr (body
, catch_list
);
142 append_to_statement_list (build_stmt (loc
, TRY_FINALLY_EXPR
, body
, dtor
),