]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/c-simplify.c
Merge tree-ssa-20020619-branch into mainline.
[thirdparty/gcc.git] / gcc / c-simplify.c
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, 2003 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>
9
10 This file is part of GCC.
11
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 2, or (at your option) any later
15 version.
16
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.
21
22 You should have received a copy of the GNU General Public License
23 along with GCC; see the file COPYING. If not, write to the Free
24 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 02111-1307, USA. */
26
27 #include "config.h"
28 #include "system.h"
29 #include "coretypes.h"
30 #include "tm.h"
31 #include "tree.h"
32 #include "errors.h"
33 #include "varray.h"
34 #include "c-tree.h"
35 #include "c-common.h"
36 #include "tree-simple.h"
37 #include "hard-reg-set.h"
38 #include "basic-block.h"
39 #include "tree-flow.h"
40 #include "tree-inline.h"
41 #include "diagnostic.h"
42 #include "langhooks.h"
43 #include "langhooks-def.h"
44 #include "flags.h"
45 #include "rtl.h"
46 #include "toplev.h"
47 #include "tree-dump.h"
48 #include "c-pretty-print.h"
49 #include "cgraph.h"
50
51
52 /* The gimplification pass converts the language-dependent trees
53 (ld-trees) emitted by the parser into language-independent trees
54 (li-trees) that are the target of SSA analysis and transformations.
55
56 Language-independent trees are based on the SIMPLE intermediate
57 representation used in the McCAT compiler framework:
58
59 "Designing the McCAT Compiler Based on a Family of Structured
60 Intermediate Representations,"
61 L. Hendren, C. Donawa, M. Emami, G. Gao, Justiani, and B. Sridharan,
62 Proceedings of the 5th International Workshop on Languages and
63 Compilers for Parallel Computing, no. 757 in Lecture Notes in
64 Computer Science, New Haven, Connecticut, pp. 406-420,
65 Springer-Verlag, August 3-5, 1992.
66
67 http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html
68
69 Basically, we walk down gimplifying the nodes that we encounter. As we
70 walk back up, we check that they fit our constraints, and copy them
71 into temporaries if not. */
72
73 /* Local declarations. */
74
75 static enum gimplify_status gimplify_expr_stmt (tree *);
76 static enum gimplify_status gimplify_decl_stmt (tree *);
77 static enum gimplify_status gimplify_for_stmt (tree *, tree *);
78 static enum gimplify_status gimplify_while_stmt (tree *);
79 static enum gimplify_status gimplify_do_stmt (tree *);
80 static enum gimplify_status gimplify_if_stmt (tree *);
81 static enum gimplify_status gimplify_switch_stmt (tree *);
82 static enum gimplify_status gimplify_return_stmt (tree *);
83 static enum gimplify_status gimplify_stmt_expr (tree *);
84 static enum gimplify_status gimplify_compound_literal_expr (tree *);
85 #if defined ENABLE_CHECKING
86 static int is_last_stmt_of_scope (tree);
87 #endif
88 static enum gimplify_status gimplify_block (tree *, tree *);
89 static enum gimplify_status gimplify_cleanup (tree *, tree *);
90 static tree gimplify_c_loop (tree, tree, tree, bool);
91 static void push_context (void);
92 static void pop_context (void);
93 static tree c_build_bind_expr (tree, tree);
94 static void add_block_to_enclosing (tree);
95 static void gimplify_condition (tree *);
96
97 enum bc_t { bc_break = 0, bc_continue = 1 };
98 static tree begin_bc_block (enum bc_t);
99 static tree finish_bc_block (tree, tree);
100 static tree build_bc_goto (enum bc_t);
101
102 static struct c_gimplify_ctx
103 {
104 /* For handling break and continue. */
105 tree current_bc_label;
106 tree bc_id[2];
107 } *ctxp;
108
109 static void
110 push_context (void)
111 {
112 if (ctxp)
113 abort ();
114 ctxp = (struct c_gimplify_ctx *) xcalloc (1, sizeof (struct c_gimplify_ctx));
115 ctxp->bc_id[bc_continue] = get_identifier ("continue");
116 ctxp->bc_id[bc_break] = get_identifier ("break");
117 }
118
119 static void
120 pop_context (void)
121 {
122 if (!ctxp || ctxp->current_bc_label)
123 abort ();
124 free (ctxp);
125 ctxp = NULL;
126 }
127
128 /* Gimplification of statement trees. */
129
130 /* Convert the tree representation of FNDECL from C frontend trees to
131 GENERIC. */
132
133 void
134 c_genericize (tree fndecl)
135 {
136 FILE *dump_file;
137 int local_dump_flags;
138 struct cgraph_node *cgn;
139
140 /* Dump the C-specific tree IR. */
141 dump_file = dump_begin (TDI_original, &local_dump_flags);
142 if (dump_file)
143 {
144 fprintf (dump_file, "\n;; Function %s",
145 (*lang_hooks.decl_printable_name) (fndecl, 2));
146 fprintf (dump_file, " (%s)\n",
147 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)));
148 fprintf (dump_file, ";; enabled by -%s\n", dump_flag_name (TDI_original));
149 fprintf (dump_file, "\n");
150
151 if (local_dump_flags & TDF_RAW)
152 dump_node (DECL_SAVED_TREE (fndecl),
153 TDF_SLIM | local_dump_flags, dump_file);
154 else
155 print_c_tree (dump_file, DECL_SAVED_TREE (fndecl));
156 fprintf (dump_file, "\n");
157
158 dump_end (TDI_original, dump_file);
159 }
160
161 /* Go ahead and gimplify for now. */
162 push_context ();
163 gimplify_function_tree (fndecl);
164 pop_context ();
165
166 /* Dump the genericized tree IR. */
167 dump_function (TDI_generic, fndecl);
168
169 /* Genericize all nested functions now. We do things in this order so
170 that items like VLA sizes are expanded properly in the context of
171 the correct function. */
172 cgn = cgraph_node (fndecl);
173 for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
174 c_genericize (cgn->decl);
175 }
176
177 /* Entry point for the tree lowering pass. Recursively scan
178 *STMT_P and convert it to a GIMPLE tree. */
179
180 int
181 c_gimplify_stmt (tree *stmt_p)
182 {
183 tree stmt, next;
184 tree outer_pre = NULL_TREE;
185
186 /* PRE and POST are tree chains that contain the side-effects of the
187 gimplified tree. For instance, given the expression tree:
188
189 c = ++a * 3 + b++;
190
191 After gimplification, the tree will be re-written as:
192
193 a = a + 1;
194 t1 = a * 3; <-- PRE
195 c = t1 + b;
196 b = b + 1; <-- POST */
197
198 for (stmt = *stmt_p; stmt && stmt != error_mark_node; stmt = next)
199 {
200 tree pre, post;
201 int saved_stmts_are_full_exprs_p;
202 location_t stmt_locus;
203 enum gimplify_status ret;
204
205 /* Set up context appropriately for handling this statement. */
206 saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
207 prep_stmt (stmt);
208 stmt_locus = input_location;
209
210 pre = NULL_TREE;
211 post = NULL_TREE;
212
213 next = TREE_CHAIN (stmt);
214
215 switch (TREE_CODE (stmt))
216 {
217 case COMPOUND_STMT:
218 stmt = COMPOUND_BODY (stmt);
219 ret = GS_OK;
220 break;
221
222 case SCOPE_STMT:
223 ret = gimplify_block (&stmt, &next);
224 break;
225
226 case FOR_STMT:
227 ret = gimplify_for_stmt (&stmt, &next);
228 break;
229
230 case WHILE_STMT:
231 ret = gimplify_while_stmt (&stmt);
232 break;
233
234 case DO_STMT:
235 ret = gimplify_do_stmt (&stmt);
236 break;
237
238 case IF_STMT:
239 ret = gimplify_if_stmt (&stmt);
240 break;
241
242 case SWITCH_STMT:
243 ret = gimplify_switch_stmt (&stmt);
244 break;
245
246 case EXPR_STMT:
247 ret = gimplify_expr_stmt (&stmt);
248 break;
249
250 case RETURN_STMT:
251 ret = gimplify_return_stmt (&stmt);
252 break;
253
254 case DECL_STMT:
255 ret = gimplify_decl_stmt (&stmt);
256 break;
257
258 case LABEL_STMT:
259 stmt = build1 (LABEL_EXPR, void_type_node, LABEL_STMT_LABEL (stmt));
260 ret = GS_OK;
261 break;
262
263 case GOTO_STMT:
264 stmt = build1 (GOTO_EXPR, void_type_node, GOTO_DESTINATION (stmt));
265 ret = GS_OK;
266 break;
267
268 case CASE_LABEL:
269 {
270 tree label = create_artificial_label ();
271 stmt = build (CASE_LABEL_EXPR, void_type_node,
272 CASE_LOW (stmt), CASE_HIGH (stmt), label);
273 ret = GS_OK;
274 }
275 break;
276
277 case CONTINUE_STMT:
278 stmt = build_bc_goto (bc_continue);
279 ret = GS_OK;
280 break;
281
282 case BREAK_STMT:
283 stmt = build_bc_goto (bc_break);
284 ret = GS_OK;
285 break;
286
287 case CLEANUP_STMT:
288 ret = gimplify_cleanup (&stmt, &next);
289 break;
290
291 case ASM_STMT:
292 {
293 tree new_stmt = build (ASM_EXPR, void_type_node, ASM_STRING (stmt),
294 ASM_OUTPUTS (stmt), ASM_INPUTS (stmt),
295 ASM_CLOBBERS (stmt));
296 ASM_INPUT_P (new_stmt) = ASM_INPUT_P (stmt);
297 ASM_VOLATILE_P (new_stmt) = ASM_VOLATILE_P (stmt);
298 stmt = new_stmt;
299 ret = GS_OK;
300 }
301 break;
302
303 default:
304 if (lang_gimplify_stmt && (*lang_gimplify_stmt) (&stmt, &next))
305 {
306 ret = GS_OK;
307 break;
308 }
309
310 fprintf (stderr, "unhandled statement node in c_gimplify_stmt:\n");
311 debug_tree (stmt);
312 abort ();
313 break;
314 }
315
316 switch (ret)
317 {
318 case GS_ERROR:
319 goto cont;
320 case GS_OK:
321 gimplify_stmt (&stmt);
322 break;
323 case GS_ALL_DONE:
324 break;
325 default:
326 abort ();
327 }
328
329 /* PRE and POST now contain a list of statements for all the
330 side-effects in STMT. */
331
332 append_to_statement_list (stmt, &pre);
333 append_to_statement_list (post, &pre);
334 annotate_all_with_locus (&pre, stmt_locus);
335
336 append_to_statement_list (pre, &outer_pre);
337 cont:
338 /* Restore saved state. */
339 current_stmt_tree ()->stmts_are_full_exprs_p
340 = saved_stmts_are_full_exprs_p;
341 }
342 append_to_statement_list (stmt, &outer_pre);
343 *stmt_p = outer_pre;
344
345 return GS_ALL_DONE;
346 }
347
348 static void
349 add_block_to_enclosing (tree block)
350 {
351 tree enclosing;
352
353 for (enclosing = gimple_current_bind_expr ();
354 enclosing; enclosing = TREE_CHAIN (enclosing))
355 if (BIND_EXPR_BLOCK (enclosing))
356 break;
357
358 enclosing = BIND_EXPR_BLOCK (enclosing);
359 BLOCK_SUBBLOCKS (enclosing) = chainon (BLOCK_SUBBLOCKS (enclosing), block);
360 }
361
362 /* Genericize a scope by creating a new BIND_EXPR.
363 BLOCK is either a BLOCK representing the scope or a chain of _DECLs.
364 In the latter case, we need to create a new BLOCK and add it to the
365 BLOCK_SUBBLOCKS of the enclosing block.
366 BODY is a chain of C _STMT nodes for the contents of the scope, to be
367 genericized. */
368
369 static tree
370 c_build_bind_expr (tree block, tree body)
371 {
372 tree decls, bind;
373
374 if (block == NULL_TREE)
375 decls = NULL_TREE;
376 else if (TREE_CODE (block) == BLOCK)
377 decls = BLOCK_VARS (block);
378 else
379 {
380 decls = block;
381 if (DECL_ARTIFICIAL (decls))
382 block = NULL_TREE;
383 else
384 {
385 block = make_node (BLOCK);
386 BLOCK_VARS (block) = decls;
387 add_block_to_enclosing (block);
388 }
389 }
390
391 if (!body)
392 body = build_empty_stmt ();
393
394 bind = build (BIND_EXPR, void_type_node, decls, body, block);
395 TREE_SIDE_EFFECTS (bind) = 1;
396
397 return bind;
398 }
399
400 /* Genericize a syntactic block by removing the bracketing SCOPE_STMTs and
401 wrapping the intervening code in a BIND_EXPR. This function assumes
402 that matching SCOPE_STMTs will always appear in the same statement
403 sequence. */
404
405 static enum gimplify_status
406 gimplify_block (tree *stmt_p, tree *next_p)
407 {
408 tree *p;
409 tree block;
410 tree bind;
411 int depth;
412 location_t stmt_locus;
413
414 if (!SCOPE_BEGIN_P (*stmt_p))
415 {
416 /* Can wind up mismatched with syntax errors. */
417 if (!errorcount && !sorrycount)
418 abort ();
419 *stmt_p = NULL;
420 return GS_ERROR;
421 }
422
423 block = SCOPE_STMT_BLOCK (*stmt_p);
424
425 /* Find the matching ending SCOPE_STMT. */
426 depth = 1;
427 for (p = &TREE_CHAIN (*stmt_p);; p = &TREE_CHAIN (*p))
428 {
429 if (*p == NULL)
430 break;
431 if (TREE_CODE (*p) == SCOPE_STMT)
432 {
433 if (SCOPE_BEGIN_P (*p))
434 ++depth;
435 else if (--depth == 0)
436 break;
437 }
438 }
439
440 stmt_locus = input_location;
441 if (*p)
442 {
443 if (SCOPE_STMT_BLOCK (*p) != block)
444 abort ();
445 if (EXPR_LOCUS (*p))
446 stmt_locus = *EXPR_LOCUS (*p);
447 *next_p = TREE_CHAIN (*p);
448 *p = NULL_TREE;
449 }
450 else
451 {
452 /* Can wind up mismatched with syntax errors. */
453 if (!errorcount && !sorrycount)
454 abort ();
455 }
456
457 bind = c_build_bind_expr (block, TREE_CHAIN (*stmt_p));
458 *stmt_p = bind;
459 input_location = stmt_locus;
460
461 return GS_OK;
462 }
463
464 /* Genericize a CLEANUP_STMT. Just wrap everything from here to the end of
465 the block in a TRY_FINALLY_EXPR. Or a TRY_CATCH_EXPR, if it's an
466 EH-only cleanup. */
467
468 static enum gimplify_status
469 gimplify_cleanup (tree *stmt_p, tree *next_p)
470 {
471 tree stmt = *stmt_p;
472 tree body = TREE_CHAIN (stmt);
473 tree cleanup = CLEANUP_EXPR (stmt);
474 enum tree_code code
475 = (CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR : TRY_FINALLY_EXPR);
476
477 if (!body)
478 body = build_empty_stmt ();
479 if (!cleanup)
480 cleanup = build_empty_stmt ();
481
482 *stmt_p = build (code, void_type_node, body, cleanup);
483 *next_p = NULL_TREE;
484
485 return GS_OK;
486 }
487
488 /* Gimplify an EXPR_STMT node.
489
490 STMT is the statement node.
491
492 PRE_P points to the list where side effects that must happen before
493 STMT should be stored.
494
495 POST_P points to the list where side effects that must happen after
496 STMT should be stored. */
497
498 static enum gimplify_status
499 gimplify_expr_stmt (tree *stmt_p)
500 {
501 tree stmt = EXPR_STMT_EXPR (*stmt_p);
502
503 if (stmt == error_mark_node)
504 stmt = NULL;
505
506 /* Gimplification of a statement expression will nullify the
507 statement if all its side effects are moved to *PRE_P and *POST_P.
508
509 In this case we will not want to emit the gimplified statement.
510 However, we may still want to emit a warning, so we do that before
511 gimplification. */
512 if (stmt && (extra_warnings || warn_unused_value))
513 {
514 if (!TREE_SIDE_EFFECTS (stmt))
515 {
516 if (!IS_EMPTY_STMT (stmt)
517 && !VOID_TYPE_P (TREE_TYPE (stmt))
518 && !TREE_NO_WARNING (stmt))
519 warning ("statement with no effect");
520 }
521 else if (warn_unused_value)
522 {
523 /* Kludge for 20020220-2.c. warn_if_unused_value shouldn't use
524 the stmt file location info. */
525 set_file_and_line_for_stmt (input_location);
526 warn_if_unused_value (stmt);
527 }
528 }
529
530 if (stmt == NULL_TREE)
531 stmt = build_empty_stmt ();
532 else if (stmts_are_full_exprs_p ())
533 stmt = build1 (CLEANUP_POINT_EXPR, void_type_node, stmt);
534
535 *stmt_p = stmt;
536
537 return GS_OK;
538 }
539
540 /* If the condition for a loop (or the like) is a decl, it will be a
541 TREE_LIST where the TREE_PURPOSE is a DECL_STMT and the TREE_VALUE is
542 a use of the decl. Turn such a thing into a COMPOUND_EXPR. */
543
544 static void
545 gimplify_condition (tree *cond_p)
546 {
547 tree cond = *cond_p;
548 if (cond && TREE_CODE (cond) == TREE_LIST)
549 {
550 tree decl = TREE_PURPOSE (cond);
551 tree value = TREE_VALUE (cond);
552 c_gimplify_stmt (&decl);
553 *cond_p = build (COMPOUND_EXPR, TREE_TYPE (value), decl, value);
554 }
555 }
556
557 /* Begin a scope which can be exited by a break or continue statement. BC
558 indicates which.
559
560 Just creates a label and pushes it into the current context. */
561
562 static tree
563 begin_bc_block (enum bc_t bc)
564 {
565 tree label = create_artificial_label ();
566 DECL_NAME (label) = ctxp->bc_id[bc];
567 TREE_CHAIN (label) = ctxp->current_bc_label;
568 ctxp->current_bc_label = label;
569 return label;
570 }
571
572 /* Finish a scope which can be exited by a break or continue statement.
573 LABEL was returned from the most recent call to begin_bc_block. BODY is
574 an expression for the contents of the scope.
575
576 If we saw a break (or continue) in the scope, append a LABEL_EXPR to
577 body. Otherwise, just forget the label. */
578
579 static tree
580 finish_bc_block (tree label, tree body)
581 {
582 if (label != ctxp->current_bc_label)
583 abort ();
584
585 if (TREE_USED (label))
586 {
587 tree t, sl = NULL;
588
589 /* Clear the name so flow can delete the label. */
590 DECL_NAME (label) = NULL_TREE;
591 t = build1 (LABEL_EXPR, void_type_node, label);
592
593 append_to_statement_list (body, &sl);
594 append_to_statement_list (t, &sl);
595 body = sl;
596 }
597
598 ctxp->current_bc_label = TREE_CHAIN (label);
599 TREE_CHAIN (label) = NULL_TREE;
600 return body;
601 }
602
603 /* Build a GOTO_EXPR to represent a break or continue statement. BC
604 indicates which. */
605
606 static tree
607 build_bc_goto (enum bc_t bc)
608 {
609 tree label;
610 tree target_name = ctxp->bc_id[bc];
611
612 /* Look for the appropriate type of label. */
613 for (label = ctxp->current_bc_label;
614 label;
615 label = TREE_CHAIN (label))
616 if (DECL_NAME (label) == target_name)
617 break;
618
619 if (label == NULL_TREE)
620 {
621 if (bc == bc_break)
622 error ("break statement not within loop or switch");
623 else
624 error ("continue statement not within loop or switch");
625
626 return NULL_TREE;
627 }
628
629 /* Mark the label used for finish_bc_block. */
630 TREE_USED (label) = 1;
631 return build1 (GOTO_EXPR, void_type_node, label);
632 }
633
634 /* Build a generic representation of one of the C loop forms. COND is the
635 loop condition or NULL_TREE. BODY is the (possibly compound) statement
636 controlled by the loop. INCR is the increment expression of a for-loop,
637 or NULL_TREE. COND_IS_FIRST indicates whether the condition is
638 evaluated before the loop body as in while and for loops, or after the
639 loop body as in do-while loops. */
640
641 static tree
642 gimplify_c_loop (tree cond, tree body, tree incr, bool cond_is_first)
643 {
644 tree top, entry, exit, cont_block, break_block, stmt_list, t;
645 location_t stmt_locus;
646
647 stmt_locus = input_location;
648
649 /* Detect do { ... } while (0) and don't generate loop construct. */
650 if (!cond_is_first && cond && integer_zerop (cond))
651 top = cond = NULL;
652 else
653 {
654 /* If we use a LOOP_EXPR here, we have to feed the whole thing
655 back through the main gimplifier to lower it. Given that we
656 have to gimplify the loop body NOW so that we can resolve
657 break/continue stmts, seems easier to just expand to gotos. */
658 top = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
659 }
660
661 break_block = begin_bc_block (bc_break);
662
663 if (top)
664 {
665 /* If we have an exit condition, then we build an IF with gotos either
666 out of the loop, or to the top of it. If there's no exit condition,
667 then we just build a jump back to the top. */
668 exit = build_and_jump (&LABEL_EXPR_LABEL (top));
669 if (cond)
670 {
671 gimplify_condition (&cond);
672 t = build_bc_goto (bc_break);
673 exit = build (COND_EXPR, void_type_node, cond, exit, t);
674 exit = fold (exit);
675 gimplify_stmt (&exit);
676 }
677 }
678 else
679 exit = NULL_TREE;
680
681 cont_block = begin_bc_block (bc_continue);
682
683 gimplify_stmt (&body);
684 if (incr && stmts_are_full_exprs_p ())
685 incr = fold (build1 (CLEANUP_POINT_EXPR, void_type_node, incr));
686 gimplify_stmt (&incr);
687
688 body = finish_bc_block (cont_block, body);
689
690 stmt_list = NULL;
691
692 if (cond_is_first && cond)
693 {
694 entry = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
695 t = build_and_jump (&LABEL_EXPR_LABEL (entry));
696 append_to_statement_list (t, &stmt_list);
697 }
698 else
699 entry = NULL_TREE;
700
701 append_to_statement_list (top, &stmt_list);
702 append_to_statement_list (body, &stmt_list);
703 append_to_statement_list (incr, &stmt_list);
704 append_to_statement_list (entry, &stmt_list);
705 append_to_statement_list (exit, &stmt_list);
706
707 annotate_all_with_locus (&stmt_list, stmt_locus);
708
709 return finish_bc_block (break_block, stmt_list);
710 }
711
712 /* Gimplify a FOR_STMT node. Move the stuff in the for-init-stmt into the
713 prequeue and hand off to gimplify_c_loop. */
714
715 static enum gimplify_status
716 gimplify_for_stmt (tree *stmt_p, tree *next_p)
717 {
718 tree stmt = *stmt_p;
719 tree init = FOR_INIT_STMT (stmt);
720
721 if (init)
722 {
723 /* Reorganize the statements so that we do the right thing with a
724 CLEANUP_STMT. We want the FOR_STMT and nothing else to be in the
725 scope of the cleanup, so play with pointers to accomplish that. */
726 FOR_INIT_STMT (stmt) = NULL_TREE;
727 chainon (init, stmt);
728 *stmt_p = init;
729 *next_p = TREE_CHAIN (stmt);
730 TREE_CHAIN (stmt) = NULL_TREE;
731 c_gimplify_stmt (stmt_p);
732 }
733 else
734 *stmt_p = gimplify_c_loop (FOR_COND (stmt), FOR_BODY (stmt),
735 FOR_EXPR (stmt), 1);
736
737 return GS_ALL_DONE;
738 }
739
740 /* Gimplify a WHILE_STMT node. */
741
742 static enum gimplify_status
743 gimplify_while_stmt (tree *stmt_p)
744 {
745 tree stmt = *stmt_p;
746 *stmt_p = gimplify_c_loop (WHILE_COND (stmt), WHILE_BODY (stmt),
747 NULL_TREE, 1);
748 return GS_ALL_DONE;
749 }
750
751 /* Gimplify a DO_STMT node. */
752
753 static enum gimplify_status
754 gimplify_do_stmt (tree *stmt_p)
755 {
756 tree stmt = *stmt_p;
757 *stmt_p = gimplify_c_loop (DO_COND (stmt), DO_BODY (stmt),
758 NULL_TREE, 0);
759 return GS_ALL_DONE;
760 }
761
762 /* Genericize an IF_STMT by turning it into a COND_EXPR. */
763
764 static enum gimplify_status
765 gimplify_if_stmt (tree *stmt_p)
766 {
767 tree stmt, then_, else_;
768
769 stmt = *stmt_p;
770 restart:
771 then_ = THEN_CLAUSE (stmt);
772 else_ = ELSE_CLAUSE (stmt);
773
774 if (!then_)
775 then_ = build_empty_stmt ();
776 if (!else_)
777 else_ = build_empty_stmt ();
778
779 stmt = build (COND_EXPR, void_type_node, IF_COND (stmt), then_, else_);
780 gimplify_condition (& TREE_OPERAND (stmt, 0));
781 *stmt_p = stmt;
782
783 /* Handle properly nested if-else chains via iteration instead of
784 mutual recursion between gimplify.c and c-simplify.c. */
785 annotate_with_locus (stmt, input_location);
786 if (TREE_CODE (else_) == IF_STMT && !TREE_CHAIN (else_))
787 {
788 stmt_p = &COND_EXPR_ELSE (stmt);
789 stmt = else_;
790 prep_stmt (stmt);
791 goto restart;
792 }
793
794 return GS_OK;
795 }
796
797 /* Genericize a SWITCH_STMT by turning it into a SWITCH_EXPR. */
798
799 static enum gimplify_status
800 gimplify_switch_stmt (tree *stmt_p)
801 {
802 tree stmt = *stmt_p;
803 tree break_block, body;
804 location_t stmt_locus = input_location;
805
806 break_block = begin_bc_block (bc_break);
807
808 gimplify_condition (&SWITCH_COND (stmt));
809
810 body = SWITCH_BODY (stmt);
811 if (!body)
812 body = build_empty_stmt ();
813
814 *stmt_p = build (SWITCH_EXPR, SWITCH_TYPE (stmt), SWITCH_COND (stmt),
815 body, NULL_TREE);
816 annotate_with_locus (*stmt_p, stmt_locus);
817 gimplify_stmt (stmt_p);
818
819 *stmt_p = finish_bc_block (break_block, *stmt_p);
820 return GS_ALL_DONE;
821 }
822
823 /* Genericize a RETURN_STMT by turning it into a RETURN_EXPR. */
824
825 static enum gimplify_status
826 gimplify_return_stmt (tree *stmt_p)
827 {
828 tree expr = RETURN_STMT_EXPR (*stmt_p);
829 expr = build1 (RETURN_EXPR, void_type_node, expr);
830 if (stmts_are_full_exprs_p ())
831 expr = build1 (CLEANUP_POINT_EXPR, void_type_node, expr);
832 *stmt_p = expr;
833 return GS_OK;
834 }
835
836 /* Gimplifies a DECL_STMT node T.
837
838 If a declaration V has an initial value I, create an expression 'V = I'
839 and insert it after the DECL_STMT.
840
841 PRE_P is a queue for effects that should happen before the DECL_STMT.
842
843 MID_P is a queue for effects that should happen after the DECL_STMT,
844 but before uses of the initialized decl.
845
846 POST_P is a queue for effects that should happen after uses of the
847 initialized decl.
848
849 Usually these last two will be the same, but they may need to be
850 different if the DECL_STMT is somehow embedded in an expression. */
851
852 static enum gimplify_status
853 gimplify_decl_stmt (tree *stmt_p)
854 {
855 tree stmt = *stmt_p;
856 tree decl = DECL_STMT_DECL (stmt);
857 tree pre = NULL_TREE;
858 tree post = NULL_TREE;
859
860 if (TREE_TYPE (decl) == error_mark_node)
861 {
862 *stmt_p = NULL;
863 return GS_ERROR;
864 }
865
866 if (TREE_CODE (decl) == TYPE_DECL)
867 {
868 tree type = TREE_TYPE (decl);
869 if (TYPE_SIZE_UNIT (type)
870 && !TREE_CONSTANT (TYPE_SIZE_UNIT (type)))
871 {
872 /* This is a variable-sized array type. Simplify its size. */
873 tree temp = TYPE_SIZE_UNIT (type);
874 gimplify_expr (&temp, &pre, &post, is_gimple_val, fb_rvalue);
875 }
876 }
877
878 if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
879 {
880 tree init = DECL_INITIAL (decl);
881
882 if (!TREE_CONSTANT (DECL_SIZE (decl)))
883 {
884 tree pt_type = build_pointer_type (TREE_TYPE (decl));
885 tree alloc, size;
886
887 /* This is a variable-sized decl. Simplify its size and mark it
888 for deferred expansion. Note that mudflap depends on the format
889 of the emitted code: see mx_register_decls(). */
890
891 size = get_initialized_tmp_var (DECL_SIZE_UNIT (decl), &pre, &post);
892 DECL_DEFER_OUTPUT (decl) = 1;
893 alloc = build_function_call_expr
894 (implicit_built_in_decls[BUILT_IN_STACK_ALLOC],
895 tree_cons (NULL_TREE,
896 build1 (ADDR_EXPR, pt_type, decl),
897 tree_cons (NULL_TREE, size, NULL_TREE)));
898 append_to_compound_expr (alloc, &pre);
899 }
900
901 if (init && init != error_mark_node)
902 {
903 if (!TREE_STATIC (decl))
904 {
905 /* Do not warn about int x = x; as it is a GCC extension
906 to turn off this warning but only if warn_init_self
907 is zero. */
908 if (init == decl && !warn_init_self)
909 TREE_NO_WARNING (decl) = 1;
910
911 DECL_INITIAL (decl) = NULL_TREE;
912 init = build (MODIFY_EXPR, void_type_node, decl, init);
913 if (stmts_are_full_exprs_p ())
914 init = build1 (CLEANUP_POINT_EXPR, void_type_node, init);
915 append_to_compound_expr (init, &pre);
916 }
917 else
918 {
919 /* We must still examine initializers for static variables
920 as they may contain a label address. */
921 walk_tree (&init, force_labels_r, NULL, NULL);
922 }
923 }
924
925 /* This decl isn't mentioned in the enclosing block, so add it to the
926 list of temps. FIXME it seems a bit of a kludge to say that
927 anonymous artificial vars aren't pushed, but everything else is. */
928 if (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
929 gimple_add_tmp_var (decl);
930 }
931
932 append_to_compound_expr (post, &pre);
933 *stmt_p = pre;
934 return GS_OK;
935 }
936
937 /* Gimplification of expression trees. */
938
939 /* Gimplify a C99 compound literal expression. This just means adding the
940 DECL_STMT before the current EXPR_STMT and using its anonymous decl
941 instead. */
942
943 static enum gimplify_status
944 gimplify_compound_literal_expr (tree *expr_p)
945 {
946 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
947 tree decl = DECL_STMT_DECL (decl_s);
948
949 /* This decl isn't mentioned in the enclosing block, so add it to the
950 list of temps. FIXME it seems a bit of a kludge to say that
951 anonymous artificial vars aren't pushed, but everything else is. */
952 if (DECL_NAME (decl) == NULL_TREE)
953 gimple_add_tmp_var (decl);
954
955 gimplify_decl_stmt (&decl_s);
956 *expr_p = decl_s ? decl_s : decl;
957 return GS_OK;
958 }
959
960 /* Do C-specific gimplification. Args are as for gimplify_expr. */
961
962 int
963 c_gimplify_expr (tree *expr_p, tree *pre_p ATTRIBUTE_UNUSED,
964 tree *post_p ATTRIBUTE_UNUSED)
965 {
966 enum tree_code code = TREE_CODE (*expr_p);
967
968 if (STATEMENT_CODE_P (code))
969 return c_gimplify_stmt (expr_p);
970
971 switch (code)
972 {
973 case COMPOUND_LITERAL_EXPR:
974 return gimplify_compound_literal_expr (expr_p);
975
976 case STMT_EXPR:
977 return gimplify_stmt_expr (expr_p);
978
979 default:
980 return GS_UNHANDLED;
981 }
982 }
983
984 /* Returns the final EXPR_STMT which represents the return value of a
985 STMT_EXPR, or NULL_TREE if none. */
986
987 tree
988 stmt_expr_last_stmt (tree stmt_expr)
989 {
990 tree body = STMT_EXPR_STMT (stmt_expr);
991 tree last_stmt, substmt;
992
993 /* Splice the last expression out of the STMT chain. */
994 last_stmt = NULL_TREE;
995 for (substmt = COMPOUND_BODY (body); substmt;
996 substmt = TREE_CHAIN (substmt))
997 if (TREE_CODE (substmt) != SCOPE_STMT)
998 last_stmt = substmt;
999
1000 if (last_stmt == NULL_TREE
1001 || TREE_CODE (last_stmt) != EXPR_STMT
1002 || (TREE_TYPE (last_stmt)
1003 && VOID_TYPE_P (TREE_TYPE (last_stmt))))
1004 {
1005 location_t loc;
1006 if (last_stmt && EXPR_LOCUS (last_stmt))
1007 loc = *EXPR_LOCUS (last_stmt);
1008 else if (EXPR_LOCUS (stmt_expr))
1009 loc = *EXPR_LOCUS (stmt_expr);
1010 else
1011 loc = input_location;
1012 warning ("%Hstatement-expressions should end with a "
1013 "non-void expression", &loc);
1014 last_stmt = NULL_TREE;
1015 }
1016
1017 #if defined ENABLE_CHECKING
1018 if (last_stmt && !is_last_stmt_of_scope (last_stmt))
1019 abort ();
1020 #endif
1021
1022 return last_stmt;
1023 }
1024
1025 /* Gimplify a STMT_EXPR. EXPR_P points to the expression to gimplify.
1026 After gimplification, if the STMT_EXPR returns a value, EXPR_P will
1027 point to a new temporary that holds that value; otherwise it will be
1028 null.
1029
1030 PRE_P points to the list where side effects that must happen before
1031 *EXPR_P should be stored. */
1032
1033 static enum gimplify_status
1034 gimplify_stmt_expr (tree *expr_p)
1035 {
1036 tree body = STMT_EXPR_STMT (*expr_p);
1037
1038 if (VOID_TYPE_P (TREE_TYPE (*expr_p)))
1039 {
1040 *expr_p = body;
1041 return c_gimplify_stmt (expr_p);
1042 }
1043 else
1044 {
1045 tree last_stmt = stmt_expr_last_stmt (*expr_p);
1046 tree last_expr = NULL_TREE;
1047
1048 if (last_stmt)
1049 {
1050 last_expr = EXPR_STMT_EXPR (last_stmt);
1051
1052 if (stmts_are_full_exprs_p ())
1053 last_expr = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (last_expr),
1054 last_expr);
1055 EXPR_STMT_EXPR (last_stmt) = NULL_TREE;
1056 }
1057
1058 /* Genericize the block. */
1059 c_gimplify_stmt (&body);
1060
1061 /* Now retrofit that last expression into the BIND_EXPR. */
1062 if (last_expr)
1063 {
1064 tree *sub_p;
1065
1066 if (!STMT_EXPR_NO_SCOPE (*expr_p))
1067 {
1068 /* Our BIND_EXPR will always be hidden within
1069 a STATEMENT_LIST. Discard that. */
1070 body = expr_first (body);
1071 sub_p = &BIND_EXPR_BODY (body);
1072
1073 /* Append the last expression to the end of the BIND_EXPR.
1074 We'll now re-process this, and let voidify_wrapper_expr
1075 do its job. */
1076 append_to_statement_list_force (last_expr, sub_p);
1077 TREE_TYPE (body) = TREE_TYPE (last_expr);
1078 }
1079 else
1080 append_to_compound_expr (last_expr, &body);
1081 }
1082
1083 *expr_p = body;
1084 return GS_OK;
1085 }
1086 }
1087
1088 /* Code generation. */
1089
1090 /* Miscellaneous helpers. */
1091
1092 #if defined ENABLE_CHECKING
1093 /* Return nonzero if STMT is the last statement of its scope. */
1094
1095 static int
1096 is_last_stmt_of_scope (tree stmt)
1097 {
1098 return (TREE_CHAIN (stmt) == NULL_TREE
1099 || (TREE_CODE (TREE_CHAIN (stmt)) == SCOPE_STMT
1100 && SCOPE_END_P (TREE_CHAIN (stmt))));
1101 }
1102 #endif