]>
Commit | Line | Data |
---|---|---|
6de9cd9a DN |
1 | /* Tree lowering pass. This pass converts the GENERIC functions-as-trees |
2 | tree representation into the GIMPLE form. | |
6de9cd9a DN |
3 | Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. |
4 | Major work done by Sebastian Pop <s.pop@laposte.net>, | |
5 | Diego Novillo <dnovillo@redhat.com> and Jason Merrill <jason@redhat.com>. | |
6 | ||
7 | This file is part of GCC. | |
8 | ||
9 | GCC is free software; you can redistribute it and/or modify it under | |
10 | the terms of the GNU General Public License as published by the Free | |
11 | Software Foundation; either version 2, or (at your option) any later | |
12 | version. | |
13 | ||
14 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
15 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
17 | for more details. | |
18 | ||
19 | You should have received a copy of the GNU General Public License | |
20 | along with GCC; see the file COPYING. If not, write to the Free | |
21 | Software Foundation, 59 Temple Place - Suite 330, Boston, MA | |
22 | 02111-1307, USA. */ | |
23 | ||
24 | #include "config.h" | |
25 | #include "system.h" | |
26 | #include "coretypes.h" | |
27 | #include "tm.h" | |
28 | #include "tree.h" | |
29 | #include "rtl.h" | |
30 | #include "errors.h" | |
31 | #include "varray.h" | |
eadf906f | 32 | #include "tree-gimple.h" |
6de9cd9a DN |
33 | #include "tree-inline.h" |
34 | #include "diagnostic.h" | |
35 | #include "langhooks.h" | |
36 | #include "langhooks-def.h" | |
37 | #include "tree-flow.h" | |
44de5aeb | 38 | #include "cgraph.h" |
6de9cd9a DN |
39 | #include "timevar.h" |
40 | #include "except.h" | |
41 | #include "hashtab.h" | |
42 | #include "flags.h" | |
43 | #include "real.h" | |
44 | #include "function.h" | |
45 | #include "output.h" | |
46 | #include "expr.h" | |
47 | #include "ggc.h" | |
cd3ce9b4 | 48 | #include "target.h" |
6de9cd9a DN |
49 | |
50 | static struct gimplify_ctx | |
51 | { | |
52 | tree current_bind_expr; | |
6de9cd9a DN |
53 | tree temps; |
54 | tree conditional_cleanups; | |
6de9cd9a | 55 | tree exit_label; |
71877985 | 56 | tree return_temp; |
6de9cd9a DN |
57 | varray_type case_labels; |
58 | /* The formal temporary table. Should this be persistent? */ | |
59 | htab_t temp_htab; | |
8b11a64c ZD |
60 | int conditions; |
61 | bool save_stack; | |
62 | bool into_ssa; | |
6de9cd9a DN |
63 | } *gimplify_ctxp; |
64 | ||
65 | ||
66 | /* Formal (expression) temporary table handling: Multiple occurrences of | |
67 | the same scalar expression are evaluated into the same temporary. */ | |
68 | ||
69 | typedef struct gimple_temp_hash_elt | |
70 | { | |
71 | tree val; /* Key */ | |
72 | tree temp; /* Value */ | |
73 | } elt_t; | |
74 | ||
44de5aeb | 75 | /* Forward declarations. */ |
44de5aeb | 76 | static enum gimplify_status gimplify_compound_expr (tree *, tree *, bool); |
eb6127a4 RK |
77 | |
78 | ||
6de9cd9a DN |
79 | /* Return a hash value for a formal temporary table entry. */ |
80 | ||
81 | static hashval_t | |
82 | gimple_tree_hash (const void *p) | |
83 | { | |
aa4a53af | 84 | tree t = ((const elt_t *) p)->val; |
6de9cd9a DN |
85 | return iterative_hash_expr (t, 0); |
86 | } | |
87 | ||
88 | /* Compare two formal temporary table entries. */ | |
89 | ||
90 | static int | |
91 | gimple_tree_eq (const void *p1, const void *p2) | |
92 | { | |
aa4a53af RK |
93 | tree t1 = ((const elt_t *) p1)->val; |
94 | tree t2 = ((const elt_t *) p2)->val; | |
6de9cd9a DN |
95 | enum tree_code code = TREE_CODE (t1); |
96 | ||
97 | if (TREE_CODE (t2) != code | |
98 | || TREE_TYPE (t1) != TREE_TYPE (t2)) | |
99 | return 0; | |
100 | ||
101 | if (!operand_equal_p (t1, t2, 0)) | |
102 | return 0; | |
103 | ||
104 | /* Only allow them to compare equal if they also hash equal; otherwise | |
105 | results are nondeterminate, and we fail bootstrap comparison. */ | |
106 | if (gimple_tree_hash (p1) != gimple_tree_hash (p2)) | |
107 | abort (); | |
108 | ||
109 | return 1; | |
110 | } | |
111 | ||
112 | /* Set up a context for the gimplifier. */ | |
113 | ||
114 | void | |
115 | push_gimplify_context (void) | |
116 | { | |
117 | if (gimplify_ctxp) | |
118 | abort (); | |
119 | gimplify_ctxp | |
120 | = (struct gimplify_ctx *) xcalloc (1, sizeof (struct gimplify_ctx)); | |
bbbb79d4 GK |
121 | if (optimize) |
122 | gimplify_ctxp->temp_htab | |
123 | = htab_create (1000, gimple_tree_hash, gimple_tree_eq, free); | |
124 | else | |
125 | gimplify_ctxp->temp_htab = NULL; | |
6de9cd9a DN |
126 | } |
127 | ||
128 | /* Tear down a context for the gimplifier. If BODY is non-null, then | |
129 | put the temporaries into the outer BIND_EXPR. Otherwise, put them | |
130 | in the unexpanded_var_list. */ | |
131 | ||
132 | void | |
133 | pop_gimplify_context (tree body) | |
134 | { | |
17ad5b5e RH |
135 | tree t; |
136 | ||
6de9cd9a DN |
137 | if (!gimplify_ctxp || gimplify_ctxp->current_bind_expr) |
138 | abort (); | |
139 | ||
17ad5b5e RH |
140 | for (t = gimplify_ctxp->temps; t ; t = TREE_CHAIN (t)) |
141 | DECL_GIMPLE_FORMAL_TEMP_P (t) = 0; | |
142 | ||
6de9cd9a DN |
143 | if (body) |
144 | declare_tmp_vars (gimplify_ctxp->temps, body); | |
145 | else | |
146 | record_vars (gimplify_ctxp->temps); | |
147 | ||
148 | #if 0 | |
bbbb79d4 | 149 | if (!quiet_flag && optimize) |
6de9cd9a DN |
150 | fprintf (stderr, " collisions: %f ", |
151 | htab_collisions (gimplify_ctxp->temp_htab)); | |
152 | #endif | |
153 | ||
bbbb79d4 GK |
154 | if (optimize) |
155 | htab_delete (gimplify_ctxp->temp_htab); | |
6de9cd9a DN |
156 | free (gimplify_ctxp); |
157 | gimplify_ctxp = NULL; | |
158 | } | |
159 | ||
160 | void | |
161 | gimple_push_bind_expr (tree bind) | |
162 | { | |
163 | TREE_CHAIN (bind) = gimplify_ctxp->current_bind_expr; | |
164 | gimplify_ctxp->current_bind_expr = bind; | |
165 | } | |
166 | ||
167 | void | |
168 | gimple_pop_bind_expr (void) | |
169 | { | |
170 | gimplify_ctxp->current_bind_expr | |
171 | = TREE_CHAIN (gimplify_ctxp->current_bind_expr); | |
172 | } | |
173 | ||
174 | tree | |
175 | gimple_current_bind_expr (void) | |
176 | { | |
177 | return gimplify_ctxp->current_bind_expr; | |
178 | } | |
179 | ||
180 | /* Returns true iff there is a COND_EXPR between us and the innermost | |
181 | CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */ | |
182 | ||
183 | static bool | |
184 | gimple_conditional_context (void) | |
185 | { | |
186 | return gimplify_ctxp->conditions > 0; | |
187 | } | |
188 | ||
189 | /* Note that we've entered a COND_EXPR. */ | |
190 | ||
191 | static void | |
192 | gimple_push_condition (void) | |
193 | { | |
194 | ++(gimplify_ctxp->conditions); | |
195 | } | |
196 | ||
197 | /* Note that we've left a COND_EXPR. If we're back at unconditional scope | |
198 | now, add any conditional cleanups we've seen to the prequeue. */ | |
199 | ||
200 | static void | |
201 | gimple_pop_condition (tree *pre_p) | |
202 | { | |
203 | int conds = --(gimplify_ctxp->conditions); | |
aa4a53af | 204 | |
6de9cd9a DN |
205 | if (conds == 0) |
206 | { | |
207 | append_to_statement_list (gimplify_ctxp->conditional_cleanups, pre_p); | |
208 | gimplify_ctxp->conditional_cleanups = NULL_TREE; | |
209 | } | |
210 | else if (conds < 0) | |
211 | abort (); | |
212 | } | |
213 | ||
214 | /* A subroutine of append_to_statement_list{,_force}. */ | |
215 | ||
216 | static void | |
217 | append_to_statement_list_1 (tree t, tree *list_p, bool side_effects) | |
218 | { | |
219 | tree list = *list_p; | |
220 | tree_stmt_iterator i; | |
221 | ||
be00f578 JM |
222 | if (!side_effects) |
223 | return; | |
224 | ||
6de9cd9a DN |
225 | if (!list) |
226 | { | |
227 | if (t && TREE_CODE (t) == STATEMENT_LIST) | |
228 | { | |
229 | *list_p = t; | |
230 | return; | |
231 | } | |
232 | *list_p = list = alloc_stmt_list (); | |
233 | } | |
234 | ||
6de9cd9a DN |
235 | i = tsi_last (list); |
236 | tsi_link_after (&i, t, TSI_CONTINUE_LINKING); | |
237 | } | |
238 | ||
239 | /* Add T to the end of the list container pointed by LIST_P. | |
240 | If T is an expression with no effects, it is ignored. */ | |
241 | ||
242 | void | |
243 | append_to_statement_list (tree t, tree *list_p) | |
244 | { | |
245 | append_to_statement_list_1 (t, list_p, t ? TREE_SIDE_EFFECTS (t) : false); | |
246 | } | |
247 | ||
248 | /* Similar, but the statement is always added, regardless of side effects. */ | |
249 | ||
250 | void | |
251 | append_to_statement_list_force (tree t, tree *list_p) | |
252 | { | |
253 | append_to_statement_list_1 (t, list_p, t != NULL); | |
254 | } | |
255 | ||
cd3ce9b4 JM |
256 | /* Both gimplify the statement T and append it to LIST_P. */ |
257 | ||
258 | void | |
259 | gimplify_and_add (tree t, tree *list_p) | |
260 | { | |
261 | gimplify_stmt (&t); | |
262 | append_to_statement_list (t, list_p); | |
263 | } | |
264 | ||
6de9cd9a DN |
265 | /* Strip off a legitimate source ending from the input string NAME of |
266 | length LEN. Rather than having to know the names used by all of | |
267 | our front ends, we strip off an ending of a period followed by | |
268 | up to five characters. (Java uses ".class".) */ | |
269 | ||
270 | static inline void | |
271 | remove_suffix (char *name, int len) | |
272 | { | |
273 | int i; | |
274 | ||
275 | for (i = 2; i < 8 && len > i; i++) | |
276 | { | |
277 | if (name[len - i] == '.') | |
278 | { | |
279 | name[len - i] = '\0'; | |
280 | break; | |
281 | } | |
282 | } | |
283 | } | |
284 | ||
285 | /* Create a nameless artificial label and put it in the current function | |
286 | context. Returns the newly created label. */ | |
287 | ||
288 | tree | |
289 | create_artificial_label (void) | |
290 | { | |
291 | tree lab = build_decl (LABEL_DECL, NULL_TREE, void_type_node); | |
aa4a53af | 292 | |
6de9cd9a DN |
293 | DECL_ARTIFICIAL (lab) = 1; |
294 | DECL_CONTEXT (lab) = current_function_decl; | |
295 | return lab; | |
296 | } | |
297 | ||
1ea7e6ad | 298 | /* Create a new temporary name with PREFIX. Returns an identifier. */ |
6de9cd9a DN |
299 | |
300 | static GTY(()) unsigned int tmp_var_id_num; | |
301 | ||
7e140280 | 302 | tree |
6de9cd9a DN |
303 | create_tmp_var_name (const char *prefix) |
304 | { | |
305 | char *tmp_name; | |
306 | ||
307 | if (prefix) | |
308 | { | |
309 | char *preftmp = ASTRDUP (prefix); | |
aa4a53af | 310 | |
6de9cd9a DN |
311 | remove_suffix (preftmp, strlen (preftmp)); |
312 | prefix = preftmp; | |
313 | } | |
314 | ||
315 | ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix ? prefix : "T", tmp_var_id_num++); | |
316 | return get_identifier (tmp_name); | |
317 | } | |
318 | ||
319 | ||
320 | /* Create a new temporary variable declaration of type TYPE. | |
321 | Does NOT push it into the current binding. */ | |
322 | ||
323 | tree | |
324 | create_tmp_var_raw (tree type, const char *prefix) | |
325 | { | |
326 | tree tmp_var; | |
327 | tree new_type; | |
328 | ||
329 | /* Make the type of the variable writable. */ | |
330 | new_type = build_type_variant (type, 0, 0); | |
331 | TYPE_ATTRIBUTES (new_type) = TYPE_ATTRIBUTES (type); | |
332 | ||
333 | tmp_var = build_decl (VAR_DECL, create_tmp_var_name (prefix), type); | |
334 | ||
335 | /* The variable was declared by the compiler. */ | |
336 | DECL_ARTIFICIAL (tmp_var) = 1; | |
337 | /* And we don't want debug info for it. */ | |
338 | DECL_IGNORED_P (tmp_var) = 1; | |
339 | ||
340 | /* Make the variable writable. */ | |
341 | TREE_READONLY (tmp_var) = 0; | |
342 | ||
343 | DECL_EXTERNAL (tmp_var) = 0; | |
344 | TREE_STATIC (tmp_var) = 0; | |
345 | TREE_USED (tmp_var) = 1; | |
346 | ||
347 | return tmp_var; | |
348 | } | |
349 | ||
350 | /* Create a new temporary variable declaration of type TYPE. DOES push the | |
351 | variable into the current binding. Further, assume that this is called | |
352 | only from gimplification or optimization, at which point the creation of | |
353 | certain types are bugs. */ | |
354 | ||
355 | tree | |
356 | create_tmp_var (tree type, const char *prefix) | |
357 | { | |
358 | tree tmp_var; | |
359 | ||
360 | #if defined ENABLE_CHECKING | |
44de5aeb RK |
361 | /* We don't allow types that are addressable (meaning we can't make copies), |
362 | incomplete, or of variable size. */ | |
363 | if (TREE_ADDRESSABLE (type) | |
364 | || !COMPLETE_TYPE_P (type) | |
365 | || TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST) | |
6de9cd9a DN |
366 | abort (); |
367 | #endif | |
368 | ||
369 | tmp_var = create_tmp_var_raw (type, prefix); | |
370 | gimple_add_tmp_var (tmp_var); | |
371 | return tmp_var; | |
372 | } | |
373 | ||
374 | /* Given a tree, try to return a useful variable name that we can use | |
375 | to prefix a temporary that is being assigned the value of the tree. | |
376 | I.E. given <temp> = &A, return A. */ | |
377 | ||
378 | const char * | |
379 | get_name (tree t) | |
380 | { | |
381 | tree stripped_decl; | |
382 | ||
383 | stripped_decl = t; | |
384 | STRIP_NOPS (stripped_decl); | |
385 | if (DECL_P (stripped_decl) && DECL_NAME (stripped_decl)) | |
386 | return IDENTIFIER_POINTER (DECL_NAME (stripped_decl)); | |
387 | else | |
388 | { | |
389 | switch (TREE_CODE (stripped_decl)) | |
390 | { | |
391 | case ADDR_EXPR: | |
392 | return get_name (TREE_OPERAND (stripped_decl, 0)); | |
393 | break; | |
394 | default: | |
395 | return NULL; | |
396 | } | |
397 | } | |
398 | } | |
399 | ||
400 | /* Create a temporary with a name derived from VAL. Subroutine of | |
401 | lookup_tmp_var; nobody else should call this function. */ | |
402 | ||
403 | static inline tree | |
404 | create_tmp_from_val (tree val) | |
405 | { | |
406 | return create_tmp_var (TREE_TYPE (val), get_name (val)); | |
407 | } | |
408 | ||
409 | /* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse | |
410 | an existing expression temporary. */ | |
411 | ||
412 | static tree | |
413 | lookup_tmp_var (tree val, bool is_formal) | |
414 | { | |
17ad5b5e RH |
415 | tree ret; |
416 | ||
bbbb79d4 GK |
417 | /* If not optimizing, never really reuse a temporary. local-alloc |
418 | won't allocate any variable that is used in more than one basic | |
419 | block, which means it will go into memory, causing much extra | |
420 | work in reload and final and poorer code generation, outweighing | |
421 | the extra memory allocation here. */ | |
422 | if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val)) | |
17ad5b5e | 423 | ret = create_tmp_from_val (val); |
6de9cd9a DN |
424 | else |
425 | { | |
426 | elt_t elt, *elt_p; | |
427 | void **slot; | |
428 | ||
429 | elt.val = val; | |
430 | slot = htab_find_slot (gimplify_ctxp->temp_htab, (void *)&elt, INSERT); | |
431 | if (*slot == NULL) | |
432 | { | |
433 | elt_p = xmalloc (sizeof (*elt_p)); | |
434 | elt_p->val = val; | |
17ad5b5e | 435 | elt_p->temp = ret = create_tmp_from_val (val); |
af72267c | 436 | *slot = (void *) elt_p; |
6de9cd9a DN |
437 | } |
438 | else | |
17ad5b5e RH |
439 | { |
440 | elt_p = (elt_t *) *slot; | |
441 | ret = elt_p->temp; | |
442 | } | |
6de9cd9a | 443 | } |
17ad5b5e RH |
444 | |
445 | if (is_formal) | |
446 | DECL_GIMPLE_FORMAL_TEMP_P (ret) = 1; | |
447 | ||
448 | return ret; | |
6de9cd9a DN |
449 | } |
450 | ||
451 | /* Returns a formal temporary variable initialized with VAL. PRE_P is as | |
452 | in gimplify_expr. Only use this function if: | |
453 | ||
454 | 1) The value of the unfactored expression represented by VAL will not | |
455 | change between the initialization and use of the temporary, and | |
456 | 2) The temporary will not be otherwise modified. | |
457 | ||
458 | For instance, #1 means that this is inappropriate for SAVE_EXPR temps, | |
459 | and #2 means it is inappropriate for && temps. | |
460 | ||
461 | For other cases, use get_initialized_tmp_var instead. */ | |
462 | ||
463 | static tree | |
464 | internal_get_tmp_var (tree val, tree *pre_p, tree *post_p, bool is_formal) | |
465 | { | |
466 | tree t, mod; | |
6de9cd9a | 467 | |
17ad5b5e | 468 | gimplify_expr (&val, pre_p, post_p, is_gimple_formal_tmp_rhs, fb_rvalue); |
6de9cd9a DN |
469 | |
470 | t = lookup_tmp_var (val, is_formal); | |
471 | ||
472 | mod = build (MODIFY_EXPR, TREE_TYPE (t), t, val); | |
473 | ||
a281759f | 474 | if (EXPR_HAS_LOCATION (val)) |
6de9cd9a DN |
475 | SET_EXPR_LOCUS (mod, EXPR_LOCUS (val)); |
476 | else | |
a281759f | 477 | SET_EXPR_LOCATION (mod, input_location); |
6de9cd9a | 478 | |
fff34d35 RK |
479 | /* gimplify_modify_expr might want to reduce this further. */ |
480 | gimplify_and_add (mod, pre_p); | |
8b11a64c ZD |
481 | |
482 | /* If we're gimplifying into ssa, gimplify_modify_expr will have | |
483 | given our temporary an ssa name. Find and return it. */ | |
484 | if (gimplify_ctxp->into_ssa) | |
485 | t = TREE_OPERAND (mod, 0); | |
486 | ||
6de9cd9a DN |
487 | return t; |
488 | } | |
489 | ||
490 | tree | |
491 | get_formal_tmp_var (tree val, tree *pre_p) | |
492 | { | |
493 | return internal_get_tmp_var (val, pre_p, NULL, true); | |
494 | } | |
495 | ||
496 | /* Returns a temporary variable initialized with VAL. PRE_P and POST_P | |
497 | are as in gimplify_expr. */ | |
498 | ||
499 | tree | |
500 | get_initialized_tmp_var (tree val, tree *pre_p, tree *post_p) | |
501 | { | |
502 | return internal_get_tmp_var (val, pre_p, post_p, false); | |
503 | } | |
504 | ||
aa4a53af | 505 | /* Declares all the variables in VARS in SCOPE. */ |
6de9cd9a DN |
506 | |
507 | void | |
508 | declare_tmp_vars (tree vars, tree scope) | |
509 | { | |
510 | tree last = vars; | |
511 | if (last) | |
512 | { | |
513 | tree temps; | |
514 | ||
aa4a53af | 515 | /* C99 mode puts the default 'return 0;' for main outside the outer |
6de9cd9a DN |
516 | braces. So drill down until we find an actual scope. */ |
517 | while (TREE_CODE (scope) == COMPOUND_EXPR) | |
518 | scope = TREE_OPERAND (scope, 0); | |
519 | ||
520 | if (TREE_CODE (scope) != BIND_EXPR) | |
521 | abort (); | |
522 | ||
523 | temps = nreverse (last); | |
524 | TREE_CHAIN (last) = BIND_EXPR_VARS (scope); | |
525 | BIND_EXPR_VARS (scope) = temps; | |
6de9cd9a DN |
526 | } |
527 | } | |
528 | ||
529 | void | |
530 | gimple_add_tmp_var (tree tmp) | |
531 | { | |
48eb4e53 | 532 | if (TREE_CHAIN (tmp) || DECL_SEEN_IN_BIND_EXPR_P (tmp)) |
6de9cd9a DN |
533 | abort (); |
534 | ||
535 | DECL_CONTEXT (tmp) = current_function_decl; | |
48eb4e53 | 536 | DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1; |
6de9cd9a DN |
537 | |
538 | if (gimplify_ctxp) | |
539 | { | |
540 | TREE_CHAIN (tmp) = gimplify_ctxp->temps; | |
541 | gimplify_ctxp->temps = tmp; | |
542 | } | |
543 | else if (cfun) | |
544 | record_vars (tmp); | |
545 | else | |
546 | declare_tmp_vars (tmp, DECL_SAVED_TREE (current_function_decl)); | |
547 | } | |
548 | ||
549 | /* Determines whether to assign a locus to the statement STMT. */ | |
550 | ||
551 | static bool | |
552 | should_carry_locus_p (tree stmt) | |
553 | { | |
554 | /* Don't emit a line note for a label. We particularly don't want to | |
555 | emit one for the break label, since it doesn't actually correspond | |
556 | to the beginning of the loop/switch. */ | |
557 | if (TREE_CODE (stmt) == LABEL_EXPR) | |
558 | return false; | |
559 | ||
560 | /* Do not annotate empty statements, since it confuses gcov. */ | |
561 | if (!TREE_SIDE_EFFECTS (stmt)) | |
562 | return false; | |
563 | ||
564 | return true; | |
565 | } | |
566 | ||
7c34ced1 RH |
567 | static void |
568 | annotate_one_with_locus (tree t, location_t locus) | |
569 | { | |
570 | if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (t))) | |
571 | && ! EXPR_HAS_LOCATION (t) | |
572 | && should_carry_locus_p (t)) | |
a281759f | 573 | SET_EXPR_LOCATION (t, locus); |
7c34ced1 RH |
574 | } |
575 | ||
6de9cd9a DN |
576 | void |
577 | annotate_all_with_locus (tree *stmt_p, location_t locus) | |
578 | { | |
579 | tree_stmt_iterator i; | |
580 | ||
581 | if (!*stmt_p) | |
582 | return; | |
583 | ||
584 | for (i = tsi_start (*stmt_p); !tsi_end_p (i); tsi_next (&i)) | |
585 | { | |
586 | tree t = tsi_stmt (i); | |
587 | ||
588 | #ifdef ENABLE_CHECKING | |
589 | /* Assuming we've already been gimplified, we shouldn't | |
590 | see nested chaining constructs anymore. */ | |
591 | if (TREE_CODE (t) == STATEMENT_LIST | |
592 | || TREE_CODE (t) == COMPOUND_EXPR) | |
593 | abort (); | |
594 | #endif | |
595 | ||
7c34ced1 | 596 | annotate_one_with_locus (t, locus); |
6de9cd9a DN |
597 | } |
598 | } | |
599 | ||
600 | /* Similar to copy_tree_r() but do not copy SAVE_EXPR or TARGET_EXPR nodes. | |
601 | These nodes model computations that should only be done once. If we | |
602 | were to unshare something like SAVE_EXPR(i++), the gimplification | |
603 | process would create wrong code. */ | |
604 | ||
605 | static tree | |
606 | mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data) | |
607 | { | |
608 | enum tree_code code = TREE_CODE (*tp); | |
f0638e1d | 609 | /* Don't unshare types, decls, constants and SAVE_EXPR nodes. */ |
6de9cd9a | 610 | if (TREE_CODE_CLASS (code) == 't' |
f0638e1d | 611 | || TREE_CODE_CLASS (code) == 'd' |
6de9cd9a DN |
612 | || TREE_CODE_CLASS (code) == 'c' |
613 | || code == SAVE_EXPR || code == TARGET_EXPR | |
614 | /* We can't do anything sensible with a BLOCK used as an expression, | |
615 | but we also can't abort when we see it because of non-expression | |
616 | uses. So just avert our eyes and cross our fingers. Silly Java. */ | |
617 | || code == BLOCK) | |
618 | *walk_subtrees = 0; | |
619 | else if (code == BIND_EXPR) | |
620 | abort (); | |
621 | else | |
622 | copy_tree_r (tp, walk_subtrees, data); | |
623 | ||
624 | return NULL_TREE; | |
625 | } | |
626 | ||
6de9cd9a DN |
627 | /* Callback for walk_tree to unshare most of the shared trees rooted at |
628 | *TP. If *TP has been visited already (i.e., TREE_VISITED (*TP) == 1), | |
629 | then *TP is deep copied by calling copy_tree_r. | |
630 | ||
631 | This unshares the same trees as copy_tree_r with the exception of | |
632 | SAVE_EXPR nodes. These nodes model computations that should only be | |
633 | done once. If we were to unshare something like SAVE_EXPR(i++), the | |
634 | gimplification process would create wrong code. */ | |
635 | ||
636 | static tree | |
637 | copy_if_shared_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, | |
638 | void *data ATTRIBUTE_UNUSED) | |
639 | { | |
f0638e1d RH |
640 | tree t = *tp; |
641 | enum tree_code code = TREE_CODE (t); | |
642 | ||
44de5aeb RK |
643 | /* Skip types, decls, and constants. But we do want to look at their |
644 | types and the bounds of types. Mark them as visited so we properly | |
645 | unmark their subtrees on the unmark pass. If we've already seen them, | |
646 | don't look down further. */ | |
f0638e1d RH |
647 | if (TREE_CODE_CLASS (code) == 't' |
648 | || TREE_CODE_CLASS (code) == 'd' | |
649 | || TREE_CODE_CLASS (code) == 'c') | |
44de5aeb RK |
650 | { |
651 | if (TREE_VISITED (t)) | |
652 | *walk_subtrees = 0; | |
653 | else | |
654 | TREE_VISITED (t) = 1; | |
655 | } | |
f0638e1d | 656 | |
6de9cd9a DN |
657 | /* If this node has been visited already, unshare it and don't look |
658 | any deeper. */ | |
f0638e1d | 659 | else if (TREE_VISITED (t)) |
6de9cd9a DN |
660 | { |
661 | walk_tree (tp, mostly_copy_tree_r, NULL, NULL); | |
662 | *walk_subtrees = 0; | |
663 | } | |
f0638e1d RH |
664 | |
665 | /* Otherwise, mark the tree as visited and keep looking. */ | |
6de9cd9a | 666 | else |
77c9db77 | 667 | TREE_VISITED (t) = 1; |
f0638e1d | 668 | |
6de9cd9a DN |
669 | return NULL_TREE; |
670 | } | |
671 | ||
672 | static tree | |
673 | unmark_visited_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, | |
674 | void *data ATTRIBUTE_UNUSED) | |
675 | { | |
676 | if (TREE_VISITED (*tp)) | |
677 | TREE_VISITED (*tp) = 0; | |
678 | else | |
679 | *walk_subtrees = 0; | |
680 | ||
681 | return NULL_TREE; | |
682 | } | |
683 | ||
48eb4e53 RK |
684 | /* Unshare all the trees in BODY_P, a pointer into the body of FNDECL, and the |
685 | bodies of any nested functions if we are unsharing the entire body of | |
686 | FNDECL. */ | |
44de5aeb RK |
687 | |
688 | static void | |
689 | unshare_body (tree *body_p, tree fndecl) | |
690 | { | |
691 | struct cgraph_node *cgn = cgraph_node (fndecl); | |
692 | ||
693 | walk_tree (body_p, copy_if_shared_r, NULL, NULL); | |
48eb4e53 RK |
694 | if (body_p == &DECL_SAVED_TREE (fndecl)) |
695 | for (cgn = cgn->nested; cgn; cgn = cgn->next_nested) | |
696 | unshare_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl); | |
44de5aeb RK |
697 | } |
698 | ||
699 | /* Likewise, but mark all trees as not visited. */ | |
700 | ||
701 | static void | |
702 | unvisit_body (tree *body_p, tree fndecl) | |
703 | { | |
704 | struct cgraph_node *cgn = cgraph_node (fndecl); | |
705 | ||
706 | walk_tree (body_p, unmark_visited_r, NULL, NULL); | |
48eb4e53 RK |
707 | if (body_p == &DECL_SAVED_TREE (fndecl)) |
708 | for (cgn = cgn->nested; cgn; cgn = cgn->next_nested) | |
709 | unvisit_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl); | |
44de5aeb RK |
710 | } |
711 | ||
6de9cd9a DN |
712 | /* Unshare T and all the trees reached from T via TREE_CHAIN. */ |
713 | ||
714 | void | |
715 | unshare_all_trees (tree t) | |
716 | { | |
717 | walk_tree (&t, copy_if_shared_r, NULL, NULL); | |
718 | walk_tree (&t, unmark_visited_r, NULL, NULL); | |
719 | } | |
720 | ||
721 | /* Unconditionally make an unshared copy of EXPR. This is used when using | |
722 | stored expressions which span multiple functions, such as BINFO_VTABLE, | |
723 | as the normal unsharing process can't tell that they're shared. */ | |
724 | ||
725 | tree | |
726 | unshare_expr (tree expr) | |
727 | { | |
728 | walk_tree (&expr, mostly_copy_tree_r, NULL, NULL); | |
729 | return expr; | |
730 | } | |
731 | ||
732 | /* A terser interface for building a representation of a exception | |
733 | specification. */ | |
734 | ||
735 | tree | |
736 | gimple_build_eh_filter (tree body, tree allowed, tree failure) | |
737 | { | |
738 | tree t; | |
739 | ||
740 | /* FIXME should the allowed types go in TREE_TYPE? */ | |
741 | t = build (EH_FILTER_EXPR, void_type_node, allowed, NULL_TREE); | |
742 | append_to_statement_list (failure, &EH_FILTER_FAILURE (t)); | |
743 | ||
744 | t = build (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t); | |
745 | append_to_statement_list (body, &TREE_OPERAND (t, 0)); | |
746 | ||
747 | return t; | |
748 | } | |
749 | ||
750 | \f | |
751 | /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both | |
752 | contain statements and have a value. Assign its value to a temporary | |
753 | and give it void_type_node. Returns the temporary, or NULL_TREE if | |
754 | WRAPPER was already void. */ | |
755 | ||
756 | tree | |
325c3691 | 757 | voidify_wrapper_expr (tree wrapper, tree temp) |
6de9cd9a DN |
758 | { |
759 | if (!VOID_TYPE_P (TREE_TYPE (wrapper))) | |
760 | { | |
325c3691 | 761 | tree *p, sub = wrapper; |
6de9cd9a | 762 | |
325c3691 | 763 | restart: |
6de9cd9a | 764 | /* Set p to point to the body of the wrapper. */ |
325c3691 | 765 | switch (TREE_CODE (sub)) |
6de9cd9a DN |
766 | { |
767 | case BIND_EXPR: | |
768 | /* For a BIND_EXPR, the body is operand 1. */ | |
325c3691 | 769 | p = &BIND_EXPR_BODY (sub); |
6de9cd9a DN |
770 | break; |
771 | ||
772 | default: | |
325c3691 | 773 | p = &TREE_OPERAND (sub, 0); |
6de9cd9a DN |
774 | break; |
775 | } | |
776 | ||
777 | /* Advance to the last statement. Set all container types to void. */ | |
778 | if (TREE_CODE (*p) == STATEMENT_LIST) | |
779 | { | |
780 | tree_stmt_iterator i = tsi_last (*p); | |
781 | p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i); | |
782 | } | |
783 | else | |
784 | { | |
785 | for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1)) | |
786 | { | |
787 | TREE_SIDE_EFFECTS (*p) = 1; | |
788 | TREE_TYPE (*p) = void_type_node; | |
789 | } | |
790 | } | |
791 | ||
325c3691 RH |
792 | if (p == NULL || IS_EMPTY_STMT (*p)) |
793 | ; | |
794 | /* Look through exception handling. */ | |
795 | else if (TREE_CODE (*p) == TRY_FINALLY_EXPR | |
796 | || TREE_CODE (*p) == TRY_CATCH_EXPR) | |
6de9cd9a | 797 | { |
325c3691 RH |
798 | sub = *p; |
799 | goto restart; | |
6de9cd9a | 800 | } |
325c3691 | 801 | /* The C++ frontend already did this for us. */ |
77db1f41 RK |
802 | else if (TREE_CODE (*p) == INIT_EXPR |
803 | || TREE_CODE (*p) == TARGET_EXPR) | |
325c3691 RH |
804 | temp = TREE_OPERAND (*p, 0); |
805 | /* If we're returning a dereference, move the dereference | |
806 | outside the wrapper. */ | |
807 | else if (TREE_CODE (*p) == INDIRECT_REF) | |
6de9cd9a | 808 | { |
6de9cd9a DN |
809 | tree ptr = TREE_OPERAND (*p, 0); |
810 | temp = create_tmp_var (TREE_TYPE (ptr), "retval"); | |
811 | *p = build (MODIFY_EXPR, TREE_TYPE (ptr), temp, ptr); | |
812 | temp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (temp)), temp); | |
813 | /* If this is a BIND_EXPR for a const inline function, it might not | |
814 | have TREE_SIDE_EFFECTS set. That is no longer accurate. */ | |
815 | TREE_SIDE_EFFECTS (wrapper) = 1; | |
816 | } | |
817 | else | |
818 | { | |
325c3691 RH |
819 | if (!temp) |
820 | temp = create_tmp_var (TREE_TYPE (wrapper), "retval"); | |
821 | *p = build (MODIFY_EXPR, TREE_TYPE (temp), temp, *p); | |
822 | TREE_SIDE_EFFECTS (wrapper) = 1; | |
6de9cd9a DN |
823 | } |
824 | ||
825 | TREE_TYPE (wrapper) = void_type_node; | |
826 | return temp; | |
827 | } | |
828 | ||
829 | return NULL_TREE; | |
830 | } | |
831 | ||
832 | /* Prepare calls to builtins to SAVE and RESTORE the stack as well as | |
1ea7e6ad | 833 | a temporary through which they communicate. */ |
6de9cd9a DN |
834 | |
835 | static void | |
836 | build_stack_save_restore (tree *save, tree *restore) | |
837 | { | |
838 | tree save_call, tmp_var; | |
839 | ||
840 | save_call = | |
841 | build_function_call_expr (implicit_built_in_decls[BUILT_IN_STACK_SAVE], | |
842 | NULL_TREE); | |
843 | tmp_var = create_tmp_var (ptr_type_node, "saved_stack"); | |
844 | ||
845 | *save = build (MODIFY_EXPR, ptr_type_node, tmp_var, save_call); | |
846 | *restore = | |
847 | build_function_call_expr (implicit_built_in_decls[BUILT_IN_STACK_RESTORE], | |
848 | tree_cons (NULL_TREE, tmp_var, NULL_TREE)); | |
849 | } | |
850 | ||
851 | /* Gimplify a BIND_EXPR. Just voidify and recurse. */ | |
852 | ||
853 | static enum gimplify_status | |
325c3691 | 854 | gimplify_bind_expr (tree *expr_p, tree temp, tree *pre_p) |
6de9cd9a DN |
855 | { |
856 | tree bind_expr = *expr_p; | |
6de9cd9a DN |
857 | bool old_save_stack = gimplify_ctxp->save_stack; |
858 | tree t; | |
859 | ||
325c3691 RH |
860 | temp = voidify_wrapper_expr (bind_expr, temp); |
861 | ||
6de9cd9a DN |
862 | /* Mark variables seen in this bind expr. */ |
863 | for (t = BIND_EXPR_VARS (bind_expr); t ; t = TREE_CHAIN (t)) | |
48eb4e53 | 864 | DECL_SEEN_IN_BIND_EXPR_P (t) = 1; |
6de9cd9a DN |
865 | |
866 | gimple_push_bind_expr (bind_expr); | |
867 | gimplify_ctxp->save_stack = false; | |
868 | ||
869 | gimplify_to_stmt_list (&BIND_EXPR_BODY (bind_expr)); | |
870 | ||
871 | if (gimplify_ctxp->save_stack) | |
872 | { | |
873 | tree stack_save, stack_restore; | |
874 | ||
875 | /* Save stack on entry and restore it on exit. Add a try_finally | |
876 | block to achieve this. Note that mudflap depends on the | |
877 | format of the emitted code: see mx_register_decls(). */ | |
878 | build_stack_save_restore (&stack_save, &stack_restore); | |
879 | ||
880 | t = build (TRY_FINALLY_EXPR, void_type_node, | |
881 | BIND_EXPR_BODY (bind_expr), NULL_TREE); | |
882 | append_to_statement_list (stack_restore, &TREE_OPERAND (t, 1)); | |
883 | ||
884 | BIND_EXPR_BODY (bind_expr) = NULL_TREE; | |
885 | append_to_statement_list (stack_save, &BIND_EXPR_BODY (bind_expr)); | |
886 | append_to_statement_list (t, &BIND_EXPR_BODY (bind_expr)); | |
887 | } | |
888 | ||
889 | gimplify_ctxp->save_stack = old_save_stack; | |
890 | gimple_pop_bind_expr (); | |
891 | ||
892 | if (temp) | |
893 | { | |
894 | *expr_p = temp; | |
895 | append_to_statement_list (bind_expr, pre_p); | |
896 | return GS_OK; | |
897 | } | |
898 | else | |
899 | return GS_ALL_DONE; | |
900 | } | |
901 | ||
902 | /* Gimplify a RETURN_EXPR. If the expression to be returned is not a | |
903 | GIMPLE value, it is assigned to a new temporary and the statement is | |
904 | re-written to return the temporary. | |
905 | ||
906 | PRE_P points to the list where side effects that must happen before | |
907 | STMT should be stored. */ | |
908 | ||
909 | static enum gimplify_status | |
910 | gimplify_return_expr (tree stmt, tree *pre_p) | |
911 | { | |
912 | tree ret_expr = TREE_OPERAND (stmt, 0); | |
71877985 | 913 | tree result_decl, result; |
6de9cd9a | 914 | |
55e99d52 PB |
915 | if (!ret_expr || TREE_CODE (ret_expr) == RESULT_DECL |
916 | || ret_expr == error_mark_node) | |
6de9cd9a DN |
917 | return GS_ALL_DONE; |
918 | ||
6de9cd9a | 919 | if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))) |
71877985 | 920 | result_decl = NULL_TREE; |
6de9cd9a DN |
921 | else |
922 | { | |
71877985 | 923 | result_decl = TREE_OPERAND (ret_expr, 0); |
cc77ae10 JM |
924 | if (TREE_CODE (result_decl) == INDIRECT_REF) |
925 | /* See through a return by reference. */ | |
926 | result_decl = TREE_OPERAND (result_decl, 0); | |
6de9cd9a DN |
927 | #ifdef ENABLE_CHECKING |
928 | if ((TREE_CODE (ret_expr) != MODIFY_EXPR | |
929 | && TREE_CODE (ret_expr) != INIT_EXPR) | |
71877985 | 930 | || TREE_CODE (result_decl) != RESULT_DECL) |
6de9cd9a DN |
931 | abort (); |
932 | #endif | |
933 | } | |
934 | ||
71877985 RH |
935 | /* If aggregate_value_p is true, then we can return the bare RESULT_DECL. |
936 | Recall that aggregate_value_p is FALSE for any aggregate type that is | |
937 | returned in registers. If we're returning values in registers, then | |
938 | we don't want to extend the lifetime of the RESULT_DECL, particularly | |
939 | across another call. In addition, for those aggregates for which | |
940 | hard_function_value generates a PARALLEL, we'll abort during normal | |
941 | expansion of structure assignments; there's special code in expand_return | |
942 | to handle this case that does not exist in expand_expr. */ | |
943 | if (!result_decl | |
944 | || aggregate_value_p (result_decl, TREE_TYPE (current_function_decl))) | |
945 | result = result_decl; | |
946 | else if (gimplify_ctxp->return_temp) | |
947 | result = gimplify_ctxp->return_temp; | |
948 | else | |
949 | { | |
950 | result = create_tmp_var (TREE_TYPE (result_decl), NULL); | |
ff98621c RH |
951 | |
952 | /* ??? With complex control flow (usually involving abnormal edges), | |
953 | we can wind up warning about an uninitialized value for this. Due | |
954 | to how this variable is constructed and initialized, this is never | |
955 | true. Give up and never warn. */ | |
956 | TREE_NO_WARNING (result) = 1; | |
957 | ||
71877985 RH |
958 | gimplify_ctxp->return_temp = result; |
959 | } | |
960 | ||
961 | /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use. | |
962 | Then gimplify the whole thing. */ | |
963 | if (result != result_decl) | |
964 | TREE_OPERAND (ret_expr, 0) = result; | |
fff34d35 RK |
965 | |
966 | gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p); | |
6de9cd9a | 967 | |
71877985 RH |
968 | /* If we didn't use a temporary, then the result is just the result_decl. |
969 | Otherwise we need a simple copy. This should already be gimple. */ | |
970 | if (result == result_decl) | |
971 | ret_expr = result; | |
972 | else | |
973 | ret_expr = build (MODIFY_EXPR, TREE_TYPE (result), result_decl, result); | |
974 | TREE_OPERAND (stmt, 0) = ret_expr; | |
6de9cd9a | 975 | |
6de9cd9a DN |
976 | return GS_ALL_DONE; |
977 | } | |
978 | ||
350fae66 RK |
979 | /* Gimplifies a DECL_EXPR node *STMT_P by making any necessary allocation |
980 | and initialization explicit. */ | |
981 | ||
982 | static enum gimplify_status | |
983 | gimplify_decl_expr (tree *stmt_p) | |
984 | { | |
985 | tree stmt = *stmt_p; | |
986 | tree decl = DECL_EXPR_DECL (stmt); | |
987 | ||
988 | *stmt_p = NULL_TREE; | |
989 | ||
990 | if (TREE_TYPE (decl) == error_mark_node) | |
991 | return GS_ERROR; | |
992 | ||
993 | else if (TREE_CODE (decl) == TYPE_DECL) | |
994 | gimplify_type_sizes (TREE_TYPE (decl), stmt_p); | |
995 | ||
996 | else if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl)) | |
997 | { | |
998 | tree init = DECL_INITIAL (decl); | |
999 | ||
1000 | if (!TREE_CONSTANT (DECL_SIZE (decl))) | |
1001 | { | |
1002 | /* This is a variable-sized decl. Simplify its size and mark it | |
1003 | for deferred expansion. Note that mudflap depends on the format | |
1004 | of the emitted code: see mx_register_decls(). */ | |
1a186ec5 | 1005 | tree t, args, addr, ptr_type; |
350fae66 RK |
1006 | |
1007 | gimplify_type_sizes (TREE_TYPE (decl), stmt_p); | |
1008 | gimplify_one_sizepos (&DECL_SIZE (decl), stmt_p); | |
1009 | gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), stmt_p); | |
1010 | ||
2a7e31df | 1011 | /* All occurrences of this decl in final gimplified code will be |
1a186ec5 RH |
1012 | replaced by indirection. Setting DECL_VALUE_EXPR does two |
1013 | things: First, it lets the rest of the gimplifier know what | |
1014 | replacement to use. Second, it lets the debug info know | |
1015 | where to find the value. */ | |
1016 | ptr_type = build_pointer_type (TREE_TYPE (decl)); | |
1017 | addr = create_tmp_var (ptr_type, get_name (decl)); | |
1018 | DECL_IGNORED_P (addr) = 0; | |
1019 | t = build_fold_indirect_ref (addr); | |
1020 | DECL_VALUE_EXPR (decl) = t; | |
1021 | ||
350fae66 | 1022 | args = tree_cons (NULL, DECL_SIZE_UNIT (decl), NULL); |
1a186ec5 | 1023 | t = built_in_decls[BUILT_IN_ALLOCA]; |
350fae66 | 1024 | t = build_function_call_expr (t, args); |
1a186ec5 RH |
1025 | t = fold_convert (ptr_type, t); |
1026 | t = build2 (MODIFY_EXPR, void_type_node, addr, t); | |
350fae66 RK |
1027 | |
1028 | gimplify_and_add (t, stmt_p); | |
1a186ec5 RH |
1029 | |
1030 | /* Indicate that we need to restore the stack level when the | |
1031 | enclosing BIND_EXPR is exited. */ | |
1032 | gimplify_ctxp->save_stack = true; | |
350fae66 RK |
1033 | } |
1034 | ||
1035 | if (init && init != error_mark_node) | |
1036 | { | |
1037 | if (!TREE_STATIC (decl)) | |
1038 | { | |
1039 | DECL_INITIAL (decl) = NULL_TREE; | |
1040 | init = build (MODIFY_EXPR, void_type_node, decl, init); | |
1041 | gimplify_and_add (init, stmt_p); | |
1042 | } | |
1043 | else | |
1044 | /* We must still examine initializers for static variables | |
1045 | as they may contain a label address. */ | |
1046 | walk_tree (&init, force_labels_r, NULL, NULL); | |
1047 | } | |
1048 | ||
1049 | /* This decl isn't mentioned in the enclosing block, so add it to the | |
1050 | list of temps. FIXME it seems a bit of a kludge to say that | |
1051 | anonymous artificial vars aren't pushed, but everything else is. */ | |
1052 | if (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE) | |
1053 | gimple_add_tmp_var (decl); | |
1054 | } | |
1055 | ||
1056 | return GS_ALL_DONE; | |
1057 | } | |
1058 | ||
6de9cd9a DN |
1059 | /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body |
1060 | and replacing the LOOP_EXPR with goto, but if the loop contains an | |
1061 | EXIT_EXPR, we need to append a label for it to jump to. */ | |
1062 | ||
1063 | static enum gimplify_status | |
1064 | gimplify_loop_expr (tree *expr_p, tree *pre_p) | |
1065 | { | |
1066 | tree saved_label = gimplify_ctxp->exit_label; | |
1067 | tree start_label = build1 (LABEL_EXPR, void_type_node, NULL_TREE); | |
1068 | tree jump_stmt = build_and_jump (&LABEL_EXPR_LABEL (start_label)); | |
1069 | ||
1070 | append_to_statement_list (start_label, pre_p); | |
1071 | ||
1072 | gimplify_ctxp->exit_label = NULL_TREE; | |
1073 | ||
fff34d35 | 1074 | gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p); |
6de9cd9a DN |
1075 | |
1076 | if (gimplify_ctxp->exit_label) | |
1077 | { | |
1078 | append_to_statement_list (jump_stmt, pre_p); | |
1079 | *expr_p = build1 (LABEL_EXPR, void_type_node, gimplify_ctxp->exit_label); | |
1080 | } | |
1081 | else | |
1082 | *expr_p = jump_stmt; | |
1083 | ||
1084 | gimplify_ctxp->exit_label = saved_label; | |
1085 | ||
1086 | return GS_ALL_DONE; | |
1087 | } | |
1088 | ||
f667741c SB |
1089 | /* Compare two case labels. Because the front end should already have |
1090 | made sure that case ranges do not overlap, it is enough to only compare | |
1091 | the CASE_LOW values of each case label. */ | |
1092 | ||
1093 | static int | |
1094 | compare_case_labels (const void *p1, const void *p2) | |
1095 | { | |
1096 | tree case1 = *(tree *)p1; | |
1097 | tree case2 = *(tree *)p2; | |
1098 | ||
1099 | return tree_int_cst_compare (CASE_LOW (case1), CASE_LOW (case2)); | |
1100 | } | |
1101 | ||
165b54c3 | 1102 | /* Sort the case labels in LABEL_VEC in place in ascending order. */ |
0f1f6967 SB |
1103 | |
1104 | void | |
1105 | sort_case_labels (tree label_vec) | |
1106 | { | |
1107 | size_t len = TREE_VEC_LENGTH (label_vec); | |
1108 | tree default_case = TREE_VEC_ELT (label_vec, len - 1); | |
1109 | ||
1110 | if (CASE_LOW (default_case)) | |
1111 | { | |
1112 | size_t i; | |
1113 | ||
1114 | /* The last label in the vector should be the default case | |
1115 | but it is not. */ | |
1116 | for (i = 0; i < len; ++i) | |
1117 | { | |
1118 | tree t = TREE_VEC_ELT (label_vec, i); | |
1119 | if (!CASE_LOW (t)) | |
1120 | { | |
1121 | default_case = t; | |
1122 | TREE_VEC_ELT (label_vec, i) = TREE_VEC_ELT (label_vec, len - 1); | |
1123 | TREE_VEC_ELT (label_vec, len - 1) = default_case; | |
1124 | break; | |
1125 | } | |
1126 | } | |
1127 | } | |
1128 | ||
1129 | qsort (&TREE_VEC_ELT (label_vec, 0), len - 1, sizeof (tree), | |
1130 | compare_case_labels); | |
1131 | } | |
1132 | ||
6de9cd9a DN |
1133 | /* Gimplify a SWITCH_EXPR, and collect a TREE_VEC of the labels it can |
1134 | branch to. */ | |
1135 | ||
1136 | static enum gimplify_status | |
1137 | gimplify_switch_expr (tree *expr_p, tree *pre_p) | |
1138 | { | |
1139 | tree switch_expr = *expr_p; | |
1140 | enum gimplify_status ret; | |
1141 | ||
1142 | ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, | |
1143 | is_gimple_val, fb_rvalue); | |
1144 | ||
1145 | if (SWITCH_BODY (switch_expr)) | |
1146 | { | |
1147 | varray_type labels, saved_labels; | |
f667741c | 1148 | tree label_vec, default_case = NULL_TREE; |
6de9cd9a DN |
1149 | size_t i, len; |
1150 | ||
1151 | /* If someone can be bothered to fill in the labels, they can | |
1152 | be bothered to null out the body too. */ | |
1153 | if (SWITCH_LABELS (switch_expr)) | |
1154 | abort (); | |
1155 | ||
1156 | saved_labels = gimplify_ctxp->case_labels; | |
1157 | VARRAY_TREE_INIT (gimplify_ctxp->case_labels, 8, "case_labels"); | |
1158 | ||
1159 | gimplify_to_stmt_list (&SWITCH_BODY (switch_expr)); | |
1160 | ||
1161 | labels = gimplify_ctxp->case_labels; | |
1162 | gimplify_ctxp->case_labels = saved_labels; | |
1163 | ||
1164 | len = VARRAY_ACTIVE_SIZE (labels); | |
6de9cd9a DN |
1165 | |
1166 | for (i = 0; i < len; ++i) | |
1167 | { | |
f667741c | 1168 | tree t = VARRAY_TREE (labels, i); |
6de9cd9a DN |
1169 | if (!CASE_LOW (t)) |
1170 | { | |
f667741c SB |
1171 | /* The default case must be the last label in the list. */ |
1172 | default_case = t; | |
1173 | VARRAY_TREE (labels, i) = VARRAY_TREE (labels, len - 1); | |
1174 | len--; | |
6de9cd9a DN |
1175 | break; |
1176 | } | |
1177 | } | |
1178 | ||
f667741c | 1179 | label_vec = make_tree_vec (len + 1); |
6de9cd9a | 1180 | SWITCH_LABELS (*expr_p) = label_vec; |
6de9cd9a DN |
1181 | append_to_statement_list (switch_expr, pre_p); |
1182 | ||
f667741c | 1183 | if (! default_case) |
6de9cd9a | 1184 | { |
f667741c SB |
1185 | /* If the switch has no default label, add one, so that we jump |
1186 | around the switch body. */ | |
1187 | default_case = build (CASE_LABEL_EXPR, void_type_node, NULL_TREE, | |
1188 | NULL_TREE, create_artificial_label ()); | |
6de9cd9a | 1189 | append_to_statement_list (SWITCH_BODY (switch_expr), pre_p); |
f667741c SB |
1190 | *expr_p = build (LABEL_EXPR, void_type_node, |
1191 | CASE_LABEL (default_case)); | |
6de9cd9a DN |
1192 | } |
1193 | else | |
1194 | *expr_p = SWITCH_BODY (switch_expr); | |
1195 | ||
f667741c SB |
1196 | for (i = 0; i < len; ++i) |
1197 | TREE_VEC_ELT (label_vec, i) = VARRAY_TREE (labels, i); | |
1198 | TREE_VEC_ELT (label_vec, len) = default_case; | |
1199 | ||
0f1f6967 SB |
1200 | sort_case_labels (label_vec); |
1201 | ||
6de9cd9a DN |
1202 | SWITCH_BODY (switch_expr) = NULL; |
1203 | } | |
1204 | else if (!SWITCH_LABELS (switch_expr)) | |
1205 | abort (); | |
1206 | ||
1207 | return ret; | |
1208 | } | |
1209 | ||
1210 | static enum gimplify_status | |
1211 | gimplify_case_label_expr (tree *expr_p) | |
1212 | { | |
1213 | tree expr = *expr_p; | |
1214 | if (gimplify_ctxp->case_labels) | |
1215 | VARRAY_PUSH_TREE (gimplify_ctxp->case_labels, expr); | |
1216 | else | |
1217 | abort (); | |
1218 | *expr_p = build (LABEL_EXPR, void_type_node, CASE_LABEL (expr)); | |
1219 | return GS_ALL_DONE; | |
1220 | } | |
1221 | ||
1222 | /* Gimplify a LABELED_BLOCK_EXPR into a LABEL_EXPR following | |
1223 | a (possibly empty) body. */ | |
1224 | ||
1225 | static enum gimplify_status | |
1226 | gimplify_labeled_block_expr (tree *expr_p) | |
1227 | { | |
1228 | tree body = LABELED_BLOCK_BODY (*expr_p); | |
1229 | tree label = LABELED_BLOCK_LABEL (*expr_p); | |
1230 | tree t; | |
1231 | ||
1232 | DECL_CONTEXT (label) = current_function_decl; | |
1233 | t = build (LABEL_EXPR, void_type_node, label); | |
1234 | if (body != NULL_TREE) | |
1235 | t = build (COMPOUND_EXPR, void_type_node, body, t); | |
1236 | *expr_p = t; | |
1237 | ||
1238 | return GS_OK; | |
1239 | } | |
1240 | ||
1241 | /* Gimplify a EXIT_BLOCK_EXPR into a GOTO_EXPR. */ | |
1242 | ||
1243 | static enum gimplify_status | |
1244 | gimplify_exit_block_expr (tree *expr_p) | |
1245 | { | |
1246 | tree labeled_block = TREE_OPERAND (*expr_p, 0); | |
1247 | tree label; | |
1248 | ||
1249 | /* First operand must be a LABELED_BLOCK_EXPR, which should | |
1250 | already be lowered (or partially lowered) when we get here. */ | |
1251 | #if defined ENABLE_CHECKING | |
1252 | if (TREE_CODE (labeled_block) != LABELED_BLOCK_EXPR) | |
1253 | abort (); | |
1254 | #endif | |
1255 | ||
1256 | label = LABELED_BLOCK_LABEL (labeled_block); | |
1257 | *expr_p = build1 (GOTO_EXPR, void_type_node, label); | |
1258 | ||
1259 | return GS_OK; | |
1260 | } | |
1261 | ||
1262 | /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first | |
1263 | if necessary. */ | |
1264 | ||
1265 | tree | |
1266 | build_and_jump (tree *label_p) | |
1267 | { | |
1268 | if (label_p == NULL) | |
1269 | /* If there's nowhere to jump, just fall through. */ | |
65355d53 | 1270 | return NULL_TREE; |
6de9cd9a DN |
1271 | |
1272 | if (*label_p == NULL_TREE) | |
1273 | { | |
1274 | tree label = create_artificial_label (); | |
1275 | *label_p = label; | |
1276 | } | |
1277 | ||
1278 | return build1 (GOTO_EXPR, void_type_node, *label_p); | |
1279 | } | |
1280 | ||
1281 | /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR. | |
1282 | This also involves building a label to jump to and communicating it to | |
1283 | gimplify_loop_expr through gimplify_ctxp->exit_label. */ | |
1284 | ||
1285 | static enum gimplify_status | |
1286 | gimplify_exit_expr (tree *expr_p) | |
1287 | { | |
1288 | tree cond = TREE_OPERAND (*expr_p, 0); | |
1289 | tree expr; | |
1290 | ||
1291 | expr = build_and_jump (&gimplify_ctxp->exit_label); | |
65355d53 | 1292 | expr = build (COND_EXPR, void_type_node, cond, expr, NULL_TREE); |
6de9cd9a DN |
1293 | *expr_p = expr; |
1294 | ||
1295 | return GS_OK; | |
1296 | } | |
1297 | ||
1298 | /* A helper function to be called via walk_tree. Mark all labels under *TP | |
1299 | as being forced. To be called for DECL_INITIAL of static variables. */ | |
1300 | ||
1301 | tree | |
1302 | force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) | |
1303 | { | |
1304 | if (TYPE_P (*tp)) | |
1305 | *walk_subtrees = 0; | |
1306 | if (TREE_CODE (*tp) == LABEL_DECL) | |
1307 | FORCED_LABEL (*tp) = 1; | |
1308 | ||
1309 | return NULL_TREE; | |
1310 | } | |
1311 | ||
26d44ae2 RH |
1312 | /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is |
1313 | different from its canonical type, wrap the whole thing inside a | |
1314 | NOP_EXPR and force the type of the COMPONENT_REF to be the canonical | |
1315 | type. | |
6de9cd9a | 1316 | |
26d44ae2 RH |
1317 | The canonical type of a COMPONENT_REF is the type of the field being |
1318 | referenced--unless the field is a bit-field which can be read directly | |
1319 | in a smaller mode, in which case the canonical type is the | |
1320 | sign-appropriate type corresponding to that mode. */ | |
6de9cd9a | 1321 | |
26d44ae2 RH |
1322 | static void |
1323 | canonicalize_component_ref (tree *expr_p) | |
6de9cd9a | 1324 | { |
26d44ae2 RH |
1325 | tree expr = *expr_p; |
1326 | tree type; | |
6de9cd9a | 1327 | |
26d44ae2 RH |
1328 | if (TREE_CODE (expr) != COMPONENT_REF) |
1329 | abort (); | |
6de9cd9a | 1330 | |
26d44ae2 RH |
1331 | if (INTEGRAL_TYPE_P (TREE_TYPE (expr))) |
1332 | type = TREE_TYPE (get_unwidened (expr, NULL_TREE)); | |
1333 | else | |
1334 | type = TREE_TYPE (TREE_OPERAND (expr, 1)); | |
6de9cd9a | 1335 | |
26d44ae2 | 1336 | if (TREE_TYPE (expr) != type) |
6de9cd9a | 1337 | { |
26d44ae2 | 1338 | tree old_type = TREE_TYPE (expr); |
6de9cd9a | 1339 | |
26d44ae2 RH |
1340 | /* Set the type of the COMPONENT_REF to the underlying type. */ |
1341 | TREE_TYPE (expr) = type; | |
6de9cd9a | 1342 | |
26d44ae2 RH |
1343 | /* And wrap the whole thing inside a NOP_EXPR. */ |
1344 | expr = build1 (NOP_EXPR, old_type, expr); | |
6de9cd9a | 1345 | |
26d44ae2 RH |
1346 | *expr_p = expr; |
1347 | } | |
1348 | } | |
6de9cd9a | 1349 | |
26d44ae2 RH |
1350 | /* If a NOP conversion is changing a pointer to array of foo to a pointer |
1351 | to foo, embed that change in the ADDR_EXPR by converting | |
1352 | T array[U]; | |
1353 | (T *)&array | |
1354 | ==> | |
1355 | &array[L] | |
1356 | where L is the lower bound. For simplicity, only do this for constant | |
1357 | lower bound. */ | |
6de9cd9a | 1358 | |
26d44ae2 RH |
1359 | static void |
1360 | canonicalize_addr_expr (tree *expr_p) | |
1361 | { | |
1362 | tree expr = *expr_p; | |
1363 | tree ctype = TREE_TYPE (expr); | |
1364 | tree addr_expr = TREE_OPERAND (expr, 0); | |
1365 | tree atype = TREE_TYPE (addr_expr); | |
1366 | tree dctype, datype, ddatype, otype, obj_expr; | |
6de9cd9a | 1367 | |
26d44ae2 RH |
1368 | /* Both cast and addr_expr types should be pointers. */ |
1369 | if (!POINTER_TYPE_P (ctype) || !POINTER_TYPE_P (atype)) | |
1370 | return; | |
6de9cd9a | 1371 | |
26d44ae2 RH |
1372 | /* The addr_expr type should be a pointer to an array. */ |
1373 | datype = TREE_TYPE (atype); | |
1374 | if (TREE_CODE (datype) != ARRAY_TYPE) | |
1375 | return; | |
6de9cd9a | 1376 | |
26d44ae2 RH |
1377 | /* Both cast and addr_expr types should address the same object type. */ |
1378 | dctype = TREE_TYPE (ctype); | |
1379 | ddatype = TREE_TYPE (datype); | |
1380 | if (!lang_hooks.types_compatible_p (ddatype, dctype)) | |
1381 | return; | |
6de9cd9a | 1382 | |
26d44ae2 RH |
1383 | /* The addr_expr and the object type should match. */ |
1384 | obj_expr = TREE_OPERAND (addr_expr, 0); | |
1385 | otype = TREE_TYPE (obj_expr); | |
1386 | if (!lang_hooks.types_compatible_p (otype, datype)) | |
1387 | return; | |
6de9cd9a | 1388 | |
26d44ae2 RH |
1389 | /* The lower bound and element sizes must be constant. */ |
1390 | if (TREE_CODE (TYPE_SIZE_UNIT (dctype)) != INTEGER_CST | |
1391 | || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype)) | |
1392 | || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST) | |
1393 | return; | |
6de9cd9a | 1394 | |
26d44ae2 RH |
1395 | /* All checks succeeded. Build a new node to merge the cast. */ |
1396 | *expr_p = build4 (ARRAY_REF, dctype, obj_expr, | |
1397 | TYPE_MIN_VALUE (TYPE_DOMAIN (datype)), | |
1398 | TYPE_MIN_VALUE (TYPE_DOMAIN (datype)), | |
1399 | size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (dctype), | |
a4e9ffe5 | 1400 | size_int (TYPE_ALIGN_UNIT (dctype)))); |
26d44ae2 RH |
1401 | *expr_p = build1 (ADDR_EXPR, ctype, *expr_p); |
1402 | } | |
6de9cd9a | 1403 | |
26d44ae2 RH |
1404 | /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions |
1405 | underneath as appropriate. */ | |
6de9cd9a | 1406 | |
26d44ae2 RH |
1407 | static enum gimplify_status |
1408 | gimplify_conversion (tree *expr_p) | |
1409 | { | |
26d44ae2 RH |
1410 | /* If we still have a conversion at the toplevel, then strip |
1411 | away all but the outermost conversion. */ | |
1412 | if (TREE_CODE (*expr_p) == NOP_EXPR || TREE_CODE (*expr_p) == CONVERT_EXPR) | |
1413 | { | |
1414 | STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0)); | |
6de9cd9a | 1415 | |
26d44ae2 RH |
1416 | /* And remove the outermost conversion if it's useless. */ |
1417 | if (tree_ssa_useless_type_conversion (*expr_p)) | |
1418 | *expr_p = TREE_OPERAND (*expr_p, 0); | |
1419 | } | |
6de9cd9a | 1420 | |
26d44ae2 RH |
1421 | /* If we still have a conversion at the toplevel, |
1422 | then canonicalize some constructs. */ | |
1423 | if (TREE_CODE (*expr_p) == NOP_EXPR || TREE_CODE (*expr_p) == CONVERT_EXPR) | |
1424 | { | |
1425 | tree sub = TREE_OPERAND (*expr_p, 0); | |
6de9cd9a | 1426 | |
26d44ae2 RH |
1427 | /* If a NOP conversion is changing the type of a COMPONENT_REF |
1428 | expression, then canonicalize its type now in order to expose more | |
1429 | redundant conversions. */ | |
1430 | if (TREE_CODE (sub) == COMPONENT_REF) | |
1431 | canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0)); | |
6de9cd9a | 1432 | |
26d44ae2 RH |
1433 | /* If a NOP conversion is changing a pointer to array of foo |
1434 | to a pointer to foo, embed that change in the ADDR_EXPR. */ | |
1435 | else if (TREE_CODE (sub) == ADDR_EXPR) | |
1436 | canonicalize_addr_expr (expr_p); | |
1437 | } | |
6de9cd9a DN |
1438 | |
1439 | return GS_OK; | |
1440 | } | |
1441 | ||
6de9cd9a DN |
1442 | /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR |
1443 | node pointed by EXPR_P. | |
1444 | ||
1445 | compound_lval | |
1446 | : min_lval '[' val ']' | |
1447 | | min_lval '.' ID | |
1448 | | compound_lval '[' val ']' | |
1449 | | compound_lval '.' ID | |
1450 | ||
1451 | This is not part of the original SIMPLE definition, which separates | |
1452 | array and member references, but it seems reasonable to handle them | |
1453 | together. Also, this way we don't run into problems with union | |
1454 | aliasing; gcc requires that for accesses through a union to alias, the | |
1455 | union reference must be explicit, which was not always the case when we | |
1456 | were splitting up array and member refs. | |
1457 | ||
1458 | PRE_P points to the list where side effects that must happen before | |
1459 | *EXPR_P should be stored. | |
1460 | ||
1461 | POST_P points to the list where side effects that must happen after | |
1462 | *EXPR_P should be stored. */ | |
1463 | ||
1464 | static enum gimplify_status | |
1465 | gimplify_compound_lval (tree *expr_p, tree *pre_p, | |
90051e16 | 1466 | tree *post_p, fallback_t fallback) |
6de9cd9a DN |
1467 | { |
1468 | tree *p; | |
6de9cd9a | 1469 | varray_type stack; |
44de5aeb | 1470 | enum gimplify_status ret = GS_OK, tret; |
af72267c | 1471 | int i; |
6de9cd9a | 1472 | |
6de9cd9a | 1473 | /* Create a stack of the subexpressions so later we can walk them in |
07724022 JH |
1474 | order from inner to outer. |
1475 | ||
1476 | This array is very memory consuming. Don't even think of making | |
1477 | it VARRAY_TREE. */ | |
1478 | VARRAY_GENERIC_PTR_NOGC_INIT (stack, 10, "stack"); | |
6de9cd9a | 1479 | |
af72267c RK |
1480 | /* We can either handle REALPART_EXPR, IMAGEPART_EXPR anything that |
1481 | handled_components can deal with. */ | |
1482 | for (p = expr_p; | |
1483 | (handled_component_p (*p) | |
1484 | || TREE_CODE (*p) == REALPART_EXPR || TREE_CODE (*p) == IMAGPART_EXPR); | |
1485 | p = &TREE_OPERAND (*p, 0)) | |
07724022 | 1486 | VARRAY_PUSH_GENERIC_PTR_NOGC (stack, *p); |
6de9cd9a | 1487 | |
9e51aaf5 RK |
1488 | #if defined ENABLE_CHECKING |
1489 | if (VARRAY_ACTIVE_SIZE (stack) == 0) | |
1490 | abort (); | |
1491 | #endif | |
1492 | ||
44de5aeb RK |
1493 | /* Now STACK is a stack of pointers to all the refs we've walked through |
1494 | and P points to the innermost expression. | |
6de9cd9a | 1495 | |
af72267c RK |
1496 | Java requires that we elaborated nodes in source order. That |
1497 | means we must gimplify the inner expression followed by each of | |
1498 | the indices, in order. But we can't gimplify the inner | |
1499 | expression until we deal with any variable bounds, sizes, or | |
1500 | positions in order to deal with PLACEHOLDER_EXPRs. | |
1501 | ||
1502 | So we do this in three steps. First we deal with the annotations | |
1503 | for any variables in the components, then we gimplify the base, | |
1504 | then we gimplify any indices, from left to right. */ | |
1505 | for (i = VARRAY_ACTIVE_SIZE (stack) - 1; i >= 0; i--) | |
6de9cd9a | 1506 | { |
07724022 | 1507 | tree t = VARRAY_GENERIC_PTR_NOGC (stack, i); |
44de5aeb RK |
1508 | |
1509 | if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF) | |
6de9cd9a | 1510 | { |
44de5aeb RK |
1511 | /* Gimplify the low bound and element type size and put them into |
1512 | the ARRAY_REF. If these values are set, they have already been | |
1513 | gimplified. */ | |
1514 | if (!TREE_OPERAND (t, 2)) | |
1515 | { | |
a7cc468a RH |
1516 | tree low = unshare_expr (array_ref_low_bound (t)); |
1517 | if (!is_gimple_min_invariant (low)) | |
44de5aeb | 1518 | { |
a7cc468a | 1519 | TREE_OPERAND (t, 2) = low; |
44de5aeb | 1520 | tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p, |
17ad5b5e | 1521 | is_gimple_formal_tmp_reg, fb_rvalue); |
44de5aeb RK |
1522 | ret = MIN (ret, tret); |
1523 | } | |
1524 | } | |
1525 | ||
1526 | if (!TREE_OPERAND (t, 3)) | |
1527 | { | |
1528 | tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))); | |
1529 | tree elmt_size = unshare_expr (array_ref_element_size (t)); | |
a4e9ffe5 | 1530 | tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type)); |
44de5aeb RK |
1531 | |
1532 | /* Divide the element size by the alignment of the element | |
1533 | type (above). */ | |
1534 | elmt_size = size_binop (EXACT_DIV_EXPR, elmt_size, factor); | |
1535 | ||
a7cc468a | 1536 | if (!is_gimple_min_invariant (elmt_size)) |
44de5aeb | 1537 | { |
a7cc468a | 1538 | TREE_OPERAND (t, 3) = elmt_size; |
44de5aeb | 1539 | tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p, |
17ad5b5e | 1540 | is_gimple_formal_tmp_reg, fb_rvalue); |
44de5aeb RK |
1541 | ret = MIN (ret, tret); |
1542 | } | |
6de9cd9a DN |
1543 | } |
1544 | } | |
44de5aeb RK |
1545 | else if (TREE_CODE (t) == COMPONENT_REF) |
1546 | { | |
1547 | /* Set the field offset into T and gimplify it. */ | |
1548 | if (!TREE_OPERAND (t, 2)) | |
1549 | { | |
1550 | tree offset = unshare_expr (component_ref_field_offset (t)); | |
1551 | tree field = TREE_OPERAND (t, 1); | |
1552 | tree factor | |
1553 | = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT); | |
1554 | ||
1555 | /* Divide the offset by its alignment. */ | |
1556 | offset = size_binop (EXACT_DIV_EXPR, offset, factor); | |
1557 | ||
a7cc468a | 1558 | if (!is_gimple_min_invariant (offset)) |
44de5aeb | 1559 | { |
a7cc468a | 1560 | TREE_OPERAND (t, 2) = offset; |
44de5aeb | 1561 | tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p, |
17ad5b5e | 1562 | is_gimple_formal_tmp_reg, fb_rvalue); |
44de5aeb RK |
1563 | ret = MIN (ret, tret); |
1564 | } | |
1565 | } | |
1566 | } | |
af72267c RK |
1567 | } |
1568 | ||
1569 | /* Step 2 is to gimplify the base expression. */ | |
90051e16 | 1570 | tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval, fallback); |
af72267c RK |
1571 | ret = MIN (ret, tret); |
1572 | ||
48eb4e53 RK |
1573 | /* And finally, the indices and operands to BIT_FIELD_REF. During this |
1574 | loop we also remove any useless conversions. */ | |
af72267c RK |
1575 | for (; VARRAY_ACTIVE_SIZE (stack) > 0; ) |
1576 | { | |
1577 | tree t = VARRAY_TOP_TREE (stack); | |
1578 | ||
1579 | if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF) | |
1580 | { | |
1581 | /* Gimplify the dimension. | |
1582 | Temporary fix for gcc.c-torture/execute/20040313-1.c. | |
1583 | Gimplify non-constant array indices into a temporary | |
1584 | variable. | |
1585 | FIXME - The real fix is to gimplify post-modify | |
1586 | expressions into a minimal gimple lvalue. However, that | |
1587 | exposes bugs in alias analysis. The alias analyzer does | |
1588 | not handle &PTR->FIELD very well. Will fix after the | |
1589 | branch is merged into mainline (dnovillo 2004-05-03). */ | |
1590 | if (!is_gimple_min_invariant (TREE_OPERAND (t, 1))) | |
1591 | { | |
1592 | tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p, | |
17ad5b5e | 1593 | is_gimple_formal_tmp_reg, fb_rvalue); |
af72267c RK |
1594 | ret = MIN (ret, tret); |
1595 | } | |
1596 | } | |
44de5aeb RK |
1597 | else if (TREE_CODE (t) == BIT_FIELD_REF) |
1598 | { | |
1599 | tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p, | |
1600 | is_gimple_val, fb_rvalue); | |
1601 | ret = MIN (ret, tret); | |
1602 | tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p, | |
1603 | is_gimple_val, fb_rvalue); | |
1604 | ret = MIN (ret, tret); | |
1605 | } | |
48eb4e53 RK |
1606 | |
1607 | STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0)); | |
1608 | ||
af72267c RK |
1609 | /* The innermost expression P may have originally had TREE_SIDE_EFFECTS |
1610 | set which would have caused all the outer expressions in EXPR_P | |
1611 | leading to P to also have had TREE_SIDE_EFFECTS set. */ | |
6de9cd9a DN |
1612 | recalculate_side_effects (t); |
1613 | VARRAY_POP (stack); | |
1614 | } | |
1615 | ||
90051e16 | 1616 | tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval, fallback); |
44de5aeb RK |
1617 | ret = MIN (ret, tret); |
1618 | ||
6de9cd9a | 1619 | /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */ |
90051e16 | 1620 | if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF) |
6de9cd9a DN |
1621 | { |
1622 | canonicalize_component_ref (expr_p); | |
1623 | ret = MIN (ret, GS_OK); | |
1624 | } | |
1625 | ||
07724022 JH |
1626 | VARRAY_FREE (stack); |
1627 | ||
6de9cd9a DN |
1628 | return ret; |
1629 | } | |
1630 | ||
6de9cd9a DN |
1631 | /* Gimplify the self modifying expression pointed by EXPR_P (++, --, +=, -=). |
1632 | ||
1633 | PRE_P points to the list where side effects that must happen before | |
1634 | *EXPR_P should be stored. | |
1635 | ||
1636 | POST_P points to the list where side effects that must happen after | |
1637 | *EXPR_P should be stored. | |
1638 | ||
1639 | WANT_VALUE is nonzero iff we want to use the value of this expression | |
1640 | in another expression. */ | |
1641 | ||
1642 | static enum gimplify_status | |
1643 | gimplify_self_mod_expr (tree *expr_p, tree *pre_p, tree *post_p, | |
44de5aeb | 1644 | bool want_value) |
6de9cd9a DN |
1645 | { |
1646 | enum tree_code code; | |
1647 | tree lhs, lvalue, rhs, t1; | |
1648 | bool postfix; | |
1649 | enum tree_code arith_code; | |
1650 | enum gimplify_status ret; | |
1651 | ||
1652 | code = TREE_CODE (*expr_p); | |
1653 | ||
1654 | #if defined ENABLE_CHECKING | |
1655 | if (code != POSTINCREMENT_EXPR | |
1656 | && code != POSTDECREMENT_EXPR | |
1657 | && code != PREINCREMENT_EXPR | |
1658 | && code != PREDECREMENT_EXPR) | |
1659 | abort (); | |
1660 | #endif | |
1661 | ||
1662 | /* Prefix or postfix? */ | |
1663 | if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR) | |
1664 | /* Faster to treat as prefix if result is not used. */ | |
1665 | postfix = want_value; | |
1666 | else | |
1667 | postfix = false; | |
1668 | ||
1669 | /* Add or subtract? */ | |
1670 | if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) | |
1671 | arith_code = PLUS_EXPR; | |
1672 | else | |
1673 | arith_code = MINUS_EXPR; | |
1674 | ||
1675 | /* Gimplify the LHS into a GIMPLE lvalue. */ | |
1676 | lvalue = TREE_OPERAND (*expr_p, 0); | |
1677 | ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue); | |
1678 | if (ret == GS_ERROR) | |
1679 | return ret; | |
1680 | ||
1681 | /* Extract the operands to the arithmetic operation. */ | |
1682 | lhs = lvalue; | |
1683 | rhs = TREE_OPERAND (*expr_p, 1); | |
1684 | ||
1685 | /* For postfix operator, we evaluate the LHS to an rvalue and then use | |
1686 | that as the result value and in the postqueue operation. */ | |
1687 | if (postfix) | |
1688 | { | |
1689 | ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue); | |
1690 | if (ret == GS_ERROR) | |
1691 | return ret; | |
1692 | } | |
1693 | ||
1694 | t1 = build (arith_code, TREE_TYPE (*expr_p), lhs, rhs); | |
1695 | t1 = build (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1); | |
1696 | ||
1697 | if (postfix) | |
1698 | { | |
fff34d35 | 1699 | gimplify_and_add (t1, post_p); |
6de9cd9a DN |
1700 | *expr_p = lhs; |
1701 | return GS_ALL_DONE; | |
1702 | } | |
1703 | else | |
1704 | { | |
1705 | *expr_p = t1; | |
1706 | return GS_OK; | |
1707 | } | |
1708 | } | |
1709 | ||
d25cee4d RH |
1710 | /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */ |
1711 | ||
1712 | static void | |
1713 | maybe_with_size_expr (tree *expr_p) | |
1714 | { | |
61025d1b RK |
1715 | tree expr = *expr_p; |
1716 | tree type = TREE_TYPE (expr); | |
1717 | tree size; | |
d25cee4d | 1718 | |
61025d1b RK |
1719 | /* If we've already wrapped this or the type is error_mark_node, we can't do |
1720 | anything. */ | |
1721 | if (TREE_CODE (expr) == WITH_SIZE_EXPR | |
1722 | || type == error_mark_node) | |
d25cee4d RH |
1723 | return; |
1724 | ||
61025d1b | 1725 | /* If the size isn't known or is a constant, we have nothing to do. */ |
d25cee4d | 1726 | size = TYPE_SIZE_UNIT (type); |
61025d1b RK |
1727 | if (!size || TREE_CODE (size) == INTEGER_CST) |
1728 | return; | |
1729 | ||
1730 | /* Otherwise, make a WITH_SIZE_EXPR. */ | |
1731 | size = unshare_expr (size); | |
1732 | size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr); | |
1733 | *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size); | |
d25cee4d RH |
1734 | } |
1735 | ||
e4f78bd4 JM |
1736 | /* Subroutine of gimplify_call_expr: Gimplify a single argument. */ |
1737 | ||
1738 | static enum gimplify_status | |
1739 | gimplify_arg (tree *expr_p, tree *pre_p) | |
1740 | { | |
1741 | bool (*test) (tree); | |
1742 | fallback_t fb; | |
1743 | ||
1744 | /* In general, we allow lvalues for function arguments to avoid | |
1745 | extra overhead of copying large aggregates out of even larger | |
1746 | aggregates into temporaries only to copy the temporaries to | |
1747 | the argument list. Make optimizers happy by pulling out to | |
1748 | temporaries those types that fit in registers. */ | |
1749 | if (is_gimple_reg_type (TREE_TYPE (*expr_p))) | |
1750 | test = is_gimple_val, fb = fb_rvalue; | |
1751 | else | |
1752 | test = is_gimple_lvalue, fb = fb_either; | |
1753 | ||
d25cee4d RH |
1754 | /* If this is a variable sized type, we must remember the size. */ |
1755 | maybe_with_size_expr (expr_p); | |
1756 | ||
e4f78bd4 JM |
1757 | /* There is a sequence point before a function call. Side effects in |
1758 | the argument list must occur before the actual call. So, when | |
1759 | gimplifying arguments, force gimplify_expr to use an internal | |
1760 | post queue which is then appended to the end of PRE_P. */ | |
1761 | return gimplify_expr (expr_p, pre_p, NULL, test, fb); | |
1762 | } | |
1763 | ||
90051e16 RH |
1764 | /* Gimplify the CALL_EXPR node pointed by EXPR_P. PRE_P points to the |
1765 | list where side effects that must happen before *EXPR_P should be stored. | |
1766 | WANT_VALUE is true if the result of the call is desired. */ | |
6de9cd9a DN |
1767 | |
1768 | static enum gimplify_status | |
90051e16 | 1769 | gimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value) |
6de9cd9a DN |
1770 | { |
1771 | tree decl; | |
1772 | tree arglist; | |
1773 | enum gimplify_status ret; | |
1774 | ||
1775 | #if defined ENABLE_CHECKING | |
1776 | if (TREE_CODE (*expr_p) != CALL_EXPR) | |
1777 | abort (); | |
1778 | #endif | |
1779 | ||
1780 | /* For reliable diagnostics during inlining, it is necessary that | |
1781 | every call_expr be annotated with file and line. */ | |
a281759f PB |
1782 | if (! EXPR_HAS_LOCATION (*expr_p)) |
1783 | SET_EXPR_LOCATION (*expr_p, input_location); | |
6de9cd9a DN |
1784 | |
1785 | /* This may be a call to a builtin function. | |
1786 | ||
1787 | Builtin function calls may be transformed into different | |
1788 | (and more efficient) builtin function calls under certain | |
1789 | circumstances. Unfortunately, gimplification can muck things | |
1790 | up enough that the builtin expanders are not aware that certain | |
1791 | transformations are still valid. | |
1792 | ||
1793 | So we attempt transformation/gimplification of the call before | |
1794 | we gimplify the CALL_EXPR. At this time we do not manage to | |
1795 | transform all calls in the same manner as the expanders do, but | |
1796 | we do transform most of them. */ | |
1797 | decl = get_callee_fndecl (*expr_p); | |
1798 | if (decl && DECL_BUILT_IN (decl)) | |
1799 | { | |
1a186ec5 | 1800 | tree new = simplify_builtin (*expr_p, !want_value); |
6de9cd9a DN |
1801 | |
1802 | if (new && new != *expr_p) | |
1803 | { | |
1804 | /* There was a transformation of this call which computes the | |
1805 | same value, but in a more efficient way. Return and try | |
1806 | again. */ | |
1807 | *expr_p = new; | |
1808 | return GS_OK; | |
1809 | } | |
e4f78bd4 JM |
1810 | |
1811 | if (DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_START) | |
1812 | /* Avoid gimplifying the second argument to va_start, which needs | |
1813 | to be the plain PARM_DECL. */ | |
1814 | return gimplify_arg (&TREE_VALUE (TREE_OPERAND (*expr_p, 1)), pre_p); | |
6de9cd9a DN |
1815 | } |
1816 | ||
1817 | /* There is a sequence point before the call, so any side effects in | |
1818 | the calling expression must occur before the actual call. Force | |
1819 | gimplify_expr to use an internal post queue. */ | |
1820 | ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, NULL, | |
0f59171d | 1821 | is_gimple_call_addr, fb_rvalue); |
6de9cd9a DN |
1822 | |
1823 | if (PUSH_ARGS_REVERSED) | |
1824 | TREE_OPERAND (*expr_p, 1) = nreverse (TREE_OPERAND (*expr_p, 1)); | |
1825 | for (arglist = TREE_OPERAND (*expr_p, 1); arglist; | |
1826 | arglist = TREE_CHAIN (arglist)) | |
1827 | { | |
1828 | enum gimplify_status t; | |
1829 | ||
e4f78bd4 | 1830 | t = gimplify_arg (&TREE_VALUE (arglist), pre_p); |
6de9cd9a DN |
1831 | |
1832 | if (t == GS_ERROR) | |
1833 | ret = GS_ERROR; | |
1834 | } | |
1835 | if (PUSH_ARGS_REVERSED) | |
1836 | TREE_OPERAND (*expr_p, 1) = nreverse (TREE_OPERAND (*expr_p, 1)); | |
1837 | ||
1838 | /* Try this again in case gimplification exposed something. */ | |
1839 | if (ret != GS_ERROR && decl && DECL_BUILT_IN (decl)) | |
1840 | { | |
90051e16 | 1841 | tree new = simplify_builtin (*expr_p, !want_value); |
6de9cd9a DN |
1842 | |
1843 | if (new && new != *expr_p) | |
1844 | { | |
1845 | /* There was a transformation of this call which computes the | |
1846 | same value, but in a more efficient way. Return and try | |
1847 | again. */ | |
1848 | *expr_p = new; | |
1849 | return GS_OK; | |
1850 | } | |
1851 | } | |
1852 | ||
1853 | /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its | |
1854 | decl. This allows us to eliminate redundant or useless | |
1855 | calls to "const" functions. */ | |
1856 | if (TREE_CODE (*expr_p) == CALL_EXPR | |
1857 | && (call_expr_flags (*expr_p) & (ECF_CONST | ECF_PURE))) | |
1858 | TREE_SIDE_EFFECTS (*expr_p) = 0; | |
1859 | ||
1860 | return ret; | |
1861 | } | |
1862 | ||
1863 | /* Handle shortcut semantics in the predicate operand of a COND_EXPR by | |
1864 | rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs. | |
1865 | ||
1866 | TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the | |
1867 | condition is true or false, respectively. If null, we should generate | |
1868 | our own to skip over the evaluation of this specific expression. | |
1869 | ||
1870 | This function is the tree equivalent of do_jump. | |
1871 | ||
1872 | shortcut_cond_r should only be called by shortcut_cond_expr. */ | |
1873 | ||
1874 | static tree | |
1875 | shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p) | |
1876 | { | |
1877 | tree local_label = NULL_TREE; | |
1878 | tree t, expr = NULL; | |
1879 | ||
1880 | /* OK, it's not a simple case; we need to pull apart the COND_EXPR to | |
1881 | retain the shortcut semantics. Just insert the gotos here; | |
1882 | shortcut_cond_expr will append the real blocks later. */ | |
1883 | if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR) | |
1884 | { | |
1885 | /* Turn if (a && b) into | |
1886 | ||
1887 | if (a); else goto no; | |
1888 | if (b) goto yes; else goto no; | |
1889 | (no:) */ | |
1890 | ||
1891 | if (false_label_p == NULL) | |
1892 | false_label_p = &local_label; | |
1893 | ||
1894 | t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p); | |
1895 | append_to_statement_list (t, &expr); | |
1896 | ||
1897 | t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, | |
1898 | false_label_p); | |
1899 | append_to_statement_list (t, &expr); | |
1900 | } | |
1901 | else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR) | |
1902 | { | |
1903 | /* Turn if (a || b) into | |
1904 | ||
1905 | if (a) goto yes; | |
1906 | if (b) goto yes; else goto no; | |
1907 | (yes:) */ | |
1908 | ||
1909 | if (true_label_p == NULL) | |
1910 | true_label_p = &local_label; | |
1911 | ||
1912 | t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL); | |
1913 | append_to_statement_list (t, &expr); | |
1914 | ||
1915 | t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, | |
1916 | false_label_p); | |
1917 | append_to_statement_list (t, &expr); | |
1918 | } | |
1919 | else if (TREE_CODE (pred) == COND_EXPR) | |
1920 | { | |
1921 | /* As long as we're messing with gotos, turn if (a ? b : c) into | |
1922 | if (a) | |
1923 | if (b) goto yes; else goto no; | |
1924 | else | |
1925 | if (c) goto yes; else goto no; */ | |
1926 | expr = build (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0), | |
1927 | shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, | |
1928 | false_label_p), | |
1929 | shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p, | |
1930 | false_label_p)); | |
1931 | } | |
1932 | else | |
1933 | { | |
1934 | expr = build (COND_EXPR, void_type_node, pred, | |
1935 | build_and_jump (true_label_p), | |
1936 | build_and_jump (false_label_p)); | |
1937 | } | |
1938 | ||
1939 | if (local_label) | |
1940 | { | |
1941 | t = build1 (LABEL_EXPR, void_type_node, local_label); | |
1942 | append_to_statement_list (t, &expr); | |
1943 | } | |
1944 | ||
1945 | return expr; | |
1946 | } | |
1947 | ||
1948 | static tree | |
1949 | shortcut_cond_expr (tree expr) | |
1950 | { | |
1951 | tree pred = TREE_OPERAND (expr, 0); | |
1952 | tree then_ = TREE_OPERAND (expr, 1); | |
1953 | tree else_ = TREE_OPERAND (expr, 2); | |
1954 | tree true_label, false_label, end_label, t; | |
1955 | tree *true_label_p; | |
1956 | tree *false_label_p; | |
1957 | bool emit_end, emit_false; | |
65355d53 RH |
1958 | bool then_se = then_ && TREE_SIDE_EFFECTS (then_); |
1959 | bool else_se = else_ && TREE_SIDE_EFFECTS (else_); | |
6de9cd9a DN |
1960 | |
1961 | /* First do simple transformations. */ | |
65355d53 | 1962 | if (!else_se) |
6de9cd9a DN |
1963 | { |
1964 | /* If there is no 'else', turn (a && b) into if (a) if (b). */ | |
1965 | while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR) | |
1966 | { | |
1967 | TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1); | |
1968 | then_ = shortcut_cond_expr (expr); | |
1969 | pred = TREE_OPERAND (pred, 0); | |
65355d53 | 1970 | expr = build (COND_EXPR, void_type_node, pred, then_, NULL_TREE); |
6de9cd9a DN |
1971 | } |
1972 | } | |
65355d53 | 1973 | if (!then_se) |
6de9cd9a DN |
1974 | { |
1975 | /* If there is no 'then', turn | |
1976 | if (a || b); else d | |
1977 | into | |
1978 | if (a); else if (b); else d. */ | |
1979 | while (TREE_CODE (pred) == TRUTH_ORIF_EXPR) | |
1980 | { | |
1981 | TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1); | |
1982 | else_ = shortcut_cond_expr (expr); | |
1983 | pred = TREE_OPERAND (pred, 0); | |
65355d53 | 1984 | expr = build (COND_EXPR, void_type_node, pred, NULL_TREE, else_); |
6de9cd9a DN |
1985 | } |
1986 | } | |
1987 | ||
1988 | /* If we're done, great. */ | |
1989 | if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR | |
1990 | && TREE_CODE (pred) != TRUTH_ORIF_EXPR) | |
1991 | return expr; | |
1992 | ||
1993 | /* Otherwise we need to mess with gotos. Change | |
1994 | if (a) c; else d; | |
1995 | to | |
1996 | if (a); else goto no; | |
1997 | c; goto end; | |
1998 | no: d; end: | |
1999 | and recursively gimplify the condition. */ | |
2000 | ||
2001 | true_label = false_label = end_label = NULL_TREE; | |
2002 | ||
2003 | /* If our arms just jump somewhere, hijack those labels so we don't | |
2004 | generate jumps to jumps. */ | |
2005 | ||
65355d53 RH |
2006 | if (then_ |
2007 | && TREE_CODE (then_) == GOTO_EXPR | |
6de9cd9a DN |
2008 | && TREE_CODE (GOTO_DESTINATION (then_)) == LABEL_DECL) |
2009 | { | |
2010 | true_label = GOTO_DESTINATION (then_); | |
65355d53 RH |
2011 | then_ = NULL; |
2012 | then_se = false; | |
6de9cd9a DN |
2013 | } |
2014 | ||
65355d53 RH |
2015 | if (else_ |
2016 | && TREE_CODE (else_) == GOTO_EXPR | |
6de9cd9a DN |
2017 | && TREE_CODE (GOTO_DESTINATION (else_)) == LABEL_DECL) |
2018 | { | |
2019 | false_label = GOTO_DESTINATION (else_); | |
65355d53 RH |
2020 | else_ = NULL; |
2021 | else_se = false; | |
6de9cd9a DN |
2022 | } |
2023 | ||
9cf737f8 | 2024 | /* If we aren't hijacking a label for the 'then' branch, it falls through. */ |
6de9cd9a DN |
2025 | if (true_label) |
2026 | true_label_p = &true_label; | |
2027 | else | |
2028 | true_label_p = NULL; | |
2029 | ||
2030 | /* The 'else' branch also needs a label if it contains interesting code. */ | |
65355d53 | 2031 | if (false_label || else_se) |
6de9cd9a DN |
2032 | false_label_p = &false_label; |
2033 | else | |
2034 | false_label_p = NULL; | |
2035 | ||
2036 | /* If there was nothing else in our arms, just forward the label(s). */ | |
65355d53 | 2037 | if (!then_se && !else_se) |
6de9cd9a DN |
2038 | return shortcut_cond_r (pred, true_label_p, false_label_p); |
2039 | ||
2040 | /* If our last subexpression already has a terminal label, reuse it. */ | |
65355d53 | 2041 | if (else_se) |
6de9cd9a | 2042 | expr = expr_last (else_); |
65355d53 | 2043 | else if (then_se) |
6de9cd9a | 2044 | expr = expr_last (then_); |
65355d53 RH |
2045 | else |
2046 | expr = NULL; | |
2047 | if (expr && TREE_CODE (expr) == LABEL_EXPR) | |
6de9cd9a DN |
2048 | end_label = LABEL_EXPR_LABEL (expr); |
2049 | ||
2050 | /* If we don't care about jumping to the 'else' branch, jump to the end | |
2051 | if the condition is false. */ | |
2052 | if (!false_label_p) | |
2053 | false_label_p = &end_label; | |
2054 | ||
2055 | /* We only want to emit these labels if we aren't hijacking them. */ | |
2056 | emit_end = (end_label == NULL_TREE); | |
2057 | emit_false = (false_label == NULL_TREE); | |
2058 | ||
2059 | pred = shortcut_cond_r (pred, true_label_p, false_label_p); | |
2060 | ||
2061 | expr = NULL; | |
2062 | append_to_statement_list (pred, &expr); | |
2063 | ||
2064 | append_to_statement_list (then_, &expr); | |
65355d53 | 2065 | if (else_se) |
6de9cd9a DN |
2066 | { |
2067 | t = build_and_jump (&end_label); | |
2068 | append_to_statement_list (t, &expr); | |
2069 | if (emit_false) | |
2070 | { | |
2071 | t = build1 (LABEL_EXPR, void_type_node, false_label); | |
2072 | append_to_statement_list (t, &expr); | |
2073 | } | |
2074 | append_to_statement_list (else_, &expr); | |
2075 | } | |
2076 | if (emit_end && end_label) | |
2077 | { | |
2078 | t = build1 (LABEL_EXPR, void_type_node, end_label); | |
2079 | append_to_statement_list (t, &expr); | |
2080 | } | |
2081 | ||
2082 | return expr; | |
2083 | } | |
2084 | ||
2085 | /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */ | |
2086 | ||
2087 | static tree | |
2088 | gimple_boolify (tree expr) | |
2089 | { | |
2090 | tree type = TREE_TYPE (expr); | |
2091 | ||
2092 | if (TREE_CODE (type) == BOOLEAN_TYPE) | |
2093 | return expr; | |
2094 | ||
2095 | /* If this is the predicate of a COND_EXPR, it might not even be a | |
2096 | truthvalue yet. */ | |
673fda6b | 2097 | expr = lang_hooks.truthvalue_conversion (expr); |
6de9cd9a DN |
2098 | |
2099 | switch (TREE_CODE (expr)) | |
2100 | { | |
2101 | case TRUTH_AND_EXPR: | |
2102 | case TRUTH_OR_EXPR: | |
2103 | case TRUTH_XOR_EXPR: | |
2104 | case TRUTH_ANDIF_EXPR: | |
2105 | case TRUTH_ORIF_EXPR: | |
2106 | /* Also boolify the arguments of truth exprs. */ | |
2107 | TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1)); | |
2108 | /* FALLTHRU */ | |
2109 | ||
2110 | case TRUTH_NOT_EXPR: | |
2111 | TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0)); | |
2112 | /* FALLTHRU */ | |
2113 | ||
2114 | case EQ_EXPR: case NE_EXPR: | |
2115 | case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR: | |
2116 | /* These expressions always produce boolean results. */ | |
2117 | TREE_TYPE (expr) = boolean_type_node; | |
2118 | return expr; | |
2119 | ||
2120 | default: | |
2121 | /* Other expressions that get here must have boolean values, but | |
2122 | might need to be converted to the appropriate mode. */ | |
2123 | return convert (boolean_type_node, expr); | |
2124 | } | |
2125 | } | |
2126 | ||
2127 | /* Convert the conditional expression pointed by EXPR_P '(p) ? a : b;' | |
2128 | into | |
2129 | ||
2130 | if (p) if (p) | |
2131 | t1 = a; a; | |
2132 | else or else | |
2133 | t1 = b; b; | |
2134 | t1; | |
2135 | ||
2136 | The second form is used when *EXPR_P is of type void. | |
2137 | ||
44de5aeb RK |
2138 | TARGET is the tree for T1 above. |
2139 | ||
6de9cd9a DN |
2140 | PRE_P points to the list where side effects that must happen before |
2141 | *EXPR_P should be stored. */ | |
2142 | ||
2143 | static enum gimplify_status | |
2144 | gimplify_cond_expr (tree *expr_p, tree *pre_p, tree target) | |
2145 | { | |
2146 | tree expr = *expr_p; | |
d91ba7b0 | 2147 | tree tmp, tmp2, type; |
6de9cd9a DN |
2148 | enum gimplify_status ret; |
2149 | ||
26d44ae2 RH |
2150 | type = TREE_TYPE (expr); |
2151 | if (!type) | |
2152 | TREE_TYPE (expr) = void_type_node; | |
2153 | ||
2154 | /* If this COND_EXPR has a value, copy the values into a temporary within | |
2155 | the arms. */ | |
2156 | else if (! VOID_TYPE_P (type)) | |
2157 | { | |
2158 | if (target) | |
2159 | { | |
d91ba7b0 RH |
2160 | ret = gimplify_expr (&target, pre_p, NULL, |
2161 | is_gimple_min_lval, fb_lvalue); | |
2162 | if (ret != GS_ERROR) | |
2163 | ret = GS_OK; | |
26d44ae2 | 2164 | tmp = target; |
d91ba7b0 | 2165 | tmp2 = unshare_expr (target); |
26d44ae2 RH |
2166 | } |
2167 | else | |
2168 | { | |
d91ba7b0 | 2169 | tmp2 = tmp = create_tmp_var (TREE_TYPE (expr), "iftmp"); |
26d44ae2 RH |
2170 | ret = GS_ALL_DONE; |
2171 | } | |
2172 | ||
2173 | /* Build the then clause, 't1 = a;'. But don't build an assignment | |
2174 | if this branch is void; in C++ it can be, if it's a throw. */ | |
2175 | if (TREE_TYPE (TREE_OPERAND (expr, 1)) != void_type_node) | |
2176 | TREE_OPERAND (expr, 1) | |
2177 | = build (MODIFY_EXPR, void_type_node, tmp, TREE_OPERAND (expr, 1)); | |
2178 | ||
2179 | /* Build the else clause, 't1 = b;'. */ | |
2180 | if (TREE_TYPE (TREE_OPERAND (expr, 2)) != void_type_node) | |
2181 | TREE_OPERAND (expr, 2) | |
d91ba7b0 | 2182 | = build (MODIFY_EXPR, void_type_node, tmp2, TREE_OPERAND (expr, 2)); |
26d44ae2 RH |
2183 | |
2184 | TREE_TYPE (expr) = void_type_node; | |
2185 | recalculate_side_effects (expr); | |
2186 | ||
d91ba7b0 | 2187 | /* Move the COND_EXPR to the prequeue. */ |
26d44ae2 | 2188 | gimplify_and_add (expr, pre_p); |
26d44ae2 | 2189 | |
d91ba7b0 | 2190 | *expr_p = tmp; |
26d44ae2 RH |
2191 | return ret; |
2192 | } | |
2193 | ||
2194 | /* Make sure the condition has BOOLEAN_TYPE. */ | |
2195 | TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0)); | |
2196 | ||
2197 | /* Break apart && and || conditions. */ | |
2198 | if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR | |
2199 | || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR) | |
2200 | { | |
2201 | expr = shortcut_cond_expr (expr); | |
2202 | ||
2203 | if (expr != *expr_p) | |
2204 | { | |
2205 | *expr_p = expr; | |
2206 | ||
2207 | /* We can't rely on gimplify_expr to re-gimplify the expanded | |
2208 | form properly, as cleanups might cause the target labels to be | |
2209 | wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to | |
2210 | set up a conditional context. */ | |
2211 | gimple_push_condition (); | |
2212 | gimplify_stmt (expr_p); | |
2213 | gimple_pop_condition (pre_p); | |
2214 | ||
2215 | return GS_ALL_DONE; | |
2216 | } | |
2217 | } | |
2218 | ||
2219 | /* Now do the normal gimplification. */ | |
2220 | ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL, | |
2221 | is_gimple_condexpr, fb_rvalue); | |
2222 | ||
2223 | gimple_push_condition (); | |
2224 | ||
2225 | gimplify_to_stmt_list (&TREE_OPERAND (expr, 1)); | |
2226 | gimplify_to_stmt_list (&TREE_OPERAND (expr, 2)); | |
2227 | recalculate_side_effects (expr); | |
2228 | ||
2229 | gimple_pop_condition (pre_p); | |
2230 | ||
2231 | if (ret == GS_ERROR) | |
2232 | ; | |
2233 | else if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))) | |
2234 | ret = GS_ALL_DONE; | |
2235 | else if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 2))) | |
2236 | /* Rewrite "if (a); else b" to "if (!a) b" */ | |
2237 | { | |
2238 | TREE_OPERAND (expr, 0) = invert_truthvalue (TREE_OPERAND (expr, 0)); | |
2239 | ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL, | |
2240 | is_gimple_condexpr, fb_rvalue); | |
2241 | ||
2242 | tmp = TREE_OPERAND (expr, 1); | |
2243 | TREE_OPERAND (expr, 1) = TREE_OPERAND (expr, 2); | |
2244 | TREE_OPERAND (expr, 2) = tmp; | |
2245 | } | |
2246 | else | |
2247 | /* Both arms are empty; replace the COND_EXPR with its predicate. */ | |
2248 | expr = TREE_OPERAND (expr, 0); | |
2249 | ||
2250 | *expr_p = expr; | |
2251 | return ret; | |
2252 | } | |
2253 | ||
2254 | /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with | |
2255 | a call to __builtin_memcpy. */ | |
2256 | ||
2257 | static enum gimplify_status | |
d25cee4d | 2258 | gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value) |
26d44ae2 RH |
2259 | { |
2260 | tree args, t, to, to_ptr, from; | |
2261 | ||
2262 | to = TREE_OPERAND (*expr_p, 0); | |
2263 | from = TREE_OPERAND (*expr_p, 1); | |
2264 | ||
d25cee4d | 2265 | args = tree_cons (NULL, size, NULL); |
26d44ae2 RH |
2266 | |
2267 | t = build_fold_addr_expr (from); | |
2268 | args = tree_cons (NULL, t, args); | |
2269 | ||
2270 | to_ptr = build_fold_addr_expr (to); | |
90051e16 | 2271 | args = tree_cons (NULL, to_ptr, args); |
26d44ae2 RH |
2272 | t = implicit_built_in_decls[BUILT_IN_MEMCPY]; |
2273 | t = build_function_call_expr (t, args); | |
2274 | ||
2275 | if (want_value) | |
2276 | { | |
2277 | t = build1 (NOP_EXPR, TREE_TYPE (to_ptr), t); | |
2278 | t = build1 (INDIRECT_REF, TREE_TYPE (to), t); | |
2279 | } | |
2280 | ||
2281 | *expr_p = t; | |
2282 | return GS_OK; | |
2283 | } | |
2284 | ||
2285 | /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with | |
2286 | a call to __builtin_memset. In this case we know that the RHS is | |
2287 | a CONSTRUCTOR with an empty element list. */ | |
2288 | ||
2289 | static enum gimplify_status | |
d25cee4d | 2290 | gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value) |
26d44ae2 RH |
2291 | { |
2292 | tree args, t, to, to_ptr; | |
2293 | ||
2294 | to = TREE_OPERAND (*expr_p, 0); | |
2295 | ||
d25cee4d | 2296 | args = tree_cons (NULL, size, NULL); |
26d44ae2 RH |
2297 | |
2298 | args = tree_cons (NULL, integer_zero_node, args); | |
2299 | ||
2300 | to_ptr = build_fold_addr_expr (to); | |
73d6ddef | 2301 | args = tree_cons (NULL, to_ptr, args); |
26d44ae2 RH |
2302 | t = implicit_built_in_decls[BUILT_IN_MEMSET]; |
2303 | t = build_function_call_expr (t, args); | |
2304 | ||
2305 | if (want_value) | |
2306 | { | |
2307 | t = build1 (NOP_EXPR, TREE_TYPE (to_ptr), t); | |
2308 | t = build1 (INDIRECT_REF, TREE_TYPE (to), t); | |
2309 | } | |
2310 | ||
2311 | *expr_p = t; | |
2312 | return GS_OK; | |
2313 | } | |
2314 | ||
57d1dd87 RH |
2315 | /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree, |
2316 | determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an | |
2317 | assignment. Returns non-null if we detect a potential overlap. */ | |
2318 | ||
2319 | struct gimplify_init_ctor_preeval_data | |
2320 | { | |
2321 | /* The base decl of the lhs object. May be NULL, in which case we | |
2322 | have to assume the lhs is indirect. */ | |
2323 | tree lhs_base_decl; | |
2324 | ||
2325 | /* The alias set of the lhs object. */ | |
2326 | int lhs_alias_set; | |
2327 | }; | |
2328 | ||
2329 | static tree | |
2330 | gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata) | |
2331 | { | |
2332 | struct gimplify_init_ctor_preeval_data *data | |
2333 | = (struct gimplify_init_ctor_preeval_data *) xdata; | |
2334 | tree t = *tp; | |
2335 | ||
2336 | /* If we find the base object, obviously we have overlap. */ | |
2337 | if (data->lhs_base_decl == t) | |
2338 | return t; | |
2339 | ||
2340 | /* If the constructor component is indirect, determine if we have a | |
2341 | potential overlap with the lhs. The only bits of information we | |
2342 | have to go on at this point are addressability and alias sets. */ | |
2343 | if (TREE_CODE (t) == INDIRECT_REF | |
2344 | && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl)) | |
2345 | && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t))) | |
2346 | return t; | |
2347 | ||
2348 | if (DECL_P (t) || TYPE_P (t)) | |
2349 | *walk_subtrees = 0; | |
2350 | return NULL; | |
2351 | } | |
2352 | ||
2353 | /* A subroutine of gimplify_init_constructor. Pre-evaluate *EXPR_P, | |
2354 | force values that overlap with the lhs (as described by *DATA) | |
2355 | into temporaries. */ | |
2356 | ||
2357 | static void | |
2358 | gimplify_init_ctor_preeval (tree *expr_p, tree *pre_p, tree *post_p, | |
2359 | struct gimplify_init_ctor_preeval_data *data) | |
2360 | { | |
2361 | enum gimplify_status one; | |
2362 | ||
2363 | /* If the value is invariant, then there's nothing to pre-evaluate. | |
2364 | But ensure it doesn't have any side-effects since a SAVE_EXPR is | |
2365 | invariant but has side effects and might contain a reference to | |
2366 | the object we're initializing. */ | |
2367 | if (TREE_INVARIANT (*expr_p) && !TREE_SIDE_EFFECTS (*expr_p)) | |
2368 | return; | |
2369 | ||
2370 | /* If the type has non-trivial constructors, we can't pre-evaluate. */ | |
2371 | if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p))) | |
2372 | return; | |
2373 | ||
2374 | /* Recurse for nested constructors. */ | |
2375 | if (TREE_CODE (*expr_p) == CONSTRUCTOR) | |
2376 | { | |
2377 | tree list; | |
2378 | for (list = CONSTRUCTOR_ELTS (*expr_p); list ; list = TREE_CHAIN (list)) | |
2379 | gimplify_init_ctor_preeval (&TREE_VALUE (list), pre_p, post_p, data); | |
2380 | return; | |
2381 | } | |
2382 | ||
2383 | /* We can't preevaluate if the type contains a placeholder. */ | |
2384 | if (type_contains_placeholder_p (TREE_TYPE (*expr_p))) | |
2385 | return; | |
2386 | ||
2387 | /* Gimplify the constructor element to something appropriate for the rhs | |
2388 | of a MODIFY_EXPR. Given that we know the lhs is an aggregate, we know | |
2389 | the gimplifier will consider this a store to memory. Doing this | |
2390 | gimplification now means that we won't have to deal with complicated | |
2391 | language-specific trees, nor trees like SAVE_EXPR that can induce | |
2392 | exponential search behaviour. */ | |
2393 | one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue); | |
2394 | if (one == GS_ERROR) | |
2395 | { | |
2396 | *expr_p = NULL; | |
2397 | return; | |
2398 | } | |
2399 | ||
2400 | /* If we gimplified to a bare decl, we can be sure that it doesn't overlap | |
2401 | with the lhs, since "a = { .x=a }" doesn't make sense. This will | |
2402 | always be true for all scalars, since is_gimple_mem_rhs insists on a | |
2403 | temporary variable for them. */ | |
2404 | if (DECL_P (*expr_p)) | |
2405 | return; | |
2406 | ||
2407 | /* If this is of variable size, we have no choice but to assume it doesn't | |
2408 | overlap since we can't make a temporary for it. */ | |
2409 | if (!TREE_CONSTANT (TYPE_SIZE (TREE_TYPE (*expr_p)))) | |
2410 | return; | |
2411 | ||
2412 | /* Otherwise, we must search for overlap ... */ | |
2413 | if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL)) | |
2414 | return; | |
2415 | ||
2416 | /* ... and if found, force the value into a temporary. */ | |
2417 | *expr_p = get_formal_tmp_var (*expr_p, pre_p); | |
2418 | } | |
2419 | ||
2420 | /* A subroutine of gimplify_init_constructor. Generate individual | |
2421 | MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the | |
2422 | assignments should happen. LIST is the CONSTRUCTOR_ELTS of the | |
2423 | CONSTRUCTOR. CLEARED is true if the entire LHS object has been | |
2424 | zeroed first. */ | |
2425 | ||
2426 | static void | |
2427 | gimplify_init_ctor_eval (tree object, tree list, tree *pre_p, bool cleared) | |
2428 | { | |
2429 | tree array_elt_type = NULL; | |
2430 | ||
2431 | if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE) | |
2432 | array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object))); | |
2433 | ||
2434 | for (; list; list = TREE_CHAIN (list)) | |
2435 | { | |
2436 | tree purpose, value, cref, init; | |
2437 | ||
2438 | purpose = TREE_PURPOSE (list); | |
2439 | value = TREE_VALUE (list); | |
2440 | ||
2441 | /* NULL values are created above for gimplification errors. */ | |
2442 | if (value == NULL) | |
2443 | continue; | |
2444 | ||
2445 | if (cleared && initializer_zerop (value)) | |
2446 | continue; | |
2447 | ||
2448 | if (array_elt_type) | |
2449 | { | |
2450 | /* ??? Here's to hoping the front end fills in all of the indicies, | |
2451 | so we don't have to figure out what's missing ourselves. */ | |
2452 | if (!purpose) | |
2453 | abort (); | |
2454 | /* ??? Need to handle this. */ | |
2455 | if (TREE_CODE (purpose) == RANGE_EXPR) | |
2456 | abort (); | |
2457 | ||
2458 | cref = build (ARRAY_REF, array_elt_type, unshare_expr (object), | |
2459 | purpose, NULL_TREE, NULL_TREE); | |
2460 | } | |
2461 | else | |
2462 | cref = build (COMPONENT_REF, TREE_TYPE (purpose), | |
2463 | unshare_expr (object), purpose, NULL_TREE); | |
2464 | ||
2465 | if (TREE_CODE (value) == CONSTRUCTOR) | |
2466 | gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value), | |
2467 | pre_p, cleared); | |
2468 | else | |
2469 | { | |
2470 | init = build (MODIFY_EXPR, TREE_TYPE (cref), cref, value); | |
2471 | gimplify_and_add (init, pre_p); | |
2472 | } | |
2473 | } | |
2474 | } | |
2475 | ||
26d44ae2 RH |
2476 | /* A subroutine of gimplify_modify_expr. Break out elements of a |
2477 | CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs. | |
2478 | ||
2479 | Note that we still need to clear any elements that don't have explicit | |
2480 | initializers, so if not all elements are initialized we keep the | |
2481 | original MODIFY_EXPR, we just remove all of the constructor elements. */ | |
2482 | ||
2483 | static enum gimplify_status | |
2484 | gimplify_init_constructor (tree *expr_p, tree *pre_p, | |
2485 | tree *post_p, bool want_value) | |
2486 | { | |
57d1dd87 | 2487 | tree object; |
26d44ae2 RH |
2488 | tree ctor = TREE_OPERAND (*expr_p, 1); |
2489 | tree type = TREE_TYPE (ctor); | |
2490 | enum gimplify_status ret; | |
2491 | tree elt_list; | |
2492 | ||
2493 | if (TREE_CODE (ctor) != CONSTRUCTOR) | |
2494 | return GS_UNHANDLED; | |
2495 | ||
57d1dd87 RH |
2496 | ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, |
2497 | is_gimple_lvalue, fb_lvalue); | |
2498 | if (ret == GS_ERROR) | |
2499 | return ret; | |
2500 | object = TREE_OPERAND (*expr_p, 0); | |
2501 | ||
26d44ae2 RH |
2502 | elt_list = CONSTRUCTOR_ELTS (ctor); |
2503 | ||
2504 | ret = GS_ALL_DONE; | |
2505 | switch (TREE_CODE (type)) | |
2506 | { | |
2507 | case RECORD_TYPE: | |
2508 | case UNION_TYPE: | |
2509 | case QUAL_UNION_TYPE: | |
2510 | case ARRAY_TYPE: | |
2511 | { | |
57d1dd87 RH |
2512 | struct gimplify_init_ctor_preeval_data preeval_data; |
2513 | HOST_WIDE_INT num_elements, num_nonzero_elements; | |
26d44ae2 RH |
2514 | HOST_WIDE_INT num_nonconstant_elements; |
2515 | bool cleared; | |
2516 | ||
2517 | /* Aggregate types must lower constructors to initialization of | |
2518 | individual elements. The exception is that a CONSTRUCTOR node | |
2519 | with no elements indicates zero-initialization of the whole. */ | |
2520 | if (elt_list == NULL) | |
57d1dd87 | 2521 | break; |
26d44ae2 RH |
2522 | |
2523 | categorize_ctor_elements (ctor, &num_nonzero_elements, | |
2524 | &num_nonconstant_elements); | |
26d44ae2 RH |
2525 | |
2526 | /* If a const aggregate variable is being initialized, then it | |
2527 | should never be a lose to promote the variable to be static. */ | |
2528 | if (num_nonconstant_elements == 0 | |
2529 | && TREE_READONLY (object) | |
2530 | && TREE_CODE (object) == VAR_DECL) | |
2531 | { | |
2532 | DECL_INITIAL (object) = ctor; | |
2533 | TREE_STATIC (object) = 1; | |
2534 | if (!DECL_NAME (object)) | |
2535 | DECL_NAME (object) = create_tmp_var_name ("C"); | |
2536 | walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL); | |
2537 | ||
2538 | /* ??? C++ doesn't automatically append a .<number> to the | |
2539 | assembler name, and even when it does, it looks a FE private | |
2540 | data structures to figure out what that number should be, | |
2541 | which are not set for this variable. I suppose this is | |
2542 | important for local statics for inline functions, which aren't | |
2543 | "local" in the object file sense. So in order to get a unique | |
2544 | TU-local symbol, we must invoke the lhd version now. */ | |
2545 | lhd_set_decl_assembler_name (object); | |
2546 | ||
2547 | *expr_p = NULL_TREE; | |
2548 | break; | |
2549 | } | |
2550 | ||
2551 | /* If there are "lots" of initialized elements, and all of them | |
2552 | are valid address constants, then the entire initializer can | |
2553 | be dropped to memory, and then memcpy'd out. */ | |
2554 | if (num_nonconstant_elements == 0) | |
2555 | { | |
2556 | HOST_WIDE_INT size = int_size_in_bytes (type); | |
2557 | unsigned int align; | |
2558 | ||
2559 | /* ??? We can still get unbounded array types, at least | |
2560 | from the C++ front end. This seems wrong, but attempt | |
2561 | to work around it for now. */ | |
2562 | if (size < 0) | |
2563 | { | |
2564 | size = int_size_in_bytes (TREE_TYPE (object)); | |
2565 | if (size >= 0) | |
2566 | TREE_TYPE (ctor) = type = TREE_TYPE (object); | |
2567 | } | |
2568 | ||
2569 | /* Find the maximum alignment we can assume for the object. */ | |
2570 | /* ??? Make use of DECL_OFFSET_ALIGN. */ | |
2571 | if (DECL_P (object)) | |
2572 | align = DECL_ALIGN (object); | |
2573 | else | |
2574 | align = TYPE_ALIGN (type); | |
2575 | ||
2576 | if (size > 0 && !can_move_by_pieces (size, align)) | |
2577 | { | |
2578 | tree new = create_tmp_var_raw (type, "C"); | |
57d1dd87 | 2579 | |
26d44ae2 RH |
2580 | gimple_add_tmp_var (new); |
2581 | TREE_STATIC (new) = 1; | |
2582 | TREE_READONLY (new) = 1; | |
2583 | DECL_INITIAL (new) = ctor; | |
2584 | if (align > DECL_ALIGN (new)) | |
2585 | { | |
2586 | DECL_ALIGN (new) = align; | |
2587 | DECL_USER_ALIGN (new) = 1; | |
2588 | } | |
2589 | walk_tree (&DECL_INITIAL (new), force_labels_r, NULL, NULL); | |
2590 | ||
2591 | TREE_OPERAND (*expr_p, 1) = new; | |
57d1dd87 RH |
2592 | |
2593 | /* This is no longer an assignment of a CONSTRUCTOR, but | |
2594 | we still may have processing to do on the LHS. So | |
2595 | pretend we didn't do anything here to let that happen. */ | |
2596 | return GS_UNHANDLED; | |
26d44ae2 RH |
2597 | } |
2598 | } | |
2599 | ||
2600 | /* If there are "lots" of initialized elements, even discounting | |
2601 | those that are not address constants (and thus *must* be | |
2602 | computed at runtime), then partition the constructor into | |
2603 | constant and non-constant parts. Block copy the constant | |
2604 | parts in, then generate code for the non-constant parts. */ | |
2605 | /* TODO. There's code in cp/typeck.c to do this. */ | |
2606 | ||
57d1dd87 RH |
2607 | num_elements = count_type_elements (TREE_TYPE (ctor)); |
2608 | ||
26d44ae2 RH |
2609 | /* If there are "lots" of zeros, then block clear the object first. */ |
2610 | cleared = false; | |
2611 | if (num_elements - num_nonzero_elements > CLEAR_RATIO | |
2612 | && num_nonzero_elements < num_elements/4) | |
2613 | cleared = true; | |
2614 | ||
2615 | /* ??? This bit ought not be needed. For any element not present | |
2616 | in the initializer, we should simply set them to zero. Except | |
2617 | we'd need to *find* the elements that are not present, and that | |
2618 | requires trickery to avoid quadratic compile-time behavior in | |
2619 | large cases or excessive memory use in small cases. */ | |
2620 | else | |
2621 | { | |
2622 | HOST_WIDE_INT len = list_length (elt_list); | |
2623 | if (TREE_CODE (type) == ARRAY_TYPE) | |
2624 | { | |
2625 | tree nelts = array_type_nelts (type); | |
2626 | if (!host_integerp (nelts, 1) | |
5377d5ba | 2627 | || tree_low_cst (nelts, 1) + 1 != len) |
57d1dd87 | 2628 | cleared = true; |
26d44ae2 RH |
2629 | } |
2630 | else if (len != fields_length (type)) | |
57d1dd87 | 2631 | cleared = true; |
26d44ae2 RH |
2632 | } |
2633 | ||
2634 | if (cleared) | |
2635 | { | |
2636 | /* Zap the CONSTRUCTOR element list, which simplifies this case. | |
2637 | Note that we still have to gimplify, in order to handle the | |
57d1dd87 | 2638 | case of variable sized types. Avoid shared tree structures. */ |
26d44ae2 | 2639 | CONSTRUCTOR_ELTS (ctor) = NULL_TREE; |
57d1dd87 | 2640 | object = unshare_expr (object); |
26d44ae2 RH |
2641 | gimplify_stmt (expr_p); |
2642 | append_to_statement_list (*expr_p, pre_p); | |
2643 | } | |
2644 | ||
57d1dd87 RH |
2645 | preeval_data.lhs_base_decl = get_base_address (object); |
2646 | if (!DECL_P (preeval_data.lhs_base_decl)) | |
2647 | preeval_data.lhs_base_decl = NULL; | |
2648 | preeval_data.lhs_alias_set = get_alias_set (object); | |
26d44ae2 | 2649 | |
57d1dd87 RH |
2650 | gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1), |
2651 | pre_p, post_p, &preeval_data); | |
2652 | gimplify_init_ctor_eval (object, elt_list, pre_p, cleared); | |
26d44ae2 RH |
2653 | |
2654 | *expr_p = NULL_TREE; | |
2655 | } | |
2656 | break; | |
2657 | ||
2658 | case COMPLEX_TYPE: | |
2659 | { | |
2660 | tree r, i; | |
2661 | ||
2662 | /* Extract the real and imaginary parts out of the ctor. */ | |
2663 | r = i = NULL_TREE; | |
2664 | if (elt_list) | |
2665 | { | |
2666 | r = TREE_VALUE (elt_list); | |
2667 | elt_list = TREE_CHAIN (elt_list); | |
2668 | if (elt_list) | |
2669 | { | |
2670 | i = TREE_VALUE (elt_list); | |
2671 | if (TREE_CHAIN (elt_list)) | |
2672 | abort (); | |
2673 | } | |
2674 | } | |
2675 | if (r == NULL || i == NULL) | |
2676 | { | |
2677 | tree zero = convert (TREE_TYPE (type), integer_zero_node); | |
2678 | if (r == NULL) | |
2679 | r = zero; | |
2680 | if (i == NULL) | |
2681 | i = zero; | |
2682 | } | |
2683 | ||
2684 | /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to | |
2685 | represent creation of a complex value. */ | |
2686 | if (TREE_CONSTANT (r) && TREE_CONSTANT (i)) | |
2687 | { | |
2688 | ctor = build_complex (type, r, i); | |
2689 | TREE_OPERAND (*expr_p, 1) = ctor; | |
2690 | } | |
2691 | else | |
2692 | { | |
2693 | ctor = build (COMPLEX_EXPR, type, r, i); | |
2694 | TREE_OPERAND (*expr_p, 1) = ctor; | |
2695 | ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p, | |
17ad5b5e RH |
2696 | rhs_predicate_for (TREE_OPERAND (*expr_p, 0)), |
2697 | fb_rvalue); | |
26d44ae2 RH |
2698 | } |
2699 | } | |
2700 | break; | |
506e2710 | 2701 | |
26d44ae2 RH |
2702 | case VECTOR_TYPE: |
2703 | /* Go ahead and simplify constant constructors to VECTOR_CST. */ | |
2704 | if (TREE_CONSTANT (ctor)) | |
2705 | TREE_OPERAND (*expr_p, 1) = build_vector (type, elt_list); | |
6de9cd9a DN |
2706 | else |
2707 | { | |
26d44ae2 RH |
2708 | /* Vector types use CONSTRUCTOR all the way through gimple |
2709 | compilation as a general initializer. */ | |
2710 | for (; elt_list; elt_list = TREE_CHAIN (elt_list)) | |
2711 | { | |
2712 | enum gimplify_status tret; | |
2713 | tret = gimplify_expr (&TREE_VALUE (elt_list), pre_p, post_p, | |
17ad5b5e | 2714 | is_gimple_val, fb_rvalue); |
26d44ae2 RH |
2715 | if (tret == GS_ERROR) |
2716 | ret = GS_ERROR; | |
2717 | } | |
6de9cd9a | 2718 | } |
26d44ae2 | 2719 | break; |
6de9cd9a | 2720 | |
26d44ae2 RH |
2721 | default: |
2722 | /* So how did we get a CONSTRUCTOR for a scalar type? */ | |
2723 | abort (); | |
2724 | } | |
6de9cd9a | 2725 | |
26d44ae2 RH |
2726 | if (ret == GS_ERROR) |
2727 | return GS_ERROR; | |
2728 | else if (want_value) | |
2729 | { | |
2730 | append_to_statement_list (*expr_p, pre_p); | |
2731 | *expr_p = object; | |
2732 | return GS_OK; | |
6de9cd9a | 2733 | } |
26d44ae2 RH |
2734 | else |
2735 | return GS_ALL_DONE; | |
2736 | } | |
6de9cd9a | 2737 | |
26d44ae2 RH |
2738 | /* Subroutine of gimplify_modify_expr to do simplifications of MODIFY_EXPRs |
2739 | based on the code of the RHS. We loop for as long as something changes. */ | |
6de9cd9a | 2740 | |
26d44ae2 RH |
2741 | static enum gimplify_status |
2742 | gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p, | |
2743 | tree *post_p, bool want_value) | |
2744 | { | |
2745 | enum gimplify_status ret = GS_OK; | |
6de9cd9a | 2746 | |
26d44ae2 RH |
2747 | while (ret != GS_UNHANDLED) |
2748 | switch (TREE_CODE (*from_p)) | |
2749 | { | |
2750 | case TARGET_EXPR: | |
6de9cd9a | 2751 | { |
26d44ae2 RH |
2752 | /* If we are initializing something from a TARGET_EXPR, strip the |
2753 | TARGET_EXPR and initialize it directly, if possible. This can't | |
2754 | be done if the initializer is void, since that implies that the | |
2755 | temporary is set in some non-trivial way. | |
6de9cd9a | 2756 | |
26d44ae2 RH |
2757 | ??? What about code that pulls out the temp and uses it |
2758 | elsewhere? I think that such code never uses the TARGET_EXPR as | |
2759 | an initializer. If I'm wrong, we'll abort because the temp won't | |
2760 | have any RTL. In that case, I guess we'll need to replace | |
2761 | references somehow. */ | |
2762 | tree init = TARGET_EXPR_INITIAL (*from_p); | |
6de9cd9a | 2763 | |
26d44ae2 RH |
2764 | if (!VOID_TYPE_P (TREE_TYPE (init))) |
2765 | { | |
2766 | *from_p = init; | |
2767 | ret = GS_OK; | |
2768 | } | |
2769 | else | |
2770 | ret = GS_UNHANDLED; | |
6de9cd9a | 2771 | } |
26d44ae2 | 2772 | break; |
6de9cd9a | 2773 | |
26d44ae2 RH |
2774 | case COMPOUND_EXPR: |
2775 | /* Remove any COMPOUND_EXPR in the RHS so the following cases will be | |
2776 | caught. */ | |
2777 | gimplify_compound_expr (from_p, pre_p, true); | |
2778 | ret = GS_OK; | |
2779 | break; | |
6de9cd9a | 2780 | |
26d44ae2 RH |
2781 | case CONSTRUCTOR: |
2782 | /* If we're initializing from a CONSTRUCTOR, break this into | |
2783 | individual MODIFY_EXPRs. */ | |
2784 | return gimplify_init_constructor (expr_p, pre_p, post_p, want_value); | |
6de9cd9a | 2785 | |
26d44ae2 | 2786 | case COND_EXPR: |
d91ba7b0 RH |
2787 | /* If we're assigning to a non-register type, push the assignment |
2788 | down into the branches. This is mandatory for ADDRESSABLE types, | |
2789 | since we cannot generate temporaries for such, but it saves a | |
2790 | copy in other cases as well. */ | |
2791 | if (!is_gimple_reg_type (TREE_TYPE (*from_p))) | |
26d44ae2 RH |
2792 | { |
2793 | *expr_p = *from_p; | |
2794 | return gimplify_cond_expr (expr_p, pre_p, *to_p); | |
2795 | } | |
2796 | else | |
2797 | ret = GS_UNHANDLED; | |
2798 | break; | |
6de9cd9a | 2799 | |
26d44ae2 RH |
2800 | default: |
2801 | ret = GS_UNHANDLED; | |
2802 | break; | |
2803 | } | |
6de9cd9a | 2804 | |
6de9cd9a DN |
2805 | return ret; |
2806 | } | |
2807 | ||
26d44ae2 | 2808 | /* Gimplify the MODIFY_EXPR node pointed by EXPR_P. |
6de9cd9a DN |
2809 | |
2810 | modify_expr | |
2811 | : varname '=' rhs | |
2812 | | '*' ID '=' rhs | |
2813 | ||
2814 | PRE_P points to the list where side effects that must happen before | |
2815 | *EXPR_P should be stored. | |
2816 | ||
2817 | POST_P points to the list where side effects that must happen after | |
2818 | *EXPR_P should be stored. | |
2819 | ||
2820 | WANT_VALUE is nonzero iff we want to use the value of this expression | |
2821 | in another expression. */ | |
2822 | ||
2823 | static enum gimplify_status | |
2824 | gimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value) | |
2825 | { | |
2826 | tree *from_p = &TREE_OPERAND (*expr_p, 1); | |
2827 | tree *to_p = &TREE_OPERAND (*expr_p, 0); | |
44de5aeb | 2828 | enum gimplify_status ret = GS_UNHANDLED; |
6de9cd9a DN |
2829 | |
2830 | #if defined ENABLE_CHECKING | |
2831 | if (TREE_CODE (*expr_p) != MODIFY_EXPR && TREE_CODE (*expr_p) != INIT_EXPR) | |
2832 | abort (); | |
2833 | #endif | |
2834 | ||
2835 | /* The distinction between MODIFY_EXPR and INIT_EXPR is no longer useful. */ | |
2836 | if (TREE_CODE (*expr_p) == INIT_EXPR) | |
2837 | TREE_SET_CODE (*expr_p, MODIFY_EXPR); | |
2838 | ||
44de5aeb RK |
2839 | /* See if any simplifications can be done based on what the RHS is. */ |
2840 | ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p, | |
2841 | want_value); | |
2842 | if (ret != GS_UNHANDLED) | |
6de9cd9a DN |
2843 | return ret; |
2844 | ||
d25cee4d RH |
2845 | /* If the value being copied is of variable width, compute the length |
2846 | of the copy into a WITH_SIZE_EXPR. Note that we need to do this | |
2847 | before gimplifying any of the operands so that we can resolve any | |
2848 | PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses | |
2849 | the size of the expression to be copied, not of the destination, so | |
2850 | that is what we must here. */ | |
2851 | maybe_with_size_expr (from_p); | |
6de9cd9a | 2852 | |
44de5aeb RK |
2853 | ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue); |
2854 | if (ret == GS_ERROR) | |
2855 | return ret; | |
6de9cd9a | 2856 | |
0c322af3 JM |
2857 | ret = gimplify_expr (from_p, pre_p, post_p, |
2858 | rhs_predicate_for (*to_p), fb_rvalue); | |
6de9cd9a DN |
2859 | if (ret == GS_ERROR) |
2860 | return ret; | |
2861 | ||
44de5aeb RK |
2862 | /* Now see if the above changed *from_p to something we handle specially. */ |
2863 | ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p, | |
2864 | want_value); | |
6de9cd9a DN |
2865 | if (ret != GS_UNHANDLED) |
2866 | return ret; | |
2867 | ||
d25cee4d RH |
2868 | /* If we've got a variable sized assignment between two lvalues (i.e. does |
2869 | not involve a call), then we can make things a bit more straightforward | |
2870 | by converting the assignment to memcpy or memset. */ | |
2871 | if (TREE_CODE (*from_p) == WITH_SIZE_EXPR) | |
2872 | { | |
2873 | tree from = TREE_OPERAND (*from_p, 0); | |
2874 | tree size = TREE_OPERAND (*from_p, 1); | |
2875 | ||
2876 | if (TREE_CODE (from) == CONSTRUCTOR) | |
2877 | return gimplify_modify_expr_to_memset (expr_p, size, want_value); | |
e847cc68 | 2878 | if (is_gimple_addressable (from)) |
d25cee4d RH |
2879 | { |
2880 | *from_p = from; | |
2881 | return gimplify_modify_expr_to_memcpy (expr_p, size, want_value); | |
2882 | } | |
2883 | } | |
2884 | ||
8b11a64c ZD |
2885 | if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p)) |
2886 | { | |
2887 | /* If we've somehow already got an SSA_NAME on the LHS, then | |
2888 | we're probably modifying it twice. Not good. */ | |
2889 | if (TREE_CODE (*to_p) == SSA_NAME) | |
2890 | abort (); | |
2891 | *to_p = make_ssa_name (*to_p, *expr_p); | |
2892 | } | |
2893 | ||
6de9cd9a DN |
2894 | if (want_value) |
2895 | { | |
2896 | append_to_statement_list (*expr_p, pre_p); | |
2897 | *expr_p = *to_p; | |
17ad5b5e | 2898 | return GS_OK; |
6de9cd9a DN |
2899 | } |
2900 | ||
17ad5b5e | 2901 | return GS_ALL_DONE; |
6de9cd9a DN |
2902 | } |
2903 | ||
44de5aeb RK |
2904 | /* Gimplify a comparison between two variable-sized objects. Do this |
2905 | with a call to BUILT_IN_MEMCMP. */ | |
2906 | ||
2907 | static enum gimplify_status | |
2908 | gimplify_variable_sized_compare (tree *expr_p) | |
2909 | { | |
2910 | tree op0 = TREE_OPERAND (*expr_p, 0); | |
2911 | tree op1 = TREE_OPERAND (*expr_p, 1); | |
2912 | tree args, t, dest; | |
2913 | ||
2914 | t = TYPE_SIZE_UNIT (TREE_TYPE (op0)); | |
44de5aeb | 2915 | t = unshare_expr (t); |
73d6ddef | 2916 | t = SUBSTITUTE_PLACEHOLDER_IN_EXPR (t, op0); |
44de5aeb | 2917 | args = tree_cons (NULL, t, NULL); |
af72267c | 2918 | t = build_fold_addr_expr (op1); |
44de5aeb | 2919 | args = tree_cons (NULL, t, args); |
af72267c | 2920 | dest = build_fold_addr_expr (op0); |
44de5aeb RK |
2921 | args = tree_cons (NULL, dest, args); |
2922 | t = implicit_built_in_decls[BUILT_IN_MEMCMP]; | |
2923 | t = build_function_call_expr (t, args); | |
2924 | *expr_p | |
2925 | = build (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node); | |
2926 | ||
2927 | return GS_OK; | |
2928 | } | |
2929 | ||
6de9cd9a DN |
2930 | /* Gimplify TRUTH_ANDIF_EXPR and TRUTH_ORIF_EXPR expressions. EXPR_P |
2931 | points to the expression to gimplify. | |
2932 | ||
2933 | Expressions of the form 'a && b' are gimplified to: | |
2934 | ||
2935 | a && b ? true : false | |
2936 | ||
2937 | gimplify_cond_expr will do the rest. | |
2938 | ||
2939 | PRE_P points to the list where side effects that must happen before | |
2940 | *EXPR_P should be stored. */ | |
2941 | ||
2942 | static enum gimplify_status | |
2943 | gimplify_boolean_expr (tree *expr_p) | |
2944 | { | |
2945 | /* Preserve the original type of the expression. */ | |
2946 | tree type = TREE_TYPE (*expr_p); | |
2947 | ||
2948 | *expr_p = build (COND_EXPR, type, *expr_p, | |
2949 | convert (type, boolean_true_node), | |
2950 | convert (type, boolean_false_node)); | |
2951 | ||
2952 | return GS_OK; | |
2953 | } | |
2954 | ||
2955 | /* Gimplifies an expression sequence. This function gimplifies each | |
2956 | expression and re-writes the original expression with the last | |
2957 | expression of the sequence in GIMPLE form. | |
2958 | ||
2959 | PRE_P points to the list where the side effects for all the | |
2960 | expressions in the sequence will be emitted. | |
2961 | ||
2962 | WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */ | |
2963 | /* ??? Should rearrange to share the pre-queue with all the indirect | |
2964 | invocations of gimplify_expr. Would probably save on creations | |
2965 | of statement_list nodes. */ | |
2966 | ||
2967 | static enum gimplify_status | |
2968 | gimplify_compound_expr (tree *expr_p, tree *pre_p, bool want_value) | |
2969 | { | |
2970 | tree t = *expr_p; | |
2971 | ||
2972 | do | |
2973 | { | |
2974 | tree *sub_p = &TREE_OPERAND (t, 0); | |
2975 | ||
2976 | if (TREE_CODE (*sub_p) == COMPOUND_EXPR) | |
2977 | gimplify_compound_expr (sub_p, pre_p, false); | |
2978 | else | |
2979 | gimplify_stmt (sub_p); | |
2980 | append_to_statement_list (*sub_p, pre_p); | |
2981 | ||
2982 | t = TREE_OPERAND (t, 1); | |
2983 | } | |
2984 | while (TREE_CODE (t) == COMPOUND_EXPR); | |
2985 | ||
2986 | *expr_p = t; | |
2987 | if (want_value) | |
2988 | return GS_OK; | |
2989 | else | |
2990 | { | |
2991 | gimplify_stmt (expr_p); | |
2992 | return GS_ALL_DONE; | |
2993 | } | |
2994 | } | |
2995 | ||
2996 | /* Gimplifies a statement list. These may be created either by an | |
1ea7e6ad | 2997 | enlightened front-end, or by shortcut_cond_expr. */ |
6de9cd9a DN |
2998 | |
2999 | static enum gimplify_status | |
3000 | gimplify_statement_list (tree *expr_p) | |
3001 | { | |
3002 | tree_stmt_iterator i = tsi_start (*expr_p); | |
3003 | ||
3004 | while (!tsi_end_p (i)) | |
3005 | { | |
3006 | tree t; | |
3007 | ||
3008 | gimplify_stmt (tsi_stmt_ptr (i)); | |
3009 | ||
3010 | t = tsi_stmt (i); | |
65355d53 RH |
3011 | if (t == NULL) |
3012 | tsi_delink (&i); | |
3013 | else if (TREE_CODE (t) == STATEMENT_LIST) | |
6de9cd9a DN |
3014 | { |
3015 | tsi_link_before (&i, t, TSI_SAME_STMT); | |
3016 | tsi_delink (&i); | |
3017 | } | |
3018 | else | |
3019 | tsi_next (&i); | |
3020 | } | |
3021 | ||
3022 | return GS_ALL_DONE; | |
3023 | } | |
3024 | ||
3025 | /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to | |
3026 | gimplify. After gimplification, EXPR_P will point to a new temporary | |
3027 | that holds the original value of the SAVE_EXPR node. | |
3028 | ||
3029 | PRE_P points to the list where side effects that must happen before | |
3030 | *EXPR_P should be stored. */ | |
3031 | ||
3032 | static enum gimplify_status | |
3033 | gimplify_save_expr (tree *expr_p, tree *pre_p, tree *post_p) | |
3034 | { | |
3035 | enum gimplify_status ret = GS_ALL_DONE; | |
3036 | tree val; | |
3037 | ||
3038 | #if defined ENABLE_CHECKING | |
3039 | if (TREE_CODE (*expr_p) != SAVE_EXPR) | |
3040 | abort (); | |
3041 | #endif | |
3042 | ||
3043 | val = TREE_OPERAND (*expr_p, 0); | |
3044 | ||
7f5e6307 RH |
3045 | /* If the SAVE_EXPR has not been resolved, then evaluate it once. */ |
3046 | if (!SAVE_EXPR_RESOLVED_P (*expr_p)) | |
17ad5b5e | 3047 | { |
7f5e6307 RH |
3048 | /* The operand may be a void-valued expression such as SAVE_EXPRs |
3049 | generated by the Java frontend for class initialization. It is | |
3050 | being executed only for its side-effects. */ | |
3051 | if (TREE_TYPE (val) == void_type_node) | |
3052 | { | |
3053 | ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, | |
3054 | is_gimple_stmt, fb_none); | |
3055 | append_to_statement_list (TREE_OPERAND (*expr_p, 0), pre_p); | |
3056 | val = NULL; | |
3057 | } | |
3058 | else | |
3059 | val = get_initialized_tmp_var (val, pre_p, post_p); | |
3060 | ||
3061 | TREE_OPERAND (*expr_p, 0) = val; | |
3062 | SAVE_EXPR_RESOLVED_P (*expr_p) = 1; | |
17ad5b5e | 3063 | } |
6de9cd9a | 3064 | |
7f5e6307 RH |
3065 | *expr_p = val; |
3066 | ||
6de9cd9a DN |
3067 | return ret; |
3068 | } | |
3069 | ||
3070 | /* Re-write the ADDR_EXPR node pointed by EXPR_P | |
3071 | ||
3072 | unary_expr | |
3073 | : ... | |
3074 | | '&' varname | |
3075 | ... | |
3076 | ||
3077 | PRE_P points to the list where side effects that must happen before | |
3078 | *EXPR_P should be stored. | |
3079 | ||
3080 | POST_P points to the list where side effects that must happen after | |
3081 | *EXPR_P should be stored. */ | |
3082 | ||
3083 | static enum gimplify_status | |
3084 | gimplify_addr_expr (tree *expr_p, tree *pre_p, tree *post_p) | |
3085 | { | |
3086 | tree expr = *expr_p; | |
3087 | tree op0 = TREE_OPERAND (expr, 0); | |
3088 | enum gimplify_status ret; | |
3089 | ||
3090 | switch (TREE_CODE (op0)) | |
3091 | { | |
3092 | case INDIRECT_REF: | |
3093 | /* Check if we are dealing with an expression of the form '&*ptr'. | |
3094 | While the front end folds away '&*ptr' into 'ptr', these | |
3095 | expressions may be generated internally by the compiler (e.g., | |
3096 | builtins like __builtin_va_end). */ | |
3097 | *expr_p = TREE_OPERAND (op0, 0); | |
3098 | ret = GS_OK; | |
3099 | break; | |
3100 | ||
44de5aeb RK |
3101 | case VIEW_CONVERT_EXPR: |
3102 | /* Take the address of our operand and then convert it to the type of | |
af72267c RK |
3103 | this ADDR_EXPR. |
3104 | ||
3105 | ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at | |
3106 | all clear. The impact of this transformation is even less clear. */ | |
44de5aeb | 3107 | *expr_p = fold_convert (TREE_TYPE (expr), |
af72267c | 3108 | build_fold_addr_expr (TREE_OPERAND (op0, 0))); |
44de5aeb | 3109 | ret = GS_OK; |
6de9cd9a DN |
3110 | break; |
3111 | ||
3112 | default: | |
3113 | /* We use fb_either here because the C frontend sometimes takes | |
5201931e JM |
3114 | the address of a call that returns a struct; see |
3115 | gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make | |
3116 | the implied temporary explicit. */ | |
6de9cd9a | 3117 | ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p, |
e847cc68 | 3118 | is_gimple_addressable, fb_either); |
6de9cd9a DN |
3119 | if (ret != GS_ERROR) |
3120 | { | |
5201931e | 3121 | /* The above may have made an INDIRECT_REF (e.g, Ada's NULL_EXPR), |
9e51aaf5 RK |
3122 | so check for it here. It's not worth checking for the other |
3123 | cases above. */ | |
3124 | if (TREE_CODE (TREE_OPERAND (expr, 0)) == INDIRECT_REF) | |
3125 | { | |
3126 | *expr_p = TREE_OPERAND (TREE_OPERAND (expr, 0), 0); | |
3127 | break; | |
3128 | } | |
3129 | ||
5377d5ba RK |
3130 | /* Make sure TREE_INVARIANT, TREE_CONSTANT, and TREE_SIDE_EFFECTS |
3131 | is set properly. */ | |
6de9cd9a DN |
3132 | recompute_tree_invarant_for_addr_expr (expr); |
3133 | ||
3134 | /* Mark the RHS addressable. */ | |
673fda6b | 3135 | lang_hooks.mark_addressable (TREE_OPERAND (expr, 0)); |
6de9cd9a DN |
3136 | } |
3137 | break; | |
3138 | } | |
3139 | ||
6de9cd9a DN |
3140 | return ret; |
3141 | } | |
3142 | ||
3143 | /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple | |
3144 | value; output operands should be a gimple lvalue. */ | |
3145 | ||
3146 | static enum gimplify_status | |
3147 | gimplify_asm_expr (tree *expr_p, tree *pre_p, tree *post_p) | |
3148 | { | |
3149 | tree expr = *expr_p; | |
3150 | int noutputs = list_length (ASM_OUTPUTS (expr)); | |
3151 | const char **oconstraints | |
3152 | = (const char **) alloca ((noutputs) * sizeof (const char *)); | |
3153 | int i; | |
3154 | tree link; | |
3155 | const char *constraint; | |
3156 | bool allows_mem, allows_reg, is_inout; | |
3157 | enum gimplify_status ret, tret; | |
3158 | ||
3159 | ASM_STRING (expr) | |
3160 | = resolve_asm_operand_names (ASM_STRING (expr), ASM_OUTPUTS (expr), | |
3161 | ASM_INPUTS (expr)); | |
3162 | ||
3163 | ret = GS_ALL_DONE; | |
3164 | for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = TREE_CHAIN (link)) | |
3165 | { | |
3166 | oconstraints[i] = constraint | |
3167 | = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); | |
3168 | ||
3169 | parse_output_constraint (&constraint, i, 0, 0, | |
3170 | &allows_mem, &allows_reg, &is_inout); | |
3171 | ||
3172 | if (!allows_reg && allows_mem) | |
673fda6b | 3173 | lang_hooks.mark_addressable (TREE_VALUE (link)); |
6de9cd9a DN |
3174 | |
3175 | tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p, | |
3176 | is_inout ? is_gimple_min_lval : is_gimple_lvalue, | |
3177 | fb_lvalue | fb_mayfail); | |
3178 | if (tret == GS_ERROR) | |
3179 | { | |
3180 | error ("invalid lvalue in asm output %d", i); | |
3181 | ret = tret; | |
3182 | } | |
3183 | ||
3184 | if (is_inout) | |
3185 | { | |
3186 | /* An input/output operand. To give the optimizers more | |
3187 | flexibility, split it into separate input and output | |
3188 | operands. */ | |
3189 | tree input; | |
3190 | char buf[10]; | |
3191 | size_t constraint_len = strlen (constraint); | |
3192 | ||
3193 | /* Turn the in/out constraint into an output constraint. */ | |
3194 | char *p = xstrdup (constraint); | |
3195 | p[0] = '='; | |
3196 | TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p); | |
3197 | free (p); | |
3198 | ||
3199 | /* And add a matching input constraint. */ | |
3200 | if (allows_reg) | |
3201 | { | |
3202 | sprintf (buf, "%d", i); | |
3203 | input = build_string (strlen (buf), buf); | |
3204 | } | |
3205 | else | |
3206 | input = build_string (constraint_len - 1, constraint + 1); | |
3207 | input = build_tree_list (build_tree_list (NULL_TREE, input), | |
3208 | unshare_expr (TREE_VALUE (link))); | |
3209 | ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input); | |
3210 | } | |
3211 | } | |
3212 | ||
3213 | for (link = ASM_INPUTS (expr); link; ++i, link = TREE_CHAIN (link)) | |
3214 | { | |
3215 | constraint | |
3216 | = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); | |
3217 | parse_input_constraint (&constraint, 0, 0, noutputs, 0, | |
3218 | oconstraints, &allows_mem, &allows_reg); | |
3219 | ||
3220 | /* If the operand is a memory input, it should be an lvalue. */ | |
3221 | if (!allows_reg && allows_mem) | |
3222 | { | |
673fda6b | 3223 | lang_hooks.mark_addressable (TREE_VALUE (link)); |
6de9cd9a DN |
3224 | tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p, |
3225 | is_gimple_lvalue, fb_lvalue | fb_mayfail); | |
3226 | if (tret == GS_ERROR) | |
3227 | { | |
3228 | error ("memory input %d is not directly addressable", i); | |
3229 | ret = tret; | |
3230 | } | |
3231 | } | |
3232 | else | |
3233 | { | |
3234 | tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p, | |
3235 | is_gimple_val, fb_rvalue); | |
3236 | if (tret == GS_ERROR) | |
3237 | ret = tret; | |
3238 | } | |
3239 | } | |
3240 | ||
3241 | return ret; | |
3242 | } | |
3243 | ||
3244 | /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding | |
3245 | WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while | |
3246 | gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we | |
3247 | return to this function. | |
3248 | ||
3249 | FIXME should we complexify the prequeue handling instead? Or use flags | |
3250 | for all the cleanups and let the optimizer tighten them up? The current | |
3251 | code seems pretty fragile; it will break on a cleanup within any | |
3252 | non-conditional nesting. But any such nesting would be broken, anyway; | |
3253 | we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct | |
3254 | and continues out of it. We can do that at the RTL level, though, so | |
3255 | having an optimizer to tighten up try/finally regions would be a Good | |
3256 | Thing. */ | |
3257 | ||
3258 | static enum gimplify_status | |
3259 | gimplify_cleanup_point_expr (tree *expr_p, tree *pre_p) | |
3260 | { | |
3261 | tree_stmt_iterator iter; | |
3262 | tree body; | |
3263 | ||
325c3691 | 3264 | tree temp = voidify_wrapper_expr (*expr_p, NULL); |
6de9cd9a DN |
3265 | |
3266 | /* We only care about the number of conditions between the innermost | |
3267 | CLEANUP_POINT_EXPR and the cleanup. So save and reset the count. */ | |
3268 | int old_conds = gimplify_ctxp->conditions; | |
3269 | gimplify_ctxp->conditions = 0; | |
3270 | ||
3271 | body = TREE_OPERAND (*expr_p, 0); | |
3272 | gimplify_to_stmt_list (&body); | |
3273 | ||
3274 | gimplify_ctxp->conditions = old_conds; | |
3275 | ||
3276 | for (iter = tsi_start (body); !tsi_end_p (iter); ) | |
3277 | { | |
3278 | tree *wce_p = tsi_stmt_ptr (iter); | |
3279 | tree wce = *wce_p; | |
3280 | ||
3281 | if (TREE_CODE (wce) == WITH_CLEANUP_EXPR) | |
3282 | { | |
3283 | if (tsi_one_before_end_p (iter)) | |
3284 | { | |
ac45df5d | 3285 | tsi_link_before (&iter, TREE_OPERAND (wce, 0), TSI_SAME_STMT); |
6de9cd9a DN |
3286 | tsi_delink (&iter); |
3287 | break; | |
3288 | } | |
3289 | else | |
3290 | { | |
3291 | tree sl, tfe; | |
40aac948 JM |
3292 | enum tree_code code; |
3293 | ||
3294 | if (CLEANUP_EH_ONLY (wce)) | |
3295 | code = TRY_CATCH_EXPR; | |
3296 | else | |
3297 | code = TRY_FINALLY_EXPR; | |
6de9cd9a DN |
3298 | |
3299 | sl = tsi_split_statement_list_after (&iter); | |
40aac948 | 3300 | tfe = build (code, void_type_node, sl, NULL_TREE); |
ac45df5d RH |
3301 | append_to_statement_list (TREE_OPERAND (wce, 0), |
3302 | &TREE_OPERAND (tfe, 1)); | |
6de9cd9a DN |
3303 | *wce_p = tfe; |
3304 | iter = tsi_start (sl); | |
3305 | } | |
3306 | } | |
3307 | else | |
3308 | tsi_next (&iter); | |
3309 | } | |
3310 | ||
3311 | if (temp) | |
3312 | { | |
3313 | *expr_p = temp; | |
3314 | append_to_statement_list (body, pre_p); | |
3315 | return GS_OK; | |
3316 | } | |
3317 | else | |
3318 | { | |
3319 | *expr_p = body; | |
3320 | return GS_ALL_DONE; | |
3321 | } | |
3322 | } | |
3323 | ||
3324 | /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP | |
3325 | is the cleanup action required. */ | |
3326 | ||
3327 | static void | |
40aac948 | 3328 | gimple_push_cleanup (tree var, tree cleanup, bool eh_only, tree *pre_p) |
6de9cd9a DN |
3329 | { |
3330 | tree wce; | |
3331 | ||
3332 | /* Errors can result in improperly nested cleanups. Which results in | |
3333 | confusion when trying to resolve the WITH_CLEANUP_EXPR. */ | |
3334 | if (errorcount || sorrycount) | |
3335 | return; | |
3336 | ||
3337 | if (gimple_conditional_context ()) | |
3338 | { | |
3339 | /* If we're in a conditional context, this is more complex. We only | |
3340 | want to run the cleanup if we actually ran the initialization that | |
3341 | necessitates it, but we want to run it after the end of the | |
3342 | conditional context. So we wrap the try/finally around the | |
3343 | condition and use a flag to determine whether or not to actually | |
3344 | run the destructor. Thus | |
3345 | ||
3346 | test ? f(A()) : 0 | |
3347 | ||
3348 | becomes (approximately) | |
3349 | ||
3350 | flag = 0; | |
3351 | try { | |
3352 | if (test) { A::A(temp); flag = 1; val = f(temp); } | |
3353 | else { val = 0; } | |
3354 | } finally { | |
3355 | if (flag) A::~A(temp); | |
3356 | } | |
3357 | val | |
3358 | */ | |
3359 | ||
3360 | tree flag = create_tmp_var (boolean_type_node, "cleanup"); | |
3361 | tree ffalse = build (MODIFY_EXPR, void_type_node, flag, | |
3362 | boolean_false_node); | |
3363 | tree ftrue = build (MODIFY_EXPR, void_type_node, flag, | |
3364 | boolean_true_node); | |
65355d53 | 3365 | cleanup = build (COND_EXPR, void_type_node, flag, cleanup, NULL); |
ac45df5d | 3366 | wce = build (WITH_CLEANUP_EXPR, void_type_node, cleanup); |
6de9cd9a DN |
3367 | append_to_statement_list (ffalse, &gimplify_ctxp->conditional_cleanups); |
3368 | append_to_statement_list (wce, &gimplify_ctxp->conditional_cleanups); | |
3369 | append_to_statement_list (ftrue, pre_p); | |
3370 | ||
3371 | /* Because of this manipulation, and the EH edges that jump | |
3372 | threading cannot redirect, the temporary (VAR) will appear | |
3373 | to be used uninitialized. Don't warn. */ | |
3374 | TREE_NO_WARNING (var) = 1; | |
3375 | } | |
3376 | else | |
3377 | { | |
ac45df5d | 3378 | wce = build (WITH_CLEANUP_EXPR, void_type_node, cleanup); |
40aac948 | 3379 | CLEANUP_EH_ONLY (wce) = eh_only; |
6de9cd9a DN |
3380 | append_to_statement_list (wce, pre_p); |
3381 | } | |
3382 | ||
ac45df5d | 3383 | gimplify_stmt (&TREE_OPERAND (wce, 0)); |
6de9cd9a DN |
3384 | } |
3385 | ||
3386 | /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */ | |
3387 | ||
3388 | static enum gimplify_status | |
3389 | gimplify_target_expr (tree *expr_p, tree *pre_p, tree *post_p) | |
3390 | { | |
3391 | tree targ = *expr_p; | |
3392 | tree temp = TARGET_EXPR_SLOT (targ); | |
3393 | tree init = TARGET_EXPR_INITIAL (targ); | |
3394 | enum gimplify_status ret; | |
3395 | ||
3396 | if (init) | |
3397 | { | |
3a5b9284 RH |
3398 | /* TARGET_EXPR temps aren't part of the enclosing block, so add it |
3399 | to the temps list. */ | |
6de9cd9a DN |
3400 | gimple_add_tmp_var (temp); |
3401 | ||
3a5b9284 RH |
3402 | /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the |
3403 | expression is supposed to initialize the slot. */ | |
3404 | if (VOID_TYPE_P (TREE_TYPE (init))) | |
3405 | ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none); | |
3406 | else | |
325c3691 | 3407 | { |
3a5b9284 RH |
3408 | /* Special handling for BIND_EXPR can result in fewer temps. */ |
3409 | ret = GS_OK; | |
3410 | if (TREE_CODE (init) == BIND_EXPR) | |
3411 | gimplify_bind_expr (&init, temp, pre_p); | |
3412 | if (init != temp) | |
3413 | { | |
3414 | init = build (MODIFY_EXPR, void_type_node, temp, init); | |
3415 | ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, | |
3416 | fb_none); | |
3417 | } | |
325c3691 | 3418 | } |
3a5b9284 RH |
3419 | if (ret == GS_ERROR) |
3420 | return GS_ERROR; | |
6de9cd9a DN |
3421 | append_to_statement_list (init, pre_p); |
3422 | ||
3423 | /* If needed, push the cleanup for the temp. */ | |
3424 | if (TARGET_EXPR_CLEANUP (targ)) | |
3425 | { | |
3426 | gimplify_stmt (&TARGET_EXPR_CLEANUP (targ)); | |
40aac948 JM |
3427 | gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ), |
3428 | CLEANUP_EH_ONLY (targ), pre_p); | |
6de9cd9a DN |
3429 | } |
3430 | ||
3431 | /* Only expand this once. */ | |
3432 | TREE_OPERAND (targ, 3) = init; | |
3433 | TARGET_EXPR_INITIAL (targ) = NULL_TREE; | |
3434 | } | |
48eb4e53 | 3435 | else if (!DECL_SEEN_IN_BIND_EXPR_P (temp)) |
6de9cd9a DN |
3436 | /* We should have expanded this before. */ |
3437 | abort (); | |
3438 | ||
3439 | *expr_p = temp; | |
3440 | return GS_OK; | |
3441 | } | |
3442 | ||
3443 | /* Gimplification of expression trees. */ | |
3444 | ||
3445 | /* Gimplify an expression which appears at statement context; usually, this | |
be00f578 | 3446 | means replacing it with a suitably gimple STATEMENT_LIST. */ |
6de9cd9a DN |
3447 | |
3448 | void | |
3449 | gimplify_stmt (tree *stmt_p) | |
3450 | { | |
3451 | gimplify_expr (stmt_p, NULL, NULL, is_gimple_stmt, fb_none); | |
6de9cd9a DN |
3452 | } |
3453 | ||
3454 | /* Similarly, but force the result to be a STATEMENT_LIST. */ | |
3455 | ||
3456 | void | |
3457 | gimplify_to_stmt_list (tree *stmt_p) | |
3458 | { | |
3459 | gimplify_stmt (stmt_p); | |
65355d53 RH |
3460 | if (!*stmt_p) |
3461 | *stmt_p = alloc_stmt_list (); | |
3462 | else if (TREE_CODE (*stmt_p) != STATEMENT_LIST) | |
6de9cd9a DN |
3463 | { |
3464 | tree t = *stmt_p; | |
be00f578 | 3465 | *stmt_p = alloc_stmt_list (); |
6de9cd9a DN |
3466 | append_to_statement_list (t, stmt_p); |
3467 | } | |
3468 | } | |
3469 | ||
3470 | ||
3471 | /* Gimplifies the expression tree pointed by EXPR_P. Return 0 if | |
3472 | gimplification failed. | |
3473 | ||
3474 | PRE_P points to the list where side effects that must happen before | |
3475 | EXPR should be stored. | |
3476 | ||
3477 | POST_P points to the list where side effects that must happen after | |
3478 | EXPR should be stored, or NULL if there is no suitable list. In | |
3479 | that case, we copy the result to a temporary, emit the | |
3480 | post-effects, and then return the temporary. | |
3481 | ||
3482 | GIMPLE_TEST_F points to a function that takes a tree T and | |
3483 | returns nonzero if T is in the GIMPLE form requested by the | |
eadf906f | 3484 | caller. The GIMPLE predicates are in tree-gimple.c. |
6de9cd9a DN |
3485 | |
3486 | This test is used twice. Before gimplification, the test is | |
3487 | invoked to determine whether *EXPR_P is already gimple enough. If | |
3488 | that fails, *EXPR_P is gimplified according to its code and | |
3489 | GIMPLE_TEST_F is called again. If the test still fails, then a new | |
3490 | temporary variable is created and assigned the value of the | |
3491 | gimplified expression. | |
3492 | ||
3493 | FALLBACK tells the function what sort of a temporary we want. If the 1 | |
3494 | bit is set, an rvalue is OK. If the 2 bit is set, an lvalue is OK. | |
3495 | If both are set, either is OK, but an lvalue is preferable. | |
3496 | ||
3497 | The return value is either GS_ERROR or GS_ALL_DONE, since this function | |
3498 | iterates until solution. */ | |
3499 | ||
3500 | enum gimplify_status | |
3501 | gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p, | |
3502 | bool (* gimple_test_f) (tree), fallback_t fallback) | |
3503 | { | |
3504 | tree tmp; | |
3505 | tree internal_pre = NULL_TREE; | |
3506 | tree internal_post = NULL_TREE; | |
3507 | tree save_expr; | |
3508 | int is_statement = (pre_p == NULL); | |
6de9cd9a DN |
3509 | location_t saved_location; |
3510 | enum gimplify_status ret; | |
3511 | ||
3512 | save_expr = *expr_p; | |
3513 | if (save_expr == NULL_TREE) | |
3514 | return GS_ALL_DONE; | |
3515 | ||
3516 | /* We used to check the predicate here and return immediately if it | |
3517 | succeeds. This is wrong; the design is for gimplification to be | |
3518 | idempotent, and for the predicates to only test for valid forms, not | |
3519 | whether they are fully simplified. */ | |
3520 | ||
3521 | /* Set up our internal queues if needed. */ | |
3522 | if (pre_p == NULL) | |
3523 | pre_p = &internal_pre; | |
3524 | if (post_p == NULL) | |
3525 | post_p = &internal_post; | |
3526 | ||
3527 | saved_location = input_location; | |
a281759f PB |
3528 | if (save_expr != error_mark_node |
3529 | && EXPR_HAS_LOCATION (*expr_p)) | |
3530 | input_location = EXPR_LOCATION (*expr_p); | |
6de9cd9a DN |
3531 | |
3532 | /* Loop over the specific gimplifiers until the toplevel node | |
3533 | remains the same. */ | |
3534 | do | |
3535 | { | |
73d6ddef RK |
3536 | /* Strip away as many useless type conversions as possible |
3537 | at the toplevel. */ | |
3538 | STRIP_USELESS_TYPE_CONVERSION (*expr_p); | |
6de9cd9a DN |
3539 | |
3540 | /* Remember the expr. */ | |
3541 | save_expr = *expr_p; | |
3542 | ||
3543 | /* Die, die, die, my darling. */ | |
3544 | if (save_expr == error_mark_node | |
65355d53 RH |
3545 | || (TREE_TYPE (save_expr) |
3546 | && TREE_TYPE (save_expr) == error_mark_node)) | |
6de9cd9a DN |
3547 | { |
3548 | ret = GS_ERROR; | |
3549 | break; | |
3550 | } | |
3551 | ||
3552 | /* Do any language-specific gimplification. */ | |
673fda6b | 3553 | ret = lang_hooks.gimplify_expr (expr_p, pre_p, post_p); |
6de9cd9a DN |
3554 | if (ret == GS_OK) |
3555 | { | |
3556 | if (*expr_p == NULL_TREE) | |
3557 | break; | |
3558 | if (*expr_p != save_expr) | |
3559 | continue; | |
3560 | } | |
3561 | else if (ret != GS_UNHANDLED) | |
3562 | break; | |
3563 | ||
3564 | ret = GS_OK; | |
3565 | switch (TREE_CODE (*expr_p)) | |
3566 | { | |
3567 | /* First deal with the special cases. */ | |
3568 | ||
3569 | case POSTINCREMENT_EXPR: | |
3570 | case POSTDECREMENT_EXPR: | |
3571 | case PREINCREMENT_EXPR: | |
3572 | case PREDECREMENT_EXPR: | |
3573 | ret = gimplify_self_mod_expr (expr_p, pre_p, post_p, | |
3574 | fallback != fb_none); | |
3575 | break; | |
3576 | ||
3577 | case ARRAY_REF: | |
44de5aeb RK |
3578 | case ARRAY_RANGE_REF: |
3579 | case REALPART_EXPR: | |
3580 | case IMAGPART_EXPR: | |
6de9cd9a | 3581 | case COMPONENT_REF: |
9e51aaf5 | 3582 | case VIEW_CONVERT_EXPR: |
6de9cd9a | 3583 | ret = gimplify_compound_lval (expr_p, pre_p, post_p, |
90051e16 | 3584 | fallback ? fallback : fb_rvalue); |
6de9cd9a DN |
3585 | break; |
3586 | ||
3587 | case COND_EXPR: | |
3588 | ret = gimplify_cond_expr (expr_p, pre_p, NULL_TREE); | |
3589 | break; | |
3590 | ||
3591 | case CALL_EXPR: | |
90051e16 | 3592 | ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none); |
6de9cd9a DN |
3593 | break; |
3594 | ||
3595 | case TREE_LIST: | |
3596 | abort (); | |
3597 | ||
3598 | case COMPOUND_EXPR: | |
3599 | ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none); | |
3600 | break; | |
3601 | ||
6de9cd9a DN |
3602 | case MODIFY_EXPR: |
3603 | case INIT_EXPR: | |
3604 | ret = gimplify_modify_expr (expr_p, pre_p, post_p, | |
3605 | fallback != fb_none); | |
3606 | break; | |
3607 | ||
3608 | case TRUTH_ANDIF_EXPR: | |
3609 | case TRUTH_ORIF_EXPR: | |
3610 | ret = gimplify_boolean_expr (expr_p); | |
3611 | break; | |
3612 | ||
3613 | case TRUTH_NOT_EXPR: | |
3614 | TREE_OPERAND (*expr_p, 0) | |
3615 | = gimple_boolify (TREE_OPERAND (*expr_p, 0)); | |
3616 | ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, | |
3617 | is_gimple_val, fb_rvalue); | |
3618 | recalculate_side_effects (*expr_p); | |
3619 | break; | |
3620 | ||
3621 | case ADDR_EXPR: | |
3622 | ret = gimplify_addr_expr (expr_p, pre_p, post_p); | |
3623 | break; | |
3624 | ||
3625 | case VA_ARG_EXPR: | |
cd3ce9b4 | 3626 | ret = gimplify_va_arg_expr (expr_p, pre_p, post_p); |
6de9cd9a DN |
3627 | break; |
3628 | ||
3629 | case CONVERT_EXPR: | |
3630 | case NOP_EXPR: | |
3631 | if (IS_EMPTY_STMT (*expr_p)) | |
3632 | { | |
3633 | ret = GS_ALL_DONE; | |
3634 | break; | |
3635 | } | |
3636 | ||
3637 | if (VOID_TYPE_P (TREE_TYPE (*expr_p)) | |
3638 | || fallback == fb_none) | |
3639 | { | |
3640 | /* Just strip a conversion to void (or in void context) and | |
3641 | try again. */ | |
3642 | *expr_p = TREE_OPERAND (*expr_p, 0); | |
3643 | break; | |
3644 | } | |
3645 | ||
3646 | ret = gimplify_conversion (expr_p); | |
3647 | if (ret == GS_ERROR) | |
3648 | break; | |
3649 | if (*expr_p != save_expr) | |
3650 | break; | |
3651 | /* FALLTHRU */ | |
3652 | ||
3653 | case FIX_TRUNC_EXPR: | |
3654 | case FIX_CEIL_EXPR: | |
3655 | case FIX_FLOOR_EXPR: | |
3656 | case FIX_ROUND_EXPR: | |
3657 | /* unary_expr: ... | '(' cast ')' val | ... */ | |
3658 | ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, | |
3659 | is_gimple_val, fb_rvalue); | |
3660 | recalculate_side_effects (*expr_p); | |
3661 | break; | |
3662 | ||
3663 | case INDIRECT_REF: | |
3664 | ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, | |
3665 | is_gimple_reg, fb_rvalue); | |
3666 | recalculate_side_effects (*expr_p); | |
3667 | break; | |
3668 | ||
3669 | /* Constants need not be gimplified. */ | |
3670 | case INTEGER_CST: | |
3671 | case REAL_CST: | |
3672 | case STRING_CST: | |
3673 | case COMPLEX_CST: | |
3674 | case VECTOR_CST: | |
3675 | ret = GS_ALL_DONE; | |
3676 | break; | |
3677 | ||
3678 | case CONST_DECL: | |
0534fa56 | 3679 | /* If we require an lvalue, such as for ADDR_EXPR, retain the |
2a7e31df | 3680 | CONST_DECL node. Otherwise the decl is replaceable by its |
0534fa56 RH |
3681 | value. */ |
3682 | /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */ | |
3683 | if (fallback & fb_lvalue) | |
3684 | ret = GS_ALL_DONE; | |
3685 | else | |
3686 | *expr_p = DECL_INITIAL (*expr_p); | |
6de9cd9a DN |
3687 | break; |
3688 | ||
350fae66 RK |
3689 | case DECL_EXPR: |
3690 | ret = gimplify_decl_expr (expr_p); | |
3691 | break; | |
3692 | ||
6de9cd9a DN |
3693 | case EXC_PTR_EXPR: |
3694 | /* FIXME make this a decl. */ | |
3695 | ret = GS_ALL_DONE; | |
3696 | break; | |
3697 | ||
3698 | case BIND_EXPR: | |
325c3691 | 3699 | ret = gimplify_bind_expr (expr_p, NULL, pre_p); |
6de9cd9a DN |
3700 | break; |
3701 | ||
3702 | case LOOP_EXPR: | |
3703 | ret = gimplify_loop_expr (expr_p, pre_p); | |
3704 | break; | |
3705 | ||
3706 | case SWITCH_EXPR: | |
3707 | ret = gimplify_switch_expr (expr_p, pre_p); | |
3708 | break; | |
3709 | ||
3710 | case LABELED_BLOCK_EXPR: | |
3711 | ret = gimplify_labeled_block_expr (expr_p); | |
3712 | break; | |
3713 | ||
3714 | case EXIT_BLOCK_EXPR: | |
3715 | ret = gimplify_exit_block_expr (expr_p); | |
3716 | break; | |
3717 | ||
3718 | case EXIT_EXPR: | |
3719 | ret = gimplify_exit_expr (expr_p); | |
3720 | break; | |
3721 | ||
3722 | case GOTO_EXPR: | |
3723 | /* If the target is not LABEL, then it is a computed jump | |
3724 | and the target needs to be gimplified. */ | |
3725 | if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL) | |
3726 | ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p, | |
3727 | NULL, is_gimple_val, fb_rvalue); | |
3728 | break; | |
3729 | ||
3730 | case LABEL_EXPR: | |
3731 | ret = GS_ALL_DONE; | |
3732 | #ifdef ENABLE_CHECKING | |
3733 | if (decl_function_context (LABEL_EXPR_LABEL (*expr_p)) != current_function_decl) | |
3734 | abort (); | |
3735 | #endif | |
3736 | break; | |
3737 | ||
3738 | case CASE_LABEL_EXPR: | |
3739 | ret = gimplify_case_label_expr (expr_p); | |
3740 | break; | |
3741 | ||
3742 | case RETURN_EXPR: | |
3743 | ret = gimplify_return_expr (*expr_p, pre_p); | |
3744 | break; | |
3745 | ||
3746 | case CONSTRUCTOR: | |
48eb4e53 RK |
3747 | /* Don't reduce this in place; let gimplify_init_constructor work its |
3748 | magic. Buf if we're just elaborating this for side effects, just | |
3749 | gimplify any element that has side-effects. */ | |
3750 | if (fallback == fb_none) | |
3751 | { | |
3752 | for (tmp = CONSTRUCTOR_ELTS (*expr_p); tmp; | |
3753 | tmp = TREE_CHAIN (tmp)) | |
3754 | if (TREE_SIDE_EFFECTS (TREE_VALUE (tmp))) | |
3755 | gimplify_expr (&TREE_VALUE (tmp), pre_p, post_p, | |
3756 | gimple_test_f, fallback); | |
3757 | ||
3758 | *expr_p = NULL_TREE; | |
3759 | } | |
3760 | ||
6de9cd9a DN |
3761 | ret = GS_ALL_DONE; |
3762 | break; | |
3763 | ||
3764 | /* The following are special cases that are not handled by the | |
3765 | original GIMPLE grammar. */ | |
3766 | ||
3767 | /* SAVE_EXPR nodes are converted into a GIMPLE identifier and | |
3768 | eliminated. */ | |
3769 | case SAVE_EXPR: | |
3770 | ret = gimplify_save_expr (expr_p, pre_p, post_p); | |
3771 | break; | |
3772 | ||
3773 | case BIT_FIELD_REF: | |
3774 | { | |
3775 | enum gimplify_status r0, r1, r2; | |
3776 | ||
3777 | r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, | |
90051e16 | 3778 | is_gimple_lvalue, fb_either); |
6de9cd9a DN |
3779 | r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p, |
3780 | is_gimple_val, fb_rvalue); | |
3781 | r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p, post_p, | |
3782 | is_gimple_val, fb_rvalue); | |
3783 | recalculate_side_effects (*expr_p); | |
3784 | ||
3785 | ret = MIN (r0, MIN (r1, r2)); | |
3786 | } | |
3787 | break; | |
3788 | ||
3789 | case NON_LVALUE_EXPR: | |
3790 | /* This should have been stripped above. */ | |
3791 | abort (); | |
3792 | break; | |
3793 | ||
3794 | case ASM_EXPR: | |
3795 | ret = gimplify_asm_expr (expr_p, pre_p, post_p); | |
3796 | break; | |
3797 | ||
3798 | case TRY_FINALLY_EXPR: | |
3799 | case TRY_CATCH_EXPR: | |
3800 | gimplify_to_stmt_list (&TREE_OPERAND (*expr_p, 0)); | |
3801 | gimplify_to_stmt_list (&TREE_OPERAND (*expr_p, 1)); | |
3802 | ret = GS_ALL_DONE; | |
3803 | break; | |
3804 | ||
3805 | case CLEANUP_POINT_EXPR: | |
3806 | ret = gimplify_cleanup_point_expr (expr_p, pre_p); | |
3807 | break; | |
3808 | ||
3809 | case TARGET_EXPR: | |
3810 | ret = gimplify_target_expr (expr_p, pre_p, post_p); | |
3811 | break; | |
3812 | ||
3813 | case CATCH_EXPR: | |
3814 | gimplify_to_stmt_list (&CATCH_BODY (*expr_p)); | |
3815 | ret = GS_ALL_DONE; | |
3816 | break; | |
3817 | ||
3818 | case EH_FILTER_EXPR: | |
3819 | gimplify_to_stmt_list (&EH_FILTER_FAILURE (*expr_p)); | |
3820 | ret = GS_ALL_DONE; | |
3821 | break; | |
3822 | ||
0f59171d RH |
3823 | case OBJ_TYPE_REF: |
3824 | { | |
3825 | enum gimplify_status r0, r1; | |
3826 | r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, post_p, | |
3827 | is_gimple_val, fb_rvalue); | |
3828 | r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p, | |
3829 | is_gimple_val, fb_rvalue); | |
3830 | ret = MIN (r0, r1); | |
3831 | } | |
6de9cd9a DN |
3832 | break; |
3833 | ||
6de9cd9a DN |
3834 | case LABEL_DECL: |
3835 | /* We get here when taking the address of a label. We mark | |
3836 | the label as "forced"; meaning it can never be removed and | |
3837 | it is a potential target for any computed goto. */ | |
3838 | FORCED_LABEL (*expr_p) = 1; | |
3839 | ret = GS_ALL_DONE; | |
3840 | break; | |
3841 | ||
3842 | case STATEMENT_LIST: | |
3843 | ret = gimplify_statement_list (expr_p); | |
3844 | break; | |
3845 | ||
d25cee4d RH |
3846 | case WITH_SIZE_EXPR: |
3847 | { | |
3848 | enum gimplify_status r0, r1; | |
3849 | r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, | |
3850 | post_p == &internal_post ? NULL : post_p, | |
3851 | gimple_test_f, fallback); | |
3852 | r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p, | |
3853 | is_gimple_val, fb_rvalue); | |
3854 | } | |
3855 | break; | |
3856 | ||
6de9cd9a DN |
3857 | case VAR_DECL: |
3858 | /* ??? If this is a local variable, and it has not been seen in any | |
3859 | outer BIND_EXPR, then it's probably the result of a duplicate | |
3860 | declaration, for which we've already issued an error. It would | |
3861 | be really nice if the front end wouldn't leak these at all. | |
3862 | Currently the only known culprit is C++ destructors, as seen | |
3863 | in g++.old-deja/g++.jason/binding.C. */ | |
3864 | tmp = *expr_p; | |
3865 | if (!TREE_STATIC (tmp) && !DECL_EXTERNAL (tmp) | |
3866 | && decl_function_context (tmp) == current_function_decl | |
48eb4e53 | 3867 | && !DECL_SEEN_IN_BIND_EXPR_P (tmp)) |
6de9cd9a DN |
3868 | { |
3869 | #ifdef ENABLE_CHECKING | |
3870 | if (!errorcount && !sorrycount) | |
3871 | abort (); | |
3872 | #endif | |
3873 | ret = GS_ERROR; | |
1a186ec5 | 3874 | break; |
6de9cd9a | 3875 | } |
1a186ec5 RH |
3876 | |
3877 | /* If this is a local variable sized decl, it must be accessed | |
3878 | indirectly. Perform that substitution. */ | |
3879 | if (DECL_VALUE_EXPR (tmp)) | |
3880 | { | |
3881 | *expr_p = unshare_expr (DECL_VALUE_EXPR (tmp)); | |
3882 | ret = GS_OK; | |
3883 | break; | |
3884 | } | |
3885 | ||
3886 | ret = GS_ALL_DONE; | |
6de9cd9a DN |
3887 | break; |
3888 | ||
71956db3 RH |
3889 | case SSA_NAME: |
3890 | /* Allow callbacks into the gimplifier during optimization. */ | |
3891 | ret = GS_ALL_DONE; | |
3892 | break; | |
3893 | ||
6de9cd9a | 3894 | default: |
44de5aeb RK |
3895 | /* If this is a comparison of objects of aggregate type, handle |
3896 | it specially (by converting to a call to memcmp). It would be | |
3897 | nice to only have to do this for variable-sized objects, but | |
3898 | then we'd have to allow the same nest of reference nodes we | |
3899 | allow for MODIFY_EXPR and that's too complex. */ | |
3900 | if (TREE_CODE_CLASS (TREE_CODE (*expr_p)) == '<' | |
3901 | && (AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (*expr_p, 1))))) | |
3902 | ret = gimplify_variable_sized_compare (expr_p); | |
3903 | ||
6de9cd9a DN |
3904 | /* If *EXPR_P does not need to be special-cased, handle it |
3905 | according to its class. */ | |
44de5aeb | 3906 | else if (TREE_CODE_CLASS (TREE_CODE (*expr_p)) == '1') |
6de9cd9a DN |
3907 | ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, |
3908 | post_p, is_gimple_val, fb_rvalue); | |
3909 | else if (TREE_CODE_CLASS (TREE_CODE (*expr_p)) == '2' | |
3910 | || TREE_CODE_CLASS (TREE_CODE (*expr_p)) == '<' | |
3911 | || TREE_CODE (*expr_p) == TRUTH_AND_EXPR | |
3912 | || TREE_CODE (*expr_p) == TRUTH_OR_EXPR | |
3913 | || TREE_CODE (*expr_p) == TRUTH_XOR_EXPR) | |
3914 | { | |
3915 | enum gimplify_status r0, r1; | |
3916 | ||
3917 | r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, | |
3918 | post_p, is_gimple_val, fb_rvalue); | |
3919 | r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, | |
3920 | post_p, is_gimple_val, fb_rvalue); | |
3921 | ||
3922 | ret = MIN (r0, r1); | |
3923 | } | |
3924 | else if (TREE_CODE_CLASS (TREE_CODE (*expr_p)) == 'd' | |
3925 | || TREE_CODE_CLASS (TREE_CODE (*expr_p)) == 'c') | |
3926 | { | |
3927 | ret = GS_ALL_DONE; | |
3928 | break; | |
3929 | } | |
3930 | else | |
3931 | /* Fail if we don't know how to handle this tree code. */ | |
3932 | abort (); | |
3933 | ||
3934 | recalculate_side_effects (*expr_p); | |
3935 | break; | |
3936 | } | |
3937 | ||
3938 | /* If we replaced *expr_p, gimplify again. */ | |
3939 | if (ret == GS_OK && (*expr_p == NULL || *expr_p == save_expr)) | |
3940 | ret = GS_ALL_DONE; | |
3941 | } | |
3942 | while (ret == GS_OK); | |
3943 | ||
3944 | /* If we encountered an error_mark somewhere nested inside, either | |
3945 | stub out the statement or propagate the error back out. */ | |
3946 | if (ret == GS_ERROR) | |
3947 | { | |
3948 | if (is_statement) | |
65355d53 | 3949 | *expr_p = NULL; |
6de9cd9a DN |
3950 | goto out; |
3951 | } | |
3952 | ||
3953 | #ifdef ENABLE_CHECKING | |
3954 | /* This was only valid as a return value from the langhook, which | |
3955 | we handled. Make sure it doesn't escape from any other context. */ | |
3956 | if (ret == GS_UNHANDLED) | |
3957 | abort (); | |
3958 | #endif | |
3959 | ||
65355d53 | 3960 | if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p)) |
6de9cd9a DN |
3961 | { |
3962 | /* We aren't looking for a value, and we don't have a valid | |
3963 | statement. If it doesn't have side-effects, throw it away. */ | |
3964 | if (!TREE_SIDE_EFFECTS (*expr_p)) | |
65355d53 | 3965 | *expr_p = NULL; |
6de9cd9a | 3966 | else if (!TREE_THIS_VOLATILE (*expr_p)) |
44de5aeb RK |
3967 | { |
3968 | /* This is probably a _REF that contains something nested that | |
3969 | has side effects. Recurse through the operands to find it. */ | |
3970 | enum tree_code code = TREE_CODE (*expr_p); | |
3971 | ||
3972 | if (code == COMPONENT_REF | |
3973 | || code == REALPART_EXPR || code == IMAGPART_EXPR) | |
3974 | gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, | |
3975 | gimple_test_f, fallback); | |
3976 | else if (code == ARRAY_REF || code == ARRAY_RANGE_REF) | |
3977 | { | |
3978 | gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, | |
3979 | gimple_test_f, fallback); | |
3980 | gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p, | |
3981 | gimple_test_f, fallback); | |
3982 | } | |
3983 | else | |
3984 | /* Anything else with side-effects | |
3985 | must be converted to a valid statement before we get here. */ | |
3986 | abort (); | |
3987 | ||
65355d53 | 3988 | *expr_p = NULL; |
44de5aeb | 3989 | } |
6de9cd9a DN |
3990 | else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))) |
3991 | { | |
3992 | /* Historically, the compiler has treated a bare | |
3993 | reference to a volatile lvalue as forcing a load. */ | |
3994 | tree tmp = create_tmp_var (TREE_TYPE (*expr_p), "vol"); | |
3995 | *expr_p = build (MODIFY_EXPR, TREE_TYPE (tmp), tmp, *expr_p); | |
3996 | } | |
3997 | else | |
3998 | /* We can't do anything useful with a volatile reference to | |
3999 | incomplete type, so just throw it away. */ | |
65355d53 | 4000 | *expr_p = NULL; |
6de9cd9a DN |
4001 | } |
4002 | ||
4003 | /* If we are gimplifying at the statement level, we're done. Tack | |
4004 | everything together and replace the original statement with the | |
4005 | gimplified form. */ | |
325c3691 | 4006 | if (fallback == fb_none || is_statement) |
6de9cd9a | 4007 | { |
be00f578 JM |
4008 | if (internal_pre || internal_post) |
4009 | { | |
4010 | append_to_statement_list (*expr_p, &internal_pre); | |
4011 | append_to_statement_list (internal_post, &internal_pre); | |
4012 | annotate_all_with_locus (&internal_pre, input_location); | |
4013 | *expr_p = internal_pre; | |
4014 | } | |
65355d53 RH |
4015 | else if (!*expr_p) |
4016 | ; | |
7c34ced1 RH |
4017 | else if (TREE_CODE (*expr_p) == STATEMENT_LIST) |
4018 | annotate_all_with_locus (expr_p, input_location); | |
4019 | else | |
4020 | annotate_one_with_locus (*expr_p, input_location); | |
6de9cd9a DN |
4021 | goto out; |
4022 | } | |
4023 | ||
4024 | /* Otherwise we're gimplifying a subexpression, so the resulting value is | |
4025 | interesting. */ | |
4026 | ||
4027 | /* If it's sufficiently simple already, we're done. Unless we are | |
4028 | handling some post-effects internally; if that's the case, we need to | |
4029 | copy into a temp before adding the post-effects to the tree. */ | |
4030 | if (!internal_post && (*gimple_test_f) (*expr_p)) | |
4031 | goto out; | |
4032 | ||
4033 | /* Otherwise, we need to create a new temporary for the gimplified | |
4034 | expression. */ | |
4035 | ||
4036 | /* We can't return an lvalue if we have an internal postqueue. The | |
4037 | object the lvalue refers to would (probably) be modified by the | |
4038 | postqueue; we need to copy the value out first, which means an | |
4039 | rvalue. */ | |
4040 | if ((fallback & fb_lvalue) && !internal_post | |
e847cc68 | 4041 | && is_gimple_addressable (*expr_p)) |
6de9cd9a DN |
4042 | { |
4043 | /* An lvalue will do. Take the address of the expression, store it | |
4044 | in a temporary, and replace the expression with an INDIRECT_REF of | |
4045 | that temporary. */ | |
cd3ce9b4 | 4046 | tmp = build_fold_addr_expr (*expr_p); |
6de9cd9a DN |
4047 | gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue); |
4048 | *expr_p = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (tmp)), tmp); | |
4049 | } | |
17ad5b5e | 4050 | else if ((fallback & fb_rvalue) && is_gimple_formal_tmp_rhs (*expr_p)) |
6de9cd9a DN |
4051 | { |
4052 | #if defined ENABLE_CHECKING | |
4053 | if (VOID_TYPE_P (TREE_TYPE (*expr_p))) | |
4054 | abort (); | |
4055 | #endif | |
4056 | ||
4057 | /* An rvalue will do. Assign the gimplified expression into a new | |
4058 | temporary TMP and replace the original expression with TMP. */ | |
4059 | ||
4060 | if (internal_post || (fallback & fb_lvalue)) | |
4061 | /* The postqueue might change the value of the expression between | |
4062 | the initialization and use of the temporary, so we can't use a | |
4063 | formal temp. FIXME do we care? */ | |
4064 | *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p); | |
4065 | else | |
4066 | *expr_p = get_formal_tmp_var (*expr_p, pre_p); | |
8b11a64c ZD |
4067 | |
4068 | if (TREE_CODE (*expr_p) != SSA_NAME) | |
4069 | DECL_GIMPLE_FORMAL_TEMP_P (*expr_p) = 1; | |
6de9cd9a DN |
4070 | } |
4071 | else if (fallback & fb_mayfail) | |
4072 | { | |
4073 | /* If this is an asm statement, and the user asked for the impossible, | |
4074 | don't abort. Fail and let gimplify_asm_expr issue an error. */ | |
4075 | ret = GS_ERROR; | |
4076 | goto out; | |
4077 | } | |
4078 | else | |
4079 | { | |
4080 | fprintf (stderr, "gimplification failed:\n"); | |
4081 | print_generic_expr (stderr, *expr_p, 0); | |
4082 | debug_tree (*expr_p); | |
4083 | abort (); | |
4084 | } | |
4085 | ||
4086 | #if defined ENABLE_CHECKING | |
4087 | /* Make sure the temporary matches our predicate. */ | |
4088 | if (!(*gimple_test_f) (*expr_p)) | |
4089 | abort (); | |
4090 | #endif | |
4091 | ||
4092 | if (internal_post) | |
4093 | { | |
4094 | annotate_all_with_locus (&internal_post, input_location); | |
4095 | append_to_statement_list (internal_post, pre_p); | |
4096 | } | |
4097 | ||
4098 | out: | |
4099 | input_location = saved_location; | |
4100 | return ret; | |
4101 | } | |
4102 | ||
44de5aeb | 4103 | /* Look through TYPE for variable-sized objects and gimplify each such |
65355d53 | 4104 | size that we find. Add to LIST_P any statements generated. */ |
44de5aeb | 4105 | |
65355d53 RH |
4106 | void |
4107 | gimplify_type_sizes (tree type, tree *list_p) | |
44de5aeb | 4108 | { |
44de5aeb RK |
4109 | tree field; |
4110 | ||
4111 | switch (TREE_CODE (type)) | |
4112 | { | |
4113 | case ERROR_MARK: | |
65355d53 | 4114 | return; |
44de5aeb RK |
4115 | |
4116 | case INTEGER_TYPE: | |
4117 | case ENUMERAL_TYPE: | |
4118 | case BOOLEAN_TYPE: | |
4119 | case CHAR_TYPE: | |
4120 | case REAL_TYPE: | |
65355d53 RH |
4121 | gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p); |
4122 | gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p); | |
44de5aeb RK |
4123 | break; |
4124 | ||
4125 | case ARRAY_TYPE: | |
8c27b7d4 | 4126 | /* These anonymous types don't have declarations, so handle them here. */ |
65355d53 | 4127 | gimplify_type_sizes (TYPE_DOMAIN (type), list_p); |
44de5aeb RK |
4128 | break; |
4129 | ||
4130 | case RECORD_TYPE: | |
4131 | case UNION_TYPE: | |
4132 | case QUAL_UNION_TYPE: | |
4133 | for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) | |
4134 | if (TREE_CODE (field) == FIELD_DECL) | |
65355d53 | 4135 | gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p); |
44de5aeb RK |
4136 | break; |
4137 | ||
4138 | default: | |
4139 | break; | |
4140 | } | |
4141 | ||
65355d53 RH |
4142 | gimplify_one_sizepos (&TYPE_SIZE (type), list_p); |
4143 | gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p); | |
44de5aeb RK |
4144 | } |
4145 | ||
4146 | /* Subroutine of the above to gimplify one size or position, *EXPR_P. | |
4147 | We add any required statements to STMT_P. */ | |
4148 | ||
4149 | void | |
4150 | gimplify_one_sizepos (tree *expr_p, tree *stmt_p) | |
4151 | { | |
44de5aeb | 4152 | /* We don't do anything if the value isn't there, is constant, or contains |
1e748a2b RK |
4153 | A PLACEHOLDER_EXPR. We also don't want to do anything if it's already |
4154 | a VAR_DECL. If it's a VAR_DECL from another function, the gimplfier | |
4155 | will want to replace it with a new variable, but that will cause problems | |
4156 | if this type is from outside the function. It's OK to have that here. */ | |
44de5aeb | 4157 | if (*expr_p == NULL_TREE || TREE_CONSTANT (*expr_p) |
1e748a2b | 4158 | || TREE_CODE (*expr_p) == VAR_DECL |
44de5aeb RK |
4159 | || CONTAINS_PLACEHOLDER_P (*expr_p)) |
4160 | return; | |
4161 | ||
65355d53 | 4162 | gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue); |
44de5aeb RK |
4163 | } |
4164 | \f | |
6de9cd9a DN |
4165 | #ifdef ENABLE_CHECKING |
4166 | /* Compare types A and B for a "close enough" match. */ | |
4167 | ||
4168 | static bool | |
4169 | cpt_same_type (tree a, tree b) | |
4170 | { | |
4171 | if (lang_hooks.types_compatible_p (a, b)) | |
4172 | return true; | |
4173 | ||
4174 | /* ??? The C++ FE decomposes METHOD_TYPES to FUNCTION_TYPES and doesn't | |
4175 | link them together. This routine is intended to catch type errors | |
4176 | that will affect the optimizers, and the optimizers don't add new | |
4177 | dereferences of function pointers, so ignore it. */ | |
4178 | if ((TREE_CODE (a) == FUNCTION_TYPE || TREE_CODE (a) == METHOD_TYPE) | |
4179 | && (TREE_CODE (b) == FUNCTION_TYPE || TREE_CODE (b) == METHOD_TYPE)) | |
4180 | return true; | |
4181 | ||
4182 | /* ??? The C FE pushes type qualifiers after the fact into the type of | |
4183 | the element from the type of the array. See build_unary_op's handling | |
4184 | of ADDR_EXPR. This seems wrong -- if we were going to do this, we | |
4185 | should have done it when creating the variable in the first place. | |
4186 | Alternately, why aren't the two array types made variants? */ | |
4187 | if (TREE_CODE (a) == ARRAY_TYPE && TREE_CODE (b) == ARRAY_TYPE) | |
4188 | return cpt_same_type (TREE_TYPE (a), TREE_TYPE (b)); | |
4189 | ||
4190 | /* And because of those, we have to recurse down through pointers. */ | |
4191 | if (POINTER_TYPE_P (a) && POINTER_TYPE_P (b)) | |
4192 | return cpt_same_type (TREE_TYPE (a), TREE_TYPE (b)); | |
4193 | ||
4194 | return false; | |
4195 | } | |
4196 | ||
4197 | /* Check for some cases of the front end missing cast expressions. | |
4198 | The type of a dereference should correspond to the pointer type; | |
4199 | similarly the type of an address should match its object. */ | |
4200 | ||
4201 | static tree | |
4202 | check_pointer_types_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, | |
4203 | void *data ATTRIBUTE_UNUSED) | |
4204 | { | |
4205 | tree t = *tp; | |
4206 | tree ptype, otype, dtype; | |
4207 | ||
4208 | switch (TREE_CODE (t)) | |
4209 | { | |
4210 | case INDIRECT_REF: | |
4211 | case ARRAY_REF: | |
4212 | otype = TREE_TYPE (t); | |
4213 | ptype = TREE_TYPE (TREE_OPERAND (t, 0)); | |
4214 | dtype = TREE_TYPE (ptype); | |
4215 | if (!cpt_same_type (otype, dtype)) | |
4216 | abort (); | |
4217 | break; | |
4218 | ||
4219 | case ADDR_EXPR: | |
4220 | ptype = TREE_TYPE (t); | |
4221 | otype = TREE_TYPE (TREE_OPERAND (t, 0)); | |
4222 | dtype = TREE_TYPE (ptype); | |
4223 | if (!cpt_same_type (otype, dtype)) | |
4224 | { | |
44de5aeb RK |
4225 | /* &array is allowed to produce a pointer to the element, rather than |
4226 | a pointer to the array type. We must allow this in order to | |
4227 | properly represent assigning the address of an array in C into | |
4228 | pointer to the element type. */ | |
6de9cd9a DN |
4229 | if (TREE_CODE (otype) == ARRAY_TYPE |
4230 | && POINTER_TYPE_P (ptype) | |
4231 | && cpt_same_type (TREE_TYPE (otype), dtype)) | |
4232 | break; | |
4233 | abort (); | |
4234 | } | |
4235 | break; | |
4236 | ||
4237 | default: | |
4238 | return NULL_TREE; | |
4239 | } | |
4240 | ||
4241 | ||
4242 | return NULL_TREE; | |
4243 | } | |
4244 | #endif | |
4245 | ||
4246 | /* Gimplify the body of statements pointed by BODY_P. FNDECL is the | |
4247 | function decl containing BODY. */ | |
4248 | ||
4249 | void | |
4250 | gimplify_body (tree *body_p, tree fndecl) | |
4251 | { | |
4252 | location_t saved_location = input_location; | |
4253 | tree body; | |
4254 | ||
4255 | timevar_push (TV_TREE_GIMPLIFY); | |
4256 | push_gimplify_context (); | |
4257 | ||
44de5aeb RK |
4258 | /* Unshare most shared trees in the body and in that of any nested functions. |
4259 | It would seem we don't have to do this for nested functions because | |
4260 | they are supposed to be output and then the outer function gimplified | |
4261 | first, but the g++ front end doesn't always do it that way. */ | |
4262 | unshare_body (body_p, fndecl); | |
4263 | unvisit_body (body_p, fndecl); | |
6de9cd9a DN |
4264 | |
4265 | /* Make sure input_location isn't set to something wierd. */ | |
4266 | input_location = DECL_SOURCE_LOCATION (fndecl); | |
4267 | ||
4268 | /* Gimplify the function's body. */ | |
4269 | gimplify_stmt (body_p); | |
4270 | body = *body_p; | |
4271 | ||
4272 | /* Unshare again, in case gimplification was sloppy. */ | |
4273 | unshare_all_trees (body); | |
4274 | ||
be1ba3d1 RH |
4275 | if (!body) |
4276 | body = alloc_stmt_list (); | |
4277 | else if (TREE_CODE (body) == STATEMENT_LIST) | |
6de9cd9a DN |
4278 | { |
4279 | tree t = expr_only (*body_p); | |
4280 | if (t) | |
4281 | body = t; | |
4282 | } | |
44de5aeb RK |
4283 | |
4284 | /* If there isn't an outer BIND_EXPR, add one. */ | |
6de9cd9a DN |
4285 | if (TREE_CODE (body) != BIND_EXPR) |
4286 | { | |
4287 | tree b = build (BIND_EXPR, void_type_node, NULL_TREE, | |
4288 | NULL_TREE, NULL_TREE); | |
4289 | TREE_SIDE_EFFECTS (b) = 1; | |
be00f578 | 4290 | append_to_statement_list_force (body, &BIND_EXPR_BODY (b)); |
6de9cd9a DN |
4291 | body = b; |
4292 | } | |
4293 | *body_p = body; | |
4294 | ||
4295 | pop_gimplify_context (body); | |
4296 | ||
4297 | #ifdef ENABLE_CHECKING | |
4298 | walk_tree (body_p, check_pointer_types_r, NULL, NULL); | |
4299 | #endif | |
4300 | ||
4301 | timevar_pop (TV_TREE_GIMPLIFY); | |
4302 | input_location = saved_location; | |
4303 | } | |
4304 | ||
4305 | /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL | |
4306 | node for the function we want to gimplify. */ | |
4307 | ||
4308 | void | |
4309 | gimplify_function_tree (tree fndecl) | |
4310 | { | |
4311 | tree oldfn; | |
4312 | ||
4313 | oldfn = current_function_decl; | |
4314 | current_function_decl = fndecl; | |
4315 | ||
4316 | gimplify_body (&DECL_SAVED_TREE (fndecl), fndecl); | |
4317 | ||
4318 | /* If we're instrumenting function entry/exit, then prepend the call to | |
4319 | the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to | |
4320 | catch the exit hook. */ | |
4321 | /* ??? Add some way to ignore exceptions for this TFE. */ | |
4322 | if (flag_instrument_function_entry_exit | |
4323 | && ! DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)) | |
4324 | { | |
4325 | tree tf, x, bind; | |
4326 | ||
4327 | tf = build (TRY_FINALLY_EXPR, void_type_node, NULL, NULL); | |
4328 | TREE_SIDE_EFFECTS (tf) = 1; | |
4329 | x = DECL_SAVED_TREE (fndecl); | |
4330 | append_to_statement_list (x, &TREE_OPERAND (tf, 0)); | |
4331 | x = implicit_built_in_decls[BUILT_IN_PROFILE_FUNC_EXIT]; | |
4332 | x = build_function_call_expr (x, NULL); | |
4333 | append_to_statement_list (x, &TREE_OPERAND (tf, 1)); | |
4334 | ||
4335 | bind = build (BIND_EXPR, void_type_node, NULL, NULL, NULL); | |
4336 | TREE_SIDE_EFFECTS (bind) = 1; | |
4337 | x = implicit_built_in_decls[BUILT_IN_PROFILE_FUNC_ENTER]; | |
4338 | x = build_function_call_expr (x, NULL); | |
4339 | append_to_statement_list (x, &BIND_EXPR_BODY (bind)); | |
4340 | append_to_statement_list (tf, &BIND_EXPR_BODY (bind)); | |
4341 | ||
4342 | DECL_SAVED_TREE (fndecl) = bind; | |
4343 | } | |
4344 | ||
4345 | current_function_decl = oldfn; | |
4346 | } | |
4347 | ||
8b11a64c ZD |
4348 | \f |
4349 | /* Expands EXPR to list of gimple statements STMTS. If SIMPLE is true, | |
4350 | force the result to be either ssa_name or an invariant, otherwise | |
4351 | just force it to be a rhs expression. If VAR is not NULL, make the | |
4352 | base variable of the final destination be VAR if suitable. */ | |
4353 | ||
4354 | tree | |
4355 | force_gimple_operand (tree expr, tree *stmts, bool simple, tree var) | |
4356 | { | |
4357 | tree t; | |
4358 | enum gimplify_status ret; | |
4359 | gimple_predicate gimple_test_f; | |
4360 | ||
4361 | *stmts = NULL_TREE; | |
4362 | ||
4363 | if (is_gimple_val (expr)) | |
4364 | return expr; | |
4365 | ||
4366 | gimple_test_f = simple ? is_gimple_val : is_gimple_reg_rhs; | |
4367 | ||
4368 | push_gimplify_context (); | |
4369 | gimplify_ctxp->into_ssa = true; | |
4370 | ||
4371 | if (var) | |
4372 | expr = build (MODIFY_EXPR, TREE_TYPE (var), var, expr); | |
4373 | ||
4374 | ret = gimplify_expr (&expr, stmts, NULL, | |
4375 | gimple_test_f, fb_rvalue); | |
4376 | if (ret == GS_ERROR) | |
4377 | abort (); | |
4378 | ||
4379 | for (t = gimplify_ctxp->temps; t ; t = TREE_CHAIN (t)) | |
4380 | add_referenced_tmp_var (t); | |
4381 | ||
4382 | pop_gimplify_context (NULL); | |
4383 | ||
4384 | return expr; | |
4385 | } | |
4386 | ||
6de9cd9a | 4387 | #include "gt-gimplify.h" |