]>
Commit | Line | Data |
---|---|---|
6de9cd9a | 1 | /* Liveness for SSA trees. |
5624e564 | 2 | Copyright (C) 2003-2015 Free Software Foundation, Inc. |
6de9cd9a DN |
3 | Contributed by Andrew MacLeod <amacleod@redhat.com> |
4 | ||
5 | This file is part of GCC. | |
6 | ||
7 | GCC is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9dcd6f09 | 9 | the Free Software Foundation; either version 3, or (at your option) |
6de9cd9a DN |
10 | any later version. |
11 | ||
12 | GCC is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
9dcd6f09 NC |
18 | along with GCC; see the file COPYING3. If not see |
19 | <http://www.gnu.org/licenses/>. */ | |
6de9cd9a DN |
20 | |
21 | #include "config.h" | |
22 | #include "system.h" | |
23 | #include "coretypes.h" | |
4a8fb1a1 | 24 | #include "hash-table.h" |
6de9cd9a | 25 | #include "tm.h" |
40e23961 MC |
26 | #include "hash-set.h" |
27 | #include "machmode.h" | |
28 | #include "vec.h" | |
29 | #include "double-int.h" | |
30 | #include "input.h" | |
31 | #include "alias.h" | |
32 | #include "symtab.h" | |
33 | #include "wide-int.h" | |
34 | #include "inchash.h" | |
6de9cd9a | 35 | #include "tree.h" |
40e23961 | 36 | #include "fold-const.h" |
cf835838 | 37 | #include "gimple-pretty-print.h" |
6de9cd9a | 38 | #include "bitmap.h" |
4484a35a | 39 | #include "sbitmap.h" |
60393bbc | 40 | #include "predict.h" |
60393bbc | 41 | #include "hard-reg-set.h" |
60393bbc AM |
42 | #include "function.h" |
43 | #include "dominance.h" | |
44 | #include "cfg.h" | |
2fb9a547 AM |
45 | #include "basic-block.h" |
46 | #include "tree-ssa-alias.h" | |
47 | #include "internal-fn.h" | |
48 | #include "gimple-expr.h" | |
49 | #include "is-a.h" | |
442b4905 | 50 | #include "gimple.h" |
5be5c238 | 51 | #include "gimple-iterator.h" |
442b4905 AM |
52 | #include "gimple-ssa.h" |
53 | #include "tree-phinodes.h" | |
54 | #include "ssa-iterators.h" | |
d8a2d370 | 55 | #include "stringpool.h" |
442b4905 | 56 | #include "tree-ssanames.h" |
36566b39 PK |
57 | #include "hashtab.h" |
58 | #include "rtl.h" | |
59 | #include "flags.h" | |
60 | #include "statistics.h" | |
61 | #include "real.h" | |
62 | #include "fixed-value.h" | |
63 | #include "insn-config.h" | |
64 | #include "expmed.h" | |
65 | #include "dojump.h" | |
66 | #include "explow.h" | |
67 | #include "calls.h" | |
68 | #include "emit-rtl.h" | |
69 | #include "varasm.h" | |
70 | #include "stmt.h" | |
d8a2d370 | 71 | #include "expr.h" |
442b4905 | 72 | #include "tree-dfa.h" |
7ee2468b SB |
73 | #include "timevar.h" |
74 | #include "dumpfile.h" | |
6de9cd9a | 75 | #include "tree-ssa-live.h" |
718f9c0f | 76 | #include "diagnostic-core.h" |
aee46bbd | 77 | #include "debug.h" |
956623c1 | 78 | #include "tree-ssa.h" |
7290d709 | 79 | |
32ace6e2 AM |
80 | #ifdef ENABLE_CHECKING |
81 | static void verify_live_on_entry (tree_live_info_p); | |
82 | #endif | |
6de9cd9a | 83 | |
6de9cd9a | 84 | |
7290d709 AM |
85 | /* VARMAP maintains a mapping from SSA version number to real variables. |
86 | ||
87 | All SSA_NAMES are divided into partitions. Initially each ssa_name is the | |
88 | only member of it's own partition. Coalescing will attempt to group any | |
89 | ssa_names which occur in a copy or in a PHI node into the same partition. | |
90 | ||
91 | At the end of out-of-ssa, each partition becomes a "real" variable and is | |
92 | rewritten as a compiler variable. | |
93 | ||
fa10beec | 94 | The var_map data structure is used to manage these partitions. It allows |
7290d709 AM |
95 | partitions to be combined, and determines which partition belongs to what |
96 | ssa_name or variable, and vice versa. */ | |
97 | ||
98 | ||
4a8fb1a1 LC |
99 | /* Hashtable helpers. */ |
100 | ||
101 | struct tree_int_map_hasher : typed_noop_remove <tree_int_map> | |
102 | { | |
103 | typedef tree_int_map value_type; | |
104 | typedef tree_int_map compare_type; | |
105 | static inline hashval_t hash (const value_type *); | |
106 | static inline bool equal (const value_type *, const compare_type *); | |
107 | }; | |
108 | ||
109 | inline hashval_t | |
110 | tree_int_map_hasher::hash (const value_type *v) | |
111 | { | |
112 | return tree_map_base_hash (v); | |
113 | } | |
114 | ||
115 | inline bool | |
116 | tree_int_map_hasher::equal (const value_type *v, const compare_type *c) | |
117 | { | |
118 | return tree_int_map_eq (v, c); | |
119 | } | |
120 | ||
121 | ||
7290d709 AM |
122 | /* This routine will initialize the basevar fields of MAP. */ |
123 | ||
124 | static void | |
125 | var_map_base_init (var_map map) | |
126 | { | |
5f564b8f | 127 | int x, num_part; |
7290d709 | 128 | tree var; |
5f564b8f | 129 | struct tree_int_map *m, *mapstorage; |
b8698a0f | 130 | |
7290d709 | 131 | num_part = num_var_partitions (map); |
c203e8a7 | 132 | hash_table<tree_int_map_hasher> tree_to_index (num_part); |
5f564b8f MM |
133 | /* We can have at most num_part entries in the hash tables, so it's |
134 | enough to allocate so many map elements once, saving some malloc | |
135 | calls. */ | |
136 | mapstorage = m = XNEWVEC (struct tree_int_map, num_part); | |
7290d709 AM |
137 | |
138 | /* If a base table already exists, clear it, otherwise create it. */ | |
5f564b8f | 139 | free (map->partition_to_base_index); |
7290d709 AM |
140 | map->partition_to_base_index = (int *) xmalloc (sizeof (int) * num_part); |
141 | ||
142 | /* Build the base variable list, and point partitions at their bases. */ | |
143 | for (x = 0; x < num_part; x++) | |
144 | { | |
5f564b8f MM |
145 | struct tree_int_map **slot; |
146 | unsigned baseindex; | |
7290d709 | 147 | var = partition_to_var (map, x); |
a2544177 RB |
148 | if (SSA_NAME_VAR (var) |
149 | && (!VAR_P (SSA_NAME_VAR (var)) | |
150 | || !DECL_IGNORED_P (SSA_NAME_VAR (var)))) | |
70b5e7dc RG |
151 | m->base.from = SSA_NAME_VAR (var); |
152 | else | |
153 | /* This restricts what anonymous SSA names we can coalesce | |
154 | as it restricts the sets we compute conflicts for. | |
155 | Using TREE_TYPE to generate sets is the easies as | |
156 | type equivalency also holds for SSA names with the same | |
e91d0adb JL |
157 | underlying decl. |
158 | ||
159 | Check gimple_can_coalesce_p when changing this code. */ | |
160 | m->base.from = (TYPE_CANONICAL (TREE_TYPE (var)) | |
161 | ? TYPE_CANONICAL (TREE_TYPE (var)) | |
162 | : TREE_TYPE (var)); | |
7290d709 | 163 | /* If base variable hasn't been seen, set it up. */ |
4a8fb1a1 | 164 | slot = tree_to_index.find_slot (m, INSERT); |
5f564b8f MM |
165 | if (!*slot) |
166 | { | |
167 | baseindex = m - mapstorage; | |
168 | m->to = baseindex; | |
169 | *slot = m; | |
170 | m++; | |
7290d709 | 171 | } |
5f564b8f MM |
172 | else |
173 | baseindex = (*slot)->to; | |
174 | map->partition_to_base_index[x] = baseindex; | |
7290d709 AM |
175 | } |
176 | ||
5f564b8f | 177 | map->num_basevars = m - mapstorage; |
7290d709 | 178 | |
5f564b8f | 179 | free (mapstorage); |
7290d709 AM |
180 | } |
181 | ||
6de9cd9a | 182 | |
7290d709 | 183 | /* Remove the base table in MAP. */ |
6de9cd9a | 184 | |
7290d709 AM |
185 | static void |
186 | var_map_base_fini (var_map map) | |
187 | { | |
188 | /* Free the basevar info if it is present. */ | |
189 | if (map->partition_to_base_index != NULL) | |
190 | { | |
7290d709 AM |
191 | free (map->partition_to_base_index); |
192 | map->partition_to_base_index = NULL; | |
193 | map->num_basevars = 0; | |
194 | } | |
195 | } | |
6de9cd9a DN |
196 | /* Create a variable partition map of SIZE, initialize and return it. */ |
197 | ||
198 | var_map | |
199 | init_var_map (int size) | |
200 | { | |
201 | var_map map; | |
202 | ||
203 | map = (var_map) xmalloc (sizeof (struct _var_map)); | |
204 | map->var_partition = partition_new (size); | |
6de9cd9a | 205 | |
7290d709 AM |
206 | map->partition_to_view = NULL; |
207 | map->view_to_partition = NULL; | |
6de9cd9a DN |
208 | map->num_partitions = size; |
209 | map->partition_size = size; | |
7290d709 AM |
210 | map->num_basevars = 0; |
211 | map->partition_to_base_index = NULL; | |
6de9cd9a DN |
212 | return map; |
213 | } | |
214 | ||
215 | ||
216 | /* Free memory associated with MAP. */ | |
217 | ||
218 | void | |
219 | delete_var_map (var_map map) | |
220 | { | |
7290d709 | 221 | var_map_base_fini (map); |
6de9cd9a | 222 | partition_delete (map->var_partition); |
04695783 JM |
223 | free (map->partition_to_view); |
224 | free (map->view_to_partition); | |
6de9cd9a DN |
225 | free (map); |
226 | } | |
227 | ||
228 | ||
b8698a0f L |
229 | /* This function will combine the partitions in MAP for VAR1 and VAR2. It |
230 | Returns the partition which represents the new partition. If the two | |
9cf737f8 | 231 | partitions cannot be combined, NO_PARTITION is returned. */ |
6de9cd9a DN |
232 | |
233 | int | |
234 | var_union (var_map map, tree var1, tree var2) | |
235 | { | |
236 | int p1, p2, p3; | |
4e3825db MM |
237 | |
238 | gcc_assert (TREE_CODE (var1) == SSA_NAME); | |
239 | gcc_assert (TREE_CODE (var2) == SSA_NAME); | |
6de9cd9a | 240 | |
b8698a0f | 241 | /* This is independent of partition_to_view. If partition_to_view is |
6de9cd9a | 242 | on, then whichever one of these partitions is absorbed will never have a |
7290d709 | 243 | dereference into the partition_to_view array any more. */ |
6de9cd9a | 244 | |
4e3825db MM |
245 | p1 = partition_find (map->var_partition, SSA_NAME_VERSION (var1)); |
246 | p2 = partition_find (map->var_partition, SSA_NAME_VERSION (var2)); | |
6de9cd9a | 247 | |
1e128c5f GB |
248 | gcc_assert (p1 != NO_PARTITION); |
249 | gcc_assert (p2 != NO_PARTITION); | |
6de9cd9a DN |
250 | |
251 | if (p1 == p2) | |
252 | p3 = p1; | |
253 | else | |
254 | p3 = partition_union (map->var_partition, p1, p2); | |
255 | ||
7290d709 AM |
256 | if (map->partition_to_view) |
257 | p3 = map->partition_to_view[p3]; | |
6de9cd9a | 258 | |
6de9cd9a DN |
259 | return p3; |
260 | } | |
261 | ||
b8698a0f L |
262 | |
263 | /* Compress the partition numbers in MAP such that they fall in the range | |
6de9cd9a DN |
264 | 0..(num_partitions-1) instead of wherever they turned out during |
265 | the partitioning exercise. This removes any references to unused | |
266 | partitions, thereby allowing bitmaps and other vectors to be much | |
b8698a0f | 267 | denser. |
6de9cd9a DN |
268 | |
269 | This is implemented such that compaction doesn't affect partitioning. | |
270 | Ie., once partitions are created and possibly merged, running one | |
271 | or more different kind of compaction will not affect the partitions | |
272 | themselves. Their index might change, but all the same variables will | |
273 | still be members of the same partition group. This allows work on reduced | |
274 | sets, and no loss of information when a larger set is later desired. | |
275 | ||
276 | In particular, coalescing can work on partitions which have 2 or more | |
277 | definitions, and then 'recompact' later to include all the single | |
278 | definitions for assignment to program variables. */ | |
279 | ||
7290d709 | 280 | |
b8698a0f L |
281 | /* Set MAP back to the initial state of having no partition view. Return a |
282 | bitmap which has a bit set for each partition number which is in use in the | |
7290d709 AM |
283 | varmap. */ |
284 | ||
285 | static bitmap | |
286 | partition_view_init (var_map map) | |
6de9cd9a | 287 | { |
7290d709 AM |
288 | bitmap used; |
289 | int tmp; | |
290 | unsigned int x; | |
6de9cd9a | 291 | |
7290d709 | 292 | used = BITMAP_ALLOC (NULL); |
6de9cd9a | 293 | |
7290d709 AM |
294 | /* Already in a view? Abandon the old one. */ |
295 | if (map->partition_to_view) | |
6de9cd9a | 296 | { |
7290d709 AM |
297 | free (map->partition_to_view); |
298 | map->partition_to_view = NULL; | |
6de9cd9a | 299 | } |
7290d709 | 300 | if (map->view_to_partition) |
6de9cd9a | 301 | { |
7290d709 AM |
302 | free (map->view_to_partition); |
303 | map->view_to_partition = NULL; | |
6de9cd9a DN |
304 | } |
305 | ||
6de9cd9a | 306 | /* Find out which partitions are actually referenced. */ |
7290d709 | 307 | for (x = 0; x < map->partition_size; x++) |
6de9cd9a DN |
308 | { |
309 | tmp = partition_find (map->var_partition, x); | |
ea057359 | 310 | if (ssa_name (tmp) != NULL_TREE && !virtual_operand_p (ssa_name (tmp)) |
4e3825db MM |
311 | && (!has_zero_uses (ssa_name (tmp)) |
312 | || !SSA_NAME_IS_DEFAULT_DEF (ssa_name (tmp)))) | |
7290d709 | 313 | bitmap_set_bit (used, tmp); |
6de9cd9a DN |
314 | } |
315 | ||
7290d709 AM |
316 | map->num_partitions = map->partition_size; |
317 | return used; | |
318 | } | |
319 | ||
320 | ||
321 | /* This routine will finalize the view data for MAP based on the partitions | |
b8698a0f | 322 | set in SELECTED. This is either the same bitmap returned from |
7290d709 AM |
323 | partition_view_init, or a trimmed down version if some of those partitions |
324 | were not desired in this view. SELECTED is freed before returning. */ | |
325 | ||
b8698a0f | 326 | static void |
7290d709 AM |
327 | partition_view_fini (var_map map, bitmap selected) |
328 | { | |
329 | bitmap_iterator bi; | |
330 | unsigned count, i, x, limit; | |
7290d709 AM |
331 | |
332 | gcc_assert (selected); | |
333 | ||
334 | count = bitmap_count_bits (selected); | |
335 | limit = map->partition_size; | |
336 | ||
337 | /* If its a one-to-one ratio, we don't need any view compaction. */ | |
338 | if (count < limit) | |
6de9cd9a | 339 | { |
7290d709 AM |
340 | map->partition_to_view = (int *)xmalloc (limit * sizeof (int)); |
341 | memset (map->partition_to_view, 0xff, (limit * sizeof (int))); | |
342 | map->view_to_partition = (int *)xmalloc (count * sizeof (int)); | |
b6e7e9af | 343 | |
7290d709 AM |
344 | i = 0; |
345 | /* Give each selected partition an index. */ | |
346 | EXECUTE_IF_SET_IN_BITMAP (selected, 0, x, bi) | |
6de9cd9a | 347 | { |
7290d709 AM |
348 | map->partition_to_view[x] = i; |
349 | map->view_to_partition[i] = x; | |
7290d709 | 350 | i++; |
b6e7e9af | 351 | } |
7290d709 AM |
352 | gcc_assert (i == count); |
353 | map->num_partitions = i; | |
6de9cd9a | 354 | } |
7290d709 AM |
355 | |
356 | BITMAP_FREE (selected); | |
357 | } | |
358 | ||
359 | ||
b8698a0f | 360 | /* Create a partition view which includes all the used partitions in MAP. If |
7290d709 AM |
361 | WANT_BASES is true, create the base variable map as well. */ |
362 | ||
3f9b14ff | 363 | void |
7290d709 AM |
364 | partition_view_normal (var_map map, bool want_bases) |
365 | { | |
366 | bitmap used; | |
367 | ||
368 | used = partition_view_init (map); | |
369 | partition_view_fini (map, used); | |
370 | ||
371 | if (want_bases) | |
372 | var_map_base_init (map); | |
6de9cd9a | 373 | else |
7290d709 AM |
374 | var_map_base_fini (map); |
375 | } | |
376 | ||
377 | ||
b8698a0f L |
378 | /* Create a partition view in MAP which includes just partitions which occur in |
379 | the bitmap ONLY. If WANT_BASES is true, create the base variable map | |
7290d709 AM |
380 | as well. */ |
381 | ||
3f9b14ff | 382 | void |
7290d709 AM |
383 | partition_view_bitmap (var_map map, bitmap only, bool want_bases) |
384 | { | |
385 | bitmap used; | |
386 | bitmap new_partitions = BITMAP_ALLOC (NULL); | |
387 | unsigned x, p; | |
388 | bitmap_iterator bi; | |
389 | ||
390 | used = partition_view_init (map); | |
391 | EXECUTE_IF_SET_IN_BITMAP (only, 0, x, bi) | |
6de9cd9a | 392 | { |
7290d709 AM |
393 | p = partition_find (map->var_partition, x); |
394 | gcc_assert (bitmap_bit_p (used, p)); | |
395 | bitmap_set_bit (new_partitions, p); | |
6de9cd9a | 396 | } |
7290d709 | 397 | partition_view_fini (map, new_partitions); |
6de9cd9a | 398 | |
7290d709 AM |
399 | if (want_bases) |
400 | var_map_base_init (map); | |
401 | else | |
402 | var_map_base_fini (map); | |
6de9cd9a DN |
403 | } |
404 | ||
405 | ||
5f564b8f MM |
406 | static bitmap usedvars; |
407 | ||
329df070 MM |
408 | /* Mark VAR as used, so that it'll be preserved during rtl expansion. |
409 | Returns true if VAR wasn't marked before. */ | |
5f564b8f | 410 | |
329df070 | 411 | static inline bool |
5f564b8f MM |
412 | set_is_used (tree var) |
413 | { | |
329df070 | 414 | return bitmap_set_bit (usedvars, DECL_UID (var)); |
5f564b8f MM |
415 | } |
416 | ||
417 | /* Return true if VAR is marked as used. */ | |
418 | ||
419 | static inline bool | |
420 | is_used_p (tree var) | |
421 | { | |
422 | return bitmap_bit_p (usedvars, DECL_UID (var)); | |
423 | } | |
424 | ||
329df070 | 425 | static inline void mark_all_vars_used (tree *); |
6de9cd9a | 426 | |
727a31fa RH |
427 | /* Helper function for mark_all_vars_used, called via walk_tree. */ |
428 | ||
429 | static tree | |
329df070 | 430 | mark_all_vars_used_1 (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) |
727a31fa RH |
431 | { |
432 | tree t = *tp; | |
aee46bbd JH |
433 | enum tree_code_class c = TREE_CODE_CLASS (TREE_CODE (t)); |
434 | tree b; | |
727a31fa | 435 | |
3f519b35 | 436 | if (TREE_CODE (t) == SSA_NAME) |
70b5e7dc RG |
437 | { |
438 | *walk_subtrees = 0; | |
439 | t = SSA_NAME_VAR (t); | |
440 | if (!t) | |
441 | return NULL; | |
442 | } | |
726a989a RB |
443 | |
444 | if (IS_EXPR_CODE_CLASS (c) | |
aee46bbd JH |
445 | && (b = TREE_BLOCK (t)) != NULL) |
446 | TREE_USED (b) = true; | |
3f519b35 | 447 | |
4d948885 RG |
448 | /* Ignore TMR_OFFSET and TMR_STEP for TARGET_MEM_REFS, as those |
449 | fields do not contain vars. */ | |
89632019 ZD |
450 | if (TREE_CODE (t) == TARGET_MEM_REF) |
451 | { | |
329df070 MM |
452 | mark_all_vars_used (&TMR_BASE (t)); |
453 | mark_all_vars_used (&TMR_INDEX (t)); | |
454 | mark_all_vars_used (&TMR_INDEX2 (t)); | |
89632019 ZD |
455 | *walk_subtrees = 0; |
456 | return NULL; | |
457 | } | |
458 | ||
727a31fa RH |
459 | /* Only need to mark VAR_DECLS; parameters and return results are not |
460 | eliminated as unused. */ | |
461 | if (TREE_CODE (t) == VAR_DECL) | |
900461f3 | 462 | { |
329df070 MM |
463 | /* When a global var becomes used for the first time also walk its |
464 | initializer (non global ones don't have any). */ | |
32417082 RB |
465 | if (set_is_used (t) && is_global_var (t) |
466 | && DECL_CONTEXT (t) == current_function_decl) | |
329df070 | 467 | mark_all_vars_used (&DECL_INITIAL (t)); |
900461f3 | 468 | } |
ccf134c7 RG |
469 | /* remove_unused_scope_block_p requires information about labels |
470 | which are not DECL_IGNORED_P to tell if they might be used in the IL. */ | |
9c09f152 | 471 | else if (TREE_CODE (t) == LABEL_DECL) |
ccf134c7 RG |
472 | /* Although the TREE_USED values that the frontend uses would be |
473 | acceptable (albeit slightly over-conservative) for our purposes, | |
474 | init_vars_expansion clears TREE_USED for LABEL_DECLs too, so we | |
475 | must re-compute it here. */ | |
476 | TREE_USED (t) = 1; | |
727a31fa | 477 | |
6615c446 | 478 | if (IS_TYPE_OR_DECL_P (t)) |
727a31fa RH |
479 | *walk_subtrees = 0; |
480 | ||
481 | return NULL; | |
482 | } | |
483 | ||
aee46bbd JH |
484 | /* Mark the scope block SCOPE and its subblocks unused when they can be |
485 | possibly eliminated if dead. */ | |
486 | ||
487 | static void | |
488 | mark_scope_block_unused (tree scope) | |
489 | { | |
490 | tree t; | |
491 | TREE_USED (scope) = false; | |
492 | if (!(*debug_hooks->ignore_block) (scope)) | |
493 | TREE_USED (scope) = true; | |
494 | for (t = BLOCK_SUBBLOCKS (scope); t ; t = BLOCK_CHAIN (t)) | |
495 | mark_scope_block_unused (t); | |
496 | } | |
497 | ||
498 | /* Look if the block is dead (by possibly eliminating its dead subblocks) | |
b8698a0f | 499 | and return true if so. |
aee46bbd JH |
500 | Block is declared dead if: |
501 | 1) No statements are associated with it. | |
502 | 2) Declares no live variables | |
503 | 3) All subblocks are dead | |
504 | or there is precisely one subblocks and the block | |
505 | has same abstract origin as outer block and declares | |
506 | no variables, so it is pure wrapper. | |
cea618ac | 507 | When we are not outputting full debug info, we also eliminate dead variables |
aee46bbd JH |
508 | out of scope blocks to let them to be recycled by GGC and to save copying work |
509 | done by the inliner. */ | |
510 | ||
511 | static bool | |
329df070 | 512 | remove_unused_scope_block_p (tree scope) |
aee46bbd | 513 | { |
d1aed86b | 514 | tree *t, *next; |
aee46bbd | 515 | bool unused = !TREE_USED (scope); |
aee46bbd JH |
516 | int nsubblocks = 0; |
517 | ||
d1aed86b AO |
518 | for (t = &BLOCK_VARS (scope); *t; t = next) |
519 | { | |
910ad8de | 520 | next = &DECL_CHAIN (*t); |
d1aed86b AO |
521 | |
522 | /* Debug info of nested function refers to the block of the | |
61e04322 JH |
523 | function. We might stil call it even if all statements |
524 | of function it was nested into was elliminated. | |
b8698a0f | 525 | |
61e04322 JH |
526 | TODO: We can actually look into cgraph to see if function |
527 | will be output to file. */ | |
d1aed86b AO |
528 | if (TREE_CODE (*t) == FUNCTION_DECL) |
529 | unused = false; | |
2ce59df7 AO |
530 | |
531 | /* If a decl has a value expr, we need to instantiate it | |
532 | regardless of debug info generation, to avoid codegen | |
533 | differences in memory overlap tests. update_equiv_regs() may | |
534 | indirectly call validate_equiv_mem() to test whether a | |
535 | SET_DEST overlaps with others, and if the value expr changes | |
536 | by virtual register instantiation, we may get end up with | |
537 | different results. */ | |
538 | else if (TREE_CODE (*t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (*t)) | |
539 | unused = false; | |
540 | ||
a300e459 EB |
541 | /* Remove everything we don't generate debug info for. */ |
542 | else if (DECL_IGNORED_P (*t)) | |
b91bc349 | 543 | { |
910ad8de | 544 | *t = DECL_CHAIN (*t); |
b91bc349 JH |
545 | next = t; |
546 | } | |
547 | ||
d1aed86b AO |
548 | /* When we are outputting debug info, we usually want to output |
549 | info about optimized-out variables in the scope blocks. | |
550 | Exception are the scope blocks not containing any instructions | |
551 | at all so user can't get into the scopes at first place. */ | |
329df070 | 552 | else if (is_used_p (*t)) |
d1aed86b | 553 | unused = false; |
ccf134c7 RG |
554 | else if (TREE_CODE (*t) == LABEL_DECL && TREE_USED (*t)) |
555 | /* For labels that are still used in the IL, the decision to | |
556 | preserve them must not depend DEBUG_INFO_LEVEL, otherwise we | |
557 | risk having different ordering in debug vs. non-debug builds | |
558 | during inlining or versioning. | |
559 | A label appearing here (we have already checked DECL_IGNORED_P) | |
560 | should not be used in the IL unless it has been explicitly used | |
561 | before, so we use TREE_USED as an approximation. */ | |
562 | /* In principle, we should do the same here as for the debug case | |
563 | below, however, when debugging, there might be additional nested | |
564 | levels that keep an upper level with a label live, so we have to | |
565 | force this block to be considered used, too. */ | |
566 | unused = false; | |
d1aed86b AO |
567 | |
568 | /* When we are not doing full debug info, we however can keep around | |
569 | only the used variables for cfgexpand's memory packing saving quite | |
b8698a0f | 570 | a lot of memory. |
61e04322 JH |
571 | |
572 | For sake of -g3, we keep around those vars but we don't count this as | |
573 | use of block, so innermost block with no used vars and no instructions | |
574 | can be considered dead. We only want to keep around blocks user can | |
b8698a0f | 575 | breakpoint into and ask about value of optimized out variables. |
61e04322 | 576 | |
427f6cec AO |
577 | Similarly we need to keep around types at least until all |
578 | variables of all nested blocks are gone. We track no | |
579 | information on whether given type is used or not, so we have | |
580 | to keep them even when not emitting debug information, | |
581 | otherwise we may end up remapping variables and their (local) | |
582 | types in different orders depending on whether debug | |
583 | information is being generated. */ | |
584 | ||
585 | else if (TREE_CODE (*t) == TYPE_DECL | |
586 | || debug_info_level == DINFO_LEVEL_NORMAL | |
c7ba0cfb | 587 | || debug_info_level == DINFO_LEVEL_VERBOSE) |
61e04322 | 588 | ; |
3c8da8a5 | 589 | else |
d1aed86b | 590 | { |
910ad8de | 591 | *t = DECL_CHAIN (*t); |
d1aed86b AO |
592 | next = t; |
593 | } | |
594 | } | |
595 | ||
aee46bbd | 596 | for (t = &BLOCK_SUBBLOCKS (scope); *t ;) |
329df070 | 597 | if (remove_unused_scope_block_p (*t)) |
aee46bbd JH |
598 | { |
599 | if (BLOCK_SUBBLOCKS (*t)) | |
600 | { | |
601 | tree next = BLOCK_CHAIN (*t); | |
602 | tree supercontext = BLOCK_SUPERCONTEXT (*t); | |
cff7525f | 603 | |
aee46bbd | 604 | *t = BLOCK_SUBBLOCKS (*t); |
cff7525f JH |
605 | while (BLOCK_CHAIN (*t)) |
606 | { | |
607 | BLOCK_SUPERCONTEXT (*t) = supercontext; | |
608 | t = &BLOCK_CHAIN (*t); | |
609 | } | |
aee46bbd JH |
610 | BLOCK_CHAIN (*t) = next; |
611 | BLOCK_SUPERCONTEXT (*t) = supercontext; | |
612 | t = &BLOCK_CHAIN (*t); | |
613 | nsubblocks ++; | |
614 | } | |
615 | else | |
61e04322 | 616 | *t = BLOCK_CHAIN (*t); |
aee46bbd JH |
617 | } |
618 | else | |
619 | { | |
620 | t = &BLOCK_CHAIN (*t); | |
621 | nsubblocks ++; | |
622 | } | |
cff7525f JH |
623 | |
624 | ||
625 | if (!unused) | |
626 | ; | |
aee46bbd | 627 | /* Outer scope is always used. */ |
cff7525f JH |
628 | else if (!BLOCK_SUPERCONTEXT (scope) |
629 | || TREE_CODE (BLOCK_SUPERCONTEXT (scope)) == FUNCTION_DECL) | |
aee46bbd | 630 | unused = false; |
cff7525f JH |
631 | /* Innermost blocks with no live variables nor statements can be always |
632 | eliminated. */ | |
633 | else if (!nsubblocks) | |
634 | ; | |
51b83fdd CC |
635 | /* When not generating debug info we can eliminate info on unused |
636 | variables. */ | |
be3c16c4 | 637 | else if (!flag_auto_profile && debug_info_level == DINFO_LEVEL_NONE) |
9f706f23 | 638 | { |
51b83fdd | 639 | /* Even for -g0 don't prune outer scopes from artificial |
9f706f23 JJ |
640 | functions, otherwise diagnostics using tree_nonartificial_location |
641 | will not be emitted properly. */ | |
642 | if (inlined_function_outer_scope_p (scope)) | |
643 | { | |
644 | tree ao = scope; | |
645 | ||
646 | while (ao | |
647 | && TREE_CODE (ao) == BLOCK | |
648 | && BLOCK_ABSTRACT_ORIGIN (ao) != ao) | |
649 | ao = BLOCK_ABSTRACT_ORIGIN (ao); | |
650 | if (ao | |
651 | && TREE_CODE (ao) == FUNCTION_DECL | |
652 | && DECL_DECLARED_INLINE_P (ao) | |
653 | && lookup_attribute ("artificial", DECL_ATTRIBUTES (ao))) | |
654 | unused = false; | |
655 | } | |
656 | } | |
526d73ab | 657 | else if (BLOCK_VARS (scope) || BLOCK_NUM_NONLOCALIZED_VARS (scope)) |
aee46bbd | 658 | unused = false; |
cff7525f JH |
659 | /* See if this block is important for representation of inlined function. |
660 | Inlined functions are always represented by block with | |
661 | block_ultimate_origin being set to FUNCTION_DECL and DECL_SOURCE_LOCATION | |
662 | set... */ | |
663 | else if (inlined_function_outer_scope_p (scope)) | |
664 | unused = false; | |
665 | else | |
666 | /* Verfify that only blocks with source location set | |
667 | are entry points to the inlined functions. */ | |
2f13f2de DC |
668 | gcc_assert (LOCATION_LOCUS (BLOCK_SOURCE_LOCATION (scope)) |
669 | == UNKNOWN_LOCATION); | |
5b4c43d7 EB |
670 | |
671 | TREE_USED (scope) = !unused; | |
aee46bbd JH |
672 | return unused; |
673 | } | |
7290d709 | 674 | |
b8698a0f | 675 | /* Mark all VAR_DECLS under *EXPR_P as used, so that they won't be |
727a31fa RH |
676 | eliminated during the tree->rtl conversion process. */ |
677 | ||
678 | static inline void | |
329df070 | 679 | mark_all_vars_used (tree *expr_p) |
727a31fa | 680 | { |
329df070 | 681 | walk_tree (expr_p, mark_all_vars_used_1, NULL, NULL); |
727a31fa RH |
682 | } |
683 | ||
5368224f DC |
684 | /* Helper function for clear_unused_block_pointer, called via walk_tree. */ |
685 | ||
686 | static tree | |
687 | clear_unused_block_pointer_1 (tree *tp, int *, void *) | |
688 | { | |
689 | if (EXPR_P (*tp) && TREE_BLOCK (*tp) | |
690 | && !TREE_USED (TREE_BLOCK (*tp))) | |
691 | TREE_SET_BLOCK (*tp, NULL); | |
5368224f DC |
692 | return NULL_TREE; |
693 | } | |
694 | ||
5d751b0c JJ |
695 | /* Set all block pointer in debug or clobber stmt to NULL if the block |
696 | is unused, so that they will not be streamed out. */ | |
5368224f DC |
697 | |
698 | static void | |
6040bb5f | 699 | clear_unused_block_pointer (void) |
5368224f DC |
700 | { |
701 | basic_block bb; | |
702 | gimple_stmt_iterator gsi; | |
28957eab | 703 | |
11cd3bed | 704 | FOR_EACH_BB_FN (bb, cfun) |
5368224f DC |
705 | for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) |
706 | { | |
707 | unsigned i; | |
708 | tree b; | |
709 | gimple stmt = gsi_stmt (gsi); | |
710 | ||
5d751b0c | 711 | if (!is_gimple_debug (stmt) && !gimple_clobber_p (stmt)) |
5368224f DC |
712 | continue; |
713 | b = gimple_block (stmt); | |
714 | if (b && !TREE_USED (b)) | |
715 | gimple_set_block (stmt, NULL); | |
716 | for (i = 0; i < gimple_num_ops (stmt); i++) | |
717 | walk_tree (gimple_op_ptr (stmt, i), clear_unused_block_pointer_1, | |
718 | NULL, NULL); | |
719 | } | |
720 | } | |
ac80ba07 DN |
721 | |
722 | /* Dump scope blocks starting at SCOPE to FILE. INDENT is the | |
723 | indentation level and FLAGS is as in print_generic_expr. */ | |
61e04322 JH |
724 | |
725 | static void | |
726 | dump_scope_block (FILE *file, int indent, tree scope, int flags) | |
727 | { | |
728 | tree var, t; | |
526d73ab | 729 | unsigned int i; |
61e04322 | 730 | |
cff7525f JH |
731 | fprintf (file, "\n%*s{ Scope block #%i%s%s",indent, "" , BLOCK_NUMBER (scope), |
732 | TREE_USED (scope) ? "" : " (unused)", | |
733 | BLOCK_ABSTRACT (scope) ? " (abstract)": ""); | |
2f13f2de | 734 | if (LOCATION_LOCUS (BLOCK_SOURCE_LOCATION (scope)) != UNKNOWN_LOCATION) |
cff7525f JH |
735 | { |
736 | expanded_location s = expand_location (BLOCK_SOURCE_LOCATION (scope)); | |
737 | fprintf (file, " %s:%i", s.file, s.line); | |
738 | } | |
739 | if (BLOCK_ABSTRACT_ORIGIN (scope)) | |
61e04322 | 740 | { |
cff7525f JH |
741 | tree origin = block_ultimate_origin (scope); |
742 | if (origin) | |
743 | { | |
744 | fprintf (file, " Originating from :"); | |
745 | if (DECL_P (origin)) | |
746 | print_generic_decl (file, origin, flags); | |
747 | else | |
748 | fprintf (file, "#%i", BLOCK_NUMBER (origin)); | |
749 | } | |
61e04322 | 750 | } |
cff7525f | 751 | fprintf (file, " \n"); |
910ad8de | 752 | for (var = BLOCK_VARS (scope); var; var = DECL_CHAIN (var)) |
61e04322 | 753 | { |
83d70792 | 754 | fprintf (file, "%*s", indent, ""); |
61e04322 | 755 | print_generic_decl (file, var, flags); |
5f564b8f | 756 | fprintf (file, "\n"); |
61e04322 | 757 | } |
526d73ab JH |
758 | for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (scope); i++) |
759 | { | |
760 | fprintf (file, "%*s",indent, ""); | |
761 | print_generic_decl (file, BLOCK_NONLOCALIZED_VAR (scope, i), | |
762 | flags); | |
763 | fprintf (file, " (nonlocalized)\n"); | |
764 | } | |
61e04322 JH |
765 | for (t = BLOCK_SUBBLOCKS (scope); t ; t = BLOCK_CHAIN (t)) |
766 | dump_scope_block (file, indent + 2, t, flags); | |
cff7525f | 767 | fprintf (file, "\n%*s}\n",indent, ""); |
61e04322 JH |
768 | } |
769 | ||
c6a21142 RG |
770 | /* Dump the tree of lexical scopes starting at SCOPE to stderr. FLAGS |
771 | is as in print_generic_expr. */ | |
772 | ||
24e47c76 | 773 | DEBUG_FUNCTION void |
c6a21142 RG |
774 | debug_scope_block (tree scope, int flags) |
775 | { | |
776 | dump_scope_block (stderr, 0, scope, flags); | |
777 | } | |
778 | ||
ac80ba07 DN |
779 | |
780 | /* Dump the tree of lexical scopes of current_function_decl to FILE. | |
781 | FLAGS is as in print_generic_expr. */ | |
782 | ||
cff7525f JH |
783 | void |
784 | dump_scope_blocks (FILE *file, int flags) | |
785 | { | |
786 | dump_scope_block (file, 0, DECL_INITIAL (current_function_decl), flags); | |
787 | } | |
3f519b35 | 788 | |
ac80ba07 DN |
789 | |
790 | /* Dump the tree of lexical scopes of current_function_decl to stderr. | |
791 | FLAGS is as in print_generic_expr. */ | |
792 | ||
24e47c76 | 793 | DEBUG_FUNCTION void |
ac80ba07 DN |
794 | debug_scope_blocks (int flags) |
795 | { | |
796 | dump_scope_blocks (stderr, flags); | |
797 | } | |
798 | ||
3f519b35 RG |
799 | /* Remove local variables that are not referenced in the IL. */ |
800 | ||
801 | void | |
802 | remove_unused_locals (void) | |
803 | { | |
804 | basic_block bb; | |
46eb666a | 805 | tree var; |
329df070 | 806 | unsigned srcidx, dstidx, num; |
47598145 | 807 | bool have_local_clobbers = false; |
3f519b35 | 808 | |
89fbbe4e AO |
809 | /* Removing declarations from lexical blocks when not optimizing is |
810 | not only a waste of time, it actually causes differences in stack | |
811 | layout. */ | |
812 | if (!optimize) | |
813 | return; | |
814 | ||
a222c01a MM |
815 | timevar_push (TV_REMOVE_UNUSED); |
816 | ||
61e04322 | 817 | mark_scope_block_unused (DECL_INITIAL (current_function_decl)); |
726a989a | 818 | |
5f564b8f | 819 | usedvars = BITMAP_ALLOC (NULL); |
3f519b35 RG |
820 | |
821 | /* Walk the CFG marking all referenced symbols. */ | |
11cd3bed | 822 | FOR_EACH_BB_FN (bb, cfun) |
3f519b35 | 823 | { |
726a989a RB |
824 | gimple_stmt_iterator gsi; |
825 | size_t i; | |
cc2a64dd JJ |
826 | edge_iterator ei; |
827 | edge e; | |
3f519b35 RG |
828 | |
829 | /* Walk the statements. */ | |
726a989a RB |
830 | for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) |
831 | { | |
832 | gimple stmt = gsi_stmt (gsi); | |
833 | tree b = gimple_block (stmt); | |
834 | ||
b5b8b0ac AO |
835 | if (is_gimple_debug (stmt)) |
836 | continue; | |
837 | ||
47598145 MM |
838 | if (gimple_clobber_p (stmt)) |
839 | { | |
840 | have_local_clobbers = true; | |
841 | continue; | |
842 | } | |
843 | ||
726a989a RB |
844 | if (b) |
845 | TREE_USED (b) = true; | |
3f519b35 | 846 | |
726a989a | 847 | for (i = 0; i < gimple_num_ops (stmt); i++) |
329df070 | 848 | mark_all_vars_used (gimple_op_ptr (gsi_stmt (gsi), i)); |
726a989a RB |
849 | } |
850 | ||
538dd0b7 DM |
851 | for (gphi_iterator gpi = gsi_start_phis (bb); |
852 | !gsi_end_p (gpi); | |
853 | gsi_next (&gpi)) | |
3f519b35 RG |
854 | { |
855 | use_operand_p arg_p; | |
856 | ssa_op_iter i; | |
726a989a | 857 | tree def; |
538dd0b7 | 858 | gphi *phi = gpi.phi (); |
3f519b35 | 859 | |
ea057359 | 860 | if (virtual_operand_p (gimple_phi_result (phi))) |
3f519b35 RG |
861 | continue; |
862 | ||
726a989a | 863 | def = gimple_phi_result (phi); |
329df070 | 864 | mark_all_vars_used (&def); |
3f519b35 RG |
865 | |
866 | FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_ALL_USES) | |
867 | { | |
868 | tree arg = USE_FROM_PTR (arg_p); | |
5368224f DC |
869 | int index = PHI_ARG_INDEX_FROM_USE (arg_p); |
870 | tree block = | |
871 | LOCATION_BLOCK (gimple_phi_arg_location (phi, index)); | |
872 | if (block != NULL) | |
873 | TREE_USED (block) = true; | |
329df070 | 874 | mark_all_vars_used (&arg); |
3f519b35 RG |
875 | } |
876 | } | |
cc2a64dd JJ |
877 | |
878 | FOR_EACH_EDGE (e, ei, bb->succs) | |
6040bb5f | 879 | if (LOCATION_BLOCK (e->goto_locus) != NULL) |
5368224f | 880 | TREE_USED (LOCATION_BLOCK (e->goto_locus)) = true; |
3f519b35 RG |
881 | } |
882 | ||
47598145 MM |
883 | /* We do a two-pass approach about the out-of-scope clobbers. We want |
884 | to remove them if they are the only references to a local variable, | |
885 | but we want to retain them when there's any other. So the first pass | |
886 | ignores them, and the second pass (if there were any) tries to remove | |
887 | them. */ | |
888 | if (have_local_clobbers) | |
11cd3bed | 889 | FOR_EACH_BB_FN (bb, cfun) |
47598145 MM |
890 | { |
891 | gimple_stmt_iterator gsi; | |
892 | ||
893 | for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);) | |
894 | { | |
895 | gimple stmt = gsi_stmt (gsi); | |
896 | tree b = gimple_block (stmt); | |
897 | ||
898 | if (gimple_clobber_p (stmt)) | |
899 | { | |
900 | tree lhs = gimple_assign_lhs (stmt); | |
5d751b0c JJ |
901 | tree base = get_base_address (lhs); |
902 | /* Remove clobbers referencing unused vars, or clobbers | |
903 | with MEM_REF lhs referencing uninitialized pointers. */ | |
904 | if ((TREE_CODE (base) == VAR_DECL && !is_used_p (base)) | |
905 | || (TREE_CODE (lhs) == MEM_REF | |
906 | && TREE_CODE (TREE_OPERAND (lhs, 0)) == SSA_NAME | |
907 | && SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (lhs, 0)) | |
908 | && (TREE_CODE (SSA_NAME_VAR (TREE_OPERAND (lhs, 0))) | |
909 | != PARM_DECL))) | |
47598145 MM |
910 | { |
911 | unlink_stmt_vdef (stmt); | |
912 | gsi_remove (&gsi, true); | |
913 | release_defs (stmt); | |
914 | continue; | |
915 | } | |
916 | if (b) | |
917 | TREE_USED (b) = true; | |
918 | } | |
919 | gsi_next (&gsi); | |
920 | } | |
921 | } | |
922 | ||
fc3103e7 JJ |
923 | cfun->has_local_explicit_reg_vars = false; |
924 | ||
329df070 | 925 | /* Remove unmarked local and global vars from local_decls. */ |
9771b263 | 926 | num = vec_safe_length (cfun->local_decls); |
2fed2012 | 927 | for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++) |
3f519b35 | 928 | { |
9771b263 | 929 | var = (*cfun->local_decls)[srcidx]; |
9c09f152 | 930 | if (TREE_CODE (var) == VAR_DECL) |
3f519b35 | 931 | { |
329df070 | 932 | if (!is_used_p (var)) |
9c09f152 | 933 | { |
01c59d23 | 934 | tree def; |
ca5f4331 MM |
935 | if (cfun->nonlocal_goto_save_area |
936 | && TREE_OPERAND (cfun->nonlocal_goto_save_area, 0) == var) | |
937 | cfun->nonlocal_goto_save_area = NULL; | |
01c59d23 RG |
938 | /* Release any default def associated with var. */ |
939 | if ((def = ssa_default_def (cfun, var)) != NULL_TREE) | |
940 | { | |
941 | set_ssa_default_def (cfun, var, NULL_TREE); | |
942 | release_ssa_name (def); | |
943 | } | |
9c09f152 | 944 | continue; |
900461f3 | 945 | } |
3f519b35 | 946 | } |
9c09f152 RB |
947 | if (TREE_CODE (var) == VAR_DECL |
948 | && DECL_HARD_REGISTER (var) | |
949 | && !is_global_var (var)) | |
fc3103e7 | 950 | cfun->has_local_explicit_reg_vars = true; |
c021f10b | 951 | |
2fed2012 | 952 | if (srcidx != dstidx) |
9771b263 | 953 | (*cfun->local_decls)[dstidx] = var; |
2fed2012 | 954 | dstidx++; |
3f519b35 | 955 | } |
2fed2012 | 956 | if (dstidx != num) |
c0e50f72 RB |
957 | { |
958 | statistics_counter_event (cfun, "unused VAR_DECLs removed", num - dstidx); | |
959 | cfun->local_decls->truncate (dstidx); | |
960 | } | |
1431ce01 | 961 | |
329df070 | 962 | remove_unused_scope_block_p (DECL_INITIAL (current_function_decl)); |
5368224f | 963 | clear_unused_block_pointer (); |
1431ce01 | 964 | |
5f564b8f | 965 | BITMAP_FREE (usedvars); |
326648f1 | 966 | |
61e04322 JH |
967 | if (dump_file && (dump_flags & TDF_DETAILS)) |
968 | { | |
969 | fprintf (dump_file, "Scope blocks after cleanups:\n"); | |
cff7525f | 970 | dump_scope_blocks (dump_file, dump_flags); |
61e04322 | 971 | } |
a222c01a MM |
972 | |
973 | timevar_pop (TV_REMOVE_UNUSED); | |
3f519b35 RG |
974 | } |
975 | ||
3f9b14ff SB |
976 | /* Obstack for globale liveness info bitmaps. We don't want to put these |
977 | on the default obstack because these bitmaps can grow quite large and | |
978 | we'll hold on to all that memory until the end of the compiler run. | |
979 | As a bonus, delete_tree_live_info can destroy all the bitmaps by just | |
980 | releasing the whole obstack. */ | |
981 | static bitmap_obstack liveness_bitmap_obstack; | |
6de9cd9a DN |
982 | |
983 | /* Allocate and return a new live range information object base on MAP. */ | |
984 | ||
985 | static tree_live_info_p | |
986 | new_tree_live_info (var_map map) | |
987 | { | |
988 | tree_live_info_p live; | |
3f9b14ff | 989 | basic_block bb; |
6de9cd9a | 990 | |
3f9b14ff | 991 | live = XNEW (struct tree_live_info_d); |
6de9cd9a | 992 | live->map = map; |
8b1c6fd7 | 993 | live->num_blocks = last_basic_block_for_fn (cfun); |
6de9cd9a | 994 | |
8b1c6fd7 | 995 | live->livein = XNEWVEC (bitmap_head, last_basic_block_for_fn (cfun)); |
11cd3bed | 996 | FOR_EACH_BB_FN (bb, cfun) |
3f9b14ff | 997 | bitmap_initialize (&live->livein[bb->index], &liveness_bitmap_obstack); |
6de9cd9a | 998 | |
8b1c6fd7 | 999 | live->liveout = XNEWVEC (bitmap_head, last_basic_block_for_fn (cfun)); |
11cd3bed | 1000 | FOR_EACH_BB_FN (bb, cfun) |
3f9b14ff | 1001 | bitmap_initialize (&live->liveout[bb->index], &liveness_bitmap_obstack); |
32ace6e2 | 1002 | |
8b1c6fd7 | 1003 | live->work_stack = XNEWVEC (int, last_basic_block_for_fn (cfun)); |
32ace6e2 AM |
1004 | live->stack_top = live->work_stack; |
1005 | ||
3f9b14ff | 1006 | live->global = BITMAP_ALLOC (&liveness_bitmap_obstack); |
6de9cd9a DN |
1007 | return live; |
1008 | } | |
1009 | ||
1010 | ||
1011 | /* Free storage for live range info object LIVE. */ | |
1012 | ||
b8698a0f | 1013 | void |
6de9cd9a DN |
1014 | delete_tree_live_info (tree_live_info_p live) |
1015 | { | |
3f9b14ff | 1016 | bitmap_obstack_release (&liveness_bitmap_obstack); |
32ace6e2 | 1017 | free (live->work_stack); |
32ace6e2 | 1018 | free (live->liveout); |
32ace6e2 | 1019 | free (live->livein); |
32ace6e2 | 1020 | free (live); |
6de9cd9a DN |
1021 | } |
1022 | ||
1023 | ||
b8698a0f L |
1024 | /* Visit basic block BB and propagate any required live on entry bits from |
1025 | LIVE into the predecessors. VISITED is the bitmap of visited blocks. | |
2e226e66 | 1026 | TMP is a temporary work bitmap which is passed in to avoid reallocating |
32ace6e2 | 1027 | it each time. */ |
6de9cd9a | 1028 | |
b8698a0f | 1029 | static void |
32ace6e2 AM |
1030 | loe_visit_block (tree_live_info_p live, basic_block bb, sbitmap visited, |
1031 | bitmap tmp) | |
6de9cd9a | 1032 | { |
32ace6e2 AM |
1033 | edge e; |
1034 | bool change; | |
1035 | edge_iterator ei; | |
1036 | basic_block pred_bb; | |
1037 | bitmap loe; | |
6de9cd9a | 1038 | |
a2544177 | 1039 | gcc_checking_assert (!bitmap_bit_p (visited, bb->index)); |
d7c028c0 | 1040 | bitmap_set_bit (visited, bb->index); |
a2544177 | 1041 | |
32ace6e2 | 1042 | loe = live_on_entry (live, bb); |
6de9cd9a | 1043 | |
32ace6e2 | 1044 | FOR_EACH_EDGE (e, ei, bb->preds) |
6de9cd9a | 1045 | { |
32ace6e2 | 1046 | pred_bb = e->src; |
fefa31b5 | 1047 | if (pred_bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)) |
32ace6e2 | 1048 | continue; |
7290d709 | 1049 | /* TMP is variables live-on-entry from BB that aren't defined in the |
b8698a0f | 1050 | predecessor block. This should be the live on entry vars to pred. |
32ace6e2 AM |
1051 | Note that liveout is the DEFs in a block while live on entry is |
1052 | being calculated. */ | |
3f9b14ff | 1053 | bitmap_and_compl (tmp, loe, &live->liveout[pred_bb->index]); |
32ace6e2 | 1054 | |
b8698a0f | 1055 | /* Add these bits to live-on-entry for the pred. if there are any |
32ace6e2 AM |
1056 | changes, and pred_bb has been visited already, add it to the |
1057 | revisit stack. */ | |
1058 | change = bitmap_ior_into (live_on_entry (live, pred_bb), tmp); | |
d7c028c0 | 1059 | if (bitmap_bit_p (visited, pred_bb->index) && change) |
32ace6e2 | 1060 | { |
d7c028c0 | 1061 | bitmap_clear_bit (visited, pred_bb->index); |
32ace6e2 AM |
1062 | *(live->stack_top)++ = pred_bb->index; |
1063 | } | |
6de9cd9a DN |
1064 | } |
1065 | } | |
1066 | ||
1067 | ||
b8698a0f | 1068 | /* Using LIVE, fill in all the live-on-entry blocks between the defs and uses |
2e226e66 | 1069 | of all the variables. */ |
6de9cd9a | 1070 | |
32ace6e2 AM |
1071 | static void |
1072 | live_worklist (tree_live_info_p live) | |
6de9cd9a | 1073 | { |
32ace6e2 | 1074 | unsigned b; |
6de9cd9a | 1075 | basic_block bb; |
8b1c6fd7 | 1076 | sbitmap visited = sbitmap_alloc (last_basic_block_for_fn (cfun) + 1); |
3f9b14ff | 1077 | bitmap tmp = BITMAP_ALLOC (&liveness_bitmap_obstack); |
6de9cd9a | 1078 | |
f61e445a | 1079 | bitmap_clear (visited); |
6de9cd9a | 1080 | |
110abdbc | 1081 | /* Visit all the blocks in reverse order and propagate live on entry values |
32ace6e2 | 1082 | into the predecessors blocks. */ |
4f42035e | 1083 | FOR_EACH_BB_REVERSE_FN (bb, cfun) |
32ace6e2 | 1084 | loe_visit_block (live, bb, visited, tmp); |
6de9cd9a | 1085 | |
32ace6e2 AM |
1086 | /* Process any blocks which require further iteration. */ |
1087 | while (live->stack_top != live->work_stack) | |
6de9cd9a | 1088 | { |
32ace6e2 | 1089 | b = *--(live->stack_top); |
06e28de2 | 1090 | loe_visit_block (live, BASIC_BLOCK_FOR_FN (cfun, b), visited, tmp); |
32ace6e2 | 1091 | } |
6de9cd9a | 1092 | |
32ace6e2 AM |
1093 | BITMAP_FREE (tmp); |
1094 | sbitmap_free (visited); | |
1095 | } | |
6de9cd9a | 1096 | |
6de9cd9a | 1097 | |
2e226e66 | 1098 | /* Calculate the initial live on entry vector for SSA_NAME using immediate_use |
32ace6e2 AM |
1099 | links. Set the live on entry fields in LIVE. Def's are marked temporarily |
1100 | in the liveout vector. */ | |
6de9cd9a | 1101 | |
32ace6e2 AM |
1102 | static void |
1103 | set_var_live_on_entry (tree ssa_name, tree_live_info_p live) | |
1104 | { | |
1105 | int p; | |
726a989a | 1106 | gimple stmt; |
32ace6e2 AM |
1107 | use_operand_p use; |
1108 | basic_block def_bb = NULL; | |
1109 | imm_use_iterator imm_iter; | |
1110 | bool global = false; | |
6de9cd9a | 1111 | |
32ace6e2 AM |
1112 | p = var_to_partition (live->map, ssa_name); |
1113 | if (p == NO_PARTITION) | |
1114 | return; | |
6de9cd9a | 1115 | |
32ace6e2 AM |
1116 | stmt = SSA_NAME_DEF_STMT (ssa_name); |
1117 | if (stmt) | |
6de9cd9a | 1118 | { |
726a989a | 1119 | def_bb = gimple_bb (stmt); |
7290d709 | 1120 | /* Mark defs in liveout bitmap temporarily. */ |
32ace6e2 | 1121 | if (def_bb) |
3f9b14ff | 1122 | bitmap_set_bit (&live->liveout[def_bb->index], p); |
87c476a2 | 1123 | } |
32ace6e2 | 1124 | else |
fefa31b5 | 1125 | def_bb = ENTRY_BLOCK_PTR_FOR_FN (cfun); |
6de9cd9a | 1126 | |
956623c1 MG |
1127 | /* An undefined local variable does not need to be very alive. */ |
1128 | if (ssa_undefined_value_p (ssa_name, false)) | |
1129 | return; | |
1130 | ||
32ace6e2 AM |
1131 | /* Visit each use of SSA_NAME and if it isn't in the same block as the def, |
1132 | add it to the list of live on entry blocks. */ | |
1133 | FOR_EACH_IMM_USE_FAST (use, imm_iter, ssa_name) | |
6de9cd9a | 1134 | { |
726a989a | 1135 | gimple use_stmt = USE_STMT (use); |
32ace6e2 | 1136 | basic_block add_block = NULL; |
6de9cd9a | 1137 | |
726a989a | 1138 | if (gimple_code (use_stmt) == GIMPLE_PHI) |
32ace6e2 AM |
1139 | { |
1140 | /* Uses in PHI's are considered to be live at exit of the SRC block | |
1141 | as this is where a copy would be inserted. Check to see if it is | |
1142 | defined in that block, or whether its live on entry. */ | |
1143 | int index = PHI_ARG_INDEX_FROM_USE (use); | |
538dd0b7 | 1144 | edge e = gimple_phi_arg_edge (as_a <gphi *> (use_stmt), index); |
fefa31b5 | 1145 | if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun)) |
6de9cd9a | 1146 | { |
32ace6e2 AM |
1147 | if (e->src != def_bb) |
1148 | add_block = e->src; | |
6de9cd9a | 1149 | } |
32ace6e2 | 1150 | } |
b5b8b0ac AO |
1151 | else if (is_gimple_debug (use_stmt)) |
1152 | continue; | |
32ace6e2 AM |
1153 | else |
1154 | { | |
1155 | /* If its not defined in this block, its live on entry. */ | |
726a989a | 1156 | basic_block use_bb = gimple_bb (use_stmt); |
32ace6e2 AM |
1157 | if (use_bb != def_bb) |
1158 | add_block = use_bb; | |
b8698a0f | 1159 | } |
32ace6e2 AM |
1160 | |
1161 | /* If there was a live on entry use, set the bit. */ | |
1162 | if (add_block) | |
1163 | { | |
1164 | global = true; | |
3f9b14ff | 1165 | bitmap_set_bit (&live->livein[add_block->index], p); |
6de9cd9a DN |
1166 | } |
1167 | } | |
6de9cd9a | 1168 | |
32ace6e2 AM |
1169 | /* If SSA_NAME is live on entry to at least one block, fill in all the live |
1170 | on entry blocks between the def and all the uses. */ | |
1171 | if (global) | |
1172 | bitmap_set_bit (live->global, p); | |
6de9cd9a DN |
1173 | } |
1174 | ||
1175 | ||
1176 | /* Calculate the live on exit vectors based on the entry info in LIVEINFO. */ | |
1177 | ||
1178 | void | |
1179 | calculate_live_on_exit (tree_live_info_p liveinfo) | |
1180 | { | |
6de9cd9a DN |
1181 | basic_block bb; |
1182 | edge e; | |
32ace6e2 | 1183 | edge_iterator ei; |
6de9cd9a | 1184 | |
7290d709 | 1185 | /* live on entry calculations used liveout vectors for defs, clear them. */ |
11cd3bed | 1186 | FOR_EACH_BB_FN (bb, cfun) |
3f9b14ff | 1187 | bitmap_clear (&liveinfo->liveout[bb->index]); |
6de9cd9a DN |
1188 | |
1189 | /* Set all the live-on-exit bits for uses in PHIs. */ | |
11cd3bed | 1190 | FOR_EACH_BB_FN (bb, cfun) |
6de9cd9a | 1191 | { |
538dd0b7 | 1192 | gphi_iterator gsi; |
726a989a RB |
1193 | size_t i; |
1194 | ||
32ace6e2 | 1195 | /* Mark the PHI arguments which are live on exit to the pred block. */ |
726a989a RB |
1196 | for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) |
1197 | { | |
538dd0b7 | 1198 | gphi *phi = gsi.phi (); |
726a989a | 1199 | for (i = 0; i < gimple_phi_num_args (phi); i++) |
b8698a0f | 1200 | { |
726a989a RB |
1201 | tree t = PHI_ARG_DEF (phi, i); |
1202 | int p; | |
1203 | ||
1204 | if (TREE_CODE (t) != SSA_NAME) | |
1205 | continue; | |
1206 | ||
1207 | p = var_to_partition (liveinfo->map, t); | |
1208 | if (p == NO_PARTITION) | |
1209 | continue; | |
1210 | e = gimple_phi_arg_edge (phi, i); | |
fefa31b5 | 1211 | if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun)) |
3f9b14ff | 1212 | bitmap_set_bit (&liveinfo->liveout[e->src->index], p); |
726a989a RB |
1213 | } |
1214 | } | |
32ace6e2 | 1215 | |
7290d709 | 1216 | /* Add each successors live on entry to this bock live on exit. */ |
32ace6e2 | 1217 | FOR_EACH_EDGE (e, ei, bb->succs) |
fefa31b5 | 1218 | if (e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)) |
3f9b14ff | 1219 | bitmap_ior_into (&liveinfo->liveout[bb->index], |
32ace6e2 | 1220 | live_on_entry (liveinfo, e->dest)); |
6de9cd9a | 1221 | } |
32ace6e2 AM |
1222 | } |
1223 | ||
7290d709 | 1224 | |
b8698a0f | 1225 | /* Given partition map MAP, calculate all the live on entry bitmaps for |
32ace6e2 AM |
1226 | each partition. Return a new live info object. */ |
1227 | ||
b8698a0f | 1228 | tree_live_info_p |
32ace6e2 AM |
1229 | calculate_live_ranges (var_map map) |
1230 | { | |
1231 | tree var; | |
1232 | unsigned i; | |
1233 | tree_live_info_p live; | |
6de9cd9a | 1234 | |
3f9b14ff | 1235 | bitmap_obstack_initialize (&liveness_bitmap_obstack); |
32ace6e2 | 1236 | live = new_tree_live_info (map); |
6de9cd9a DN |
1237 | for (i = 0; i < num_var_partitions (map); i++) |
1238 | { | |
32ace6e2 AM |
1239 | var = partition_to_var (map, i); |
1240 | if (var != NULL_TREE) | |
1241 | set_var_live_on_entry (var, live); | |
6de9cd9a DN |
1242 | } |
1243 | ||
32ace6e2 AM |
1244 | live_worklist (live); |
1245 | ||
1246 | #ifdef ENABLE_CHECKING | |
1247 | verify_live_on_entry (live); | |
1248 | #endif | |
1249 | ||
1250 | calculate_live_on_exit (live); | |
1251 | return live; | |
6de9cd9a DN |
1252 | } |
1253 | ||
1254 | ||
6de9cd9a DN |
1255 | /* Output partition map MAP to file F. */ |
1256 | ||
1257 | void | |
1258 | dump_var_map (FILE *f, var_map map) | |
1259 | { | |
1260 | int t; | |
1261 | unsigned x, y; | |
1262 | int p; | |
1263 | ||
1264 | fprintf (f, "\nPartition map \n\n"); | |
1265 | ||
1266 | for (x = 0; x < map->num_partitions; x++) | |
1267 | { | |
7290d709 AM |
1268 | if (map->view_to_partition != NULL) |
1269 | p = map->view_to_partition[x]; | |
6de9cd9a DN |
1270 | else |
1271 | p = x; | |
1272 | ||
12fdc099 SB |
1273 | if (ssa_name (p) == NULL_TREE |
1274 | || virtual_operand_p (ssa_name (p))) | |
6de9cd9a DN |
1275 | continue; |
1276 | ||
1277 | t = 0; | |
95a3742c | 1278 | for (y = 1; y < num_ssa_names; y++) |
6de9cd9a DN |
1279 | { |
1280 | p = partition_find (map->var_partition, y); | |
7290d709 AM |
1281 | if (map->partition_to_view) |
1282 | p = map->partition_to_view[p]; | |
6de9cd9a DN |
1283 | if (p == (int)x) |
1284 | { | |
1285 | if (t++ == 0) | |
1286 | { | |
c3284718 | 1287 | fprintf (f, "Partition %d (", x); |
6de9cd9a DN |
1288 | print_generic_expr (f, partition_to_var (map, p), TDF_SLIM); |
1289 | fprintf (f, " - "); | |
1290 | } | |
1291 | fprintf (f, "%d ", y); | |
1292 | } | |
1293 | } | |
1294 | if (t != 0) | |
1295 | fprintf (f, ")\n"); | |
1296 | } | |
1297 | fprintf (f, "\n"); | |
1298 | } | |
1299 | ||
1300 | ||
7b3b6ae4 LC |
1301 | /* Generic dump for the above. */ |
1302 | ||
1303 | DEBUG_FUNCTION void | |
1304 | debug (_var_map &ref) | |
1305 | { | |
1306 | dump_var_map (stderr, &ref); | |
1307 | } | |
1308 | ||
1309 | DEBUG_FUNCTION void | |
1310 | debug (_var_map *ptr) | |
1311 | { | |
1312 | if (ptr) | |
1313 | debug (*ptr); | |
1314 | else | |
1315 | fprintf (stderr, "<nil>\n"); | |
1316 | } | |
1317 | ||
1318 | ||
6de9cd9a DN |
1319 | /* Output live range info LIVE to file F, controlled by FLAG. */ |
1320 | ||
1321 | void | |
1322 | dump_live_info (FILE *f, tree_live_info_p live, int flag) | |
1323 | { | |
1324 | basic_block bb; | |
3cd8c58a | 1325 | unsigned i; |
6de9cd9a | 1326 | var_map map = live->map; |
87c476a2 | 1327 | bitmap_iterator bi; |
6de9cd9a DN |
1328 | |
1329 | if ((flag & LIVEDUMP_ENTRY) && live->livein) | |
1330 | { | |
11cd3bed | 1331 | FOR_EACH_BB_FN (bb, cfun) |
6de9cd9a DN |
1332 | { |
1333 | fprintf (f, "\nLive on entry to BB%d : ", bb->index); | |
3f9b14ff | 1334 | EXECUTE_IF_SET_IN_BITMAP (&live->livein[bb->index], 0, i, bi) |
6de9cd9a | 1335 | { |
32ace6e2 AM |
1336 | print_generic_expr (f, partition_to_var (map, i), TDF_SLIM); |
1337 | fprintf (f, " "); | |
6de9cd9a DN |
1338 | } |
1339 | fprintf (f, "\n"); | |
1340 | } | |
1341 | } | |
1342 | ||
1343 | if ((flag & LIVEDUMP_EXIT) && live->liveout) | |
1344 | { | |
11cd3bed | 1345 | FOR_EACH_BB_FN (bb, cfun) |
6de9cd9a DN |
1346 | { |
1347 | fprintf (f, "\nLive on exit from BB%d : ", bb->index); | |
3f9b14ff | 1348 | EXECUTE_IF_SET_IN_BITMAP (&live->liveout[bb->index], 0, i, bi) |
6de9cd9a DN |
1349 | { |
1350 | print_generic_expr (f, partition_to_var (map, i), TDF_SLIM); | |
1351 | fprintf (f, " "); | |
87c476a2 | 1352 | } |
6de9cd9a DN |
1353 | fprintf (f, "\n"); |
1354 | } | |
1355 | } | |
1356 | } | |
1e128c5f | 1357 | |
7b3b6ae4 LC |
1358 | |
1359 | /* Generic dump for the above. */ | |
1360 | ||
1361 | DEBUG_FUNCTION void | |
1362 | debug (tree_live_info_d &ref) | |
1363 | { | |
1364 | dump_live_info (stderr, &ref, 0); | |
1365 | } | |
1366 | ||
1367 | DEBUG_FUNCTION void | |
1368 | debug (tree_live_info_d *ptr) | |
1369 | { | |
1370 | if (ptr) | |
1371 | debug (*ptr); | |
1372 | else | |
1373 | fprintf (stderr, "<nil>\n"); | |
1374 | } | |
1375 | ||
1376 | ||
1e128c5f | 1377 | #ifdef ENABLE_CHECKING |
7290d709 AM |
1378 | /* Verify that SSA_VAR is a non-virtual SSA_NAME. */ |
1379 | ||
1e128c5f GB |
1380 | void |
1381 | register_ssa_partition_check (tree ssa_var) | |
1382 | { | |
1383 | gcc_assert (TREE_CODE (ssa_var) == SSA_NAME); | |
ea057359 | 1384 | if (virtual_operand_p (ssa_var)) |
1e128c5f GB |
1385 | { |
1386 | fprintf (stderr, "Illegally registering a virtual SSA name :"); | |
1387 | print_generic_expr (stderr, ssa_var, TDF_SLIM); | |
1388 | fprintf (stderr, " in the SSA->Normal phase.\n"); | |
1389 | internal_error ("SSA corruption"); | |
1390 | } | |
1391 | } | |
32ace6e2 AM |
1392 | |
1393 | ||
1394 | /* Verify that the info in LIVE matches the current cfg. */ | |
7290d709 | 1395 | |
32ace6e2 AM |
1396 | static void |
1397 | verify_live_on_entry (tree_live_info_p live) | |
1398 | { | |
1399 | unsigned i; | |
1400 | tree var; | |
726a989a | 1401 | gimple stmt; |
32ace6e2 AM |
1402 | basic_block bb; |
1403 | edge e; | |
1404 | int num; | |
1405 | edge_iterator ei; | |
1406 | var_map map = live->map; | |
1407 | ||
1408 | /* Check for live on entry partitions and report those with a DEF in | |
1409 | the program. This will typically mean an optimization has done | |
1410 | something wrong. */ | |
fefa31b5 | 1411 | bb = ENTRY_BLOCK_PTR_FOR_FN (cfun); |
32ace6e2 AM |
1412 | num = 0; |
1413 | FOR_EACH_EDGE (e, ei, bb->succs) | |
1414 | { | |
1415 | int entry_block = e->dest->index; | |
fefa31b5 | 1416 | if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun)) |
32ace6e2 AM |
1417 | continue; |
1418 | for (i = 0; i < (unsigned)num_var_partitions (map); i++) | |
1419 | { | |
1420 | basic_block tmp; | |
70b5e7dc | 1421 | tree d = NULL_TREE; |
32ace6e2 AM |
1422 | bitmap loe; |
1423 | var = partition_to_var (map, i); | |
1424 | stmt = SSA_NAME_DEF_STMT (var); | |
726a989a | 1425 | tmp = gimple_bb (stmt); |
70b5e7dc RG |
1426 | if (SSA_NAME_VAR (var)) |
1427 | d = ssa_default_def (cfun, SSA_NAME_VAR (var)); | |
32ace6e2 AM |
1428 | |
1429 | loe = live_on_entry (live, e->dest); | |
1430 | if (loe && bitmap_bit_p (loe, i)) | |
1431 | { | |
726a989a | 1432 | if (!gimple_nop_p (stmt)) |
32ace6e2 AM |
1433 | { |
1434 | num++; | |
1435 | print_generic_expr (stderr, var, TDF_SLIM); | |
1436 | fprintf (stderr, " is defined "); | |
1437 | if (tmp) | |
1438 | fprintf (stderr, " in BB%d, ", tmp->index); | |
1439 | fprintf (stderr, "by:\n"); | |
726a989a | 1440 | print_gimple_stmt (stderr, stmt, 0, TDF_SLIM); |
b8698a0f | 1441 | fprintf (stderr, "\nIt is also live-on-entry to entry BB %d", |
32ace6e2 AM |
1442 | entry_block); |
1443 | fprintf (stderr, " So it appears to have multiple defs.\n"); | |
1444 | } | |
1445 | else | |
1446 | { | |
1447 | if (d != var) | |
1448 | { | |
1449 | num++; | |
1450 | print_generic_expr (stderr, var, TDF_SLIM); | |
726a989a RB |
1451 | fprintf (stderr, " is live-on-entry to BB%d ", |
1452 | entry_block); | |
32ace6e2 AM |
1453 | if (d) |
1454 | { | |
1455 | fprintf (stderr, " but is not the default def of "); | |
1456 | print_generic_expr (stderr, d, TDF_SLIM); | |
1457 | fprintf (stderr, "\n"); | |
1458 | } | |
1459 | else | |
1460 | fprintf (stderr, " and there is no default def.\n"); | |
1461 | } | |
1462 | } | |
1463 | } | |
1464 | else | |
1465 | if (d == var) | |
1466 | { | |
956623c1 MG |
1467 | /* An undefined local variable does not need to be very |
1468 | alive. */ | |
1469 | if (ssa_undefined_value_p (var, false)) | |
1470 | continue; | |
1471 | ||
b8698a0f | 1472 | /* The only way this var shouldn't be marked live on entry is |
32ace6e2 | 1473 | if it occurs in a PHI argument of the block. */ |
726a989a RB |
1474 | size_t z; |
1475 | bool ok = false; | |
538dd0b7 | 1476 | gphi_iterator gsi; |
726a989a RB |
1477 | for (gsi = gsi_start_phis (e->dest); |
1478 | !gsi_end_p (gsi) && !ok; | |
1479 | gsi_next (&gsi)) | |
32ace6e2 | 1480 | { |
538dd0b7 | 1481 | gphi *phi = gsi.phi (); |
726a989a RB |
1482 | for (z = 0; z < gimple_phi_num_args (phi); z++) |
1483 | if (var == gimple_phi_arg_def (phi, z)) | |
32ace6e2 | 1484 | { |
726a989a | 1485 | ok = true; |
32ace6e2 AM |
1486 | break; |
1487 | } | |
1488 | } | |
1489 | if (ok) | |
1490 | continue; | |
1491 | num++; | |
1492 | print_generic_expr (stderr, var, TDF_SLIM); | |
b8698a0f | 1493 | fprintf (stderr, " is not marked live-on-entry to entry BB%d ", |
32ace6e2 AM |
1494 | entry_block); |
1495 | fprintf (stderr, "but it is a default def so it should be.\n"); | |
1496 | } | |
1497 | } | |
1498 | } | |
1499 | gcc_assert (num <= 0); | |
1500 | } | |
1e128c5f | 1501 | #endif |