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, 2009, 2010
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 "c-common.h"
33 #include "gimple.h"
34 #include "basic-block.h"
35 #include "tree-inline.h"
36 #include "diagnostic-core.h"
37 #include "langhooks.h"
38 #include "langhooks-def.h"
39 #include "flags.h"
40 #include "tree-dump.h"
41 #include "c-pretty-print.h"
42 #include "cgraph.h"
43 
44 
45 /*  The gimplification pass converts the language-dependent trees
46     (ld-trees) emitted by the parser into language-independent trees
47     (li-trees) that are the target of SSA analysis and transformations.
48 
49     Language-independent trees are based on the SIMPLE intermediate
50     representation used in the McCAT compiler framework:
51 
52     "Designing the McCAT Compiler Based on a Family of Structured
53     Intermediate Representations,"
54     L. Hendren, C. Donawa, M. Emami, G. Gao, Justiani, and B. Sridharan,
55     Proceedings of the 5th International Workshop on Languages and
56     Compilers for Parallel Computing, no. 757 in Lecture Notes in
57     Computer Science, New Haven, Connecticut, pp. 406-420,
58     Springer-Verlag, August 3-5, 1992.
59 
60     http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html
61 
62     Basically, we walk down gimplifying the nodes that we encounter.  As we
63     walk back up, we check that they fit our constraints, and copy them
64     into temporaries if not.  */
65 
66 /* Gimplification of statement trees.  */
67 
68 /* Convert the tree representation of FNDECL from C frontend trees to
69    GENERIC.  */
70 
71 void
72 c_genericize (tree fndecl)
73 {
74   FILE *dump_orig;
75   int local_dump_flags;
76   struct cgraph_node *cgn;
77 
78   /* Dump the C-specific tree IR.  */
79   dump_orig = dump_begin (TDI_original, &local_dump_flags);
80   if (dump_orig)
81     {
82       fprintf (dump_orig, "\n;; Function %s",
83 	       lang_hooks.decl_printable_name (fndecl, 2));
84       fprintf (dump_orig, " (%s)\n",
85 	       (!DECL_ASSEMBLER_NAME_SET_P (fndecl) ? "null"
86 		: IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl))));
87       fprintf (dump_orig, ";; enabled by -%s\n", dump_flag_name (TDI_original));
88       fprintf (dump_orig, "\n");
89 
90       if (local_dump_flags & TDF_RAW)
91 	dump_node (DECL_SAVED_TREE (fndecl),
92 		   TDF_SLIM | local_dump_flags, dump_orig);
93       else
94 	print_c_tree (dump_orig, DECL_SAVED_TREE (fndecl));
95       fprintf (dump_orig, "\n");
96 
97       dump_end (TDI_original, dump_orig);
98     }
99 
100   /* Dump all nested functions now.  */
101   cgn = cgraph_get_create_node (fndecl);
102   for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
103     c_genericize (cgn->decl);
104 }
105 
106 static void
107 add_block_to_enclosing (tree block)
108 {
109   unsigned i;
110   tree enclosing;
111   gimple bind;
112   VEC(gimple, heap) *stack = gimple_bind_expr_stack ();
113 
114   FOR_EACH_VEC_ELT (gimple, stack, i, bind)
115     if (gimple_bind_block (bind))
116       break;
117 
118   enclosing = gimple_bind_block (bind);
119   BLOCK_SUBBLOCKS (enclosing) = chainon (BLOCK_SUBBLOCKS (enclosing), block);
120 }
121 
122 /* Genericize a scope by creating a new BIND_EXPR.
123    BLOCK is either a BLOCK representing the scope or a chain of _DECLs.
124      In the latter case, we need to create a new BLOCK and add it to the
125      BLOCK_SUBBLOCKS of the enclosing block.
126    BODY is a chain of C _STMT nodes for the contents of the scope, to be
127      genericized.  */
128 
129 tree
130 c_build_bind_expr (location_t loc, tree block, tree body)
131 {
132   tree decls, bind;
133 
134   if (block == NULL_TREE)
135     decls = NULL_TREE;
136   else if (TREE_CODE (block) == BLOCK)
137     decls = BLOCK_VARS (block);
138   else
139     {
140       decls = block;
141       if (DECL_ARTIFICIAL (decls))
142 	block = NULL_TREE;
143       else
144 	{
145 	  block = make_node (BLOCK);
146 	  BLOCK_VARS (block) = decls;
147 	  add_block_to_enclosing (block);
148 	}
149     }
150 
151   if (!body)
152     body = build_empty_stmt (loc);
153   if (decls || block)
154     {
155       bind = build3 (BIND_EXPR, void_type_node, decls, body, block);
156       TREE_SIDE_EFFECTS (bind) = 1;
157       SET_EXPR_LOCATION (bind, loc);
158     }
159   else
160     bind = body;
161 
162   return bind;
163 }
164 
165 /* Gimplification of expression trees.  */
166 
167 /* Do C-specific gimplification on *EXPR_P.  PRE_P and POST_P are as in
168    gimplify_expr.  */
169 
170 int
171 c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
172 		 gimple_seq *post_p ATTRIBUTE_UNUSED)
173 {
174   enum tree_code code = TREE_CODE (*expr_p);
175 
176   /* This is handled mostly by gimplify.c, but we have to deal with
177      not warning about int x = x; as it is a GCC extension to turn off
178      this warning but only if warn_init_self is zero.  */
179   if (code == DECL_EXPR
180       && TREE_CODE (DECL_EXPR_DECL (*expr_p)) == VAR_DECL
181       && !DECL_EXTERNAL (DECL_EXPR_DECL (*expr_p))
182       && !TREE_STATIC (DECL_EXPR_DECL (*expr_p))
183       && (DECL_INITIAL (DECL_EXPR_DECL (*expr_p)) == DECL_EXPR_DECL (*expr_p))
184       && !warn_init_self)
185     TREE_NO_WARNING (DECL_EXPR_DECL (*expr_p)) = 1;
186 
187   return GS_UNHANDLED;
188 }
189