Mercurial > hg > CbC > CbC_gcc
annotate gcc/tree-nested.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
rev | line source |
---|---|
0 | 1 /* Nested function decomposition for GIMPLE. |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
3 Free Software Foundation, Inc. |
0 | 4 |
5 This file is part of GCC. | |
6 | |
7 GCC is free software; you can redistribute it and/or modify | |
8 it under the terms of the GNU General Public License as published by | |
9 the Free Software Foundation; either version 3, or (at your option) | |
10 any later version. | |
11 | |
12 GCC is distributed in the hope that it will be useful, | |
13 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 GNU General Public License for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with GCC; see the file COPYING3. If not see | |
19 <http://www.gnu.org/licenses/>. */ | |
20 | |
21 #include "config.h" | |
22 #include "system.h" | |
23 #include "coretypes.h" | |
24 #include "tm.h" | |
25 #include "tree.h" | |
26 #include "tm_p.h" | |
27 #include "function.h" | |
28 #include "tree-dump.h" | |
29 #include "tree-inline.h" | |
30 #include "gimple.h" | |
31 #include "tree-iterator.h" | |
32 #include "tree-flow.h" | |
33 #include "cgraph.h" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
34 #include "expr.h" /* FIXME: For STACK_SAVEAREA_MODE and SAVE_NONLOCAL. */ |
0 | 35 #include "langhooks.h" |
36 #include "pointer-set.h" | |
37 | |
38 | |
39 /* The object of this pass is to lower the representation of a set of nested | |
40 functions in order to expose all of the gory details of the various | |
41 nonlocal references. We want to do this sooner rather than later, in | |
42 order to give us more freedom in emitting all of the functions in question. | |
43 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
44 Back in olden times, when gcc was young, we developed an insanely |
0 | 45 complicated scheme whereby variables which were referenced nonlocally |
46 were forced to live in the stack of the declaring function, and then | |
47 the nested functions magically discovered where these variables were | |
48 placed. In order for this scheme to function properly, it required | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
49 that the outer function be partially expanded, then we switch to |
0 | 50 compiling the inner function, and once done with those we switch back |
51 to compiling the outer function. Such delicate ordering requirements | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
52 makes it difficult to do whole translation unit optimizations |
0 | 53 involving such functions. |
54 | |
55 The implementation here is much more direct. Everything that can be | |
56 referenced by an inner function is a member of an explicitly created | |
57 structure herein called the "nonlocal frame struct". The incoming | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
58 static chain for a nested function is a pointer to this struct in |
0 | 59 the parent. In this way, we settle on known offsets from a known |
60 base, and so are decoupled from the logic that places objects in the | |
61 function's stack frame. More importantly, we don't have to wait for | |
62 that to happen -- since the compilation of the inner function is no | |
63 longer tied to a real stack frame, the nonlocal frame struct can be | |
64 allocated anywhere. Which means that the outer function is now | |
65 inlinable. | |
66 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
67 Theory of operation here is very simple. Iterate over all the |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
68 statements in all the functions (depth first) several times, |
0 | 69 allocating structures and fields on demand. In general we want to |
70 examine inner functions first, so that we can avoid making changes | |
71 to outer functions which are unnecessary. | |
72 | |
73 The order of the passes matters a bit, in that later passes will be | |
74 skipped if it is discovered that the functions don't actually interact | |
75 at all. That is, they're nested in the lexical sense but could have | |
76 been written as independent functions without change. */ | |
77 | |
78 | |
79 struct nesting_info | |
80 { | |
81 struct nesting_info *outer; | |
82 struct nesting_info *inner; | |
83 struct nesting_info *next; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
84 |
0 | 85 struct pointer_map_t *field_map; |
86 struct pointer_map_t *var_map; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
87 struct pointer_set_t *mem_refs; |
0 | 88 bitmap suppress_expansion; |
89 | |
90 tree context; | |
91 tree new_local_var_chain; | |
92 tree debug_var_chain; | |
93 tree frame_type; | |
94 tree frame_decl; | |
95 tree chain_field; | |
96 tree chain_decl; | |
97 tree nl_goto_field; | |
98 | |
99 bool any_parm_remapped; | |
100 bool any_tramp_created; | |
101 char static_chain_added; | |
102 }; | |
103 | |
104 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
105 /* Iterate over the nesting tree, starting with ROOT, depth first. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
106 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
107 static inline struct nesting_info * |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
108 iter_nestinfo_start (struct nesting_info *root) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
109 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
110 while (root->inner) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
111 root = root->inner; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
112 return root; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
113 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
114 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
115 static inline struct nesting_info * |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
116 iter_nestinfo_next (struct nesting_info *node) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
117 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
118 if (node->next) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
119 return iter_nestinfo_start (node->next); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
120 return node->outer; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
121 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
122 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
123 #define FOR_EACH_NEST_INFO(I, ROOT) \ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
124 for ((I) = iter_nestinfo_start (ROOT); (I); (I) = iter_nestinfo_next (I)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
125 |
0 | 126 /* Obstack used for the bitmaps in the struct above. */ |
127 static struct bitmap_obstack nesting_info_bitmap_obstack; | |
128 | |
129 | |
130 /* We're working in so many different function contexts simultaneously, | |
131 that create_tmp_var is dangerous. Prevent mishap. */ | |
132 #define create_tmp_var cant_use_create_tmp_var_here_dummy | |
133 | |
134 /* Like create_tmp_var, except record the variable for registration at | |
135 the given nesting level. */ | |
136 | |
137 static tree | |
138 create_tmp_var_for (struct nesting_info *info, tree type, const char *prefix) | |
139 { | |
140 tree tmp_var; | |
141 | |
142 /* If the type is of variable size or a type which must be created by the | |
143 frontend, something is wrong. Note that we explicitly allow | |
144 incomplete types here, since we create them ourselves here. */ | |
145 gcc_assert (!TREE_ADDRESSABLE (type)); | |
146 gcc_assert (!TYPE_SIZE_UNIT (type) | |
147 || TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST); | |
148 | |
149 tmp_var = create_tmp_var_raw (type, prefix); | |
150 DECL_CONTEXT (tmp_var) = info->context; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
151 DECL_CHAIN (tmp_var) = info->new_local_var_chain; |
0 | 152 DECL_SEEN_IN_BIND_EXPR_P (tmp_var) = 1; |
153 if (TREE_CODE (type) == COMPLEX_TYPE | |
154 || TREE_CODE (type) == VECTOR_TYPE) | |
155 DECL_GIMPLE_REG_P (tmp_var) = 1; | |
156 | |
157 info->new_local_var_chain = tmp_var; | |
158 | |
159 return tmp_var; | |
160 } | |
161 | |
162 /* Take the address of EXP to be used within function CONTEXT. | |
163 Mark it for addressability as necessary. */ | |
164 | |
165 tree | |
166 build_addr (tree exp, tree context) | |
167 { | |
168 tree base = exp; | |
169 tree save_context; | |
170 tree retval; | |
171 | |
172 while (handled_component_p (base)) | |
173 base = TREE_OPERAND (base, 0); | |
174 | |
175 if (DECL_P (base)) | |
176 TREE_ADDRESSABLE (base) = 1; | |
177 | |
178 /* Building the ADDR_EXPR will compute a set of properties for | |
179 that ADDR_EXPR. Those properties are unfortunately context | |
180 specific, i.e., they are dependent on CURRENT_FUNCTION_DECL. | |
181 | |
182 Temporarily set CURRENT_FUNCTION_DECL to the desired context, | |
183 build the ADDR_EXPR, then restore CURRENT_FUNCTION_DECL. That | |
184 way the properties are for the ADDR_EXPR are computed properly. */ | |
185 save_context = current_function_decl; | |
186 current_function_decl = context; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
187 retval = build_fold_addr_expr (exp); |
0 | 188 current_function_decl = save_context; |
189 return retval; | |
190 } | |
191 | |
192 /* Insert FIELD into TYPE, sorted by alignment requirements. */ | |
193 | |
194 void | |
195 insert_field_into_struct (tree type, tree field) | |
196 { | |
197 tree *p; | |
198 | |
199 DECL_CONTEXT (field) = type; | |
200 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
201 for (p = &TYPE_FIELDS (type); *p ; p = &DECL_CHAIN (*p)) |
0 | 202 if (DECL_ALIGN (field) >= DECL_ALIGN (*p)) |
203 break; | |
204 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
205 DECL_CHAIN (field) = *p; |
0 | 206 *p = field; |
207 | |
208 /* Set correct alignment for frame struct type. */ | |
209 if (TYPE_ALIGN (type) < DECL_ALIGN (field)) | |
210 TYPE_ALIGN (type) = DECL_ALIGN (field); | |
211 } | |
212 | |
213 /* Build or return the RECORD_TYPE that describes the frame state that is | |
214 shared between INFO->CONTEXT and its nested functions. This record will | |
215 not be complete until finalize_nesting_tree; up until that point we'll | |
216 be adding fields as necessary. | |
217 | |
218 We also build the DECL that represents this frame in the function. */ | |
219 | |
220 static tree | |
221 get_frame_type (struct nesting_info *info) | |
222 { | |
223 tree type = info->frame_type; | |
224 if (!type) | |
225 { | |
226 char *name; | |
227 | |
228 type = make_node (RECORD_TYPE); | |
229 | |
230 name = concat ("FRAME.", | |
231 IDENTIFIER_POINTER (DECL_NAME (info->context)), | |
232 NULL); | |
233 TYPE_NAME (type) = get_identifier (name); | |
234 free (name); | |
235 | |
236 info->frame_type = type; | |
237 info->frame_decl = create_tmp_var_for (info, type, "FRAME"); | |
238 | |
239 /* ??? Always make it addressable for now, since it is meant to | |
240 be pointed to by the static chain pointer. This pessimizes | |
241 when it turns out that no static chains are needed because | |
242 the nested functions referencing non-local variables are not | |
243 reachable, but the true pessimization is to create the non- | |
244 local frame structure in the first place. */ | |
245 TREE_ADDRESSABLE (info->frame_decl) = 1; | |
246 } | |
247 return type; | |
248 } | |
249 | |
250 /* Return true if DECL should be referenced by pointer in the non-local | |
251 frame structure. */ | |
252 | |
253 static bool | |
254 use_pointer_in_frame (tree decl) | |
255 { | |
256 if (TREE_CODE (decl) == PARM_DECL) | |
257 { | |
258 /* It's illegal to copy TREE_ADDRESSABLE, impossible to copy variable | |
259 sized decls, and inefficient to copy large aggregates. Don't bother | |
260 moving anything but scalar variables. */ | |
261 return AGGREGATE_TYPE_P (TREE_TYPE (decl)); | |
262 } | |
263 else | |
264 { | |
265 /* Variable sized types make things "interesting" in the frame. */ | |
266 return DECL_SIZE (decl) == NULL || !TREE_CONSTANT (DECL_SIZE (decl)); | |
267 } | |
268 } | |
269 | |
270 /* Given DECL, a non-locally accessed variable, find or create a field | |
271 in the non-local frame structure for the given nesting context. */ | |
272 | |
273 static tree | |
274 lookup_field_for_decl (struct nesting_info *info, tree decl, | |
275 enum insert_option insert) | |
276 { | |
277 void **slot; | |
278 | |
279 if (insert == NO_INSERT) | |
280 { | |
281 slot = pointer_map_contains (info->field_map, decl); | |
282 return slot ? (tree) *slot : NULL_TREE; | |
283 } | |
284 | |
285 slot = pointer_map_insert (info->field_map, decl); | |
286 if (!*slot) | |
287 { | |
288 tree field = make_node (FIELD_DECL); | |
289 DECL_NAME (field) = DECL_NAME (decl); | |
290 | |
291 if (use_pointer_in_frame (decl)) | |
292 { | |
293 TREE_TYPE (field) = build_pointer_type (TREE_TYPE (decl)); | |
294 DECL_ALIGN (field) = TYPE_ALIGN (TREE_TYPE (field)); | |
295 DECL_NONADDRESSABLE_P (field) = 1; | |
296 } | |
297 else | |
298 { | |
299 TREE_TYPE (field) = TREE_TYPE (decl); | |
300 DECL_SOURCE_LOCATION (field) = DECL_SOURCE_LOCATION (decl); | |
301 DECL_ALIGN (field) = DECL_ALIGN (decl); | |
302 DECL_USER_ALIGN (field) = DECL_USER_ALIGN (decl); | |
303 TREE_ADDRESSABLE (field) = TREE_ADDRESSABLE (decl); | |
304 DECL_NONADDRESSABLE_P (field) = !TREE_ADDRESSABLE (decl); | |
305 TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (decl); | |
306 } | |
307 | |
308 insert_field_into_struct (get_frame_type (info), field); | |
309 *slot = field; | |
310 | |
311 if (TREE_CODE (decl) == PARM_DECL) | |
312 info->any_parm_remapped = true; | |
313 } | |
314 | |
315 return (tree) *slot; | |
316 } | |
317 | |
318 /* Build or return the variable that holds the static chain within | |
319 INFO->CONTEXT. This variable may only be used within INFO->CONTEXT. */ | |
320 | |
321 static tree | |
322 get_chain_decl (struct nesting_info *info) | |
323 { | |
324 tree decl = info->chain_decl; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
325 |
0 | 326 if (!decl) |
327 { | |
328 tree type; | |
329 | |
330 type = get_frame_type (info->outer); | |
331 type = build_pointer_type (type); | |
332 | |
333 /* Note that this variable is *not* entered into any BIND_EXPR; | |
334 the construction of this variable is handled specially in | |
335 expand_function_start and initialize_inlined_parameters. | |
336 Note also that it's represented as a parameter. This is more | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
337 close to the truth, since the initial value does come from |
0 | 338 the caller. */ |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
339 decl = build_decl (DECL_SOURCE_LOCATION (info->context), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
340 PARM_DECL, create_tmp_var_name ("CHAIN"), type); |
0 | 341 DECL_ARTIFICIAL (decl) = 1; |
342 DECL_IGNORED_P (decl) = 1; | |
343 TREE_USED (decl) = 1; | |
344 DECL_CONTEXT (decl) = info->context; | |
345 DECL_ARG_TYPE (decl) = type; | |
346 | |
347 /* Tell tree-inline.c that we never write to this variable, so | |
348 it can copy-prop the replacement value immediately. */ | |
349 TREE_READONLY (decl) = 1; | |
350 | |
351 info->chain_decl = decl; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
352 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
353 if (dump_file |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
354 && (dump_flags & TDF_DETAILS) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
355 && !DECL_STATIC_CHAIN (info->context)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
356 fprintf (dump_file, "Setting static-chain for %s\n", |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
357 lang_hooks.decl_printable_name (info->context, 2)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
358 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
359 DECL_STATIC_CHAIN (info->context) = 1; |
0 | 360 } |
361 return decl; | |
362 } | |
363 | |
364 /* Build or return the field within the non-local frame state that holds | |
365 the static chain for INFO->CONTEXT. This is the way to walk back up | |
366 multiple nesting levels. */ | |
367 | |
368 static tree | |
369 get_chain_field (struct nesting_info *info) | |
370 { | |
371 tree field = info->chain_field; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
372 |
0 | 373 if (!field) |
374 { | |
375 tree type = build_pointer_type (get_frame_type (info->outer)); | |
376 | |
377 field = make_node (FIELD_DECL); | |
378 DECL_NAME (field) = get_identifier ("__chain"); | |
379 TREE_TYPE (field) = type; | |
380 DECL_ALIGN (field) = TYPE_ALIGN (type); | |
381 DECL_NONADDRESSABLE_P (field) = 1; | |
382 | |
383 insert_field_into_struct (get_frame_type (info), field); | |
384 | |
385 info->chain_field = field; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
386 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
387 if (dump_file |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
388 && (dump_flags & TDF_DETAILS) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
389 && !DECL_STATIC_CHAIN (info->context)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
390 fprintf (dump_file, "Setting static-chain for %s\n", |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
391 lang_hooks.decl_printable_name (info->context, 2)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
392 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
393 DECL_STATIC_CHAIN (info->context) = 1; |
0 | 394 } |
395 return field; | |
396 } | |
397 | |
398 /* Initialize a new temporary with the GIMPLE_CALL STMT. */ | |
399 | |
400 static tree | |
401 init_tmp_var_with_call (struct nesting_info *info, gimple_stmt_iterator *gsi, | |
402 gimple call) | |
403 { | |
404 tree t; | |
405 | |
406 t = create_tmp_var_for (info, gimple_call_return_type (call), NULL); | |
407 gimple_call_set_lhs (call, t); | |
408 if (! gsi_end_p (*gsi)) | |
409 gimple_set_location (call, gimple_location (gsi_stmt (*gsi))); | |
410 gsi_insert_before (gsi, call, GSI_SAME_STMT); | |
411 | |
412 return t; | |
413 } | |
414 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
415 |
0 | 416 /* Copy EXP into a temporary. Allocate the temporary in the context of |
417 INFO and insert the initialization statement before GSI. */ | |
418 | |
419 static tree | |
420 init_tmp_var (struct nesting_info *info, tree exp, gimple_stmt_iterator *gsi) | |
421 { | |
422 tree t; | |
423 gimple stmt; | |
424 | |
425 t = create_tmp_var_for (info, TREE_TYPE (exp), NULL); | |
426 stmt = gimple_build_assign (t, exp); | |
427 if (! gsi_end_p (*gsi)) | |
428 gimple_set_location (stmt, gimple_location (gsi_stmt (*gsi))); | |
429 gsi_insert_before_without_update (gsi, stmt, GSI_SAME_STMT); | |
430 | |
431 return t; | |
432 } | |
433 | |
434 | |
435 /* Similarly, but only do so to force EXP to satisfy is_gimple_val. */ | |
436 | |
437 static tree | |
438 gsi_gimplify_val (struct nesting_info *info, tree exp, | |
439 gimple_stmt_iterator *gsi) | |
440 { | |
441 if (is_gimple_val (exp)) | |
442 return exp; | |
443 else | |
444 return init_tmp_var (info, exp, gsi); | |
445 } | |
446 | |
447 /* Similarly, but copy from the temporary and insert the statement | |
448 after the iterator. */ | |
449 | |
450 static tree | |
451 save_tmp_var (struct nesting_info *info, tree exp, gimple_stmt_iterator *gsi) | |
452 { | |
453 tree t; | |
454 gimple stmt; | |
455 | |
456 t = create_tmp_var_for (info, TREE_TYPE (exp), NULL); | |
457 stmt = gimple_build_assign (exp, t); | |
458 if (! gsi_end_p (*gsi)) | |
459 gimple_set_location (stmt, gimple_location (gsi_stmt (*gsi))); | |
460 gsi_insert_after_without_update (gsi, stmt, GSI_SAME_STMT); | |
461 | |
462 return t; | |
463 } | |
464 | |
465 /* Build or return the type used to represent a nested function trampoline. */ | |
466 | |
467 static GTY(()) tree trampoline_type; | |
468 | |
469 static tree | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
470 get_trampoline_type (struct nesting_info *info) |
0 | 471 { |
472 unsigned align, size; | |
473 tree t; | |
474 | |
475 if (trampoline_type) | |
476 return trampoline_type; | |
477 | |
478 align = TRAMPOLINE_ALIGNMENT; | |
479 size = TRAMPOLINE_SIZE; | |
480 | |
481 /* If we won't be able to guarantee alignment simply via TYPE_ALIGN, | |
482 then allocate extra space so that we can do dynamic alignment. */ | |
483 if (align > STACK_BOUNDARY) | |
484 { | |
485 size += ((align/BITS_PER_UNIT) - 1) & -(STACK_BOUNDARY/BITS_PER_UNIT); | |
486 align = STACK_BOUNDARY; | |
487 } | |
488 | |
489 t = build_index_type (build_int_cst (NULL_TREE, size - 1)); | |
490 t = build_array_type (char_type_node, t); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
491 t = build_decl (DECL_SOURCE_LOCATION (info->context), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
492 FIELD_DECL, get_identifier ("__data"), t); |
0 | 493 DECL_ALIGN (t) = align; |
494 DECL_USER_ALIGN (t) = 1; | |
495 | |
496 trampoline_type = make_node (RECORD_TYPE); | |
497 TYPE_NAME (trampoline_type) = get_identifier ("__builtin_trampoline"); | |
498 TYPE_FIELDS (trampoline_type) = t; | |
499 layout_type (trampoline_type); | |
500 DECL_CONTEXT (t) = trampoline_type; | |
501 | |
502 return trampoline_type; | |
503 } | |
504 | |
505 /* Given DECL, a nested function, find or create a field in the non-local | |
506 frame structure for a trampoline for this function. */ | |
507 | |
508 static tree | |
509 lookup_tramp_for_decl (struct nesting_info *info, tree decl, | |
510 enum insert_option insert) | |
511 { | |
512 void **slot; | |
513 | |
514 if (insert == NO_INSERT) | |
515 { | |
516 slot = pointer_map_contains (info->var_map, decl); | |
517 return slot ? (tree) *slot : NULL_TREE; | |
518 } | |
519 | |
520 slot = pointer_map_insert (info->var_map, decl); | |
521 if (!*slot) | |
522 { | |
523 tree field = make_node (FIELD_DECL); | |
524 DECL_NAME (field) = DECL_NAME (decl); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
525 TREE_TYPE (field) = get_trampoline_type (info); |
0 | 526 TREE_ADDRESSABLE (field) = 1; |
527 | |
528 insert_field_into_struct (get_frame_type (info), field); | |
529 *slot = field; | |
530 | |
531 info->any_tramp_created = true; | |
532 } | |
533 | |
534 return (tree) *slot; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
535 } |
0 | 536 |
537 /* Build or return the field within the non-local frame state that holds | |
538 the non-local goto "jmp_buf". The buffer itself is maintained by the | |
539 rtl middle-end as dynamic stack space is allocated. */ | |
540 | |
541 static tree | |
542 get_nl_goto_field (struct nesting_info *info) | |
543 { | |
544 tree field = info->nl_goto_field; | |
545 if (!field) | |
546 { | |
547 unsigned size; | |
548 tree type; | |
549 | |
550 /* For __builtin_nonlocal_goto, we need N words. The first is the | |
551 frame pointer, the rest is for the target's stack pointer save | |
552 area. The number of words is controlled by STACK_SAVEAREA_MODE; | |
553 not the best interface, but it'll do for now. */ | |
554 if (Pmode == ptr_mode) | |
555 type = ptr_type_node; | |
556 else | |
557 type = lang_hooks.types.type_for_mode (Pmode, 1); | |
558 | |
559 size = GET_MODE_SIZE (STACK_SAVEAREA_MODE (SAVE_NONLOCAL)); | |
560 size = size / GET_MODE_SIZE (Pmode); | |
561 size = size + 1; | |
562 | |
563 type = build_array_type | |
564 (type, build_index_type (build_int_cst (NULL_TREE, size))); | |
565 | |
566 field = make_node (FIELD_DECL); | |
567 DECL_NAME (field) = get_identifier ("__nl_goto_buf"); | |
568 TREE_TYPE (field) = type; | |
569 DECL_ALIGN (field) = TYPE_ALIGN (type); | |
570 TREE_ADDRESSABLE (field) = 1; | |
571 | |
572 insert_field_into_struct (get_frame_type (info), field); | |
573 | |
574 info->nl_goto_field = field; | |
575 } | |
576 | |
577 return field; | |
578 } | |
579 | |
580 /* Invoke CALLBACK on all statements of GIMPLE sequence SEQ. */ | |
581 | |
582 static void | |
583 walk_body (walk_stmt_fn callback_stmt, walk_tree_fn callback_op, | |
584 struct nesting_info *info, gimple_seq seq) | |
585 { | |
586 struct walk_stmt_info wi; | |
587 | |
588 memset (&wi, 0, sizeof (wi)); | |
589 wi.info = info; | |
590 wi.val_only = true; | |
591 walk_gimple_seq (seq, callback_stmt, callback_op, &wi); | |
592 } | |
593 | |
594 | |
595 /* Invoke CALLBACK_STMT/CALLBACK_OP on all statements of INFO->CONTEXT. */ | |
596 | |
597 static inline void | |
598 walk_function (walk_stmt_fn callback_stmt, walk_tree_fn callback_op, | |
599 struct nesting_info *info) | |
600 { | |
601 walk_body (callback_stmt, callback_op, info, gimple_body (info->context)); | |
602 } | |
603 | |
604 /* Invoke CALLBACK on a GIMPLE_OMP_FOR's init, cond, incr and pre-body. */ | |
605 | |
606 static void | |
607 walk_gimple_omp_for (gimple for_stmt, | |
608 walk_stmt_fn callback_stmt, walk_tree_fn callback_op, | |
609 struct nesting_info *info) | |
610 { | |
611 struct walk_stmt_info wi; | |
612 gimple_seq seq; | |
613 tree t; | |
614 size_t i; | |
615 | |
616 walk_body (callback_stmt, callback_op, info, gimple_omp_for_pre_body (for_stmt)); | |
617 | |
618 seq = gimple_seq_alloc (); | |
619 memset (&wi, 0, sizeof (wi)); | |
620 wi.info = info; | |
621 wi.gsi = gsi_last (seq); | |
622 | |
623 for (i = 0; i < gimple_omp_for_collapse (for_stmt); i++) | |
624 { | |
625 wi.val_only = false; | |
626 walk_tree (gimple_omp_for_index_ptr (for_stmt, i), callback_op, | |
627 &wi, NULL); | |
628 wi.val_only = true; | |
629 wi.is_lhs = false; | |
630 walk_tree (gimple_omp_for_initial_ptr (for_stmt, i), callback_op, | |
631 &wi, NULL); | |
632 | |
633 wi.val_only = true; | |
634 wi.is_lhs = false; | |
635 walk_tree (gimple_omp_for_final_ptr (for_stmt, i), callback_op, | |
636 &wi, NULL); | |
637 | |
638 t = gimple_omp_for_incr (for_stmt, i); | |
639 gcc_assert (BINARY_CLASS_P (t)); | |
640 wi.val_only = false; | |
641 walk_tree (&TREE_OPERAND (t, 0), callback_op, &wi, NULL); | |
642 wi.val_only = true; | |
643 wi.is_lhs = false; | |
644 walk_tree (&TREE_OPERAND (t, 1), callback_op, &wi, NULL); | |
645 } | |
646 | |
647 if (gimple_seq_empty_p (seq)) | |
648 gimple_seq_free (seq); | |
649 else | |
650 { | |
651 gimple_seq pre_body = gimple_omp_for_pre_body (for_stmt); | |
652 annotate_all_with_location (seq, gimple_location (for_stmt)); | |
653 gimple_seq_add_seq (&pre_body, seq); | |
654 gimple_omp_for_set_pre_body (for_stmt, pre_body); | |
655 } | |
656 } | |
657 | |
658 /* Similarly for ROOT and all functions nested underneath, depth first. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
659 |
0 | 660 static void |
661 walk_all_functions (walk_stmt_fn callback_stmt, walk_tree_fn callback_op, | |
662 struct nesting_info *root) | |
663 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
664 struct nesting_info *n; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
665 FOR_EACH_NEST_INFO (n, root) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
666 walk_function (callback_stmt, callback_op, n); |
0 | 667 } |
668 | |
669 | |
670 /* We have to check for a fairly pathological case. The operands of function | |
671 nested function are to be interpreted in the context of the enclosing | |
672 function. So if any are variably-sized, they will get remapped when the | |
673 enclosing function is inlined. But that remapping would also have to be | |
674 done in the types of the PARM_DECLs of the nested function, meaning the | |
675 argument types of that function will disagree with the arguments in the | |
676 calls to that function. So we'd either have to make a copy of the nested | |
677 function corresponding to each time the enclosing function was inlined or | |
678 add a VIEW_CONVERT_EXPR to each such operand for each call to the nested | |
679 function. The former is not practical. The latter would still require | |
680 detecting this case to know when to add the conversions. So, for now at | |
681 least, we don't inline such an enclosing function. | |
682 | |
683 We have to do that check recursively, so here return indicating whether | |
684 FNDECL has such a nested function. ORIG_FN is the function we were | |
685 trying to inline to use for checking whether any argument is variably | |
686 modified by anything in it. | |
687 | |
688 It would be better to do this in tree-inline.c so that we could give | |
689 the appropriate warning for why a function can't be inlined, but that's | |
690 too late since the nesting structure has already been flattened and | |
691 adding a flag just to record this fact seems a waste of a flag. */ | |
692 | |
693 static bool | |
694 check_for_nested_with_variably_modified (tree fndecl, tree orig_fndecl) | |
695 { | |
696 struct cgraph_node *cgn = cgraph_node (fndecl); | |
697 tree arg; | |
698 | |
699 for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested) | |
700 { | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
701 for (arg = DECL_ARGUMENTS (cgn->decl); arg; arg = DECL_CHAIN (arg)) |
0 | 702 if (variably_modified_type_p (TREE_TYPE (arg), orig_fndecl)) |
703 return true; | |
704 | |
705 if (check_for_nested_with_variably_modified (cgn->decl, orig_fndecl)) | |
706 return true; | |
707 } | |
708 | |
709 return false; | |
710 } | |
711 | |
712 /* Construct our local datastructure describing the function nesting | |
713 tree rooted by CGN. */ | |
714 | |
715 static struct nesting_info * | |
716 create_nesting_tree (struct cgraph_node *cgn) | |
717 { | |
718 struct nesting_info *info = XCNEW (struct nesting_info); | |
719 info->field_map = pointer_map_create (); | |
720 info->var_map = pointer_map_create (); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
721 info->mem_refs = pointer_set_create (); |
0 | 722 info->suppress_expansion = BITMAP_ALLOC (&nesting_info_bitmap_obstack); |
723 info->context = cgn->decl; | |
724 | |
725 for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested) | |
726 { | |
727 struct nesting_info *sub = create_nesting_tree (cgn); | |
728 sub->outer = info; | |
729 sub->next = info->inner; | |
730 info->inner = sub; | |
731 } | |
732 | |
733 /* See discussion at check_for_nested_with_variably_modified for a | |
734 discussion of why this has to be here. */ | |
735 if (check_for_nested_with_variably_modified (info->context, info->context)) | |
736 DECL_UNINLINABLE (info->context) = true; | |
737 | |
738 return info; | |
739 } | |
740 | |
741 /* Return an expression computing the static chain for TARGET_CONTEXT | |
742 from INFO->CONTEXT. Insert any necessary computations before TSI. */ | |
743 | |
744 static tree | |
745 get_static_chain (struct nesting_info *info, tree target_context, | |
746 gimple_stmt_iterator *gsi) | |
747 { | |
748 struct nesting_info *i; | |
749 tree x; | |
750 | |
751 if (info->context == target_context) | |
752 { | |
753 x = build_addr (info->frame_decl, target_context); | |
754 } | |
755 else | |
756 { | |
757 x = get_chain_decl (info); | |
758 | |
759 for (i = info->outer; i->context != target_context; i = i->outer) | |
760 { | |
761 tree field = get_chain_field (i); | |
762 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
763 x = build_simple_mem_ref (x); |
0 | 764 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); |
765 x = init_tmp_var (info, x, gsi); | |
766 } | |
767 } | |
768 | |
769 return x; | |
770 } | |
771 | |
772 | |
773 /* Return an expression referencing FIELD from TARGET_CONTEXT's non-local | |
774 frame as seen from INFO->CONTEXT. Insert any necessary computations | |
775 before GSI. */ | |
776 | |
777 static tree | |
778 get_frame_field (struct nesting_info *info, tree target_context, | |
779 tree field, gimple_stmt_iterator *gsi) | |
780 { | |
781 struct nesting_info *i; | |
782 tree x; | |
783 | |
784 if (info->context == target_context) | |
785 { | |
786 /* Make sure frame_decl gets created. */ | |
787 (void) get_frame_type (info); | |
788 x = info->frame_decl; | |
789 } | |
790 else | |
791 { | |
792 x = get_chain_decl (info); | |
793 | |
794 for (i = info->outer; i->context != target_context; i = i->outer) | |
795 { | |
796 tree field = get_chain_field (i); | |
797 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
798 x = build_simple_mem_ref (x); |
0 | 799 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); |
800 x = init_tmp_var (info, x, gsi); | |
801 } | |
802 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
803 x = build_simple_mem_ref (x); |
0 | 804 } |
805 | |
806 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); | |
807 return x; | |
808 } | |
809 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
810 static void note_nonlocal_vla_type (struct nesting_info *info, tree type); |
0 | 811 |
812 /* A subroutine of convert_nonlocal_reference_op. Create a local variable | |
813 in the nested function with DECL_VALUE_EXPR set to reference the true | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
814 variable in the parent function. This is used both for debug info |
0 | 815 and in OpenMP lowering. */ |
816 | |
817 static tree | |
818 get_nonlocal_debug_decl (struct nesting_info *info, tree decl) | |
819 { | |
820 tree target_context; | |
821 struct nesting_info *i; | |
822 tree x, field, new_decl; | |
823 void **slot; | |
824 | |
825 slot = pointer_map_insert (info->var_map, decl); | |
826 | |
827 if (*slot) | |
828 return (tree) *slot; | |
829 | |
830 target_context = decl_function_context (decl); | |
831 | |
832 /* A copy of the code in get_frame_field, but without the temporaries. */ | |
833 if (info->context == target_context) | |
834 { | |
835 /* Make sure frame_decl gets created. */ | |
836 (void) get_frame_type (info); | |
837 x = info->frame_decl; | |
838 i = info; | |
839 } | |
840 else | |
841 { | |
842 x = get_chain_decl (info); | |
843 for (i = info->outer; i->context != target_context; i = i->outer) | |
844 { | |
845 field = get_chain_field (i); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
846 x = build_simple_mem_ref (x); |
0 | 847 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); |
848 } | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
849 x = build_simple_mem_ref (x); |
0 | 850 } |
851 | |
852 field = lookup_field_for_decl (i, decl, INSERT); | |
853 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); | |
854 if (use_pointer_in_frame (decl)) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
855 x = build_simple_mem_ref (x); |
0 | 856 |
857 /* ??? We should be remapping types as well, surely. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
858 new_decl = build_decl (DECL_SOURCE_LOCATION (decl), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
859 VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl)); |
0 | 860 DECL_CONTEXT (new_decl) = info->context; |
861 DECL_ARTIFICIAL (new_decl) = DECL_ARTIFICIAL (decl); | |
862 DECL_IGNORED_P (new_decl) = DECL_IGNORED_P (decl); | |
863 TREE_THIS_VOLATILE (new_decl) = TREE_THIS_VOLATILE (decl); | |
864 TREE_SIDE_EFFECTS (new_decl) = TREE_SIDE_EFFECTS (decl); | |
865 TREE_READONLY (new_decl) = TREE_READONLY (decl); | |
866 TREE_ADDRESSABLE (new_decl) = TREE_ADDRESSABLE (decl); | |
867 DECL_SEEN_IN_BIND_EXPR_P (new_decl) = 1; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
868 if ((TREE_CODE (decl) == PARM_DECL |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
869 || TREE_CODE (decl) == RESULT_DECL |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
870 || TREE_CODE (decl) == VAR_DECL) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
871 && DECL_BY_REFERENCE (decl)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
872 DECL_BY_REFERENCE (new_decl) = 1; |
0 | 873 |
874 SET_DECL_VALUE_EXPR (new_decl, x); | |
875 DECL_HAS_VALUE_EXPR_P (new_decl) = 1; | |
876 | |
877 *slot = new_decl; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
878 DECL_CHAIN (new_decl) = info->debug_var_chain; |
0 | 879 info->debug_var_chain = new_decl; |
880 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
881 if (!optimize |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
882 && info->context != target_context |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
883 && variably_modified_type_p (TREE_TYPE (decl), NULL)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
884 note_nonlocal_vla_type (info, TREE_TYPE (decl)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
885 |
0 | 886 return new_decl; |
887 } | |
888 | |
889 | |
890 /* Callback for walk_gimple_stmt, rewrite all references to VAR | |
891 and PARM_DECLs that belong to outer functions. | |
892 | |
893 The rewrite will involve some number of structure accesses back up | |
894 the static chain. E.g. for a variable FOO up one nesting level it'll | |
895 be CHAIN->FOO. For two levels it'll be CHAIN->__chain->FOO. Further | |
896 indirections apply to decls for which use_pointer_in_frame is true. */ | |
897 | |
898 static tree | |
899 convert_nonlocal_reference_op (tree *tp, int *walk_subtrees, void *data) | |
900 { | |
901 struct walk_stmt_info *wi = (struct walk_stmt_info *) data; | |
902 struct nesting_info *const info = (struct nesting_info *) wi->info; | |
903 tree t = *tp; | |
904 | |
905 *walk_subtrees = 0; | |
906 switch (TREE_CODE (t)) | |
907 { | |
908 case VAR_DECL: | |
909 /* Non-automatic variables are never processed. */ | |
910 if (TREE_STATIC (t) || DECL_EXTERNAL (t)) | |
911 break; | |
912 /* FALLTHRU */ | |
913 | |
914 case PARM_DECL: | |
915 if (decl_function_context (t) != info->context) | |
916 { | |
917 tree x; | |
918 wi->changed = true; | |
919 | |
920 x = get_nonlocal_debug_decl (info, t); | |
921 if (!bitmap_bit_p (info->suppress_expansion, DECL_UID (t))) | |
922 { | |
923 tree target_context = decl_function_context (t); | |
924 struct nesting_info *i; | |
925 for (i = info->outer; i->context != target_context; i = i->outer) | |
926 continue; | |
927 x = lookup_field_for_decl (i, t, INSERT); | |
928 x = get_frame_field (info, target_context, x, &wi->gsi); | |
929 if (use_pointer_in_frame (t)) | |
930 { | |
931 x = init_tmp_var (info, x, &wi->gsi); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
932 x = build_simple_mem_ref (x); |
0 | 933 } |
934 } | |
935 | |
936 if (wi->val_only) | |
937 { | |
938 if (wi->is_lhs) | |
939 x = save_tmp_var (info, x, &wi->gsi); | |
940 else | |
941 x = init_tmp_var (info, x, &wi->gsi); | |
942 } | |
943 | |
944 *tp = x; | |
945 } | |
946 break; | |
947 | |
948 case LABEL_DECL: | |
949 /* We're taking the address of a label from a parent function, but | |
950 this is not itself a non-local goto. Mark the label such that it | |
951 will not be deleted, much as we would with a label address in | |
952 static storage. */ | |
953 if (decl_function_context (t) != info->context) | |
954 FORCED_LABEL (t) = 1; | |
955 break; | |
956 | |
957 case ADDR_EXPR: | |
958 { | |
959 bool save_val_only = wi->val_only; | |
960 | |
961 wi->val_only = false; | |
962 wi->is_lhs = false; | |
963 wi->changed = false; | |
964 walk_tree (&TREE_OPERAND (t, 0), convert_nonlocal_reference_op, wi, 0); | |
965 wi->val_only = true; | |
966 | |
967 if (wi->changed) | |
968 { | |
969 tree save_context; | |
970 | |
971 /* If we changed anything, we might no longer be directly | |
972 referencing a decl. */ | |
973 save_context = current_function_decl; | |
974 current_function_decl = info->context; | |
975 recompute_tree_invariant_for_addr_expr (t); | |
976 current_function_decl = save_context; | |
977 | |
978 /* If the callback converted the address argument in a context | |
979 where we only accept variables (and min_invariant, presumably), | |
980 then compute the address into a temporary. */ | |
981 if (save_val_only) | |
982 *tp = gsi_gimplify_val ((struct nesting_info *) wi->info, | |
983 t, &wi->gsi); | |
984 } | |
985 } | |
986 break; | |
987 | |
988 case REALPART_EXPR: | |
989 case IMAGPART_EXPR: | |
990 case COMPONENT_REF: | |
991 case ARRAY_REF: | |
992 case ARRAY_RANGE_REF: | |
993 case BIT_FIELD_REF: | |
994 /* Go down this entire nest and just look at the final prefix and | |
995 anything that describes the references. Otherwise, we lose track | |
996 of whether a NOP_EXPR or VIEW_CONVERT_EXPR needs a simple value. */ | |
997 wi->val_only = true; | |
998 wi->is_lhs = false; | |
999 for (; handled_component_p (t); tp = &TREE_OPERAND (t, 0), t = *tp) | |
1000 { | |
1001 if (TREE_CODE (t) == COMPONENT_REF) | |
1002 walk_tree (&TREE_OPERAND (t, 2), convert_nonlocal_reference_op, wi, | |
1003 NULL); | |
1004 else if (TREE_CODE (t) == ARRAY_REF | |
1005 || TREE_CODE (t) == ARRAY_RANGE_REF) | |
1006 { | |
1007 walk_tree (&TREE_OPERAND (t, 1), convert_nonlocal_reference_op, | |
1008 wi, NULL); | |
1009 walk_tree (&TREE_OPERAND (t, 2), convert_nonlocal_reference_op, | |
1010 wi, NULL); | |
1011 walk_tree (&TREE_OPERAND (t, 3), convert_nonlocal_reference_op, | |
1012 wi, NULL); | |
1013 } | |
1014 else if (TREE_CODE (t) == BIT_FIELD_REF) | |
1015 { | |
1016 walk_tree (&TREE_OPERAND (t, 1), convert_nonlocal_reference_op, | |
1017 wi, NULL); | |
1018 walk_tree (&TREE_OPERAND (t, 2), convert_nonlocal_reference_op, | |
1019 wi, NULL); | |
1020 } | |
1021 } | |
1022 wi->val_only = false; | |
1023 walk_tree (tp, convert_nonlocal_reference_op, wi, NULL); | |
1024 break; | |
1025 | |
1026 case VIEW_CONVERT_EXPR: | |
1027 /* Just request to look at the subtrees, leaving val_only and lhs | |
1028 untouched. This might actually be for !val_only + lhs, in which | |
1029 case we don't want to force a replacement by a temporary. */ | |
1030 *walk_subtrees = 1; | |
1031 break; | |
1032 | |
1033 default: | |
1034 if (!IS_TYPE_OR_DECL_P (t)) | |
1035 { | |
1036 *walk_subtrees = 1; | |
1037 wi->val_only = true; | |
1038 wi->is_lhs = false; | |
1039 } | |
1040 break; | |
1041 } | |
1042 | |
1043 return NULL_TREE; | |
1044 } | |
1045 | |
1046 static tree convert_nonlocal_reference_stmt (gimple_stmt_iterator *, bool *, | |
1047 struct walk_stmt_info *); | |
1048 | |
1049 /* Helper for convert_nonlocal_references, rewrite all references to VAR | |
1050 and PARM_DECLs that belong to outer functions. */ | |
1051 | |
1052 static bool | |
1053 convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi) | |
1054 { | |
1055 struct nesting_info *const info = (struct nesting_info *) wi->info; | |
1056 bool need_chain = false, need_stmts = false; | |
1057 tree clause, decl; | |
1058 int dummy; | |
1059 bitmap new_suppress; | |
1060 | |
1061 new_suppress = BITMAP_GGC_ALLOC (); | |
1062 bitmap_copy (new_suppress, info->suppress_expansion); | |
1063 | |
1064 for (clause = *pclauses; clause ; clause = OMP_CLAUSE_CHAIN (clause)) | |
1065 { | |
1066 switch (OMP_CLAUSE_CODE (clause)) | |
1067 { | |
1068 case OMP_CLAUSE_REDUCTION: | |
1069 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause)) | |
1070 need_stmts = true; | |
1071 goto do_decl_clause; | |
1072 | |
1073 case OMP_CLAUSE_LASTPRIVATE: | |
1074 if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (clause)) | |
1075 need_stmts = true; | |
1076 goto do_decl_clause; | |
1077 | |
1078 case OMP_CLAUSE_PRIVATE: | |
1079 case OMP_CLAUSE_FIRSTPRIVATE: | |
1080 case OMP_CLAUSE_COPYPRIVATE: | |
1081 case OMP_CLAUSE_SHARED: | |
1082 do_decl_clause: | |
1083 decl = OMP_CLAUSE_DECL (clause); | |
1084 if (TREE_CODE (decl) == VAR_DECL | |
1085 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))) | |
1086 break; | |
1087 if (decl_function_context (decl) != info->context) | |
1088 { | |
1089 bitmap_set_bit (new_suppress, DECL_UID (decl)); | |
1090 OMP_CLAUSE_DECL (clause) = get_nonlocal_debug_decl (info, decl); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1091 if (OMP_CLAUSE_CODE (clause) != OMP_CLAUSE_PRIVATE) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1092 need_chain = true; |
0 | 1093 } |
1094 break; | |
1095 | |
1096 case OMP_CLAUSE_SCHEDULE: | |
1097 if (OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause) == NULL) | |
1098 break; | |
1099 /* FALLTHRU */ | |
1100 case OMP_CLAUSE_IF: | |
1101 case OMP_CLAUSE_NUM_THREADS: | |
1102 wi->val_only = true; | |
1103 wi->is_lhs = false; | |
1104 convert_nonlocal_reference_op (&OMP_CLAUSE_OPERAND (clause, 0), | |
1105 &dummy, wi); | |
1106 break; | |
1107 | |
1108 case OMP_CLAUSE_NOWAIT: | |
1109 case OMP_CLAUSE_ORDERED: | |
1110 case OMP_CLAUSE_DEFAULT: | |
1111 case OMP_CLAUSE_COPYIN: | |
1112 case OMP_CLAUSE_COLLAPSE: | |
1113 case OMP_CLAUSE_UNTIED: | |
1114 break; | |
1115 | |
1116 default: | |
1117 gcc_unreachable (); | |
1118 } | |
1119 } | |
1120 | |
1121 info->suppress_expansion = new_suppress; | |
1122 | |
1123 if (need_stmts) | |
1124 for (clause = *pclauses; clause ; clause = OMP_CLAUSE_CHAIN (clause)) | |
1125 switch (OMP_CLAUSE_CODE (clause)) | |
1126 { | |
1127 case OMP_CLAUSE_REDUCTION: | |
1128 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause)) | |
1129 { | |
1130 tree old_context | |
1131 = DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause)); | |
1132 DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause)) | |
1133 = info->context; | |
1134 walk_body (convert_nonlocal_reference_stmt, | |
1135 convert_nonlocal_reference_op, info, | |
1136 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (clause)); | |
1137 walk_body (convert_nonlocal_reference_stmt, | |
1138 convert_nonlocal_reference_op, info, | |
1139 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (clause)); | |
1140 DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause)) | |
1141 = old_context; | |
1142 } | |
1143 break; | |
1144 | |
1145 case OMP_CLAUSE_LASTPRIVATE: | |
1146 walk_body (convert_nonlocal_reference_stmt, | |
1147 convert_nonlocal_reference_op, info, | |
1148 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (clause)); | |
1149 break; | |
1150 | |
1151 default: | |
1152 break; | |
1153 } | |
1154 | |
1155 return need_chain; | |
1156 } | |
1157 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1158 /* Create nonlocal debug decls for nonlocal VLA array bounds. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1159 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1160 static void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1161 note_nonlocal_vla_type (struct nesting_info *info, tree type) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1162 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1163 while (POINTER_TYPE_P (type) && !TYPE_NAME (type)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1164 type = TREE_TYPE (type); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1165 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1166 if (TYPE_NAME (type) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1167 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1168 && DECL_ORIGINAL_TYPE (TYPE_NAME (type))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1169 type = DECL_ORIGINAL_TYPE (TYPE_NAME (type)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1170 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1171 while (POINTER_TYPE_P (type) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1172 || TREE_CODE (type) == VECTOR_TYPE |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1173 || TREE_CODE (type) == FUNCTION_TYPE |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1174 || TREE_CODE (type) == METHOD_TYPE) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1175 type = TREE_TYPE (type); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1176 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1177 if (TREE_CODE (type) == ARRAY_TYPE) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1178 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1179 tree domain, t; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1180 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1181 note_nonlocal_vla_type (info, TREE_TYPE (type)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1182 domain = TYPE_DOMAIN (type); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1183 if (domain) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1184 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1185 t = TYPE_MIN_VALUE (domain); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1186 if (t && (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == PARM_DECL) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1187 && decl_function_context (t) != info->context) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1188 get_nonlocal_debug_decl (info, t); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1189 t = TYPE_MAX_VALUE (domain); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1190 if (t && (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == PARM_DECL) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1191 && decl_function_context (t) != info->context) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1192 get_nonlocal_debug_decl (info, t); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1193 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1194 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1195 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1196 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1197 /* Create nonlocal debug decls for nonlocal VLA array bounds for VLAs |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1198 in BLOCK. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1199 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1200 static void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1201 note_nonlocal_block_vlas (struct nesting_info *info, tree block) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1202 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1203 tree var; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1204 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1205 for (var = BLOCK_VARS (block); var; var = DECL_CHAIN (var)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1206 if (TREE_CODE (var) == VAR_DECL |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1207 && variably_modified_type_p (TREE_TYPE (var), NULL) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1208 && DECL_HAS_VALUE_EXPR_P (var) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1209 && decl_function_context (var) != info->context) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1210 note_nonlocal_vla_type (info, TREE_TYPE (var)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1211 } |
0 | 1212 |
1213 /* Callback for walk_gimple_stmt. Rewrite all references to VAR and | |
1214 PARM_DECLs that belong to outer functions. This handles statements | |
1215 that are not handled via the standard recursion done in | |
1216 walk_gimple_stmt. STMT is the statement to examine, DATA is as in | |
1217 convert_nonlocal_reference_op. Set *HANDLED_OPS_P to true if all the | |
1218 operands of STMT have been handled by this function. */ | |
1219 | |
1220 static tree | |
1221 convert_nonlocal_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p, | |
1222 struct walk_stmt_info *wi) | |
1223 { | |
1224 struct nesting_info *info = (struct nesting_info *) wi->info; | |
1225 tree save_local_var_chain; | |
1226 bitmap save_suppress; | |
1227 gimple stmt = gsi_stmt (*gsi); | |
1228 | |
1229 switch (gimple_code (stmt)) | |
1230 { | |
1231 case GIMPLE_GOTO: | |
1232 /* Don't walk non-local gotos for now. */ | |
1233 if (TREE_CODE (gimple_goto_dest (stmt)) != LABEL_DECL) | |
1234 { | |
1235 wi->val_only = true; | |
1236 wi->is_lhs = false; | |
1237 *handled_ops_p = true; | |
1238 return NULL_TREE; | |
1239 } | |
1240 break; | |
1241 | |
1242 case GIMPLE_OMP_PARALLEL: | |
1243 case GIMPLE_OMP_TASK: | |
1244 save_suppress = info->suppress_expansion; | |
1245 if (convert_nonlocal_omp_clauses (gimple_omp_taskreg_clauses_ptr (stmt), | |
1246 wi)) | |
1247 { | |
1248 tree c, decl; | |
1249 decl = get_chain_decl (info); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1250 c = build_omp_clause (gimple_location (stmt), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1251 OMP_CLAUSE_FIRSTPRIVATE); |
0 | 1252 OMP_CLAUSE_DECL (c) = decl; |
1253 OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt); | |
1254 gimple_omp_taskreg_set_clauses (stmt, c); | |
1255 } | |
1256 | |
1257 save_local_var_chain = info->new_local_var_chain; | |
1258 info->new_local_var_chain = NULL; | |
1259 | |
1260 walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op, | |
1261 info, gimple_omp_body (stmt)); | |
1262 | |
1263 if (info->new_local_var_chain) | |
1264 declare_vars (info->new_local_var_chain, | |
1265 gimple_seq_first_stmt (gimple_omp_body (stmt)), | |
1266 false); | |
1267 info->new_local_var_chain = save_local_var_chain; | |
1268 info->suppress_expansion = save_suppress; | |
1269 break; | |
1270 | |
1271 case GIMPLE_OMP_FOR: | |
1272 save_suppress = info->suppress_expansion; | |
1273 convert_nonlocal_omp_clauses (gimple_omp_for_clauses_ptr (stmt), wi); | |
1274 walk_gimple_omp_for (stmt, convert_nonlocal_reference_stmt, | |
1275 convert_nonlocal_reference_op, info); | |
1276 walk_body (convert_nonlocal_reference_stmt, | |
1277 convert_nonlocal_reference_op, info, gimple_omp_body (stmt)); | |
1278 info->suppress_expansion = save_suppress; | |
1279 break; | |
1280 | |
1281 case GIMPLE_OMP_SECTIONS: | |
1282 save_suppress = info->suppress_expansion; | |
1283 convert_nonlocal_omp_clauses (gimple_omp_sections_clauses_ptr (stmt), wi); | |
1284 walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op, | |
1285 info, gimple_omp_body (stmt)); | |
1286 info->suppress_expansion = save_suppress; | |
1287 break; | |
1288 | |
1289 case GIMPLE_OMP_SINGLE: | |
1290 save_suppress = info->suppress_expansion; | |
1291 convert_nonlocal_omp_clauses (gimple_omp_single_clauses_ptr (stmt), wi); | |
1292 walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op, | |
1293 info, gimple_omp_body (stmt)); | |
1294 info->suppress_expansion = save_suppress; | |
1295 break; | |
1296 | |
1297 case GIMPLE_OMP_SECTION: | |
1298 case GIMPLE_OMP_MASTER: | |
1299 case GIMPLE_OMP_ORDERED: | |
1300 walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op, | |
1301 info, gimple_omp_body (stmt)); | |
1302 break; | |
1303 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1304 case GIMPLE_BIND: |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1305 if (!optimize && gimple_bind_block (stmt)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1306 note_nonlocal_block_vlas (info, gimple_bind_block (stmt)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1307 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1308 *handled_ops_p = false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1309 return NULL_TREE; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1310 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1311 case GIMPLE_COND: |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1312 wi->val_only = true; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1313 wi->is_lhs = false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1314 *handled_ops_p = false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1315 return NULL_TREE; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1316 |
0 | 1317 default: |
1318 /* For every other statement that we are not interested in | |
1319 handling here, let the walker traverse the operands. */ | |
1320 *handled_ops_p = false; | |
1321 return NULL_TREE; | |
1322 } | |
1323 | |
1324 /* We have handled all of STMT operands, no need to traverse the operands. */ | |
1325 *handled_ops_p = true; | |
1326 return NULL_TREE; | |
1327 } | |
1328 | |
1329 | |
1330 /* A subroutine of convert_local_reference. Create a local variable | |
1331 in the parent function with DECL_VALUE_EXPR set to reference the | |
1332 field in FRAME. This is used both for debug info and in OpenMP | |
1333 lowering. */ | |
1334 | |
1335 static tree | |
1336 get_local_debug_decl (struct nesting_info *info, tree decl, tree field) | |
1337 { | |
1338 tree x, new_decl; | |
1339 void **slot; | |
1340 | |
1341 slot = pointer_map_insert (info->var_map, decl); | |
1342 if (*slot) | |
1343 return (tree) *slot; | |
1344 | |
1345 /* Make sure frame_decl gets created. */ | |
1346 (void) get_frame_type (info); | |
1347 x = info->frame_decl; | |
1348 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); | |
1349 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1350 new_decl = build_decl (DECL_SOURCE_LOCATION (decl), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1351 VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl)); |
0 | 1352 DECL_CONTEXT (new_decl) = info->context; |
1353 DECL_ARTIFICIAL (new_decl) = DECL_ARTIFICIAL (decl); | |
1354 DECL_IGNORED_P (new_decl) = DECL_IGNORED_P (decl); | |
1355 TREE_THIS_VOLATILE (new_decl) = TREE_THIS_VOLATILE (decl); | |
1356 TREE_SIDE_EFFECTS (new_decl) = TREE_SIDE_EFFECTS (decl); | |
1357 TREE_READONLY (new_decl) = TREE_READONLY (decl); | |
1358 TREE_ADDRESSABLE (new_decl) = TREE_ADDRESSABLE (decl); | |
1359 DECL_SEEN_IN_BIND_EXPR_P (new_decl) = 1; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1360 if ((TREE_CODE (decl) == PARM_DECL |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1361 || TREE_CODE (decl) == RESULT_DECL |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1362 || TREE_CODE (decl) == VAR_DECL) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1363 && DECL_BY_REFERENCE (decl)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1364 DECL_BY_REFERENCE (new_decl) = 1; |
0 | 1365 |
1366 SET_DECL_VALUE_EXPR (new_decl, x); | |
1367 DECL_HAS_VALUE_EXPR_P (new_decl) = 1; | |
1368 *slot = new_decl; | |
1369 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1370 DECL_CHAIN (new_decl) = info->debug_var_chain; |
0 | 1371 info->debug_var_chain = new_decl; |
1372 | |
1373 /* Do not emit debug info twice. */ | |
1374 DECL_IGNORED_P (decl) = 1; | |
1375 | |
1376 return new_decl; | |
1377 } | |
1378 | |
1379 | |
1380 /* Called via walk_function+walk_gimple_stmt, rewrite all references to VAR | |
1381 and PARM_DECLs that were referenced by inner nested functions. | |
1382 The rewrite will be a structure reference to the local frame variable. */ | |
1383 | |
1384 static bool convert_local_omp_clauses (tree *, struct walk_stmt_info *); | |
1385 | |
1386 static tree | |
1387 convert_local_reference_op (tree *tp, int *walk_subtrees, void *data) | |
1388 { | |
1389 struct walk_stmt_info *wi = (struct walk_stmt_info *) data; | |
1390 struct nesting_info *const info = (struct nesting_info *) wi->info; | |
1391 tree t = *tp, field, x; | |
1392 bool save_val_only; | |
1393 | |
1394 *walk_subtrees = 0; | |
1395 switch (TREE_CODE (t)) | |
1396 { | |
1397 case VAR_DECL: | |
1398 /* Non-automatic variables are never processed. */ | |
1399 if (TREE_STATIC (t) || DECL_EXTERNAL (t)) | |
1400 break; | |
1401 /* FALLTHRU */ | |
1402 | |
1403 case PARM_DECL: | |
1404 if (decl_function_context (t) == info->context) | |
1405 { | |
1406 /* If we copied a pointer to the frame, then the original decl | |
1407 is used unchanged in the parent function. */ | |
1408 if (use_pointer_in_frame (t)) | |
1409 break; | |
1410 | |
1411 /* No need to transform anything if no child references the | |
1412 variable. */ | |
1413 field = lookup_field_for_decl (info, t, NO_INSERT); | |
1414 if (!field) | |
1415 break; | |
1416 wi->changed = true; | |
1417 | |
1418 x = get_local_debug_decl (info, t, field); | |
1419 if (!bitmap_bit_p (info->suppress_expansion, DECL_UID (t))) | |
1420 x = get_frame_field (info, info->context, field, &wi->gsi); | |
1421 | |
1422 if (wi->val_only) | |
1423 { | |
1424 if (wi->is_lhs) | |
1425 x = save_tmp_var (info, x, &wi->gsi); | |
1426 else | |
1427 x = init_tmp_var (info, x, &wi->gsi); | |
1428 } | |
1429 | |
1430 *tp = x; | |
1431 } | |
1432 break; | |
1433 | |
1434 case ADDR_EXPR: | |
1435 save_val_only = wi->val_only; | |
1436 wi->val_only = false; | |
1437 wi->is_lhs = false; | |
1438 wi->changed = false; | |
1439 walk_tree (&TREE_OPERAND (t, 0), convert_local_reference_op, wi, NULL); | |
1440 wi->val_only = save_val_only; | |
1441 | |
1442 /* If we converted anything ... */ | |
1443 if (wi->changed) | |
1444 { | |
1445 tree save_context; | |
1446 | |
1447 /* Then the frame decl is now addressable. */ | |
1448 TREE_ADDRESSABLE (info->frame_decl) = 1; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1449 |
0 | 1450 save_context = current_function_decl; |
1451 current_function_decl = info->context; | |
1452 recompute_tree_invariant_for_addr_expr (t); | |
1453 current_function_decl = save_context; | |
1454 | |
1455 /* If we are in a context where we only accept values, then | |
1456 compute the address into a temporary. */ | |
1457 if (save_val_only) | |
1458 *tp = gsi_gimplify_val ((struct nesting_info *) wi->info, | |
1459 t, &wi->gsi); | |
1460 } | |
1461 break; | |
1462 | |
1463 case REALPART_EXPR: | |
1464 case IMAGPART_EXPR: | |
1465 case COMPONENT_REF: | |
1466 case ARRAY_REF: | |
1467 case ARRAY_RANGE_REF: | |
1468 case BIT_FIELD_REF: | |
1469 /* Go down this entire nest and just look at the final prefix and | |
1470 anything that describes the references. Otherwise, we lose track | |
1471 of whether a NOP_EXPR or VIEW_CONVERT_EXPR needs a simple value. */ | |
1472 save_val_only = wi->val_only; | |
1473 wi->val_only = true; | |
1474 wi->is_lhs = false; | |
1475 for (; handled_component_p (t); tp = &TREE_OPERAND (t, 0), t = *tp) | |
1476 { | |
1477 if (TREE_CODE (t) == COMPONENT_REF) | |
1478 walk_tree (&TREE_OPERAND (t, 2), convert_local_reference_op, wi, | |
1479 NULL); | |
1480 else if (TREE_CODE (t) == ARRAY_REF | |
1481 || TREE_CODE (t) == ARRAY_RANGE_REF) | |
1482 { | |
1483 walk_tree (&TREE_OPERAND (t, 1), convert_local_reference_op, wi, | |
1484 NULL); | |
1485 walk_tree (&TREE_OPERAND (t, 2), convert_local_reference_op, wi, | |
1486 NULL); | |
1487 walk_tree (&TREE_OPERAND (t, 3), convert_local_reference_op, wi, | |
1488 NULL); | |
1489 } | |
1490 else if (TREE_CODE (t) == BIT_FIELD_REF) | |
1491 { | |
1492 walk_tree (&TREE_OPERAND (t, 1), convert_local_reference_op, wi, | |
1493 NULL); | |
1494 walk_tree (&TREE_OPERAND (t, 2), convert_local_reference_op, wi, | |
1495 NULL); | |
1496 } | |
1497 } | |
1498 wi->val_only = false; | |
1499 walk_tree (tp, convert_local_reference_op, wi, NULL); | |
1500 wi->val_only = save_val_only; | |
1501 break; | |
1502 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1503 case MEM_REF: |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1504 save_val_only = wi->val_only; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1505 wi->val_only = true; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1506 wi->is_lhs = false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1507 walk_tree (&TREE_OPERAND (t, 0), convert_local_reference_op, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1508 wi, NULL); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1509 /* We need to re-fold the MEM_REF as component references as |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1510 part of a ADDR_EXPR address are not allowed. But we cannot |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1511 fold here, as the chain record type is not yet finalized. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1512 if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1513 && !DECL_P (TREE_OPERAND (TREE_OPERAND (t, 0), 0))) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1514 pointer_set_insert (info->mem_refs, tp); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1515 wi->val_only = save_val_only; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1516 break; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1517 |
0 | 1518 case VIEW_CONVERT_EXPR: |
1519 /* Just request to look at the subtrees, leaving val_only and lhs | |
1520 untouched. This might actually be for !val_only + lhs, in which | |
1521 case we don't want to force a replacement by a temporary. */ | |
1522 *walk_subtrees = 1; | |
1523 break; | |
1524 | |
1525 default: | |
1526 if (!IS_TYPE_OR_DECL_P (t)) | |
1527 { | |
1528 *walk_subtrees = 1; | |
1529 wi->val_only = true; | |
1530 wi->is_lhs = false; | |
1531 } | |
1532 break; | |
1533 } | |
1534 | |
1535 return NULL_TREE; | |
1536 } | |
1537 | |
1538 static tree convert_local_reference_stmt (gimple_stmt_iterator *, bool *, | |
1539 struct walk_stmt_info *); | |
1540 | |
1541 /* Helper for convert_local_reference. Convert all the references in | |
1542 the chain of clauses at *PCLAUSES. WI is as in convert_local_reference. */ | |
1543 | |
1544 static bool | |
1545 convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi) | |
1546 { | |
1547 struct nesting_info *const info = (struct nesting_info *) wi->info; | |
1548 bool need_frame = false, need_stmts = false; | |
1549 tree clause, decl; | |
1550 int dummy; | |
1551 bitmap new_suppress; | |
1552 | |
1553 new_suppress = BITMAP_GGC_ALLOC (); | |
1554 bitmap_copy (new_suppress, info->suppress_expansion); | |
1555 | |
1556 for (clause = *pclauses; clause ; clause = OMP_CLAUSE_CHAIN (clause)) | |
1557 { | |
1558 switch (OMP_CLAUSE_CODE (clause)) | |
1559 { | |
1560 case OMP_CLAUSE_REDUCTION: | |
1561 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause)) | |
1562 need_stmts = true; | |
1563 goto do_decl_clause; | |
1564 | |
1565 case OMP_CLAUSE_LASTPRIVATE: | |
1566 if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (clause)) | |
1567 need_stmts = true; | |
1568 goto do_decl_clause; | |
1569 | |
1570 case OMP_CLAUSE_PRIVATE: | |
1571 case OMP_CLAUSE_FIRSTPRIVATE: | |
1572 case OMP_CLAUSE_COPYPRIVATE: | |
1573 case OMP_CLAUSE_SHARED: | |
1574 do_decl_clause: | |
1575 decl = OMP_CLAUSE_DECL (clause); | |
1576 if (TREE_CODE (decl) == VAR_DECL | |
1577 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))) | |
1578 break; | |
1579 if (decl_function_context (decl) == info->context | |
1580 && !use_pointer_in_frame (decl)) | |
1581 { | |
1582 tree field = lookup_field_for_decl (info, decl, NO_INSERT); | |
1583 if (field) | |
1584 { | |
1585 bitmap_set_bit (new_suppress, DECL_UID (decl)); | |
1586 OMP_CLAUSE_DECL (clause) | |
1587 = get_local_debug_decl (info, decl, field); | |
1588 need_frame = true; | |
1589 } | |
1590 } | |
1591 break; | |
1592 | |
1593 case OMP_CLAUSE_SCHEDULE: | |
1594 if (OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause) == NULL) | |
1595 break; | |
1596 /* FALLTHRU */ | |
1597 case OMP_CLAUSE_IF: | |
1598 case OMP_CLAUSE_NUM_THREADS: | |
1599 wi->val_only = true; | |
1600 wi->is_lhs = false; | |
1601 convert_local_reference_op (&OMP_CLAUSE_OPERAND (clause, 0), &dummy, | |
1602 wi); | |
1603 break; | |
1604 | |
1605 case OMP_CLAUSE_NOWAIT: | |
1606 case OMP_CLAUSE_ORDERED: | |
1607 case OMP_CLAUSE_DEFAULT: | |
1608 case OMP_CLAUSE_COPYIN: | |
1609 case OMP_CLAUSE_COLLAPSE: | |
1610 case OMP_CLAUSE_UNTIED: | |
1611 break; | |
1612 | |
1613 default: | |
1614 gcc_unreachable (); | |
1615 } | |
1616 } | |
1617 | |
1618 info->suppress_expansion = new_suppress; | |
1619 | |
1620 if (need_stmts) | |
1621 for (clause = *pclauses; clause ; clause = OMP_CLAUSE_CHAIN (clause)) | |
1622 switch (OMP_CLAUSE_CODE (clause)) | |
1623 { | |
1624 case OMP_CLAUSE_REDUCTION: | |
1625 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause)) | |
1626 { | |
1627 tree old_context | |
1628 = DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause)); | |
1629 DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause)) | |
1630 = info->context; | |
1631 walk_body (convert_local_reference_stmt, | |
1632 convert_local_reference_op, info, | |
1633 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (clause)); | |
1634 walk_body (convert_local_reference_stmt, | |
1635 convert_local_reference_op, info, | |
1636 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (clause)); | |
1637 DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause)) | |
1638 = old_context; | |
1639 } | |
1640 break; | |
1641 | |
1642 case OMP_CLAUSE_LASTPRIVATE: | |
1643 walk_body (convert_local_reference_stmt, | |
1644 convert_local_reference_op, info, | |
1645 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (clause)); | |
1646 break; | |
1647 | |
1648 default: | |
1649 break; | |
1650 } | |
1651 | |
1652 return need_frame; | |
1653 } | |
1654 | |
1655 | |
1656 /* Called via walk_function+walk_gimple_stmt, rewrite all references to VAR | |
1657 and PARM_DECLs that were referenced by inner nested functions. | |
1658 The rewrite will be a structure reference to the local frame variable. */ | |
1659 | |
1660 static tree | |
1661 convert_local_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p, | |
1662 struct walk_stmt_info *wi) | |
1663 { | |
1664 struct nesting_info *info = (struct nesting_info *) wi->info; | |
1665 tree save_local_var_chain; | |
1666 bitmap save_suppress; | |
1667 gimple stmt = gsi_stmt (*gsi); | |
1668 | |
1669 switch (gimple_code (stmt)) | |
1670 { | |
1671 case GIMPLE_OMP_PARALLEL: | |
1672 case GIMPLE_OMP_TASK: | |
1673 save_suppress = info->suppress_expansion; | |
1674 if (convert_local_omp_clauses (gimple_omp_taskreg_clauses_ptr (stmt), | |
1675 wi)) | |
1676 { | |
1677 tree c; | |
1678 (void) get_frame_type (info); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1679 c = build_omp_clause (gimple_location (stmt), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1680 OMP_CLAUSE_SHARED); |
0 | 1681 OMP_CLAUSE_DECL (c) = info->frame_decl; |
1682 OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt); | |
1683 gimple_omp_taskreg_set_clauses (stmt, c); | |
1684 } | |
1685 | |
1686 save_local_var_chain = info->new_local_var_chain; | |
1687 info->new_local_var_chain = NULL; | |
1688 | |
1689 walk_body (convert_local_reference_stmt, convert_local_reference_op, info, | |
1690 gimple_omp_body (stmt)); | |
1691 | |
1692 if (info->new_local_var_chain) | |
1693 declare_vars (info->new_local_var_chain, | |
1694 gimple_seq_first_stmt (gimple_omp_body (stmt)), false); | |
1695 info->new_local_var_chain = save_local_var_chain; | |
1696 info->suppress_expansion = save_suppress; | |
1697 break; | |
1698 | |
1699 case GIMPLE_OMP_FOR: | |
1700 save_suppress = info->suppress_expansion; | |
1701 convert_local_omp_clauses (gimple_omp_for_clauses_ptr (stmt), wi); | |
1702 walk_gimple_omp_for (stmt, convert_local_reference_stmt, | |
1703 convert_local_reference_op, info); | |
1704 walk_body (convert_local_reference_stmt, convert_local_reference_op, | |
1705 info, gimple_omp_body (stmt)); | |
1706 info->suppress_expansion = save_suppress; | |
1707 break; | |
1708 | |
1709 case GIMPLE_OMP_SECTIONS: | |
1710 save_suppress = info->suppress_expansion; | |
1711 convert_local_omp_clauses (gimple_omp_sections_clauses_ptr (stmt), wi); | |
1712 walk_body (convert_local_reference_stmt, convert_local_reference_op, | |
1713 info, gimple_omp_body (stmt)); | |
1714 info->suppress_expansion = save_suppress; | |
1715 break; | |
1716 | |
1717 case GIMPLE_OMP_SINGLE: | |
1718 save_suppress = info->suppress_expansion; | |
1719 convert_local_omp_clauses (gimple_omp_single_clauses_ptr (stmt), wi); | |
1720 walk_body (convert_local_reference_stmt, convert_local_reference_op, | |
1721 info, gimple_omp_body (stmt)); | |
1722 info->suppress_expansion = save_suppress; | |
1723 break; | |
1724 | |
1725 case GIMPLE_OMP_SECTION: | |
1726 case GIMPLE_OMP_MASTER: | |
1727 case GIMPLE_OMP_ORDERED: | |
1728 walk_body (convert_local_reference_stmt, convert_local_reference_op, | |
1729 info, gimple_omp_body (stmt)); | |
1730 break; | |
1731 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1732 case GIMPLE_COND: |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1733 wi->val_only = true; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1734 wi->is_lhs = false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1735 *handled_ops_p = false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1736 return NULL_TREE; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1737 |
0 | 1738 default: |
1739 /* For every other statement that we are not interested in | |
1740 handling here, let the walker traverse the operands. */ | |
1741 *handled_ops_p = false; | |
1742 return NULL_TREE; | |
1743 } | |
1744 | |
1745 /* Indicate that we have handled all the operands ourselves. */ | |
1746 *handled_ops_p = true; | |
1747 return NULL_TREE; | |
1748 } | |
1749 | |
1750 | |
1751 /* Called via walk_function+walk_gimple_stmt, rewrite all GIMPLE_GOTOs | |
1752 that reference labels from outer functions. The rewrite will be a | |
1753 call to __builtin_nonlocal_goto. */ | |
1754 | |
1755 static tree | |
1756 convert_nl_goto_reference (gimple_stmt_iterator *gsi, bool *handled_ops_p, | |
1757 struct walk_stmt_info *wi) | |
1758 { | |
1759 struct nesting_info *const info = (struct nesting_info *) wi->info, *i; | |
1760 tree label, new_label, target_context, x, field; | |
1761 void **slot; | |
1762 gimple call; | |
1763 gimple stmt = gsi_stmt (*gsi); | |
1764 | |
1765 if (gimple_code (stmt) != GIMPLE_GOTO) | |
1766 { | |
1767 *handled_ops_p = false; | |
1768 return NULL_TREE; | |
1769 } | |
1770 | |
1771 label = gimple_goto_dest (stmt); | |
1772 if (TREE_CODE (label) != LABEL_DECL) | |
1773 { | |
1774 *handled_ops_p = false; | |
1775 return NULL_TREE; | |
1776 } | |
1777 | |
1778 target_context = decl_function_context (label); | |
1779 if (target_context == info->context) | |
1780 { | |
1781 *handled_ops_p = false; | |
1782 return NULL_TREE; | |
1783 } | |
1784 | |
1785 for (i = info->outer; target_context != i->context; i = i->outer) | |
1786 continue; | |
1787 | |
1788 /* The original user label may also be use for a normal goto, therefore | |
1789 we must create a new label that will actually receive the abnormal | |
1790 control transfer. This new label will be marked LABEL_NONLOCAL; this | |
1791 mark will trigger proper behavior in the cfg, as well as cause the | |
1792 (hairy target-specific) non-local goto receiver code to be generated | |
1793 when we expand rtl. Enter this association into var_map so that we | |
1794 can insert the new label into the IL during a second pass. */ | |
1795 slot = pointer_map_insert (i->var_map, label); | |
1796 if (*slot == NULL) | |
1797 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1798 new_label = create_artificial_label (UNKNOWN_LOCATION); |
0 | 1799 DECL_NONLOCAL (new_label) = 1; |
1800 *slot = new_label; | |
1801 } | |
1802 else | |
1803 new_label = (tree) *slot; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1804 |
0 | 1805 /* Build: __builtin_nl_goto(new_label, &chain->nl_goto_field). */ |
1806 field = get_nl_goto_field (i); | |
1807 x = get_frame_field (info, target_context, field, &wi->gsi); | |
1808 x = build_addr (x, target_context); | |
1809 x = gsi_gimplify_val (info, x, &wi->gsi); | |
1810 call = gimple_build_call (implicit_built_in_decls[BUILT_IN_NONLOCAL_GOTO], 2, | |
1811 build_addr (new_label, target_context), x); | |
1812 gsi_replace (&wi->gsi, call, false); | |
1813 | |
1814 /* We have handled all of STMT's operands, no need to keep going. */ | |
1815 *handled_ops_p = true; | |
1816 return NULL_TREE; | |
1817 } | |
1818 | |
1819 | |
1820 /* Called via walk_function+walk_tree, rewrite all GIMPLE_LABELs whose labels | |
1821 are referenced via nonlocal goto from a nested function. The rewrite | |
1822 will involve installing a newly generated DECL_NONLOCAL label, and | |
1823 (potentially) a branch around the rtl gunk that is assumed to be | |
1824 attached to such a label. */ | |
1825 | |
1826 static tree | |
1827 convert_nl_goto_receiver (gimple_stmt_iterator *gsi, bool *handled_ops_p, | |
1828 struct walk_stmt_info *wi) | |
1829 { | |
1830 struct nesting_info *const info = (struct nesting_info *) wi->info; | |
1831 tree label, new_label; | |
1832 gimple_stmt_iterator tmp_gsi; | |
1833 void **slot; | |
1834 gimple stmt = gsi_stmt (*gsi); | |
1835 | |
1836 if (gimple_code (stmt) != GIMPLE_LABEL) | |
1837 { | |
1838 *handled_ops_p = false; | |
1839 return NULL_TREE; | |
1840 } | |
1841 | |
1842 label = gimple_label_label (stmt); | |
1843 | |
1844 slot = pointer_map_contains (info->var_map, label); | |
1845 if (!slot) | |
1846 { | |
1847 *handled_ops_p = false; | |
1848 return NULL_TREE; | |
1849 } | |
1850 | |
1851 /* If there's any possibility that the previous statement falls through, | |
1852 then we must branch around the new non-local label. */ | |
1853 tmp_gsi = wi->gsi; | |
1854 gsi_prev (&tmp_gsi); | |
1855 if (gsi_end_p (tmp_gsi) || gimple_stmt_may_fallthru (gsi_stmt (tmp_gsi))) | |
1856 { | |
1857 gimple stmt = gimple_build_goto (label); | |
1858 gsi_insert_before (gsi, stmt, GSI_SAME_STMT); | |
1859 } | |
1860 | |
1861 new_label = (tree) *slot; | |
1862 stmt = gimple_build_label (new_label); | |
1863 gsi_insert_before (gsi, stmt, GSI_SAME_STMT); | |
1864 | |
1865 *handled_ops_p = true; | |
1866 return NULL_TREE; | |
1867 } | |
1868 | |
1869 | |
1870 /* Called via walk_function+walk_stmt, rewrite all references to addresses | |
1871 of nested functions that require the use of trampolines. The rewrite | |
1872 will involve a reference a trampoline generated for the occasion. */ | |
1873 | |
1874 static tree | |
1875 convert_tramp_reference_op (tree *tp, int *walk_subtrees, void *data) | |
1876 { | |
1877 struct walk_stmt_info *wi = (struct walk_stmt_info *) data; | |
1878 struct nesting_info *const info = (struct nesting_info *) wi->info, *i; | |
1879 tree t = *tp, decl, target_context, x, builtin; | |
1880 gimple call; | |
1881 | |
1882 *walk_subtrees = 0; | |
1883 switch (TREE_CODE (t)) | |
1884 { | |
1885 case ADDR_EXPR: | |
1886 /* Build | |
1887 T.1 = &CHAIN->tramp; | |
1888 T.2 = __builtin_adjust_trampoline (T.1); | |
1889 T.3 = (func_type)T.2; | |
1890 */ | |
1891 | |
1892 decl = TREE_OPERAND (t, 0); | |
1893 if (TREE_CODE (decl) != FUNCTION_DECL) | |
1894 break; | |
1895 | |
1896 /* Only need to process nested functions. */ | |
1897 target_context = decl_function_context (decl); | |
1898 if (!target_context) | |
1899 break; | |
1900 | |
1901 /* If the nested function doesn't use a static chain, then | |
1902 it doesn't need a trampoline. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1903 if (!DECL_STATIC_CHAIN (decl)) |
0 | 1904 break; |
1905 | |
1906 /* If we don't want a trampoline, then don't build one. */ | |
1907 if (TREE_NO_TRAMPOLINE (t)) | |
1908 break; | |
1909 | |
1910 /* Lookup the immediate parent of the callee, as that's where | |
1911 we need to insert the trampoline. */ | |
1912 for (i = info; i->context != target_context; i = i->outer) | |
1913 continue; | |
1914 x = lookup_tramp_for_decl (i, decl, INSERT); | |
1915 | |
1916 /* Compute the address of the field holding the trampoline. */ | |
1917 x = get_frame_field (info, target_context, x, &wi->gsi); | |
1918 x = build_addr (x, target_context); | |
1919 x = gsi_gimplify_val (info, x, &wi->gsi); | |
1920 | |
1921 /* Do machine-specific ugliness. Normally this will involve | |
1922 computing extra alignment, but it can really be anything. */ | |
1923 builtin = implicit_built_in_decls[BUILT_IN_ADJUST_TRAMPOLINE]; | |
1924 call = gimple_build_call (builtin, 1, x); | |
1925 x = init_tmp_var_with_call (info, &wi->gsi, call); | |
1926 | |
1927 /* Cast back to the proper function type. */ | |
1928 x = build1 (NOP_EXPR, TREE_TYPE (t), x); | |
1929 x = init_tmp_var (info, x, &wi->gsi); | |
1930 | |
1931 *tp = x; | |
1932 break; | |
1933 | |
1934 default: | |
1935 if (!IS_TYPE_OR_DECL_P (t)) | |
1936 *walk_subtrees = 1; | |
1937 break; | |
1938 } | |
1939 | |
1940 return NULL_TREE; | |
1941 } | |
1942 | |
1943 | |
1944 /* Called via walk_function+walk_gimple_stmt, rewrite all references | |
1945 to addresses of nested functions that require the use of | |
1946 trampolines. The rewrite will involve a reference a trampoline | |
1947 generated for the occasion. */ | |
1948 | |
1949 static tree | |
1950 convert_tramp_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p, | |
1951 struct walk_stmt_info *wi) | |
1952 { | |
1953 gimple stmt = gsi_stmt (*gsi); | |
1954 | |
1955 switch (gimple_code (stmt)) | |
1956 { | |
1957 case GIMPLE_CALL: | |
1958 { | |
1959 /* Only walk call arguments, lest we generate trampolines for | |
1960 direct calls. */ | |
1961 unsigned long i, nargs = gimple_call_num_args (stmt); | |
1962 for (i = 0; i < nargs; i++) | |
1963 walk_tree (gimple_call_arg_ptr (stmt, i), convert_tramp_reference_op, | |
1964 wi, NULL); | |
1965 | |
1966 *handled_ops_p = true; | |
1967 return NULL_TREE; | |
1968 } | |
1969 | |
1970 default: | |
1971 break; | |
1972 } | |
1973 | |
1974 *handled_ops_p = false; | |
1975 return NULL_TREE; | |
1976 } | |
1977 | |
1978 | |
1979 | |
1980 /* Called via walk_function+walk_gimple_stmt, rewrite all GIMPLE_CALLs | |
1981 that reference nested functions to make sure that the static chain | |
1982 is set up properly for the call. */ | |
1983 | |
1984 static tree | |
1985 convert_gimple_call (gimple_stmt_iterator *gsi, bool *handled_ops_p, | |
1986 struct walk_stmt_info *wi) | |
1987 { | |
1988 struct nesting_info *const info = (struct nesting_info *) wi->info; | |
1989 tree decl, target_context; | |
1990 char save_static_chain_added; | |
1991 int i; | |
1992 gimple stmt = gsi_stmt (*gsi); | |
1993 | |
1994 switch (gimple_code (stmt)) | |
1995 { | |
1996 case GIMPLE_CALL: | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1997 if (gimple_call_chain (stmt)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1998 break; |
0 | 1999 decl = gimple_call_fndecl (stmt); |
2000 if (!decl) | |
2001 break; | |
2002 target_context = decl_function_context (decl); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2003 if (target_context && DECL_STATIC_CHAIN (decl)) |
0 | 2004 { |
2005 gimple_call_set_chain (stmt, get_static_chain (info, target_context, | |
2006 &wi->gsi)); | |
2007 info->static_chain_added |= (1 << (info->context != target_context)); | |
2008 } | |
2009 break; | |
2010 | |
2011 case GIMPLE_OMP_PARALLEL: | |
2012 case GIMPLE_OMP_TASK: | |
2013 save_static_chain_added = info->static_chain_added; | |
2014 info->static_chain_added = 0; | |
2015 walk_body (convert_gimple_call, NULL, info, gimple_omp_body (stmt)); | |
2016 for (i = 0; i < 2; i++) | |
2017 { | |
2018 tree c, decl; | |
2019 if ((info->static_chain_added & (1 << i)) == 0) | |
2020 continue; | |
2021 decl = i ? get_chain_decl (info) : info->frame_decl; | |
2022 /* Don't add CHAIN.* or FRAME.* twice. */ | |
2023 for (c = gimple_omp_taskreg_clauses (stmt); | |
2024 c; | |
2025 c = OMP_CLAUSE_CHAIN (c)) | |
2026 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE | |
2027 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED) | |
2028 && OMP_CLAUSE_DECL (c) == decl) | |
2029 break; | |
2030 if (c == NULL) | |
2031 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2032 c = build_omp_clause (gimple_location (stmt), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2033 i ? OMP_CLAUSE_FIRSTPRIVATE |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2034 : OMP_CLAUSE_SHARED); |
0 | 2035 OMP_CLAUSE_DECL (c) = decl; |
2036 OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt); | |
2037 gimple_omp_taskreg_set_clauses (stmt, c); | |
2038 } | |
2039 } | |
2040 info->static_chain_added |= save_static_chain_added; | |
2041 break; | |
2042 | |
2043 case GIMPLE_OMP_FOR: | |
2044 walk_body (convert_gimple_call, NULL, info, | |
2045 gimple_omp_for_pre_body (stmt)); | |
2046 /* FALLTHRU */ | |
2047 case GIMPLE_OMP_SECTIONS: | |
2048 case GIMPLE_OMP_SECTION: | |
2049 case GIMPLE_OMP_SINGLE: | |
2050 case GIMPLE_OMP_MASTER: | |
2051 case GIMPLE_OMP_ORDERED: | |
2052 case GIMPLE_OMP_CRITICAL: | |
2053 walk_body (convert_gimple_call, NULL, info, gimple_omp_body (stmt)); | |
2054 break; | |
2055 | |
2056 default: | |
2057 /* Keep looking for other operands. */ | |
2058 *handled_ops_p = false; | |
2059 return NULL_TREE; | |
2060 } | |
2061 | |
2062 *handled_ops_p = true; | |
2063 return NULL_TREE; | |
2064 } | |
2065 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2066 /* Walk the nesting tree starting with ROOT. Convert all trampolines and |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2067 call expressions. At the same time, determine if a nested function |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2068 actually uses its static chain; if not, remember that. */ |
0 | 2069 |
2070 static void | |
2071 convert_all_function_calls (struct nesting_info *root) | |
2072 { | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2073 unsigned int chain_count = 0, old_chain_count, iter_count; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2074 struct nesting_info *n; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2075 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2076 /* First, optimistically clear static_chain for all decls that haven't |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2077 used the static chain already for variable access. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2078 FOR_EACH_NEST_INFO (n, root) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2079 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2080 tree decl = n->context; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2081 if (!n->outer || (!n->chain_decl && !n->chain_field)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2082 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2083 DECL_STATIC_CHAIN (decl) = 0; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2084 if (dump_file && (dump_flags & TDF_DETAILS)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2085 fprintf (dump_file, "Guessing no static-chain for %s\n", |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2086 lang_hooks.decl_printable_name (decl, 2)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2087 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2088 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2089 DECL_STATIC_CHAIN (decl) = 1; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2090 chain_count += DECL_STATIC_CHAIN (decl); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2091 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2092 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2093 /* Walk the functions and perform transformations. Note that these |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2094 transformations can induce new uses of the static chain, which in turn |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2095 require re-examining all users of the decl. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2096 /* ??? It would make sense to try to use the call graph to speed this up, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2097 but the call graph hasn't really been built yet. Even if it did, we |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2098 would still need to iterate in this loop since address-of references |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2099 wouldn't show up in the callgraph anyway. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2100 iter_count = 0; |
0 | 2101 do |
2102 { | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2103 old_chain_count = chain_count; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2104 chain_count = 0; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2105 iter_count++; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2106 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2107 if (dump_file && (dump_flags & TDF_DETAILS)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2108 fputc ('\n', dump_file); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2109 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2110 FOR_EACH_NEST_INFO (n, root) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2111 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2112 tree decl = n->context; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2113 walk_function (convert_tramp_reference_stmt, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2114 convert_tramp_reference_op, n); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2115 walk_function (convert_gimple_call, NULL, n); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2116 chain_count += DECL_STATIC_CHAIN (decl); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2117 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2118 } |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2119 while (chain_count != old_chain_count); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2120 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2121 if (dump_file && (dump_flags & TDF_DETAILS)) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2122 fprintf (dump_file, "convert_all_function_calls iterations: %u\n\n", |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2123 iter_count); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2124 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2125 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2126 struct nesting_copy_body_data |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2127 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2128 copy_body_data cb; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2129 struct nesting_info *root; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2130 }; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2131 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2132 /* A helper subroutine for debug_var_chain type remapping. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2133 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2134 static tree |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2135 nesting_copy_decl (tree decl, copy_body_data *id) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2136 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2137 struct nesting_copy_body_data *nid = (struct nesting_copy_body_data *) id; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2138 void **slot = pointer_map_contains (nid->root->var_map, decl); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2139 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2140 if (slot) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2141 return (tree) *slot; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2142 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2143 if (TREE_CODE (decl) == TYPE_DECL && DECL_ORIGINAL_TYPE (decl)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2144 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2145 tree new_decl = copy_decl_no_change (decl, id); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2146 DECL_ORIGINAL_TYPE (new_decl) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2147 = remap_type (DECL_ORIGINAL_TYPE (decl), id); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2148 return new_decl; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2149 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2150 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2151 if (TREE_CODE (decl) == VAR_DECL |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2152 || TREE_CODE (decl) == PARM_DECL |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2153 || TREE_CODE (decl) == RESULT_DECL) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2154 return decl; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2155 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2156 return copy_decl_no_change (decl, id); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2157 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2158 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2159 /* A helper function for remap_vla_decls. See if *TP contains |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2160 some remapped variables. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2161 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2162 static tree |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2163 contains_remapped_vars (tree *tp, int *walk_subtrees, void *data) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2164 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2165 struct nesting_info *root = (struct nesting_info *) data; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2166 tree t = *tp; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2167 void **slot; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2168 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2169 if (DECL_P (t)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2170 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2171 *walk_subtrees = 0; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2172 slot = pointer_map_contains (root->var_map, t); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2173 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2174 if (slot) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2175 return (tree) *slot; |
0 | 2176 } |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2177 return NULL; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2178 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2179 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2180 /* Remap VLA decls in BLOCK and subblocks if remapped variables are |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2181 involved. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2182 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2183 static void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2184 remap_vla_decls (tree block, struct nesting_info *root) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2185 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2186 tree var, subblock, val, type; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2187 struct nesting_copy_body_data id; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2188 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2189 for (subblock = BLOCK_SUBBLOCKS (block); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2190 subblock; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2191 subblock = BLOCK_CHAIN (subblock)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2192 remap_vla_decls (subblock, root); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2193 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2194 for (var = BLOCK_VARS (block); var; var = DECL_CHAIN (var)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2195 if (TREE_CODE (var) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (var)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2196 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2197 val = DECL_VALUE_EXPR (var); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2198 type = TREE_TYPE (var); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2199 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2200 if (!(TREE_CODE (val) == INDIRECT_REF |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2201 && TREE_CODE (TREE_OPERAND (val, 0)) == VAR_DECL |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2202 && variably_modified_type_p (type, NULL))) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2203 continue; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2204 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2205 if (pointer_map_contains (root->var_map, TREE_OPERAND (val, 0)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2206 || walk_tree (&type, contains_remapped_vars, root, NULL)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2207 break; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2208 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2209 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2210 if (var == NULL_TREE) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2211 return; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2212 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2213 memset (&id, 0, sizeof (id)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2214 id.cb.copy_decl = nesting_copy_decl; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2215 id.cb.decl_map = pointer_map_create (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2216 id.root = root; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2217 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2218 for (; var; var = DECL_CHAIN (var)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2219 if (TREE_CODE (var) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (var)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2220 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2221 struct nesting_info *i; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2222 tree newt, context; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2223 void **slot; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2224 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2225 val = DECL_VALUE_EXPR (var); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2226 type = TREE_TYPE (var); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2227 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2228 if (!(TREE_CODE (val) == INDIRECT_REF |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2229 && TREE_CODE (TREE_OPERAND (val, 0)) == VAR_DECL |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2230 && variably_modified_type_p (type, NULL))) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2231 continue; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2232 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2233 slot = pointer_map_contains (root->var_map, TREE_OPERAND (val, 0)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2234 if (!slot && !walk_tree (&type, contains_remapped_vars, root, NULL)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2235 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2236 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2237 context = decl_function_context (var); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2238 for (i = root; i; i = i->outer) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2239 if (i->context == context) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2240 break; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2241 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2242 if (i == NULL) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2243 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2244 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2245 /* Fully expand value expressions. This avoids having debug variables |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2246 only referenced from them and that can be swept during GC. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2247 if (slot) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2248 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2249 tree t = (tree) *slot; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2250 gcc_assert (DECL_P (t) && DECL_HAS_VALUE_EXPR_P (t)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2251 val = build1 (INDIRECT_REF, TREE_TYPE (val), DECL_VALUE_EXPR (t)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2252 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2253 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2254 id.cb.src_fn = i->context; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2255 id.cb.dst_fn = i->context; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2256 id.cb.src_cfun = DECL_STRUCT_FUNCTION (root->context); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2257 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2258 TREE_TYPE (var) = newt = remap_type (type, &id.cb); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2259 while (POINTER_TYPE_P (newt) && !TYPE_NAME (newt)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2260 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2261 newt = TREE_TYPE (newt); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2262 type = TREE_TYPE (type); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2263 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2264 if (TYPE_NAME (newt) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2265 && TREE_CODE (TYPE_NAME (newt)) == TYPE_DECL |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2266 && DECL_ORIGINAL_TYPE (TYPE_NAME (newt)) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2267 && newt != type |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2268 && TYPE_NAME (newt) == TYPE_NAME (type)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2269 TYPE_NAME (newt) = remap_decl (TYPE_NAME (newt), &id.cb); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2270 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2271 walk_tree (&val, copy_tree_body_r, &id.cb, NULL); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2272 if (val != DECL_VALUE_EXPR (var)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2273 SET_DECL_VALUE_EXPR (var, val); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2274 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2275 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2276 pointer_map_destroy (id.cb.decl_map); |
0 | 2277 } |
2278 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2279 /* Fold the MEM_REF *E. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2280 static bool |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2281 fold_mem_refs (const void *e, void *data ATTRIBUTE_UNUSED) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2282 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2283 tree *ref_p = CONST_CAST2(tree *, const tree *, (const tree *)e); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2284 *ref_p = fold (*ref_p); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2285 return true; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2286 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2287 |
0 | 2288 /* Do "everything else" to clean up or complete state collected by the |
2289 various walking passes -- lay out the types and decls, generate code | |
2290 to initialize the frame decl, store critical expressions in the | |
2291 struct function for rtl to find. */ | |
2292 | |
2293 static void | |
2294 finalize_nesting_tree_1 (struct nesting_info *root) | |
2295 { | |
2296 gimple_seq stmt_list; | |
2297 gimple stmt; | |
2298 tree context = root->context; | |
2299 struct function *sf; | |
2300 | |
2301 stmt_list = NULL; | |
2302 | |
2303 /* If we created a non-local frame type or decl, we need to lay them | |
2304 out at this time. */ | |
2305 if (root->frame_type) | |
2306 { | |
2307 /* In some cases the frame type will trigger the -Wpadded warning. | |
2308 This is not helpful; suppress it. */ | |
2309 int save_warn_padded = warn_padded; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2310 tree *adjust; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2311 |
0 | 2312 warn_padded = 0; |
2313 layout_type (root->frame_type); | |
2314 warn_padded = save_warn_padded; | |
2315 layout_decl (root->frame_decl, 0); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2316 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2317 /* Remove root->frame_decl from root->new_local_var_chain, so |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2318 that we can declare it also in the lexical blocks, which |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2319 helps ensure virtual regs that end up appearing in its RTL |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2320 expression get substituted in instantiate_virtual_regs(). */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2321 for (adjust = &root->new_local_var_chain; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2322 *adjust != root->frame_decl; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2323 adjust = &DECL_CHAIN (*adjust)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2324 gcc_assert (DECL_CHAIN (*adjust)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2325 *adjust = DECL_CHAIN (*adjust); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2326 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2327 DECL_CHAIN (root->frame_decl) = NULL_TREE; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2328 declare_vars (root->frame_decl, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2329 gimple_seq_first_stmt (gimple_body (context)), true); |
0 | 2330 } |
2331 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2332 /* If any parameters were referenced non-locally, then we need to |
0 | 2333 insert a copy. Likewise, if any variables were referenced by |
2334 pointer, we need to initialize the address. */ | |
2335 if (root->any_parm_remapped) | |
2336 { | |
2337 tree p; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2338 for (p = DECL_ARGUMENTS (context); p ; p = DECL_CHAIN (p)) |
0 | 2339 { |
2340 tree field, x, y; | |
2341 | |
2342 field = lookup_field_for_decl (root, p, NO_INSERT); | |
2343 if (!field) | |
2344 continue; | |
2345 | |
2346 if (use_pointer_in_frame (p)) | |
2347 x = build_addr (p, context); | |
2348 else | |
2349 x = p; | |
2350 | |
2351 y = build3 (COMPONENT_REF, TREE_TYPE (field), | |
2352 root->frame_decl, field, NULL_TREE); | |
2353 stmt = gimple_build_assign (y, x); | |
2354 gimple_seq_add_stmt (&stmt_list, stmt); | |
2355 /* If the assignment is from a non-register the stmt is | |
2356 not valid gimple. Make it so by using a temporary instead. */ | |
2357 if (!is_gimple_reg (x) | |
2358 && is_gimple_reg_type (TREE_TYPE (x))) | |
2359 { | |
2360 gimple_stmt_iterator gsi = gsi_last (stmt_list); | |
2361 x = init_tmp_var (root, x, &gsi); | |
2362 gimple_assign_set_rhs1 (stmt, x); | |
2363 } | |
2364 } | |
2365 } | |
2366 | |
2367 /* If a chain_field was created, then it needs to be initialized | |
2368 from chain_decl. */ | |
2369 if (root->chain_field) | |
2370 { | |
2371 tree x = build3 (COMPONENT_REF, TREE_TYPE (root->chain_field), | |
2372 root->frame_decl, root->chain_field, NULL_TREE); | |
2373 stmt = gimple_build_assign (x, get_chain_decl (root)); | |
2374 gimple_seq_add_stmt (&stmt_list, stmt); | |
2375 } | |
2376 | |
2377 /* If trampolines were created, then we need to initialize them. */ | |
2378 if (root->any_tramp_created) | |
2379 { | |
2380 struct nesting_info *i; | |
2381 for (i = root->inner; i ; i = i->next) | |
2382 { | |
2383 tree arg1, arg2, arg3, x, field; | |
2384 | |
2385 field = lookup_tramp_for_decl (root, i->context, NO_INSERT); | |
2386 if (!field) | |
2387 continue; | |
2388 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2389 gcc_assert (DECL_STATIC_CHAIN (i->context)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2390 arg3 = build_addr (root->frame_decl, context); |
0 | 2391 |
2392 arg2 = build_addr (i->context, context); | |
2393 | |
2394 x = build3 (COMPONENT_REF, TREE_TYPE (field), | |
2395 root->frame_decl, field, NULL_TREE); | |
2396 arg1 = build_addr (x, context); | |
2397 | |
2398 x = implicit_built_in_decls[BUILT_IN_INIT_TRAMPOLINE]; | |
2399 stmt = gimple_build_call (x, 3, arg1, arg2, arg3); | |
2400 gimple_seq_add_stmt (&stmt_list, stmt); | |
2401 } | |
2402 } | |
2403 | |
2404 /* If we created initialization statements, insert them. */ | |
2405 if (stmt_list) | |
2406 { | |
2407 gimple bind; | |
2408 annotate_all_with_location (stmt_list, DECL_SOURCE_LOCATION (context)); | |
2409 bind = gimple_seq_first_stmt (gimple_body (context)); | |
2410 gimple_seq_add_seq (&stmt_list, gimple_bind_body (bind)); | |
2411 gimple_bind_set_body (bind, stmt_list); | |
2412 } | |
2413 | |
2414 /* If a chain_decl was created, then it needs to be registered with | |
2415 struct function so that it gets initialized from the static chain | |
2416 register at the beginning of the function. */ | |
2417 sf = DECL_STRUCT_FUNCTION (root->context); | |
2418 sf->static_chain_decl = root->chain_decl; | |
2419 | |
2420 /* Similarly for the non-local goto save area. */ | |
2421 if (root->nl_goto_field) | |
2422 { | |
2423 sf->nonlocal_goto_save_area | |
2424 = get_frame_field (root, context, root->nl_goto_field, NULL); | |
2425 sf->has_nonlocal_label = 1; | |
2426 } | |
2427 | |
2428 /* Make sure all new local variables get inserted into the | |
2429 proper BIND_EXPR. */ | |
2430 if (root->new_local_var_chain) | |
2431 declare_vars (root->new_local_var_chain, | |
2432 gimple_seq_first_stmt (gimple_body (root->context)), | |
2433 false); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2434 |
0 | 2435 if (root->debug_var_chain) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2436 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2437 tree debug_var; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2438 gimple scope; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2439 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2440 remap_vla_decls (DECL_INITIAL (root->context), root); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2441 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2442 for (debug_var = root->debug_var_chain; debug_var; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2443 debug_var = DECL_CHAIN (debug_var)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2444 if (variably_modified_type_p (TREE_TYPE (debug_var), NULL)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2445 break; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2446 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2447 /* If there are any debug decls with variable length types, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2448 remap those types using other debug_var_chain variables. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2449 if (debug_var) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2450 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2451 struct nesting_copy_body_data id; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2452 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2453 memset (&id, 0, sizeof (id)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2454 id.cb.copy_decl = nesting_copy_decl; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2455 id.cb.decl_map = pointer_map_create (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2456 id.root = root; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2457 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2458 for (; debug_var; debug_var = DECL_CHAIN (debug_var)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2459 if (variably_modified_type_p (TREE_TYPE (debug_var), NULL)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2460 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2461 tree type = TREE_TYPE (debug_var); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2462 tree newt, t = type; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2463 struct nesting_info *i; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2464 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2465 for (i = root; i; i = i->outer) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2466 if (variably_modified_type_p (type, i->context)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2467 break; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2468 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2469 if (i == NULL) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2470 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2471 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2472 id.cb.src_fn = i->context; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2473 id.cb.dst_fn = i->context; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2474 id.cb.src_cfun = DECL_STRUCT_FUNCTION (root->context); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2475 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2476 TREE_TYPE (debug_var) = newt = remap_type (type, &id.cb); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2477 while (POINTER_TYPE_P (newt) && !TYPE_NAME (newt)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2478 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2479 newt = TREE_TYPE (newt); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2480 t = TREE_TYPE (t); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2481 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2482 if (TYPE_NAME (newt) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2483 && TREE_CODE (TYPE_NAME (newt)) == TYPE_DECL |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2484 && DECL_ORIGINAL_TYPE (TYPE_NAME (newt)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2485 && newt != t |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2486 && TYPE_NAME (newt) == TYPE_NAME (t)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2487 TYPE_NAME (newt) = remap_decl (TYPE_NAME (newt), &id.cb); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2488 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2489 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2490 pointer_map_destroy (id.cb.decl_map); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2491 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2492 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2493 scope = gimple_seq_first_stmt (gimple_body (root->context)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2494 if (gimple_bind_block (scope)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2495 declare_vars (root->debug_var_chain, scope, true); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2496 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2497 BLOCK_VARS (DECL_INITIAL (root->context)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2498 = chainon (BLOCK_VARS (DECL_INITIAL (root->context)), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2499 root->debug_var_chain); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2500 } |
0 | 2501 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2502 /* Fold the rewritten MEM_REF trees. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2503 pointer_set_traverse (root->mem_refs, fold_mem_refs, NULL); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2504 |
0 | 2505 /* Dump the translated tree function. */ |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2506 if (dump_file) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2507 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2508 fputs ("\n\n", dump_file); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2509 dump_function_to_file (root->context, dump_file, dump_flags); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2510 } |
0 | 2511 } |
2512 | |
2513 static void | |
2514 finalize_nesting_tree (struct nesting_info *root) | |
2515 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2516 struct nesting_info *n; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2517 FOR_EACH_NEST_INFO (n, root) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2518 finalize_nesting_tree_1 (n); |
0 | 2519 } |
2520 | |
2521 /* Unnest the nodes and pass them to cgraph. */ | |
2522 | |
2523 static void | |
2524 unnest_nesting_tree_1 (struct nesting_info *root) | |
2525 { | |
2526 struct cgraph_node *node = cgraph_node (root->context); | |
2527 | |
2528 /* For nested functions update the cgraph to reflect unnesting. | |
2529 We also delay finalizing of these functions up to this point. */ | |
2530 if (node->origin) | |
2531 { | |
2532 cgraph_unnest_node (cgraph_node (root->context)); | |
2533 cgraph_finalize_function (root->context, true); | |
2534 } | |
2535 } | |
2536 | |
2537 static void | |
2538 unnest_nesting_tree (struct nesting_info *root) | |
2539 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2540 struct nesting_info *n; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2541 FOR_EACH_NEST_INFO (n, root) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2542 unnest_nesting_tree_1 (n); |
0 | 2543 } |
2544 | |
2545 /* Free the data structures allocated during this pass. */ | |
2546 | |
2547 static void | |
2548 free_nesting_tree (struct nesting_info *root) | |
2549 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2550 struct nesting_info *node, *next; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2551 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2552 node = iter_nestinfo_start (root); |
0 | 2553 do |
2554 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2555 next = iter_nestinfo_next (node); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2556 pointer_map_destroy (node->var_map); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2557 pointer_map_destroy (node->field_map); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2558 pointer_set_destroy (node->mem_refs); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2559 free (node); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2560 node = next; |
0 | 2561 } |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2562 while (node); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2563 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2564 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2565 /* Gimplify a function and all its nested functions. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2566 static void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2567 gimplify_all_functions (struct cgraph_node *root) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2568 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2569 struct cgraph_node *iter; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2570 if (!gimple_body (root->decl)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2571 gimplify_function_tree (root->decl); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2572 for (iter = root->nested; iter; iter = iter->next_nested) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2573 gimplify_all_functions (iter); |
0 | 2574 } |
2575 | |
2576 /* Main entry point for this pass. Process FNDECL and all of its nested | |
2577 subroutines and turn them into something less tightly bound. */ | |
2578 | |
2579 void | |
2580 lower_nested_functions (tree fndecl) | |
2581 { | |
2582 struct cgraph_node *cgn; | |
2583 struct nesting_info *root; | |
2584 | |
2585 /* If there are no nested functions, there's nothing to do. */ | |
2586 cgn = cgraph_node (fndecl); | |
2587 if (!cgn->nested) | |
2588 return; | |
2589 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2590 gimplify_all_functions (cgn); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2591 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2592 dump_file = dump_begin (TDI_nested, &dump_flags); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2593 if (dump_file) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2594 fprintf (dump_file, "\n;; Function %s\n\n", |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2595 lang_hooks.decl_printable_name (fndecl, 2)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2596 |
0 | 2597 bitmap_obstack_initialize (&nesting_info_bitmap_obstack); |
2598 root = create_nesting_tree (cgn); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2599 |
0 | 2600 walk_all_functions (convert_nonlocal_reference_stmt, |
2601 convert_nonlocal_reference_op, | |
2602 root); | |
2603 walk_all_functions (convert_local_reference_stmt, | |
2604 convert_local_reference_op, | |
2605 root); | |
2606 walk_all_functions (convert_nl_goto_reference, NULL, root); | |
2607 walk_all_functions (convert_nl_goto_receiver, NULL, root); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2608 |
0 | 2609 convert_all_function_calls (root); |
2610 finalize_nesting_tree (root); | |
2611 unnest_nesting_tree (root); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2612 |
0 | 2613 free_nesting_tree (root); |
2614 bitmap_obstack_release (&nesting_info_bitmap_obstack); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2615 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2616 if (dump_file) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2617 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2618 dump_end (TDI_nested, dump_file); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2619 dump_file = NULL; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2620 } |
0 | 2621 } |
2622 | |
2623 #include "gt-tree-nested.h" |