gcc/
[official-gcc.git] / gcc / cilk-common.c
blob8b358378799c75bedb95f5567d128bf29f39a9aa
1 /* This file is part of the Intel(R) Cilk(TM) Plus support
2 This file contains the CilkPlus Intrinsics
3 Copyright (C) 2013-2015 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 "hash-set.h"
27 #include "vec.h"
28 #include "input.h"
29 #include "alias.h"
30 #include "symtab.h"
31 #include "options.h"
32 #include "inchash.h"
33 #include "tree.h"
34 #include "fold-const.h"
35 #include "stringpool.h"
36 #include "stor-layout.h"
37 #include "langhooks.h"
38 #include "hashtab.h"
39 #include "tm.h"
40 #include "hard-reg-set.h"
41 #include "function.h"
42 #include "rtl.h"
43 #include "flags.h"
44 #include "statistics.h"
45 #include "insn-config.h"
46 #include "expmed.h"
47 #include "dojump.h"
48 #include "explow.h"
49 #include "calls.h"
50 #include "emit-rtl.h"
51 #include "varasm.h"
52 #include "stmt.h"
53 #include "expr.h"
54 #include "insn-codes.h"
55 #include "optabs.h"
56 #include "recog.h"
57 #include "tree-iterator.h"
58 #include "gimplify.h"
59 #include "cilk.h"
61 /* This structure holds all the important fields of the internal structures,
62 internal built-in functions, and Cilk-specific data types. Explanation of
63 all the these fielsd are given in cilk.h. */
64 tree cilk_trees[(int) CILK_TI_MAX];
66 /* Returns the value in structure FRAME pointed by the FIELD_NUMBER
67 (e.g. X.y).
68 FIELD_NUMBER is an index to the structure FRAME_PTR. For details
69 about these fields, refer to cilk_trees structure in cilk.h and
70 cilk_init_builtins function in this file. Returns a TREE that is the type
71 of the field represented by FIELD_NUMBER. If VOLATIL parameter is set
72 to true then the returning field is set as volatile. */
74 tree
75 cilk_dot (tree frame, int field_number, bool volatil)
77 tree field = cilk_trees[field_number];
78 field = fold_build3 (COMPONENT_REF, TREE_TYPE (field), frame, field,
79 NULL_TREE);
80 TREE_THIS_VOLATILE (field) = volatil;
81 return field;
84 /* Returns the address of a field in FRAME_PTR, pointed by FIELD_NUMBER.
85 (e.g. (&X)->y). Please see cilk_dot function for explanation of the
86 FIELD_NUMBER. Returns a tree that is the type of the field represented
87 by FIELD_NUMBER. If VOLATIL parameter is set to true then the returning
88 field is set as volatile. */
90 tree
91 cilk_arrow (tree frame_ptr, int field_number, bool volatil)
93 return cilk_dot (build_simple_mem_ref (frame_ptr),
94 field_number, volatil);
98 /* This function will add FIELD of type TYPE to a defined built-in
99 structure. *NAME is the name of the field to be added. */
101 static tree
102 add_field (const char *name, tree type, tree fields)
104 tree t = get_identifier (name);
105 tree field = build_decl (BUILTINS_LOCATION, FIELD_DECL, t, type);
106 TREE_CHAIN (field) = fields;
107 return field;
110 /* This function will define a built-in function of NAME, of type FNTYPE and
111 register it under the built-in function code CODE. If PUBLISH is set then
112 the declaration is pushed into the declaration list. CODE is the index
113 to the cilk_trees array. *NAME is the name of the function to be added. */
115 static tree
116 install_builtin (const char *name, tree fntype, enum built_in_function code,
117 bool publish)
119 tree fndecl = build_fn_decl (name, fntype);
120 DECL_BUILT_IN_CLASS (fndecl) = BUILT_IN_NORMAL;
121 DECL_FUNCTION_CODE (fndecl) = code;
122 if (publish)
124 tree t = lang_hooks.decls.pushdecl (fndecl);
125 if (t)
126 fndecl = t;
128 set_builtin_decl (code, fndecl, true);
129 return fndecl;
132 /* Returns a FUNCTION_DECL of type TYPE whose name is *NAME. */
134 static tree
135 declare_cilk_for_builtin (const char *name, tree type,
136 enum built_in_function code)
138 tree cb, ft, fn;
140 cb = build_function_type_list (void_type_node,
141 ptr_type_node, type, type,
142 NULL_TREE);
143 cb = build_pointer_type (cb);
144 ft = build_function_type_list (void_type_node,
145 cb, ptr_type_node, type,
146 integer_type_node, NULL_TREE);
147 fn = install_builtin (name, ft, code, false);
148 TREE_NOTHROW (fn) = 0;
150 return fn;
153 /* Creates and initializes all the built-in Cilk keywords functions and three
154 structures: __cilkrts_stack_frame, __cilkrts_pedigree and __cilkrts_worker.
155 Detailed information about __cilkrts_stack_frame and
156 __cilkrts_worker structures are given in libcilkrts/include/internal/abi.h.
157 __cilkrts_pedigree is described in libcilkrts/include/cilk/common.h. */
159 void
160 cilk_init_builtins (void)
162 /* Now build the following __cilkrts_pedigree struct:
163 struct __cilkrts_pedigree {
164 uint64_t rank;
165 struct __cilkrts_pedigree *parent;
166 } */
168 tree pedigree_type = lang_hooks.types.make_type (RECORD_TYPE);
169 tree pedigree_ptr = build_pointer_type (pedigree_type);
170 tree field = add_field ("rank", uint64_type_node, NULL_TREE);
171 cilk_trees[CILK_TI_PEDIGREE_RANK] = field;
172 field = add_field ("parent", pedigree_ptr, field);
173 cilk_trees[CILK_TI_PEDIGREE_PARENT] = field;
174 finish_builtin_struct (pedigree_type, "__cilkrts_pedigree_GCC", field,
175 NULL_TREE);
176 lang_hooks.types.register_builtin_type (pedigree_type,
177 "__cilkrts_pedigree_t");
178 cilk_pedigree_type_decl = pedigree_type;
180 /* Build the Cilk Stack Frame:
181 struct __cilkrts_stack_frame {
182 uint32_t flags;
183 uint32_t size;
184 struct __cilkrts_stack_frame *call_parent;
185 __cilkrts_worker *worker;
186 void *except_data;
187 void *ctx[4];
188 uint32_t mxcsr;
189 uint16_t fpcsr;
190 uint16_t reserved;
191 __cilkrts_pedigree pedigree;
192 }; */
194 tree frame = lang_hooks.types.make_type (RECORD_TYPE);
195 tree frame_ptr = build_pointer_type (frame);
196 tree worker_type = lang_hooks.types.make_type (RECORD_TYPE);
197 tree worker_ptr = build_pointer_type (worker_type);
198 tree s_type_node = build_int_cst (size_type_node, 4);
200 tree flags = add_field ("flags", uint32_type_node, NULL_TREE);
201 tree size = add_field ("size", uint32_type_node, flags);
202 tree parent = add_field ("call_parent", frame_ptr, size);
203 tree worker = add_field ("worker", worker_ptr, parent);
204 tree except = add_field ("except_data", frame_ptr, worker);
205 tree context = add_field ("ctx",
206 build_array_type (ptr_type_node,
207 build_index_type (s_type_node)),
208 except);
209 tree mxcsr = add_field ("mxcsr", uint32_type_node, context);
210 tree fpcsr = add_field ("fpcsr", uint16_type_node, mxcsr);
211 tree reserved = add_field ("reserved", uint16_type_node, fpcsr);
212 tree pedigree = add_field ("pedigree", pedigree_type, reserved);
214 /* Now add them to a common structure whose fields are #defined to something
215 that is used at a later stage. */
216 cilk_trees[CILK_TI_FRAME_FLAGS] = flags;
217 cilk_trees[CILK_TI_FRAME_PARENT] = parent;
218 cilk_trees[CILK_TI_FRAME_WORKER] = worker;
219 cilk_trees[CILK_TI_FRAME_EXCEPTION] = except;
220 cilk_trees[CILK_TI_FRAME_CONTEXT] = context;
221 /* We don't care about reserved, so no need to store it in cilk_trees. */
222 cilk_trees[CILK_TI_FRAME_PEDIGREE] = pedigree;
223 TREE_ADDRESSABLE (frame) = 1;
225 finish_builtin_struct (frame, "__cilkrts_st_frame_GCC", pedigree, NULL_TREE);
226 cilk_frame_type_decl = frame;
227 lang_hooks.types.register_builtin_type (frame, "__cilkrts_frame_t");
229 cilk_frame_ptr_type_decl = build_qualified_type (frame_ptr,
230 TYPE_QUAL_VOLATILE);
231 /* Now let's do the following worker struct:
233 struct __cilkrts_worker {
234 __cilkrts_stack_frame *volatile *volatile tail;
235 __cilkrts_stack_frame *volatile *volatile head;
236 __cilkrts_stack_frame *volatile *volatile exc;
237 __cilkrts_stack_frame *volatile *volatile protected_tail;
238 __cilkrts_stack_frame *volatile *ltq_limit;
239 int32_t self;
240 global_state_t *g;
241 local_state *l;
242 cilkred_map *reducer_map;
243 __cilkrts_stack_frame *current_stack_frame;
244 void *reserved;
245 __cilkrts_worker_sysdep_state *sysdep;
246 __cilkrts_pedigree pedigree;
247 } */
249 tree fptr_volatil_type = build_qualified_type (frame_ptr, TYPE_QUAL_VOLATILE);
250 tree fptr_volatile_ptr = build_pointer_type (fptr_volatil_type);
251 tree fptr_vol_ptr_vol = build_qualified_type (fptr_volatile_ptr,
252 TYPE_QUAL_VOLATILE);
253 tree g = lang_hooks.types.make_type (RECORD_TYPE);
254 finish_builtin_struct (g, "__cilkrts_global_state", NULL_TREE, NULL_TREE);
255 tree l = lang_hooks.types.make_type (RECORD_TYPE);
256 finish_builtin_struct (l, "__cilkrts_local_state", NULL_TREE, NULL_TREE);
257 tree sysdep_t = lang_hooks.types.make_type (RECORD_TYPE);
258 finish_builtin_struct (sysdep_t, "__cilkrts_worker_sysdep_state", NULL_TREE,
259 NULL_TREE);
261 field = add_field ("tail", fptr_vol_ptr_vol, NULL_TREE);
262 cilk_trees[CILK_TI_WORKER_TAIL] = field;
263 field = add_field ("head", fptr_vol_ptr_vol, field);
264 field = add_field ("exc", fptr_vol_ptr_vol, field);
265 field = add_field ("protected_tail", fptr_vol_ptr_vol, field);
266 field = add_field ("ltq_limit", fptr_volatile_ptr, field);
267 field = add_field ("self", integer_type_node, field);
268 field = add_field ("g", build_pointer_type (g), field);
269 field = add_field ("l", build_pointer_type (g), field);
270 field = add_field ("reducer_map", ptr_type_node, field);
271 field = add_field ("current_stack_frame", frame_ptr, field);
272 cilk_trees[CILK_TI_WORKER_CUR] = field;
273 field = add_field ("saved_protected_tail", fptr_volatile_ptr, field);
274 field = add_field ("sysdep", build_pointer_type (sysdep_t), field);
275 field = add_field ("pedigree", pedigree_type, field);
276 cilk_trees[CILK_TI_WORKER_PEDIGREE] = field;
277 finish_builtin_struct (worker_type, "__cilkrts_worker_GCC", field,
278 NULL_TREE);
280 tree fptr_arglist = tree_cons (NULL_TREE, frame_ptr, void_list_node);
281 tree fptr_fun = build_function_type (void_type_node, fptr_arglist);
283 /* void __cilkrts_enter_frame_1 (__cilkrts_stack_frame *); */
284 cilk_enter_fndecl = install_builtin ("__cilkrts_enter_frame_1", fptr_fun,
285 BUILT_IN_CILK_ENTER_FRAME, false);
287 /* void __cilkrts_enter_frame_fast_1 (__cilkrts_stack_frame *); */
288 cilk_enter_fast_fndecl =
289 install_builtin ("__cilkrts_enter_frame_fast_1", fptr_fun,
290 BUILT_IN_CILK_ENTER_FRAME_FAST, false);
292 /* void __cilkrts_pop_frame (__cilkrts_stack_frame *); */
293 cilk_pop_fndecl = install_builtin ("__cilkrts_pop_frame", fptr_fun,
294 BUILT_IN_CILK_POP_FRAME, false);
296 /* void __cilkrts_leave_frame (__cilkrts_stack_frame *); */
297 cilk_leave_fndecl = install_builtin ("__cilkrts_leave_frame", fptr_fun,
298 BUILT_IN_CILK_LEAVE_FRAME, false);
300 /* void __cilkrts_sync (__cilkrts_stack_frame *); */
301 cilk_sync_fndecl = install_builtin ("__cilkrts_sync", fptr_fun,
302 BUILT_IN_CILK_SYNC, false);
304 /* void __cilkrts_detach (__cilkrts_stack_frame *); */
305 cilk_detach_fndecl = install_builtin ("__cilkrts_detach", fptr_fun,
306 BUILT_IN_CILK_DETACH, false);
308 /* __cilkrts_rethrow (struct stack_frame *); */
309 cilk_rethrow_fndecl = install_builtin ("__cilkrts_rethrow", fptr_fun,
310 BUILT_IN_CILK_RETHROW, false);
311 TREE_NOTHROW (cilk_rethrow_fndecl) = 0;
313 /* __cilkrts_save_fp_ctrl_state (__cilkrts_stack_frame *); */
314 cilk_save_fp_fndecl = install_builtin ("__cilkrts_save_fp_ctrl_state",
315 fptr_fun, BUILT_IN_CILK_SAVE_FP,
316 false);
317 /* __cilkrts_cilk_for_32 (...); */
318 cilk_for_32_fndecl = declare_cilk_for_builtin ("__cilkrts_cilk_for_32",
319 unsigned_intSI_type_node,
320 BUILT_IN_CILK_FOR_32);
321 /* __cilkrts_cilk_for_64 (...); */
322 cilk_for_64_fndecl = declare_cilk_for_builtin ("__cilkrts_cilk_for_64",
323 unsigned_intDI_type_node,
324 BUILT_IN_CILK_FOR_64);
327 /* Get the appropriate frame arguments for CALL that is of type CALL_EXPR. */
329 static tree
330 get_frame_arg (tree call)
332 tree arg, argtype;
334 gcc_assert (call_expr_nargs (call) >= 1);
336 arg = CALL_EXPR_ARG (call, 0);
337 argtype = TREE_TYPE (arg);
338 gcc_assert (TREE_CODE (argtype) == POINTER_TYPE);
340 argtype = TREE_TYPE (argtype);
342 /* If it is passed in as an address, then just use the value directly
343 since the function is inlined. */
344 if (TREE_CODE (arg) == ADDR_EXPR)
345 return TREE_OPERAND (arg, 0);
346 return arg;
349 /* Expands the __cilkrts_pop_frame function call stored in EXP. */
351 void
352 expand_builtin_cilk_pop_frame (tree exp)
354 tree frame = get_frame_arg (exp);
355 tree parent = cilk_dot (frame, CILK_TI_FRAME_PARENT, 0);
357 tree clear_parent = build2 (MODIFY_EXPR, void_type_node, parent,
358 build_int_cst (TREE_TYPE (parent), 0));
359 expand_expr (clear_parent, const0_rtx, VOIDmode, EXPAND_NORMAL);
361 /* During LTO, the is_cilk_function flag gets cleared.
362 If __cilkrts_pop_frame is called, then this definitely must be a
363 cilk function. */
364 if (cfun)
365 cfun->is_cilk_function = 1;
368 /* Expands the cilk_detach function call stored in EXP. */
370 void
371 expand_builtin_cilk_detach (tree exp)
373 rtx_insn *insn;
374 tree fptr = get_frame_arg (exp);
376 if (fptr == NULL_TREE)
377 return;
379 tree parent = cilk_dot (fptr, CILK_TI_FRAME_PARENT, 0);
380 tree worker = cilk_dot (fptr, CILK_TI_FRAME_WORKER, 0);
381 tree tail = cilk_arrow (worker, CILK_TI_WORKER_TAIL, 1);
383 rtx wreg = expand_expr (worker, NULL_RTX, Pmode, EXPAND_NORMAL);
384 if (GET_CODE (wreg) != REG)
385 wreg = copy_to_reg (wreg);
386 rtx preg = expand_expr (parent, NULL_RTX, Pmode, EXPAND_NORMAL);
388 /* TMP <- WORKER.TAIL
389 *TMP <- PARENT
390 TMP <- TMP + 1
391 WORKER.TAIL <- TMP */
393 HOST_WIDE_INT worker_tail_offset =
394 tree_to_shwi (DECL_FIELD_OFFSET (cilk_trees[CILK_TI_WORKER_TAIL])) +
395 tree_to_shwi (DECL_FIELD_BIT_OFFSET (cilk_trees[CILK_TI_WORKER_TAIL])) /
396 BITS_PER_UNIT;
397 rtx tmem0 = gen_rtx_MEM (Pmode,
398 plus_constant (Pmode, wreg, worker_tail_offset));
399 set_mem_attributes (tmem0, tail, 0);
400 MEM_NOTRAP_P (tmem0) = 1;
401 gcc_assert (MEM_VOLATILE_P (tmem0));
402 rtx treg = copy_to_mode_reg (Pmode, tmem0);
403 rtx tmem1 = gen_rtx_MEM (Pmode, treg);
404 set_mem_attributes (tmem1, TREE_TYPE (TREE_TYPE (tail)), 0);
405 MEM_NOTRAP_P (tmem1) = 1;
406 emit_move_insn (tmem1, preg);
407 emit_move_insn (treg, plus_constant (Pmode, treg, GET_MODE_SIZE (Pmode)));
409 /* There is a release barrier (st8.rel, membar #StoreStore,
410 sfence, lwsync, etc.) between the two stores. On x86
411 normal volatile stores have proper semantics; the sfence
412 would only be needed for nontemporal stores (which we
413 could generate using the storent optab, for no benefit
414 in this case).
416 The predicate may return false even for a REG if this is
417 the limited release operation that only stores 0. */
418 enum insn_code icode = direct_optab_handler (sync_lock_release_optab, Pmode);
419 if (icode != CODE_FOR_nothing
420 && insn_data[icode].operand[1].predicate (treg, Pmode)
421 && (insn = GEN_FCN (icode) (tmem0, treg)) != NULL_RTX)
422 emit_insn (insn);
423 else
424 emit_move_insn (tmem0, treg);
426 /* The memory barrier inserted above should not prevent
427 the load of flags from being moved before the stores,
428 but in practice it does because it is implemented with
429 unspec_volatile. In-order RISC machines should
430 explicitly load flags earlier. */
432 tree flags = cilk_dot (fptr, CILK_TI_FRAME_FLAGS, 0);
433 expand_expr (build2 (MODIFY_EXPR, void_type_node, flags,
434 build2 (BIT_IOR_EXPR, TREE_TYPE (flags), flags,
435 build_int_cst (TREE_TYPE (flags),
436 CILK_FRAME_DETACHED))),
437 const0_rtx, VOIDmode, EXPAND_NORMAL);
440 /* Returns a setjmp CALL_EXPR with FRAME->context as its parameter. */
442 tree
443 cilk_call_setjmp (tree frame)
445 tree c = cilk_dot (frame, CILK_TI_FRAME_CONTEXT, false);
446 c = build1 (ADDR_EXPR, build_pointer_type (ptr_type_node), c);
447 return build_call_expr (builtin_decl_implicit (BUILT_IN_SETJMP), 1, c);
450 /* This function will expand the _Cilk_sync keyword. */
452 static tree
453 expand_cilk_sync (void)
455 tree frame = cfun->cilk_frame_decl;
457 /* Cilk_sync is converted to the following code:
459 sf.pedigree = sf.worker->pedigree;
460 if (frame.flags & CILK_FRAME_UNSYNCHED)
462 __cilkrts_save_fp_state (&sf);
463 if (!builtin_setjmp (sf.ctx)
464 __cilkrts_sync (&sf);
465 else
466 if (sf.flags & CILK_FRAME_EXCEPTING)
467 __cilkrts_rethrow (&sf);
469 sf.worker->pedigree.rank = sf.worker->pedigree.rank + 1; */
471 tree flags = cilk_dot (frame, CILK_TI_FRAME_FLAGS, false);
473 tree unsynched = fold_build2 (BIT_AND_EXPR, TREE_TYPE (flags), flags,
474 build_int_cst (TREE_TYPE (flags),
475 CILK_FRAME_UNSYNCHED));
477 unsynched = fold_build2 (NE_EXPR, TREE_TYPE (unsynched), unsynched,
478 build_int_cst (TREE_TYPE (unsynched), 0));
480 tree frame_addr = build1 (ADDR_EXPR, cilk_frame_ptr_type_decl, frame);
482 /* Check if exception (0x10) bit is set in the sf->flags. */
483 tree except_flag = fold_build2 (BIT_AND_EXPR, TREE_TYPE (flags), flags,
484 build_int_cst (TREE_TYPE (flags),
485 CILK_FRAME_EXCEPTING));
486 except_flag = fold_build2 (NE_EXPR, TREE_TYPE (except_flag), except_flag,
487 build_int_cst (TREE_TYPE (except_flag), 0));
489 /* If the exception flag is set then call the __cilkrts_rethrow (&sf). */
490 tree except_cond = fold_build3 (COND_EXPR, void_type_node, except_flag,
491 build_call_expr (cilk_rethrow_fndecl, 1,
492 frame_addr),
493 build_empty_stmt (EXPR_LOCATION (unsynched)));
495 tree sync_expr = build_call_expr (cilk_sync_fndecl, 1, frame_addr);
496 tree setjmp_expr = cilk_call_setjmp (frame);
497 setjmp_expr = fold_build2 (EQ_EXPR, TREE_TYPE (setjmp_expr), setjmp_expr,
498 build_int_cst (TREE_TYPE (setjmp_expr), 0));
500 setjmp_expr = fold_build3 (COND_EXPR, void_type_node, setjmp_expr,
501 sync_expr, except_cond);
502 tree sync_list = alloc_stmt_list ();
503 append_to_statement_list (build_call_expr (cilk_save_fp_fndecl, 1,
504 frame_addr), &sync_list);
505 append_to_statement_list (setjmp_expr, &sync_list);
506 tree sync = fold_build3 (COND_EXPR, void_type_node, unsynched, sync_list,
507 build_empty_stmt (EXPR_LOCATION (unsynched)));
508 tree parent_pedigree = cilk_dot (frame, CILK_TI_FRAME_PEDIGREE, false);
509 tree worker = cilk_dot (frame, CILK_TI_FRAME_WORKER, false);
510 tree worker_pedigree = cilk_arrow (worker, CILK_TI_WORKER_PEDIGREE, false);
511 tree assign_pedigree = fold_build2 (MODIFY_EXPR, void_type_node,
512 parent_pedigree, worker_pedigree);
513 tree w_ped_rank = cilk_dot (unshare_expr (worker_pedigree),
514 CILK_TI_PEDIGREE_RANK, false);
515 tree incr_ped_rank = fold_build2 (PLUS_EXPR, TREE_TYPE (w_ped_rank),
516 w_ped_rank,
517 build_one_cst (TREE_TYPE (w_ped_rank)));
518 incr_ped_rank = fold_build2 (MODIFY_EXPR, void_type_node, w_ped_rank,
519 incr_ped_rank);
520 tree ret_sync_exp = alloc_stmt_list ();
521 append_to_statement_list (assign_pedigree, &ret_sync_exp);
522 append_to_statement_list (sync, &ret_sync_exp);
523 append_to_statement_list (incr_ped_rank, &ret_sync_exp);
524 return ret_sync_exp;
527 /* Gimplifies the cilk_sync expression passed in *EXPR_P. Returns GS_ALL_DONE
528 when finished. */
530 void
531 gimplify_cilk_sync (tree *expr_p, gimple_seq *pre_p)
533 tree sync_expr = expand_cilk_sync ();
534 *expr_p = NULL_TREE;
535 gimplify_and_add (sync_expr, pre_p);