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