aarch64: Fix ls64 intrinsic availability
[official-gcc.git] / gcc / c-family / c-gimplify.cc
blob3e29766e092e30c29e16c7f23d0b1f02a704896a
1 /* Tree lowering pass. This pass gimplifies the tree representation built
2 by the C-based front ends. The structure of gimplified, or
3 language-independent, trees is dictated by the grammar described in this
4 file.
5 Copyright (C) 2002-2024 Free Software Foundation, Inc.
6 Lowering of expressions contributed by Sebastian Pop <s.pop@laposte.net>
7 Re-written to support lowering of whole function trees, documentation
8 and miscellaneous cleanups by Diego Novillo <dnovillo@redhat.com>
10 This file is part of GCC.
12 GCC is free software; you can redistribute it and/or modify it under
13 the terms of the GNU General Public License as published by the Free
14 Software Foundation; either version 3, or (at your option) any later
15 version.
17 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
18 WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 for more details.
22 You should have received a copy of the GNU General Public License
23 along with GCC; see the file COPYING3. If not see
24 <http://www.gnu.org/licenses/>. */
26 #include "config.h"
27 #include "system.h"
28 #include "coretypes.h"
29 #include "tm.h"
30 #include "function.h"
31 #include "basic-block.h"
32 #include "tree.h"
33 #include "tree-iterator.h"
34 #include "predict.h"
35 #include "gimple.h"
36 #include "cgraph.h"
37 #include "c-pretty-print.h"
38 #include "gimplify.h"
39 #include "langhooks.h"
40 #include "dumpfile.h"
41 #include "c-ubsan.h"
42 #include "tree-nested.h"
43 #include "context.h"
44 #include "tree-pass.h"
45 #include "internal-fn.h"
47 /* The gimplification pass converts the language-dependent trees
48 (ld-trees) emitted by the parser into language-independent trees
49 (li-trees) that are the target of SSA analysis and transformations.
51 Language-independent trees are based on the SIMPLE intermediate
52 representation used in the McCAT compiler framework:
54 "Designing the McCAT Compiler Based on a Family of Structured
55 Intermediate Representations,"
56 L. Hendren, C. Donawa, M. Emami, G. Gao, Justiani, and B. Sridharan,
57 Proceedings of the 5th International Workshop on Languages and
58 Compilers for Parallel Computing, no. 757 in Lecture Notes in
59 Computer Science, New Haven, Connecticut, pp. 406-420,
60 Springer-Verlag, August 3-5, 1992.
62 http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html
64 Basically, we walk down gimplifying the nodes that we encounter. As we
65 walk back up, we check that they fit our constraints, and copy them
66 into temporaries if not. */
68 /* Callback for c_genericize. */
70 static tree
71 ubsan_walk_array_refs_r (tree *tp, int *walk_subtrees, void *data)
73 hash_set<tree> *pset = (hash_set<tree> *) data;
75 if (TREE_CODE (*tp) == BIND_EXPR)
77 /* Since walk_tree doesn't call the callback function on the decls
78 in BIND_EXPR_VARS, we have to walk them manually, so we can avoid
79 instrumenting DECL_INITIAL of TREE_STATIC vars. */
80 *walk_subtrees = 0;
81 for (tree decl = BIND_EXPR_VARS (*tp); decl; decl = DECL_CHAIN (decl))
83 if (TREE_STATIC (decl))
84 continue;
85 walk_tree (&DECL_INITIAL (decl), ubsan_walk_array_refs_r, pset,
86 pset);
87 walk_tree (&DECL_SIZE (decl), ubsan_walk_array_refs_r, pset, pset);
88 walk_tree (&DECL_SIZE_UNIT (decl), ubsan_walk_array_refs_r, pset,
89 pset);
91 walk_tree (&BIND_EXPR_BODY (*tp), ubsan_walk_array_refs_r, pset, pset);
93 else if (TREE_CODE (*tp) == ADDR_EXPR
94 && TREE_CODE (TREE_OPERAND (*tp, 0)) == ARRAY_REF)
96 ubsan_maybe_instrument_array_ref (&TREE_OPERAND (*tp, 0), true);
97 /* Make sure ubsan_maybe_instrument_array_ref is not called again
98 on the ARRAY_REF, the above call might not instrument anything
99 as the index might be constant or masked, so ensure it is not
100 walked again and walk its subtrees manually. */
101 tree aref = TREE_OPERAND (*tp, 0);
102 pset->add (aref);
103 *walk_subtrees = 0;
104 walk_tree (&TREE_OPERAND (aref, 0), ubsan_walk_array_refs_r, pset, pset);
105 walk_tree (&TREE_OPERAND (aref, 1), ubsan_walk_array_refs_r, pset, pset);
106 walk_tree (&TREE_OPERAND (aref, 2), ubsan_walk_array_refs_r, pset, pset);
107 walk_tree (&TREE_OPERAND (aref, 3), ubsan_walk_array_refs_r, pset, pset);
109 else if (TREE_CODE (*tp) == ARRAY_REF)
110 ubsan_maybe_instrument_array_ref (tp, false);
111 else if (TREE_CODE (*tp) == MODIFY_EXPR)
113 /* Since r7-1900, we gimplify RHS before LHS. Consider
114 a[b] |= c;
115 wherein we can have a single shared tree a[b] in both LHS and RHS.
116 If we only instrument the LHS and the access is invalid, the program
117 could crash before emitting a UBSan error. So instrument the RHS
118 first. */
119 *walk_subtrees = 0;
120 walk_tree (&TREE_OPERAND (*tp, 1), ubsan_walk_array_refs_r, pset, pset);
121 walk_tree (&TREE_OPERAND (*tp, 0), ubsan_walk_array_refs_r, pset, pset);
123 return NULL_TREE;
126 /* Gimplification of statement trees. */
128 /* Local declarations. */
130 enum bc_t { bc_break = 0, bc_continue = 1 };
132 /* Stack of labels which are targets for "break" or "continue",
133 linked through TREE_CHAIN. */
134 static tree bc_label[2];
136 /* Begin a scope which can be exited by a break or continue statement. BC
137 indicates which.
139 Just creates a label with location LOCATION and pushes it into the current
140 context. */
142 static tree
143 begin_bc_block (enum bc_t bc, location_t location)
145 tree label = create_artificial_label (location);
146 DECL_CHAIN (label) = bc_label[bc];
147 bc_label[bc] = label;
148 if (bc == bc_break)
149 LABEL_DECL_BREAK (label) = true;
150 else
151 LABEL_DECL_CONTINUE (label) = true;
152 return label;
155 /* Finish a scope which can be exited by a break or continue statement.
156 LABEL was returned from the most recent call to begin_bc_block. BLOCK is
157 an expression for the contents of the scope.
159 If we saw a break (or continue) in the scope, append a LABEL_EXPR to
160 BLOCK. Otherwise, just forget the label. */
162 static void
163 finish_bc_block (tree *block, enum bc_t bc, tree label)
165 gcc_assert (label == bc_label[bc]);
167 if (TREE_USED (label))
168 append_to_statement_list (build1 (LABEL_EXPR, void_type_node, label),
169 block);
171 bc_label[bc] = DECL_CHAIN (label);
172 DECL_CHAIN (label) = NULL_TREE;
175 /* Allow saving and restoring break/continue state. */
177 void
178 save_bc_state (bc_state_t *state)
180 state->bc_label[bc_break] = bc_label[bc_break];
181 state->bc_label[bc_continue] = bc_label[bc_continue];
182 bc_label[bc_break] = NULL_TREE;
183 bc_label[bc_continue] = NULL_TREE;
186 void
187 restore_bc_state (bc_state_t *state)
189 gcc_assert (bc_label[bc_break] == NULL);
190 gcc_assert (bc_label[bc_continue] == NULL);
191 bc_label[bc_break] = state->bc_label[bc_break];
192 bc_label[bc_continue] = state->bc_label[bc_continue];
195 /* Get the LABEL_EXPR to represent a break or continue statement
196 in the current block scope. BC indicates which. */
198 static tree
199 get_bc_label (enum bc_t bc)
201 tree label = bc_label[bc];
202 gcc_assert (label);
204 /* Mark the label used for finish_bc_block. */
205 TREE_USED (label) = 1;
206 return label;
209 /* Return the location from EXPR, or OR_LOC if the former is unknown. */
211 location_t
212 expr_loc_or_loc (const_tree expr, location_t or_loc)
214 tree t = CONST_CAST_TREE (expr);
215 location_t loc = UNKNOWN_LOCATION;
216 if (t)
217 loc = EXPR_LOCATION (t);
218 if (loc == UNKNOWN_LOCATION)
219 loc = or_loc;
220 return loc;
223 /* Build a generic representation of one of the C loop forms. COND is the
224 loop condition or NULL_TREE. BODY is the (possibly compound) statement
225 controlled by the loop. INCR is the increment expression of a for-loop,
226 or NULL_TREE. COND_IS_FIRST indicates whether the condition is
227 evaluated before the loop body as in while and for loops, or after the
228 loop body as in do-while loops. */
230 static void
231 genericize_c_loop (tree *stmt_p, location_t start_locus, tree cond, tree body,
232 tree incr, bool cond_is_first, int *walk_subtrees,
233 void *data, walk_tree_fn func, walk_tree_lh lh)
235 tree blab, clab;
236 tree entry = NULL, exit = NULL, t;
237 tree stmt_list = NULL;
238 location_t cond_locus = expr_loc_or_loc (cond, start_locus);
239 location_t incr_locus = expr_loc_or_loc (incr, start_locus);
241 protected_set_expr_location_if_unset (incr, start_locus);
243 walk_tree_1 (&cond, func, data, NULL, lh);
244 walk_tree_1 (&incr, func, data, NULL, lh);
246 blab = begin_bc_block (bc_break, start_locus);
247 clab = begin_bc_block (bc_continue, start_locus);
249 walk_tree_1 (&body, func, data, NULL, lh);
250 *walk_subtrees = 0;
252 /* If condition is zero don't generate a loop construct. */
253 if (cond && integer_zerop (cond))
255 if (cond_is_first)
257 t = build1_loc (start_locus, GOTO_EXPR, void_type_node,
258 get_bc_label (bc_break));
259 append_to_statement_list (t, &stmt_list);
262 else
264 /* Expand to gotos. */
265 tree top = build1 (LABEL_EXPR, void_type_node,
266 create_artificial_label (start_locus));
268 /* If we have an exit condition, then we build an IF with gotos either
269 out of the loop, or to the top of it. If there's no exit condition,
270 then we just build a jump back to the top. */
271 exit = build1 (GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL (top));
273 if (cond && !integer_nonzerop (cond))
275 /* Canonicalize the loop condition to the end. This means
276 generating a branch to the loop condition. Reuse the
277 continue label, if there is no incr expression. */
278 if (cond_is_first)
280 if (incr)
282 entry = build1 (LABEL_EXPR, void_type_node,
283 create_artificial_label (start_locus));
284 t = build1_loc (start_locus, GOTO_EXPR, void_type_node,
285 LABEL_EXPR_LABEL (entry));
287 else
288 t = build1_loc (start_locus, GOTO_EXPR, void_type_node,
289 get_bc_label (bc_continue));
290 append_to_statement_list (t, &stmt_list);
293 t = build1 (GOTO_EXPR, void_type_node, get_bc_label (bc_break));
294 exit = fold_build3_loc (cond_locus,
295 COND_EXPR, void_type_node, cond, exit, t);
297 else
299 /* For the backward-goto's location of an unconditional loop
300 use the beginning of the body, or, if there is none, the
301 top of the loop. */
302 location_t loc = expr_loc_or_loc (expr_first (body),
303 start_locus);
304 SET_EXPR_LOCATION (exit, loc);
306 append_to_statement_list (top, &stmt_list);
309 append_to_statement_list (body, &stmt_list);
310 if (c_dialect_cxx ()
311 && stmt_list
312 && TREE_CODE (stmt_list) == STATEMENT_LIST)
314 tree_stmt_iterator tsi = tsi_last (stmt_list);
315 if (!tsi_end_p (tsi))
317 tree t = *tsi;
318 while (TREE_CODE (t) == CLEANUP_POINT_EXPR
319 || TREE_CODE (t) == EXPR_STMT
320 || CONVERT_EXPR_CODE_P (TREE_CODE (t)))
321 t = TREE_OPERAND (t, 0);
322 /* For C++, if iteration statement body ends with fallthrough
323 statement, mark it such that we diagnose it even if next
324 statement would be labeled statement with case/default label. */
325 if (TREE_CODE (t) == CALL_EXPR
326 && !CALL_EXPR_FN (t)
327 && CALL_EXPR_IFN (t) == IFN_FALLTHROUGH)
328 TREE_NOTHROW (t) = 1;
331 finish_bc_block (&stmt_list, bc_continue, clab);
332 if (incr)
334 if (MAY_HAVE_DEBUG_MARKER_STMTS && incr_locus != UNKNOWN_LOCATION)
336 tree d = build0 (DEBUG_BEGIN_STMT, void_type_node);
337 SET_EXPR_LOCATION (d, expr_loc_or_loc (incr, start_locus));
338 append_to_statement_list (d, &stmt_list);
340 append_to_statement_list (incr, &stmt_list);
342 append_to_statement_list (entry, &stmt_list);
344 if (MAY_HAVE_DEBUG_MARKER_STMTS && cond_locus != UNKNOWN_LOCATION)
346 tree d = build0 (DEBUG_BEGIN_STMT, void_type_node);
347 SET_EXPR_LOCATION (d, cond_locus);
348 append_to_statement_list (d, &stmt_list);
350 append_to_statement_list (exit, &stmt_list);
351 finish_bc_block (&stmt_list, bc_break, blab);
352 if (!stmt_list)
353 stmt_list = build_empty_stmt (start_locus);
355 *stmt_p = stmt_list;
358 /* Genericize a FOR_STMT node *STMT_P. */
360 static void
361 genericize_for_stmt (tree *stmt_p, int *walk_subtrees, void *data,
362 walk_tree_fn func, walk_tree_lh lh)
364 tree stmt = *stmt_p;
365 tree expr = NULL;
366 tree loop;
367 tree init = FOR_INIT_STMT (stmt);
369 if (init)
371 walk_tree_1 (&init, func, data, NULL, lh);
372 append_to_statement_list (init, &expr);
375 genericize_c_loop (&loop, EXPR_LOCATION (stmt), FOR_COND (stmt),
376 FOR_BODY (stmt), FOR_EXPR (stmt), 1, walk_subtrees,
377 data, func, lh);
378 append_to_statement_list (loop, &expr);
379 if (expr == NULL_TREE)
380 expr = loop;
381 *stmt_p = expr;
384 /* Genericize a WHILE_STMT node *STMT_P. */
386 static void
387 genericize_while_stmt (tree *stmt_p, int *walk_subtrees, void *data,
388 walk_tree_fn func, walk_tree_lh lh)
390 tree stmt = *stmt_p;
391 genericize_c_loop (stmt_p, EXPR_LOCATION (stmt), WHILE_COND (stmt),
392 WHILE_BODY (stmt), NULL_TREE, 1, walk_subtrees,
393 data, func, lh);
396 /* Genericize a DO_STMT node *STMT_P. */
398 static void
399 genericize_do_stmt (tree *stmt_p, int *walk_subtrees, void *data,
400 walk_tree_fn func, walk_tree_lh lh)
402 tree stmt = *stmt_p;
403 genericize_c_loop (stmt_p, EXPR_LOCATION (stmt), DO_COND (stmt),
404 DO_BODY (stmt), NULL_TREE, 0, walk_subtrees,
405 data, func, lh);
408 /* Genericize a SWITCH_STMT node *STMT_P by turning it into a SWITCH_EXPR. */
410 static void
411 genericize_switch_stmt (tree *stmt_p, int *walk_subtrees, void *data,
412 walk_tree_fn func, walk_tree_lh lh)
414 tree stmt = *stmt_p;
415 tree break_block, body, cond, type;
416 location_t stmt_locus = EXPR_LOCATION (stmt);
418 body = SWITCH_STMT_BODY (stmt);
419 if (!body)
420 body = build_empty_stmt (stmt_locus);
421 cond = SWITCH_STMT_COND (stmt);
422 type = SWITCH_STMT_TYPE (stmt);
424 walk_tree_1 (&cond, func, data, NULL, lh);
426 break_block = begin_bc_block (bc_break, stmt_locus);
428 walk_tree_1 (&body, func, data, NULL, lh);
429 walk_tree_1 (&type, func, data, NULL, lh);
430 *walk_subtrees = 0;
432 if (TREE_USED (break_block))
433 SWITCH_BREAK_LABEL_P (break_block) = 1;
434 finish_bc_block (&body, bc_break, break_block);
435 *stmt_p = build2_loc (stmt_locus, SWITCH_EXPR, type, cond, body);
436 SWITCH_ALL_CASES_P (*stmt_p) = SWITCH_STMT_ALL_CASES_P (stmt);
437 gcc_checking_assert (!SWITCH_STMT_NO_BREAK_P (stmt)
438 || !TREE_USED (break_block));
441 /* Genericize a CONTINUE_STMT node *STMT_P. */
443 static void
444 genericize_continue_stmt (tree *stmt_p)
446 tree stmt_list = NULL;
447 tree pred = build_predict_expr (PRED_CONTINUE, NOT_TAKEN);
448 tree label = get_bc_label (bc_continue);
449 location_t location = EXPR_LOCATION (*stmt_p);
450 tree jump = build1_loc (location, GOTO_EXPR, void_type_node, label);
451 append_to_statement_list_force (pred, &stmt_list);
452 append_to_statement_list (jump, &stmt_list);
453 *stmt_p = stmt_list;
456 /* Genericize a BREAK_STMT node *STMT_P. */
458 static void
459 genericize_break_stmt (tree *stmt_p)
461 tree label = get_bc_label (bc_break);
462 location_t location = EXPR_LOCATION (*stmt_p);
463 *stmt_p = build1_loc (location, GOTO_EXPR, void_type_node, label);
466 /* Genericize a OMP_FOR node *STMT_P. */
468 static void
469 genericize_omp_for_stmt (tree *stmt_p, int *walk_subtrees, void *data,
470 walk_tree_fn func, walk_tree_lh lh)
472 tree stmt = *stmt_p;
473 location_t locus = EXPR_LOCATION (stmt);
474 tree clab = begin_bc_block (bc_continue, locus);
476 walk_tree_1 (&OMP_FOR_BODY (stmt), func, data, NULL, lh);
477 if (TREE_CODE (stmt) != OMP_TASKLOOP)
478 walk_tree_1 (&OMP_FOR_CLAUSES (stmt), func, data, NULL, lh);
479 walk_tree_1 (&OMP_FOR_INIT (stmt), func, data, NULL, lh);
480 walk_tree_1 (&OMP_FOR_COND (stmt), func, data, NULL, lh);
481 walk_tree_1 (&OMP_FOR_INCR (stmt), func, data, NULL, lh);
482 walk_tree_1 (&OMP_FOR_PRE_BODY (stmt), func, data, NULL, lh);
483 *walk_subtrees = 0;
485 finish_bc_block (&OMP_FOR_BODY (stmt), bc_continue, clab);
489 /* Lower structured control flow tree nodes, such as loops. The
490 STMT_P, WALK_SUBTREES, and DATA arguments are as for the walk_tree_fn
491 type. FUNC and LH are language-specific functions passed to walk_tree_1
492 for node visiting and traversal, respectively; they are used to do
493 subtree processing in a language-dependent way. */
495 tree
496 c_genericize_control_stmt (tree *stmt_p, int *walk_subtrees, void *data,
497 walk_tree_fn func, walk_tree_lh lh)
499 tree stmt = *stmt_p;
501 switch (TREE_CODE (stmt))
503 case FOR_STMT:
504 genericize_for_stmt (stmt_p, walk_subtrees, data, func, lh);
505 break;
507 case WHILE_STMT:
508 genericize_while_stmt (stmt_p, walk_subtrees, data, func, lh);
509 break;
511 case DO_STMT:
512 genericize_do_stmt (stmt_p, walk_subtrees, data, func, lh);
513 break;
515 case SWITCH_STMT:
516 genericize_switch_stmt (stmt_p, walk_subtrees, data, func, lh);
517 break;
519 case CONTINUE_STMT:
520 genericize_continue_stmt (stmt_p);
521 break;
523 case BREAK_STMT:
524 genericize_break_stmt (stmt_p);
525 break;
527 case OMP_FOR:
528 case OMP_SIMD:
529 case OMP_DISTRIBUTE:
530 case OMP_LOOP:
531 case OMP_TASKLOOP:
532 case OMP_TILE:
533 case OMP_UNROLL:
534 case OACC_LOOP:
535 genericize_omp_for_stmt (stmt_p, walk_subtrees, data, func, lh);
536 break;
538 case STATEMENT_LIST:
539 if (TREE_SIDE_EFFECTS (stmt))
541 tree_stmt_iterator i;
542 int nondebug_stmts = 0;
543 bool clear_side_effects = true;
544 /* Genericization can clear TREE_SIDE_EFFECTS, e.g. when
545 transforming an IF_STMT into COND_EXPR. If such stmt
546 appears in a STATEMENT_LIST that contains only that
547 stmt and some DEBUG_BEGIN_STMTs, without -g where the
548 STATEMENT_LIST wouldn't be present at all the resulting
549 expression wouldn't have TREE_SIDE_EFFECTS set, so make sure
550 to clear it even on the STATEMENT_LIST in such cases. */
551 hash_set<tree> *pset = (c_dialect_cxx ()
552 ? nullptr
553 : static_cast<hash_set<tree> *>(data));
554 for (i = tsi_start (stmt); !tsi_end_p (i); tsi_next (&i))
556 tree t = tsi_stmt (i);
557 if (TREE_CODE (t) != DEBUG_BEGIN_STMT && nondebug_stmts < 2)
558 nondebug_stmts++;
559 walk_tree_1 (tsi_stmt_ptr (i), func, data, pset, lh);
560 if (TREE_CODE (t) != DEBUG_BEGIN_STMT
561 && (nondebug_stmts > 1 || TREE_SIDE_EFFECTS (tsi_stmt (i))))
562 clear_side_effects = false;
564 if (clear_side_effects)
565 TREE_SIDE_EFFECTS (stmt) = 0;
566 *walk_subtrees = 0;
568 break;
570 default:
571 break;
574 return NULL;
578 /* Wrapper for c_genericize_control_stmt to allow it to be used as a walk_tree
579 callback. This is appropriate for C; C++ calls c_genericize_control_stmt
580 directly. */
582 static tree
583 c_genericize_control_r (tree *stmt_p, int *walk_subtrees, void *data)
585 c_genericize_control_stmt (stmt_p, walk_subtrees, data,
586 c_genericize_control_r, NULL);
587 return NULL;
590 /* Convert the tree representation of FNDECL from C frontend trees to
591 GENERIC. */
593 void
594 c_genericize (tree fndecl)
596 dump_file_info *dfi;
597 FILE *dump_orig;
598 dump_flags_t local_dump_flags;
599 struct cgraph_node *cgn;
601 if (flag_sanitize & SANITIZE_BOUNDS)
603 hash_set<tree> pset;
604 walk_tree (&DECL_SAVED_TREE (fndecl), ubsan_walk_array_refs_r, &pset,
605 &pset);
608 /* Genericize loops and other structured control constructs. The C++
609 front end has already done this in lang-specific code. */
610 if (!c_dialect_cxx ())
612 bc_state_t save_state;
613 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
614 save_bc_state (&save_state);
615 hash_set<tree> pset;
616 walk_tree (&DECL_SAVED_TREE (fndecl), c_genericize_control_r, &pset,
617 &pset);
618 restore_bc_state (&save_state);
619 pop_cfun ();
622 if (warn_duplicated_branches)
623 walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl),
624 do_warn_duplicated_branches_r, NULL);
626 /* Dump the C-specific tree IR. */
627 dfi = g->get_dumps ()->get_dump_file_info (TDI_original);
628 dump_orig = dfi->pstream;
629 local_dump_flags = dfi->pflags;
630 if (dump_orig)
632 fprintf (dump_orig, "\n;; Function %s",
633 lang_hooks.decl_printable_name (fndecl, 2));
634 fprintf (dump_orig, " (%s)\n",
635 (!DECL_ASSEMBLER_NAME_SET_P (fndecl) ? "null"
636 : IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl))));
637 fprintf (dump_orig, ";; enabled by -%s\n", dump_flag_name (TDI_original));
638 fprintf (dump_orig, "\n");
640 if (local_dump_flags & TDF_RAW)
641 dump_node (DECL_SAVED_TREE (fndecl),
642 TDF_SLIM | local_dump_flags, dump_orig);
643 else
644 print_c_tree (dump_orig, DECL_SAVED_TREE (fndecl));
645 fprintf (dump_orig, "\n");
648 /* Dump all nested functions now. */
649 cgn = cgraph_node::get_create (fndecl);
650 for (cgn = first_nested_function (cgn);
651 cgn; cgn = next_nested_function (cgn))
652 c_genericize (cgn->decl);
655 static void
656 add_block_to_enclosing (tree block)
658 unsigned i;
659 tree enclosing;
660 gbind *bind;
661 vec<gbind *> stack = gimple_bind_expr_stack ();
663 FOR_EACH_VEC_ELT (stack, i, bind)
664 if (gimple_bind_block (bind))
665 break;
667 enclosing = gimple_bind_block (bind);
668 BLOCK_SUBBLOCKS (enclosing) = chainon (BLOCK_SUBBLOCKS (enclosing), block);
671 /* Genericize a scope by creating a new BIND_EXPR.
672 BLOCK is either a BLOCK representing the scope or a chain of _DECLs.
673 In the latter case, we need to create a new BLOCK and add it to the
674 BLOCK_SUBBLOCKS of the enclosing block.
675 BODY is a chain of C _STMT nodes for the contents of the scope, to be
676 genericized. */
678 tree
679 c_build_bind_expr (location_t loc, tree block, tree body)
681 tree decls, bind;
683 if (block == NULL_TREE)
684 decls = NULL_TREE;
685 else if (TREE_CODE (block) == BLOCK)
686 decls = BLOCK_VARS (block);
687 else
689 decls = block;
690 if (DECL_ARTIFICIAL (decls))
691 block = NULL_TREE;
692 else
694 block = make_node (BLOCK);
695 BLOCK_VARS (block) = decls;
696 add_block_to_enclosing (block);
700 if (!body)
701 body = build_empty_stmt (loc);
702 if (decls || block)
704 bind = build3 (BIND_EXPR, void_type_node, decls, body, block);
705 TREE_SIDE_EFFECTS (bind) = 1;
706 SET_EXPR_LOCATION (bind, loc);
708 else
709 bind = body;
711 return bind;
714 /* Helper for c_gimplify_expr: test if target supports fma-like FN. */
716 static bool
717 fma_supported_p (enum internal_fn fn, tree type)
719 return direct_internal_fn_supported_p (fn, type, OPTIMIZE_FOR_BOTH);
722 /* Gimplification of expression trees. */
724 /* Do C-specific gimplification on *EXPR_P. PRE_P and POST_P are as in
725 gimplify_expr. */
728 c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
729 gimple_seq *post_p ATTRIBUTE_UNUSED)
731 enum tree_code code = TREE_CODE (*expr_p);
733 switch (code)
735 case LSHIFT_EXPR:
736 case RSHIFT_EXPR:
737 case LROTATE_EXPR:
738 case RROTATE_EXPR:
740 /* We used to convert the right operand of a shift-expression
741 to an integer_type_node in the FEs. But it is unnecessary
742 and not desirable for diagnostics and sanitizers. We keep
743 this here to not pessimize the code, but we convert to an
744 unsigned type, because negative shift counts are undefined
745 anyway.
746 We should get rid of this conversion when we have a proper
747 type demotion/promotion pass. */
748 tree *op1_p = &TREE_OPERAND (*expr_p, 1);
749 if (!VECTOR_TYPE_P (TREE_TYPE (*op1_p))
750 && !types_compatible_p (TYPE_MAIN_VARIANT (TREE_TYPE (*op1_p)),
751 unsigned_type_node)
752 && !types_compatible_p (TYPE_MAIN_VARIANT (TREE_TYPE (*op1_p)),
753 integer_type_node))
754 /* Make sure to unshare the result, tree sharing is invalid
755 during gimplification. */
756 *op1_p = unshare_expr (convert (unsigned_type_node, *op1_p));
757 break;
760 case PREINCREMENT_EXPR:
761 case PREDECREMENT_EXPR:
762 case POSTINCREMENT_EXPR:
763 case POSTDECREMENT_EXPR:
765 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
766 if (INTEGRAL_TYPE_P (type) && c_promoting_integer_type_p (type))
768 if (!TYPE_OVERFLOW_WRAPS (type))
769 type = unsigned_type_for (type);
770 return gimplify_self_mod_expr (expr_p, pre_p, post_p, 1, type);
772 break;
775 case PLUS_EXPR:
776 case MINUS_EXPR:
778 tree type = TREE_TYPE (*expr_p);
779 /* For -ffp-contract=on we need to attempt FMA contraction only
780 during initial gimplification. Late contraction across statement
781 boundaries would violate language semantics. */
782 if (SCALAR_FLOAT_TYPE_P (type)
783 && flag_fp_contract_mode == FP_CONTRACT_ON
784 && cfun && !(cfun->curr_properties & PROP_gimple_any)
785 && fma_supported_p (IFN_FMA, type))
787 bool neg_mul = false, neg_add = code == MINUS_EXPR;
789 tree *op0_p = &TREE_OPERAND (*expr_p, 0);
790 tree *op1_p = &TREE_OPERAND (*expr_p, 1);
792 /* Look for ±(x * y) ± z, swapping operands if necessary. */
793 if (TREE_CODE (*op0_p) == NEGATE_EXPR
794 && TREE_CODE (TREE_OPERAND (*op0_p, 0)) == MULT_EXPR)
795 /* '*EXPR_P' is '-(x * y) ± z'. This is fine. */;
796 else if (TREE_CODE (*op0_p) != MULT_EXPR)
798 std::swap (op0_p, op1_p);
799 std::swap (neg_mul, neg_add);
801 if (TREE_CODE (*op0_p) == NEGATE_EXPR)
803 op0_p = &TREE_OPERAND (*op0_p, 0);
804 neg_mul = !neg_mul;
806 if (TREE_CODE (*op0_p) != MULT_EXPR)
807 break;
808 auto_vec<tree, 3> ops (3);
809 ops.quick_push (TREE_OPERAND (*op0_p, 0));
810 ops.quick_push (TREE_OPERAND (*op0_p, 1));
811 ops.quick_push (*op1_p);
813 enum internal_fn ifn = IFN_FMA;
814 if (neg_mul)
816 if (fma_supported_p (IFN_FNMA, type))
817 ifn = IFN_FNMA;
818 else
819 ops[0] = build1 (NEGATE_EXPR, type, ops[0]);
821 if (neg_add)
823 enum internal_fn ifn2 = ifn == IFN_FMA ? IFN_FMS : IFN_FNMS;
824 if (fma_supported_p (ifn2, type))
825 ifn = ifn2;
826 else
827 ops[2] = build1 (NEGATE_EXPR, type, ops[2]);
829 /* Avoid gimplify_arg: it emits all side effects into *PRE_P. */
830 for (auto &&op : ops)
831 if (gimplify_expr (&op, pre_p, post_p, is_gimple_val, fb_rvalue)
832 == GS_ERROR)
833 return GS_ERROR;
835 gcall *call = gimple_build_call_internal_vec (ifn, ops);
836 gimple_seq_add_stmt_without_update (pre_p, call);
837 *expr_p = create_tmp_var (type);
838 gimple_call_set_lhs (call, *expr_p);
839 return GS_ALL_DONE;
841 break;
844 case CALL_EXPR:
846 tree fndecl = get_callee_fndecl (*expr_p);
847 if (fndecl
848 && fndecl_built_in_p (fndecl, BUILT_IN_CLZG, BUILT_IN_CTZG)
849 && call_expr_nargs (*expr_p) == 2
850 && TREE_CODE (CALL_EXPR_ARG (*expr_p, 1)) != INTEGER_CST)
852 tree a = save_expr (CALL_EXPR_ARG (*expr_p, 0));
853 tree c = build_call_expr_loc (EXPR_LOCATION (*expr_p),
854 fndecl, 1, a);
855 *expr_p = build3_loc (EXPR_LOCATION (*expr_p), COND_EXPR,
856 integer_type_node,
857 build2_loc (EXPR_LOCATION (*expr_p),
858 NE_EXPR, boolean_type_node, a,
859 build_zero_cst (TREE_TYPE (a))),
860 c, CALL_EXPR_ARG (*expr_p, 1));
861 return GS_OK;
863 break;
866 default:;
869 return GS_UNHANDLED;