OSDN Git Service

fa3ea299cc47c8fd2c4425e4ded115f864c55f7f
[pf3gnuchains/gcc-fork.git] / gcc / c-gimplify.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-gimple.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 enum bc_t { bc_break = 0, bc_continue = 1 };
76
77 static struct c_gimplify_ctx
78 {
79   /* For handling break and continue.  */
80   tree current_bc_label;
81   tree bc_id[2];
82 } *ctxp;
83
84 static void
85 push_context (void)
86 {
87   if (ctxp)
88     abort ();
89   ctxp = (struct c_gimplify_ctx *) xcalloc (1, sizeof (struct c_gimplify_ctx));
90   ctxp->bc_id[bc_continue] = get_identifier ("continue");
91   ctxp->bc_id[bc_break] = get_identifier ("break");
92 }
93
94 static void
95 pop_context (void)
96 {
97   if (!ctxp || ctxp->current_bc_label)
98     abort ();
99   free (ctxp);
100   ctxp = NULL;
101 }
102
103 /* Gimplification of statement trees.  */
104
105 /* Convert the tree representation of FNDECL from C frontend trees to
106    GENERIC.  */
107
108 void
109 c_genericize (tree fndecl)
110 {
111   FILE *dump_file;
112   int local_dump_flags;
113   struct cgraph_node *cgn;
114
115   /* Dump the C-specific tree IR.  */
116   dump_file = dump_begin (TDI_original, &local_dump_flags);
117   if (dump_file)
118     {
119       fprintf (dump_file, "\n;; Function %s",
120                lang_hooks.decl_printable_name (fndecl, 2));
121       fprintf (dump_file, " (%s)\n",
122                IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)));
123       fprintf (dump_file, ";; enabled by -%s\n", dump_flag_name (TDI_original));
124       fprintf (dump_file, "\n");
125
126       if (local_dump_flags & TDF_RAW)
127         dump_node (DECL_SAVED_TREE (fndecl),
128                    TDF_SLIM | local_dump_flags, dump_file);
129       else
130         print_c_tree (dump_file, DECL_SAVED_TREE (fndecl));
131       fprintf (dump_file, "\n");
132
133       dump_end (TDI_original, dump_file);
134     }
135
136   /* Go ahead and gimplify for now.  */
137   push_context ();
138   gimplify_function_tree (fndecl);
139   pop_context ();
140
141   /* Dump the genericized tree IR.  */
142   dump_function (TDI_generic, fndecl);
143
144   /* Genericize all nested functions now.  We do things in this order so
145      that items like VLA sizes are expanded properly in the context of
146      the correct function.  */
147   cgn = cgraph_node (fndecl);
148   for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
149     c_genericize (cgn->decl);
150 }
151
152 static void
153 add_block_to_enclosing (tree block)
154 {
155   tree enclosing;
156
157   for (enclosing = gimple_current_bind_expr ();
158        enclosing; enclosing = TREE_CHAIN (enclosing))
159     if (BIND_EXPR_BLOCK (enclosing))
160       break;
161
162   enclosing = BIND_EXPR_BLOCK (enclosing);
163   BLOCK_SUBBLOCKS (enclosing) = chainon (BLOCK_SUBBLOCKS (enclosing), block);
164 }
165
166 /* Genericize a scope by creating a new BIND_EXPR.
167    BLOCK is either a BLOCK representing the scope or a chain of _DECLs.
168      In the latter case, we need to create a new BLOCK and add it to the
169      BLOCK_SUBBLOCKS of the enclosing block.
170    BODY is a chain of C _STMT nodes for the contents of the scope, to be
171      genericized.  */
172
173 tree
174 c_build_bind_expr (tree block, tree body)
175 {
176   tree decls, bind;
177
178   if (block == NULL_TREE)
179     decls = NULL_TREE;
180   else if (TREE_CODE (block) == BLOCK)
181     decls = BLOCK_VARS (block);
182   else
183     {
184       decls = block;
185       if (DECL_ARTIFICIAL (decls))
186         block = NULL_TREE;
187       else
188         {
189           block = make_node (BLOCK);
190           BLOCK_VARS (block) = decls;
191           add_block_to_enclosing (block);
192         }
193     }
194
195   if (!body)
196     body = build_empty_stmt ();
197   if (decls || block)
198     {
199       bind = build (BIND_EXPR, void_type_node, decls, body, block);
200       TREE_SIDE_EFFECTS (bind) = 1;
201     }
202   else
203     bind = body;
204
205   return bind;
206 }
207
208 /*  Gimplify an EXPR_STMT node.
209
210     STMT is the statement node.
211
212     PRE_P points to the list where side effects that must happen before
213         STMT should be stored.
214
215     POST_P points to the list where side effects that must happen after
216         STMT should be stored.  */
217
218 static enum gimplify_status
219 gimplify_expr_stmt (tree *stmt_p)
220 {
221   tree stmt = EXPR_STMT_EXPR (*stmt_p);
222
223   if (stmt == error_mark_node)
224     stmt = NULL;
225
226   /* Gimplification of a statement expression will nullify the
227      statement if all its side effects are moved to *PRE_P and *POST_P.
228
229      In this case we will not want to emit the gimplified statement.
230      However, we may still want to emit a warning, so we do that before
231      gimplification.  */
232   if (stmt && (extra_warnings || warn_unused_value))
233     {
234       if (!TREE_SIDE_EFFECTS (stmt))
235         {
236           if (!IS_EMPTY_STMT (stmt)
237               && !VOID_TYPE_P (TREE_TYPE (stmt))
238               && !TREE_NO_WARNING (stmt))
239             warning ("statement with no effect");
240         }
241       else if (warn_unused_value)
242         {
243           /* Kludge for 20020220-2.c.  warn_if_unused_value shouldn't use
244              the stmt file location info.  */
245           set_file_and_line_for_stmt (input_location);
246           warn_if_unused_value (stmt);
247         }
248     }
249
250   if (stmt == NULL_TREE)
251     stmt = build_empty_stmt ();
252   else if (stmts_are_full_exprs_p ())
253     stmt = build1 (CLEANUP_POINT_EXPR, void_type_node, stmt);
254
255   *stmt_p = stmt;
256
257   return GS_OK;
258 }
259
260 /* Begin a scope which can be exited by a break or continue statement.  BC
261    indicates which.
262
263    Just creates a label and pushes it into the current context.  */
264
265 static tree
266 begin_bc_block (enum bc_t bc)
267 {
268   tree label = create_artificial_label ();
269   DECL_NAME (label) = ctxp->bc_id[bc];
270   TREE_CHAIN (label) = ctxp->current_bc_label;
271   ctxp->current_bc_label = label;
272   return label;
273 }
274
275 /* Finish a scope which can be exited by a break or continue statement.
276    LABEL was returned from the most recent call to begin_bc_block.  BODY is
277    an expression for the contents of the scope.
278
279    If we saw a break (or continue) in the scope, append a LABEL_EXPR to
280    body.  Otherwise, just forget the label.  */
281
282 static tree
283 finish_bc_block (tree label, tree body)
284 {
285   if (label != ctxp->current_bc_label)
286     abort ();
287
288   if (TREE_USED (label))
289     {
290       tree t, sl = NULL;
291
292       /* Clear the name so flow can delete the label.  */
293       DECL_NAME (label) = NULL_TREE;
294       t = build1 (LABEL_EXPR, void_type_node, label);
295
296       append_to_statement_list (body, &sl);
297       append_to_statement_list (t, &sl);
298       body = sl;
299     }
300
301   ctxp->current_bc_label = TREE_CHAIN (label);
302   TREE_CHAIN (label) = NULL_TREE;
303   return body;
304 }
305
306 /* Build a GOTO_EXPR to represent a break or continue statement.  BC
307    indicates which.  */
308
309 static tree
310 build_bc_goto (enum bc_t bc)
311 {
312   tree label;
313   tree target_name = ctxp->bc_id[bc];
314
315   /* Look for the appropriate type of label.  */
316   for (label = ctxp->current_bc_label;
317        label;
318        label = TREE_CHAIN (label))
319     if (DECL_NAME (label) == target_name)
320       break;
321
322   if (label == NULL_TREE)
323     {
324       if (bc == bc_break)
325         error ("break statement not within loop or switch");
326       else
327         error ("continue statement not within loop or switch");
328
329       return NULL_TREE;
330     }
331
332   /* Mark the label used for finish_bc_block.  */
333   TREE_USED (label) = 1;
334   return build1 (GOTO_EXPR, void_type_node, label);
335 }
336
337 /* Build a generic representation of one of the C loop forms.  COND is the
338    loop condition or NULL_TREE.  BODY is the (possibly compound) statement
339    controlled by the loop.  INCR is the increment expression of a for-loop,
340    or NULL_TREE.  COND_IS_FIRST indicates whether the condition is
341    evaluated before the loop body as in while and for loops, or after the
342    loop body as in do-while loops.  */
343
344 static tree
345 gimplify_c_loop (tree cond, tree body, tree incr, bool cond_is_first)
346 {
347   tree top, entry, exit, cont_block, break_block, stmt_list, t;
348   location_t stmt_locus;
349
350   stmt_locus = input_location;
351
352   /* Detect do { ... } while (0) and don't generate loop construct.  */
353   if (!cond_is_first && cond && integer_zerop (cond))
354     top = cond = NULL;
355   else
356     {
357       /* If we use a LOOP_EXPR here, we have to feed the whole thing
358          back through the main gimplifier to lower it.  Given that we
359          have to gimplify the loop body NOW so that we can resolve
360          break/continue stmts, seems easier to just expand to gotos.  */
361       top = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
362     }
363
364   break_block = begin_bc_block (bc_break);
365
366   if (top)
367     {
368       /* If we have an exit condition, then we build an IF with gotos either
369          out of the loop, or to the top of it.  If there's no exit condition,
370          then we just build a jump back to the top.  */
371       exit = build_and_jump (&LABEL_EXPR_LABEL (top));
372       if (cond)
373         {
374           t = build_bc_goto (bc_break);
375           exit = build (COND_EXPR, void_type_node, cond, exit, t);
376           exit = fold (exit);
377           gimplify_stmt (&exit);
378         }
379     }
380   else
381     exit = NULL_TREE;
382
383   cont_block = begin_bc_block (bc_continue);
384
385   gimplify_stmt (&body);
386   if (incr && stmts_are_full_exprs_p ())
387     incr = fold (build1 (CLEANUP_POINT_EXPR, void_type_node, incr));
388   gimplify_stmt (&incr);
389
390   body = finish_bc_block (cont_block, body);
391
392   stmt_list = NULL;
393
394   if (cond_is_first && cond)
395     {
396       entry = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
397       t = build_and_jump (&LABEL_EXPR_LABEL (entry));
398       append_to_statement_list (t, &stmt_list);
399     }
400   else
401     entry = NULL_TREE;
402
403   append_to_statement_list (top, &stmt_list);
404   append_to_statement_list (body, &stmt_list);
405   append_to_statement_list (incr, &stmt_list);
406   append_to_statement_list (entry, &stmt_list);
407   append_to_statement_list (exit, &stmt_list);
408
409   annotate_all_with_locus (&stmt_list, stmt_locus);
410
411   return finish_bc_block (break_block, stmt_list);
412 }
413
414 /* Gimplify a FOR_STMT node.  Move the stuff in the for-init-stmt into the
415    prequeue and hand off to gimplify_c_loop.  */
416
417 static enum gimplify_status
418 gimplify_for_stmt (tree *stmt_p, tree *pre_p)
419 {
420   tree stmt = *stmt_p;
421
422   if (FOR_INIT_STMT (stmt))
423     {
424       gimplify_stmt (&FOR_INIT_STMT (stmt));
425       append_to_statement_list (FOR_INIT_STMT (stmt), pre_p);
426     }
427   *stmt_p = gimplify_c_loop (FOR_COND (stmt), FOR_BODY (stmt),
428                              FOR_EXPR (stmt), 1);
429
430   return GS_ALL_DONE;
431 }
432
433 /* Gimplify a WHILE_STMT node.  */
434
435 static enum gimplify_status
436 gimplify_while_stmt (tree *stmt_p)
437 {
438   tree stmt = *stmt_p;
439   *stmt_p = gimplify_c_loop (WHILE_COND (stmt), WHILE_BODY (stmt),
440                              NULL_TREE, 1);
441   return GS_ALL_DONE;
442 }
443
444 /* Gimplify a DO_STMT node.  */
445
446 static enum gimplify_status
447 gimplify_do_stmt (tree *stmt_p)
448 {
449   tree stmt = *stmt_p;
450   *stmt_p = gimplify_c_loop (DO_COND (stmt), DO_BODY (stmt),
451                              NULL_TREE, 0);
452   return GS_ALL_DONE;
453 }
454
455 /* Genericize a SWITCH_STMT by turning it into a SWITCH_EXPR.  */
456
457 static enum gimplify_status
458 gimplify_switch_stmt (tree *stmt_p)
459 {
460   tree stmt = *stmt_p;
461   tree break_block, body;
462   location_t stmt_locus = input_location;
463
464   break_block = begin_bc_block (bc_break);
465
466   body = SWITCH_BODY (stmt);
467   if (!body)
468     body = build_empty_stmt ();
469
470   *stmt_p = build (SWITCH_EXPR, SWITCH_TYPE (stmt), SWITCH_COND (stmt),
471                    body, NULL_TREE);
472   annotate_with_locus (*stmt_p, stmt_locus);
473   gimplify_stmt (stmt_p);
474
475   *stmt_p = finish_bc_block (break_block, *stmt_p);
476   return GS_ALL_DONE;
477 }
478
479 /* Genericize a RETURN_STMT by turning it into a RETURN_EXPR.  */
480
481 static enum gimplify_status
482 gimplify_return_stmt (tree *stmt_p)
483 {
484   tree expr = RETURN_STMT_EXPR (*stmt_p);
485   expr = build1 (RETURN_EXPR, void_type_node, expr);
486   if (stmts_are_full_exprs_p ())
487     expr = build1 (CLEANUP_POINT_EXPR, void_type_node, expr);
488   *stmt_p = expr;
489   return GS_OK;
490 }
491
492 /* Gimplifies a DECL_STMT node *STMT_P by making any necessary allocation
493    and initialization explicit.  */
494
495 static enum gimplify_status
496 gimplify_decl_stmt (tree *stmt_p)
497 {
498   tree stmt = *stmt_p;
499   tree decl = DECL_STMT_DECL (stmt);
500   tree pre = NULL_TREE;
501   tree post = NULL_TREE;
502
503   if (TREE_TYPE (decl) == error_mark_node)
504     {
505       *stmt_p = NULL;
506       return GS_ERROR;
507     }
508     
509   if (TREE_CODE (decl) == TYPE_DECL)
510     {
511       tree type = TREE_TYPE (decl);
512       if (TYPE_SIZE_UNIT (type)
513           && !TREE_CONSTANT (TYPE_SIZE_UNIT (type)))
514         {
515           /* This is a variable-sized array type.  Simplify its size.  */
516           tree temp = TYPE_SIZE_UNIT (type);
517           gimplify_expr (&temp, &pre, &post, is_gimple_val, fb_rvalue);
518         }
519     }
520
521   if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
522     {
523       tree init = DECL_INITIAL (decl);
524
525       if (!TREE_CONSTANT (DECL_SIZE (decl)))
526         {
527           tree pt_type = build_pointer_type (TREE_TYPE (decl));
528           tree alloc, size;
529
530           /* This is a variable-sized decl.  Simplify its size and mark it
531              for deferred expansion.  Note that mudflap depends on the format
532              of the emitted code: see mx_register_decls().  */
533
534           size = get_initialized_tmp_var (DECL_SIZE_UNIT (decl), &pre, &post);
535           DECL_DEFER_OUTPUT (decl) = 1;
536           alloc = build_function_call_expr
537             (implicit_built_in_decls[BUILT_IN_STACK_ALLOC],
538              tree_cons (NULL_TREE,
539                         build1 (ADDR_EXPR, pt_type, decl),
540                         tree_cons (NULL_TREE, size, NULL_TREE)));
541           append_to_compound_expr (alloc, &pre);
542         }
543
544       if (init && init != error_mark_node)
545         {
546           if (!TREE_STATIC (decl))
547             {
548               /* Do not warn about int x = x; as it is a GCC extension
549                  to turn off this warning but only if warn_init_self
550                  is zero.  */
551               if (init == decl && !warn_init_self)
552                 TREE_NO_WARNING (decl) = 1;
553               
554               DECL_INITIAL (decl) = NULL_TREE;
555               init = build (MODIFY_EXPR, void_type_node, decl, init);
556               if (stmts_are_full_exprs_p ())
557                 init = build1 (CLEANUP_POINT_EXPR, void_type_node, init);
558               append_to_compound_expr (init, &pre);
559             }
560           else
561             {
562               /* We must still examine initializers for static variables
563                  as they may contain a label address.  */
564               walk_tree (&init, force_labels_r, NULL, NULL);
565             }
566         }
567
568       /* This decl isn't mentioned in the enclosing block, so add it to the
569          list of temps.  FIXME it seems a bit of a kludge to say that
570          anonymous artificial vars aren't pushed, but everything else is.  */
571       if (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
572         gimple_add_tmp_var (decl);
573     }
574
575   append_to_compound_expr (post, &pre);
576   *stmt_p = pre;
577   return GS_OK;
578 }
579
580 /* Gimplification of expression trees.  */
581
582 /* Gimplify a C99 compound literal expression.  This just means adding the
583    DECL_STMT before the current EXPR_STMT and using its anonymous decl
584    instead.  */
585
586 static enum gimplify_status
587 gimplify_compound_literal_expr (tree *expr_p)
588 {
589   tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
590   tree decl = DECL_STMT_DECL (decl_s);
591
592   /* This decl isn't mentioned in the enclosing block, so add it to the
593      list of temps.  FIXME it seems a bit of a kludge to say that
594      anonymous artificial vars aren't pushed, but everything else is.  */
595   if (DECL_NAME (decl) == NULL_TREE)
596     gimple_add_tmp_var (decl);
597
598   gimplify_decl_stmt (&decl_s);
599   *expr_p = decl_s ? decl_s : decl;
600   return GS_OK;
601 }
602
603 /* Do C-specific gimplification.  Args are as for gimplify_expr.  */
604
605 int
606 c_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED)
607 {
608   enum tree_code code = TREE_CODE (*expr_p);
609
610   switch (code)
611     {
612     case COMPOUND_LITERAL_EXPR:
613       return gimplify_compound_literal_expr (expr_p);
614
615     case FOR_STMT:
616       return gimplify_for_stmt (expr_p, pre_p);
617
618     case WHILE_STMT:
619       return gimplify_while_stmt (expr_p);
620
621     case DO_STMT:
622       return gimplify_do_stmt (expr_p);
623
624     case SWITCH_STMT:
625       return gimplify_switch_stmt (expr_p);
626
627     case EXPR_STMT:
628       return gimplify_expr_stmt (expr_p);
629
630     case RETURN_STMT:
631       return gimplify_return_stmt (expr_p);
632
633     case DECL_STMT:
634       return gimplify_decl_stmt (expr_p);
635
636     case CONTINUE_STMT:
637       *expr_p = build_bc_goto (bc_continue);
638       return GS_ALL_DONE;
639
640     case BREAK_STMT:
641       *expr_p = build_bc_goto (bc_break);
642       return GS_ALL_DONE;
643
644     default:
645       return GS_UNHANDLED;
646     }
647 }