OSDN Git Service

2009-04-09 Richard Guenther <rguenther@suse.de>
[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, 2004, 2005, 2007, 2008
6    Free Software Foundation, Inc.
7    Lowering of expressions contributed by Sebastian Pop <s.pop@laposte.net>
8    Re-written to support lowering of whole function trees, documentation
9    and miscellaneous cleanups by Diego Novillo <dnovillo@redhat.com>
10
11 This file is part of GCC.
12
13 GCC is free software; you can redistribute it and/or modify it under
14 the terms of the GNU General Public License as published by the Free
15 Software Foundation; either version 3, or (at your option) any later
16 version.
17
18 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
19 WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with GCC; see the file COPYING3.  If not see
25 <http://www.gnu.org/licenses/>.  */
26
27 #include "config.h"
28 #include "system.h"
29 #include "coretypes.h"
30 #include "tm.h"
31 #include "tree.h"
32 #include "varray.h"
33 #include "c-tree.h"
34 #include "c-common.h"
35 #include "gimple.h"
36 #include "hard-reg-set.h"
37 #include "basic-block.h"
38 #include "tree-flow.h"
39 #include "tree-inline.h"
40 #include "diagnostic.h"
41 #include "langhooks.h"
42 #include "langhooks-def.h"
43 #include "flags.h"
44 #include "rtl.h"
45 #include "toplev.h"
46 #include "tree-dump.h"
47 #include "c-pretty-print.h"
48 #include "cgraph.h"
49
50
51 /*  The gimplification pass converts the language-dependent trees
52     (ld-trees) emitted by the parser into language-independent trees
53     (li-trees) that are the target of SSA analysis and transformations.
54
55     Language-independent trees are based on the SIMPLE intermediate
56     representation used in the McCAT compiler framework:
57
58     "Designing the McCAT Compiler Based on a Family of Structured
59     Intermediate Representations,"
60     L. Hendren, C. Donawa, M. Emami, G. Gao, Justiani, and B. Sridharan,
61     Proceedings of the 5th International Workshop on Languages and
62     Compilers for Parallel Computing, no. 757 in Lecture Notes in
63     Computer Science, New Haven, Connecticut, pp. 406-420,
64     Springer-Verlag, August 3-5, 1992.
65
66     http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html
67
68     Basically, we walk down gimplifying the nodes that we encounter.  As we
69     walk back up, we check that they fit our constraints, and copy them
70     into temporaries if not.  */
71
72 /* Gimplification of statement trees.  */
73
74 /* Convert the tree representation of FNDECL from C frontend trees to
75    GENERIC.  */
76
77 void
78 c_genericize (tree fndecl)
79 {
80   FILE *dump_orig;
81   int local_dump_flags;
82   struct cgraph_node *cgn;
83
84   /* Dump the C-specific tree IR.  */
85   dump_orig = dump_begin (TDI_original, &local_dump_flags);
86   if (dump_orig)
87     {
88       fprintf (dump_orig, "\n;; Function %s",
89                lang_hooks.decl_printable_name (fndecl, 2));
90       fprintf (dump_orig, " (%s)\n",
91                (!DECL_ASSEMBLER_NAME_SET_P (fndecl) ? "null"
92                 : IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl))));
93       fprintf (dump_orig, ";; enabled by -%s\n", dump_flag_name (TDI_original));
94       fprintf (dump_orig, "\n");
95
96       if (local_dump_flags & TDF_RAW)
97         dump_node (DECL_SAVED_TREE (fndecl),
98                    TDF_SLIM | local_dump_flags, dump_orig);
99       else
100         print_c_tree (dump_orig, DECL_SAVED_TREE (fndecl));
101       fprintf (dump_orig, "\n");
102
103       dump_end (TDI_original, dump_orig);
104     }
105
106   /* Go ahead and gimplify for now.  */
107   gimplify_function_tree (fndecl);
108
109   dump_function (TDI_generic, fndecl);
110
111   /* Genericize all nested functions now.  We do things in this order so
112      that items like VLA sizes are expanded properly in the context of
113      the correct function.  */
114   cgn = cgraph_node (fndecl);
115   for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
116     c_genericize (cgn->decl);
117 }
118
119 static void
120 add_block_to_enclosing (tree block)
121 {
122   unsigned i;
123   tree enclosing;
124   gimple bind;
125   VEC(gimple, heap) *stack = gimple_bind_expr_stack ();
126
127   for (i = 0; VEC_iterate (gimple, stack, i, bind); i++)
128     if (gimple_bind_block (bind))
129       break;
130
131   enclosing = gimple_bind_block (bind);
132   BLOCK_SUBBLOCKS (enclosing) = chainon (BLOCK_SUBBLOCKS (enclosing), block);
133 }
134
135 /* Genericize a scope by creating a new BIND_EXPR.
136    BLOCK is either a BLOCK representing the scope or a chain of _DECLs.
137      In the latter case, we need to create a new BLOCK and add it to the
138      BLOCK_SUBBLOCKS of the enclosing block.
139    BODY is a chain of C _STMT nodes for the contents of the scope, to be
140      genericized.  */
141
142 tree
143 c_build_bind_expr (tree block, tree body)
144 {
145   tree decls, bind;
146
147   if (block == NULL_TREE)
148     decls = NULL_TREE;
149   else if (TREE_CODE (block) == BLOCK)
150     decls = BLOCK_VARS (block);
151   else
152     {
153       decls = block;
154       if (DECL_ARTIFICIAL (decls))
155         block = NULL_TREE;
156       else
157         {
158           block = make_node (BLOCK);
159           BLOCK_VARS (block) = decls;
160           add_block_to_enclosing (block);
161         }
162     }
163
164   if (!body)
165     body = build_empty_stmt ();
166   if (decls || block)
167     {
168       bind = build3 (BIND_EXPR, void_type_node, decls, body, block);
169       TREE_SIDE_EFFECTS (bind) = 1;
170     }
171   else
172     bind = body;
173
174   return bind;
175 }
176
177 /* Gimplification of expression trees.  */
178
179 /* Do C-specific gimplification on *EXPR_P.  PRE_P and POST_P are as in
180    gimplify_expr.  */
181
182 int
183 c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
184                  gimple_seq *post_p ATTRIBUTE_UNUSED)
185 {
186   enum tree_code code = TREE_CODE (*expr_p);
187
188   /* This is handled mostly by gimplify.c, but we have to deal with
189      not warning about int x = x; as it is a GCC extension to turn off
190      this warning but only if warn_init_self is zero.  */
191   if (code == DECL_EXPR
192       && TREE_CODE (DECL_EXPR_DECL (*expr_p)) == VAR_DECL
193       && !DECL_EXTERNAL (DECL_EXPR_DECL (*expr_p))
194       && !TREE_STATIC (DECL_EXPR_DECL (*expr_p))
195       && (DECL_INITIAL (DECL_EXPR_DECL (*expr_p)) == DECL_EXPR_DECL (*expr_p))
196       && !warn_init_self)
197     TREE_NO_WARNING (DECL_EXPR_DECL (*expr_p)) = 1;
198
199   /* The C frontend is the only one producing &ARRAY with pointer-to-element
200      type.  This is invalid in gimple, so produce a properly typed
201      ADDR_EXPR instead and wrap a conversion around it.  */
202   if (code == ADDR_EXPR
203       && TREE_CODE (TREE_TYPE (TREE_OPERAND (*expr_p, 0))) == ARRAY_TYPE
204       && TREE_CODE (TREE_TYPE (TREE_TYPE (*expr_p))) != ARRAY_TYPE)
205     {
206       tree type = TREE_TYPE (*expr_p);
207       TREE_TYPE (*expr_p)
208         = build_pointer_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0)));
209       *expr_p = build1 (NOP_EXPR, type, *expr_p);
210       return GS_OK;
211     }
212
213   return GS_UNHANDLED;
214 }