]>
Commit | Line | Data |
---|---|---|
4ee9c684 | 1 | /* Generic routines for manipulating SSA_NAME expressions |
d353bf18 | 2 | Copyright (C) 2003-2015 Free Software Foundation, Inc. |
0b1615c1 | 3 | |
4ee9c684 | 4 | This file is part of GCC. |
48e1416a | 5 | |
4ee9c684 | 6 | GCC is free software; you can redistribute it and/or modify |
7 | it under the terms of the GNU General Public License as published by | |
8c4c00c1 | 8 | the Free Software Foundation; either version 3, or (at your option) |
4ee9c684 | 9 | any later version. |
48e1416a | 10 | |
4ee9c684 | 11 | GCC is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
48e1416a | 15 | |
4ee9c684 | 16 | You should have received a copy of the GNU General Public License |
8c4c00c1 | 17 | along with GCC; see the file COPYING3. If not see |
18 | <http://www.gnu.org/licenses/>. */ | |
1fa3a8f6 | 19 | |
4ee9c684 | 20 | #include "config.h" |
21 | #include "system.h" | |
22 | #include "coretypes.h" | |
9ef16211 | 23 | #include "backend.h" |
4ee9c684 | 24 | #include "tree.h" |
9ef16211 | 25 | #include "gimple.h" |
43725011 | 26 | #include "gimple-iterator.h" |
9ef16211 | 27 | #include "hard-reg-set.h" |
28 | #include "ssa.h" | |
29 | #include "alias.h" | |
b20a8bb4 | 30 | #include "fold-const.h" |
9ed99284 | 31 | #include "stor-layout.h" |
bc61cadb | 32 | #include "internal-fn.h" |
073c1fd5 | 33 | #include "tree-into-ssa.h" |
69ee5dbb | 34 | #include "tree-ssa.h" |
49290934 | 35 | #include "tree-pass.h" |
4ee9c684 | 36 | |
37 | /* Rewriting a function into SSA form can create a huge number of SSA_NAMEs, | |
38 | many of which may be thrown away shortly after their creation if jumps | |
48e1416a | 39 | were threaded through PHI nodes. |
4ee9c684 | 40 | |
41 | While our garbage collection mechanisms will handle this situation, it | |
42 | is extremely wasteful to create nodes and throw them away, especially | |
43 | when the nodes can be reused. | |
44 | ||
45 | For PR 8361, we can significantly reduce the number of nodes allocated | |
46 | and thus the total amount of memory allocated by managing SSA_NAMEs a | |
47 | little. This additionally helps reduce the amount of work done by the | |
48 | garbage collector. Similar results have been seen on a wider variety | |
49 | of tests (such as the compiler itself). | |
50 | ||
51 | Right now we maintain our free list on a per-function basis. It may | |
52 | or may not make sense to maintain the free list for the duration of | |
48e1416a | 53 | a compilation unit. |
4ee9c684 | 54 | |
55 | External code should rely solely upon HIGHEST_SSA_VERSION and the | |
56 | externally defined functions. External code should not know about | |
57 | the details of the free list management. | |
58 | ||
59 | External code should also not assume the version number on nodes is | |
60 | monotonically increasing. We reuse the version number when we | |
61 | reuse an SSA_NAME expression. This helps keep arrays and bitmaps | |
5cc13354 | 62 | more compact. */ |
4ee9c684 | 63 | |
4ee9c684 | 64 | |
65 | /* Version numbers with special meanings. We start allocating new version | |
66 | numbers after the special ones. */ | |
67 | #define UNUSED_NAME_VERSION 0 | |
68 | ||
4ee9c684 | 69 | unsigned int ssa_name_nodes_reused; |
70 | unsigned int ssa_name_nodes_created; | |
4ee9c684 | 71 | |
9e2e2283 | 72 | #define FREE_SSANAMES(fun) (fun)->gimple_df->free_ssanames |
73 | ||
74 | ||
bcaa2770 | 75 | /* Initialize management of SSA_NAMEs to default SIZE. If SIZE is |
76 | zero use default. */ | |
4ee9c684 | 77 | |
78 | void | |
bcaa2770 | 79 | init_ssanames (struct function *fn, int size) |
4ee9c684 | 80 | { |
bcaa2770 | 81 | if (size < 50) |
82 | size = 50; | |
83 | ||
f1f41a6c | 84 | vec_alloc (SSANAMES (fn), size); |
c211d998 | 85 | |
86 | /* Version 0 is special, so reserve the first slot in the table. Though | |
87 | currently unused, we may use version 0 in alias analysis as part of | |
88 | the heuristics used to group aliases when the alias sets are too | |
8b292c7f | 89 | large. |
90 | ||
f1f41a6c | 91 | We use vec::quick_push here because we know that SSA_NAMES has at |
b62e1ab2 | 92 | least 50 elements reserved in it. */ |
f1f41a6c | 93 | SSANAMES (fn)->quick_push (NULL_TREE); |
bcaa2770 | 94 | FREE_SSANAMES (fn) = NULL; |
dd277d48 | 95 | |
e70e8b13 | 96 | fn->gimple_df->ssa_renaming_needed = 0; |
97 | fn->gimple_df->rename_vops = 0; | |
4ee9c684 | 98 | } |
99 | ||
100 | /* Finalize management of SSA_NAMEs. */ | |
101 | ||
102 | void | |
103 | fini_ssanames (void) | |
104 | { | |
f1f41a6c | 105 | vec_free (SSANAMES (cfun)); |
106 | vec_free (FREE_SSANAMES (cfun)); | |
4ee9c684 | 107 | } |
108 | ||
109 | /* Dump some simple statistics regarding the re-use of SSA_NAME nodes. */ | |
110 | ||
4ee9c684 | 111 | void |
112 | ssanames_print_statistics (void) | |
113 | { | |
114 | fprintf (stderr, "SSA_NAME nodes allocated: %u\n", ssa_name_nodes_created); | |
115 | fprintf (stderr, "SSA_NAME nodes reused: %u\n", ssa_name_nodes_reused); | |
116 | } | |
4ee9c684 | 117 | |
bcaa2770 | 118 | /* Return an SSA_NAME node for variable VAR defined in statement STMT |
119 | in function FN. STMT may be an empty statement for artificial | |
120 | references (e.g., default definitions created when a variable is | |
121 | used without a preceding definition). */ | |
4ee9c684 | 122 | |
123 | tree | |
42acab1c | 124 | make_ssa_name_fn (struct function *fn, tree var, gimple *stmt) |
4ee9c684 | 125 | { |
126 | tree t; | |
b66731e8 | 127 | use_operand_p imm; |
4ee9c684 | 128 | |
2f4ec87c | 129 | gcc_assert (TREE_CODE (var) == VAR_DECL |
130 | || TREE_CODE (var) == PARM_DECL | |
ec11736b | 131 | || TREE_CODE (var) == RESULT_DECL |
132 | || (TYPE_P (var) && is_gimple_reg_type (var))); | |
4ee9c684 | 133 | |
fa0f49c6 | 134 | /* If our free list has an element, then use it. */ |
f1f41a6c | 135 | if (!vec_safe_is_empty (FREE_SSANAMES (fn))) |
4ee9c684 | 136 | { |
f1f41a6c | 137 | t = FREE_SSANAMES (fn)->pop (); |
ecd52ea9 | 138 | if (GATHER_STATISTICS) |
139 | ssa_name_nodes_reused++; | |
4ee9c684 | 140 | |
fa0f49c6 | 141 | /* The node was cleared out when we put it on the free list, so |
142 | there is no need to do so again here. */ | |
98107def | 143 | gcc_assert ((*SSANAMES (fn))[SSA_NAME_VERSION (t)] == NULL); |
f1f41a6c | 144 | (*SSANAMES (fn))[SSA_NAME_VERSION (t)] = t; |
4ee9c684 | 145 | } |
146 | else | |
147 | { | |
148 | t = make_node (SSA_NAME); | |
f1f41a6c | 149 | SSA_NAME_VERSION (t) = SSANAMES (fn)->length (); |
150 | vec_safe_push (SSANAMES (fn), t); | |
ecd52ea9 | 151 | if (GATHER_STATISTICS) |
152 | ssa_name_nodes_created++; | |
4ee9c684 | 153 | } |
154 | ||
ec11736b | 155 | if (TYPE_P (var)) |
156 | { | |
157 | TREE_TYPE (t) = var; | |
158 | SET_SSA_NAME_VAR_OR_IDENTIFIER (t, NULL_TREE); | |
159 | } | |
160 | else | |
161 | { | |
162 | TREE_TYPE (t) = TREE_TYPE (var); | |
163 | SET_SSA_NAME_VAR_OR_IDENTIFIER (t, var); | |
164 | } | |
4ee9c684 | 165 | SSA_NAME_DEF_STMT (t) = stmt; |
3c59e4a7 | 166 | if (POINTER_TYPE_P (TREE_TYPE (t))) |
167 | SSA_NAME_PTR_INFO (t) = NULL; | |
168 | else | |
169 | SSA_NAME_RANGE_INFO (t) = NULL; | |
170 | ||
81d08033 | 171 | SSA_NAME_IN_FREE_LIST (t) = 0; |
de6ed584 | 172 | SSA_NAME_IS_DEFAULT_DEF (t) = 0; |
22aa74c4 | 173 | imm = &(SSA_NAME_IMM_USE_NODE (t)); |
174 | imm->use = NULL; | |
175 | imm->prev = imm; | |
176 | imm->next = imm; | |
75a70cf9 | 177 | imm->loc.ssa_name = t; |
4ee9c684 | 178 | |
179 | return t; | |
180 | } | |
181 | ||
0c20fe49 | 182 | /* Store range information RANGE_TYPE, MIN, and MAX to tree ssa_name NAME. */ |
3c59e4a7 | 183 | |
184 | void | |
0c20fe49 | 185 | set_range_info (tree name, enum value_range_type range_type, |
9c1be15e | 186 | const wide_int_ref &min, const wide_int_ref &max) |
3c59e4a7 | 187 | { |
188 | gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name))); | |
0c20fe49 | 189 | gcc_assert (range_type == VR_RANGE || range_type == VR_ANTI_RANGE); |
3c59e4a7 | 190 | range_info_def *ri = SSA_NAME_RANGE_INFO (name); |
9c1be15e | 191 | unsigned int precision = TYPE_PRECISION (TREE_TYPE (name)); |
3c59e4a7 | 192 | |
193 | /* Allocate if not available. */ | |
194 | if (ri == NULL) | |
195 | { | |
9c1be15e | 196 | size_t size = (sizeof (range_info_def) |
197 | + trailing_wide_ints <3>::extra_size (precision)); | |
25a27413 | 198 | ri = static_cast<range_info_def *> (ggc_internal_alloc (size)); |
9c1be15e | 199 | ri->ints.set_precision (precision); |
3c59e4a7 | 200 | SSA_NAME_RANGE_INFO (name) = ri; |
9c1be15e | 201 | ri->set_nonzero_bits (wi::shwi (-1, precision)); |
3c59e4a7 | 202 | } |
203 | ||
0c20fe49 | 204 | /* Record the range type. */ |
205 | if (SSA_NAME_RANGE_TYPE (name) != range_type) | |
206 | SSA_NAME_ANTI_RANGE_P (name) = (range_type == VR_ANTI_RANGE); | |
207 | ||
3c59e4a7 | 208 | /* Set the values. */ |
9c1be15e | 209 | ri->set_min (min); |
210 | ri->set_max (max); | |
fc08b993 | 211 | |
212 | /* If it is a range, try to improve nonzero_bits from the min/max. */ | |
0c20fe49 | 213 | if (range_type == VR_RANGE) |
fc08b993 | 214 | { |
9c1be15e | 215 | wide_int xorv = ri->get_min () ^ ri->get_max (); |
aeb682a2 | 216 | if (xorv != 0) |
9c1be15e | 217 | xorv = wi::mask (precision - wi::clz (xorv), false, precision); |
218 | ri->set_nonzero_bits (ri->get_nonzero_bits () & (ri->get_min () | xorv)); | |
fc08b993 | 219 | } |
3c59e4a7 | 220 | } |
221 | ||
222 | ||
223 | /* Gets range information MIN, MAX and returns enum value_range_type | |
224 | corresponding to tree ssa_name NAME. enum value_range_type returned | |
225 | is used to determine if MIN and MAX are valid values. */ | |
226 | ||
227 | enum value_range_type | |
9c1be15e | 228 | get_range_info (const_tree name, wide_int *min, wide_int *max) |
3c59e4a7 | 229 | { |
3c59e4a7 | 230 | gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name))); |
231 | gcc_assert (min && max); | |
232 | range_info_def *ri = SSA_NAME_RANGE_INFO (name); | |
233 | ||
234 | /* Return VR_VARYING for SSA_NAMEs with NULL RANGE_INFO or SSA_NAMEs | |
235 | with integral types width > 2 * HOST_BITS_PER_WIDE_INT precision. */ | |
236 | if (!ri || (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (name))) | |
0cf78115 | 237 | > 2 * HOST_BITS_PER_WIDE_INT)) |
3c59e4a7 | 238 | return VR_VARYING; |
239 | ||
9c1be15e | 240 | *min = ri->get_min (); |
241 | *max = ri->get_max (); | |
0c20fe49 | 242 | return SSA_NAME_RANGE_TYPE (name); |
3c59e4a7 | 243 | } |
c211d998 | 244 | |
fc08b993 | 245 | /* Change non-zero bits bitmask of NAME. */ |
246 | ||
247 | void | |
9c1be15e | 248 | set_nonzero_bits (tree name, const wide_int_ref &mask) |
fc08b993 | 249 | { |
250 | gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name))); | |
251 | if (SSA_NAME_RANGE_INFO (name) == NULL) | |
0c20fe49 | 252 | set_range_info (name, VR_RANGE, |
9c1be15e | 253 | TYPE_MIN_VALUE (TREE_TYPE (name)), |
254 | TYPE_MAX_VALUE (TREE_TYPE (name))); | |
fc08b993 | 255 | range_info_def *ri = SSA_NAME_RANGE_INFO (name); |
9c1be15e | 256 | ri->set_nonzero_bits (mask); |
fc08b993 | 257 | } |
258 | ||
aeb682a2 | 259 | /* Return a widest_int with potentially non-zero bits in SSA_NAME |
260 | NAME, or -1 if unknown. */ | |
fc08b993 | 261 | |
9c1be15e | 262 | wide_int |
c8a2b4ff | 263 | get_nonzero_bits (const_tree name) |
fc08b993 | 264 | { |
9c1be15e | 265 | unsigned int precision = TYPE_PRECISION (TREE_TYPE (name)); |
fc08b993 | 266 | if (POINTER_TYPE_P (TREE_TYPE (name))) |
267 | { | |
268 | struct ptr_info_def *pi = SSA_NAME_PTR_INFO (name); | |
269 | if (pi && pi->align) | |
6e5e0d6b | 270 | return wi::shwi (-(HOST_WIDE_INT) pi->align |
271 | | (HOST_WIDE_INT) pi->misalign, precision); | |
9c1be15e | 272 | return wi::shwi (-1, precision); |
fc08b993 | 273 | } |
274 | ||
275 | range_info_def *ri = SSA_NAME_RANGE_INFO (name); | |
9c1be15e | 276 | if (!ri) |
277 | return wi::shwi (-1, precision); | |
fc08b993 | 278 | |
9c1be15e | 279 | return ri->get_nonzero_bits (); |
fc08b993 | 280 | } |
281 | ||
4ee9c684 | 282 | /* We no longer need the SSA_NAME expression VAR, release it so that |
48e1416a | 283 | it may be reused. |
4ee9c684 | 284 | |
285 | Note it is assumed that no calls to make_ssa_name will be made | |
286 | until all uses of the ssa name are released and that the only | |
287 | use of the SSA_NAME expression is to check its SSA_NAME_VAR. All | |
288 | other fields must be assumed clobbered. */ | |
289 | ||
290 | void | |
861b4e39 | 291 | release_ssa_name_fn (struct function *fn, tree var) |
4ee9c684 | 292 | { |
dec41e98 | 293 | if (!var) |
294 | return; | |
295 | ||
81d08033 | 296 | /* Never release the default definition for a symbol. It's a |
297 | special SSA name that should always exist once it's created. */ | |
de6ed584 | 298 | if (SSA_NAME_IS_DEFAULT_DEF (var)) |
81d08033 | 299 | return; |
300 | ||
095dcfa3 | 301 | /* If VAR has been registered for SSA updating, don't remove it. |
302 | After update_ssa has run, the name will be released. */ | |
303 | if (name_registered_for_update_p (var)) | |
304 | { | |
305 | release_ssa_name_after_update_ssa (var); | |
306 | return; | |
307 | } | |
deb78f9e | 308 | |
4ee9c684 | 309 | /* release_ssa_name can be called multiple times on a single SSA_NAME. |
310 | However, it should only end up on our free list one time. We | |
311 | keep a status bit in the SSA_NAME node itself to indicate it has | |
48e1416a | 312 | been put on the free list. |
4ee9c684 | 313 | |
314 | Note that once on the freelist you can not reference the SSA_NAME's | |
315 | defining statement. */ | |
316 | if (! SSA_NAME_IN_FREE_LIST (var)) | |
317 | { | |
fa0f49c6 | 318 | tree saved_ssa_name_var = SSA_NAME_VAR (var); |
319 | int saved_ssa_name_version = SSA_NAME_VERSION (var); | |
b66731e8 | 320 | use_operand_p imm = &(SSA_NAME_IMM_USE_NODE (var)); |
22aa74c4 | 321 | |
9845d120 | 322 | if (MAY_HAVE_DEBUG_STMTS) |
688ff29b | 323 | insert_debug_temp_for_var_def (NULL, var); |
9845d120 | 324 | |
22aa74c4 | 325 | #ifdef ENABLE_CHECKING |
326 | verify_imm_links (stderr, var); | |
327 | #endif | |
328 | while (imm->next != imm) | |
1fa3a8f6 | 329 | delink_imm_use (imm->next); |
fa0f49c6 | 330 | |
861b4e39 | 331 | (*SSANAMES (fn))[SSA_NAME_VERSION (var)] = NULL_TREE; |
fa0f49c6 | 332 | memset (var, 0, tree_size (var)); |
333 | ||
22aa74c4 | 334 | imm->prev = imm; |
335 | imm->next = imm; | |
75a70cf9 | 336 | imm->loc.ssa_name = var; |
337 | ||
fa0f49c6 | 338 | /* First put back the right tree node so that the tree checking |
339 | macros do not complain. */ | |
340 | TREE_SET_CODE (var, SSA_NAME); | |
341 | ||
342 | /* Restore the version number. */ | |
343 | SSA_NAME_VERSION (var) = saved_ssa_name_version; | |
344 | ||
345 | /* Hopefully this can go away once we have the new incremental | |
346 | SSA updating code installed. */ | |
ec11736b | 347 | SET_SSA_NAME_VAR_OR_IDENTIFIER (var, saved_ssa_name_var); |
fa0f49c6 | 348 | |
349 | /* Note this SSA_NAME is now in the first list. */ | |
4ee9c684 | 350 | SSA_NAME_IN_FREE_LIST (var) = 1; |
fa0f49c6 | 351 | |
acb5ba8c | 352 | /* And finally put it on the free list. */ |
861b4e39 | 353 | vec_safe_push (FREE_SSANAMES (fn), var); |
4ee9c684 | 354 | } |
355 | } | |
356 | ||
ceea063b | 357 | /* If the alignment of the pointer described by PI is known, return true and |
358 | store the alignment and the deviation from it into *ALIGNP and *MISALIGNP | |
359 | respectively. Otherwise return false. */ | |
360 | ||
361 | bool | |
362 | get_ptr_info_alignment (struct ptr_info_def *pi, unsigned int *alignp, | |
363 | unsigned int *misalignp) | |
364 | { | |
365 | if (pi->align) | |
366 | { | |
367 | *alignp = pi->align; | |
368 | *misalignp = pi->misalign; | |
369 | return true; | |
370 | } | |
371 | else | |
372 | return false; | |
373 | } | |
374 | ||
375 | /* State that the pointer described by PI has unknown alignment. */ | |
376 | ||
377 | void | |
378 | mark_ptr_info_alignment_unknown (struct ptr_info_def *pi) | |
379 | { | |
380 | pi->align = 0; | |
381 | pi->misalign = 0; | |
382 | } | |
383 | ||
47ae02b7 | 384 | /* Store the power-of-two byte alignment and the deviation from that |
ceea063b | 385 | alignment of pointer described by PI to ALIOGN and MISALIGN |
386 | respectively. */ | |
387 | ||
388 | void | |
389 | set_ptr_info_alignment (struct ptr_info_def *pi, unsigned int align, | |
390 | unsigned int misalign) | |
391 | { | |
392 | gcc_checking_assert (align != 0); | |
393 | gcc_assert ((align & (align - 1)) == 0); | |
394 | gcc_assert ((misalign & ~(align - 1)) == 0); | |
395 | ||
396 | pi->align = align; | |
397 | pi->misalign = misalign; | |
398 | } | |
399 | ||
9d75589a | 400 | /* If pointer described by PI has known alignment, increase its known |
ceea063b | 401 | misalignment by INCREMENT modulo its current alignment. */ |
402 | ||
403 | void | |
404 | adjust_ptr_info_misalignment (struct ptr_info_def *pi, | |
405 | unsigned int increment) | |
406 | { | |
407 | if (pi->align != 0) | |
408 | { | |
409 | pi->misalign += increment; | |
410 | pi->misalign &= (pi->align - 1); | |
411 | } | |
412 | } | |
3aaaf63f | 413 | |
153c3b50 | 414 | /* Return the alias information associated with pointer T. It creates a |
415 | new instance if none existed. */ | |
416 | ||
417 | struct ptr_info_def * | |
418 | get_ptr_info (tree t) | |
3aaaf63f | 419 | { |
153c3b50 | 420 | struct ptr_info_def *pi; |
abb91f0b | 421 | |
153c3b50 | 422 | gcc_assert (POINTER_TYPE_P (TREE_TYPE (t))); |
abb91f0b | 423 | |
153c3b50 | 424 | pi = SSA_NAME_PTR_INFO (t); |
425 | if (pi == NULL) | |
426 | { | |
25a27413 | 427 | pi = ggc_cleared_alloc<ptr_info_def> (); |
153c3b50 | 428 | pt_solution_reset (&pi->pt); |
ceea063b | 429 | mark_ptr_info_alignment_unknown (pi); |
153c3b50 | 430 | SSA_NAME_PTR_INFO (t) = pi; |
431 | } | |
abb91f0b | 432 | |
153c3b50 | 433 | return pi; |
434 | } | |
abb91f0b | 435 | |
874117c8 | 436 | |
437 | /* Creates a new SSA name using the template NAME tobe defined by | |
438 | statement STMT in function FN. */ | |
439 | ||
440 | tree | |
42acab1c | 441 | copy_ssa_name_fn (struct function *fn, tree name, gimple *stmt) |
874117c8 | 442 | { |
ec11736b | 443 | tree new_name; |
444 | ||
445 | if (SSA_NAME_VAR (name)) | |
446 | new_name = make_ssa_name_fn (fn, SSA_NAME_VAR (name), stmt); | |
447 | else | |
448 | { | |
449 | new_name = make_ssa_name_fn (fn, TREE_TYPE (name), stmt); | |
450 | SET_SSA_NAME_VAR_OR_IDENTIFIER (new_name, SSA_NAME_IDENTIFIER (name)); | |
451 | } | |
452 | ||
453 | return new_name; | |
874117c8 | 454 | } |
455 | ||
456 | ||
abb91f0b | 457 | /* Creates a duplicate of the ptr_info_def at PTR_INFO for use by |
095dcfa3 | 458 | the SSA name NAME. */ |
abb91f0b | 459 | |
460 | void | |
461 | duplicate_ssa_name_ptr_info (tree name, struct ptr_info_def *ptr_info) | |
462 | { | |
3aaaf63f | 463 | struct ptr_info_def *new_ptr_info; |
464 | ||
abb91f0b | 465 | gcc_assert (POINTER_TYPE_P (TREE_TYPE (name))); |
466 | gcc_assert (!SSA_NAME_PTR_INFO (name)); | |
467 | ||
468 | if (!ptr_info) | |
469 | return; | |
3aaaf63f | 470 | |
25a27413 | 471 | new_ptr_info = ggc_alloc<ptr_info_def> (); |
abb91f0b | 472 | *new_ptr_info = *ptr_info; |
3aaaf63f | 473 | |
abb91f0b | 474 | SSA_NAME_PTR_INFO (name) = new_ptr_info; |
3aaaf63f | 475 | } |
476 | ||
0c20fe49 | 477 | /* Creates a duplicate of the range_info_def at RANGE_INFO of type |
478 | RANGE_TYPE for use by the SSA name NAME. */ | |
3c59e4a7 | 479 | void |
0c20fe49 | 480 | duplicate_ssa_name_range_info (tree name, enum value_range_type range_type, |
481 | struct range_info_def *range_info) | |
3c59e4a7 | 482 | { |
483 | struct range_info_def *new_range_info; | |
484 | ||
485 | gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name))); | |
486 | gcc_assert (!SSA_NAME_RANGE_INFO (name)); | |
0c20fe49 | 487 | gcc_assert (!SSA_NAME_ANTI_RANGE_P (name)); |
3c59e4a7 | 488 | |
489 | if (!range_info) | |
490 | return; | |
491 | ||
9c1be15e | 492 | unsigned int precision = TYPE_PRECISION (TREE_TYPE (name)); |
493 | size_t size = (sizeof (range_info_def) | |
494 | + trailing_wide_ints <3>::extra_size (precision)); | |
25a27413 | 495 | new_range_info = static_cast<range_info_def *> (ggc_internal_alloc (size)); |
9c1be15e | 496 | memcpy (new_range_info, range_info, size); |
3c59e4a7 | 497 | |
0c20fe49 | 498 | gcc_assert (range_type == VR_RANGE || range_type == VR_ANTI_RANGE); |
499 | SSA_NAME_ANTI_RANGE_P (name) = (range_type == VR_ANTI_RANGE); | |
3c59e4a7 | 500 | SSA_NAME_RANGE_INFO (name) = new_range_info; |
501 | } | |
502 | ||
503 | ||
81d08033 | 504 | |
874117c8 | 505 | /* Creates a duplicate of a ssa name NAME tobe defined by statement STMT |
506 | in function FN. */ | |
153c3b50 | 507 | |
508 | tree | |
42acab1c | 509 | duplicate_ssa_name_fn (struct function *fn, tree name, gimple *stmt) |
153c3b50 | 510 | { |
874117c8 | 511 | tree new_name = copy_ssa_name_fn (fn, name, stmt); |
3c59e4a7 | 512 | if (POINTER_TYPE_P (TREE_TYPE (name))) |
513 | { | |
514 | struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name); | |
515 | ||
516 | if (old_ptr_info) | |
0cf78115 | 517 | duplicate_ssa_name_ptr_info (new_name, old_ptr_info); |
3c59e4a7 | 518 | } |
519 | else | |
520 | { | |
521 | struct range_info_def *old_range_info = SSA_NAME_RANGE_INFO (name); | |
153c3b50 | 522 | |
3c59e4a7 | 523 | if (old_range_info) |
0c20fe49 | 524 | duplicate_ssa_name_range_info (new_name, SSA_NAME_RANGE_TYPE (name), |
525 | old_range_info); | |
3c59e4a7 | 526 | } |
153c3b50 | 527 | |
528 | return new_name; | |
529 | } | |
530 | ||
531 | ||
ace499f6 | 532 | /* Reset all flow sensitive data on NAME such as range-info, nonzero |
533 | bits and alignment. */ | |
534 | ||
535 | void | |
536 | reset_flow_sensitive_info (tree name) | |
537 | { | |
538 | if (POINTER_TYPE_P (TREE_TYPE (name))) | |
539 | { | |
540 | /* points-to info is not flow-sensitive. */ | |
541 | if (SSA_NAME_PTR_INFO (name)) | |
542 | mark_ptr_info_alignment_unknown (SSA_NAME_PTR_INFO (name)); | |
543 | } | |
544 | else | |
545 | SSA_NAME_RANGE_INFO (name) = NULL; | |
546 | } | |
547 | ||
43725011 | 548 | /* Clear all flow sensitive data from all statements and PHI definitions |
549 | in BB. */ | |
550 | ||
551 | void | |
552 | reset_flow_sensitive_info_in_bb (basic_block bb) | |
553 | { | |
554 | for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); | |
555 | gsi_next (&gsi)) | |
556 | { | |
557 | gimple *stmt = gsi_stmt (gsi); | |
558 | ssa_op_iter i; | |
559 | tree op; | |
560 | FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_DEF) | |
561 | reset_flow_sensitive_info (op); | |
562 | } | |
563 | ||
564 | for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi); | |
565 | gsi_next (&gsi)) | |
566 | { | |
567 | tree phi_def = gimple_phi_result (gsi.phi ()); | |
568 | reset_flow_sensitive_info (phi_def); | |
569 | } | |
570 | } | |
ace499f6 | 571 | |
81d08033 | 572 | /* Release all the SSA_NAMEs created by STMT. */ |
573 | ||
574 | void | |
42acab1c | 575 | release_defs (gimple *stmt) |
81d08033 | 576 | { |
43daa21e | 577 | tree def; |
578 | ssa_op_iter iter; | |
81d08033 | 579 | |
d7eb56de | 580 | /* Make sure that we are in SSA. Otherwise, operand cache may point |
581 | to garbage. */ | |
2d04fd8d | 582 | gcc_assert (gimple_in_ssa_p (cfun)); |
d7eb56de | 583 | |
43daa21e | 584 | FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS) |
ac6db781 | 585 | if (TREE_CODE (def) == SSA_NAME) |
586 | release_ssa_name (def); | |
81d08033 | 587 | } |
588 | ||
cbbefea4 | 589 | |
590 | /* Replace the symbol associated with SSA_NAME with SYM. */ | |
591 | ||
592 | void | |
593 | replace_ssa_name_symbol (tree ssa_name, tree sym) | |
594 | { | |
ec11736b | 595 | SET_SSA_NAME_VAR_OR_IDENTIFIER (ssa_name, sym); |
cbbefea4 | 596 | TREE_TYPE (ssa_name) = TREE_TYPE (sym); |
597 | } | |
49290934 | 598 | |
f901fae2 | 599 | /* Return SSA names that are unused to GGC memory and compact the SSA |
600 | version namespace. This is used to keep footprint of compiler during | |
601 | interprocedural optimization. */ | |
49290934 | 602 | |
7620bc82 | 603 | namespace { |
604 | ||
605 | const pass_data pass_data_release_ssa_names = | |
49290934 | 606 | { |
cbe8bda8 | 607 | GIMPLE_PASS, /* type */ |
608 | "release_ssa", /* name */ | |
609 | OPTGROUP_NONE, /* optinfo_flags */ | |
cbe8bda8 | 610 | TV_TREE_SSA_OTHER, /* tv_id */ |
611 | PROP_ssa, /* properties_required */ | |
612 | 0, /* properties_provided */ | |
613 | 0, /* properties_destroyed */ | |
614 | TODO_remove_unused_locals, /* todo_flags_start */ | |
615 | 0, /* todo_flags_finish */ | |
49290934 | 616 | }; |
cbe8bda8 | 617 | |
7620bc82 | 618 | class pass_release_ssa_names : public gimple_opt_pass |
cbe8bda8 | 619 | { |
620 | public: | |
9af5ce0c | 621 | pass_release_ssa_names (gcc::context *ctxt) |
622 | : gimple_opt_pass (pass_data_release_ssa_names, ctxt) | |
cbe8bda8 | 623 | {} |
624 | ||
625 | /* opt_pass methods: */ | |
65b0537f | 626 | virtual unsigned int execute (function *); |
cbe8bda8 | 627 | |
628 | }; // class pass_release_ssa_names | |
629 | ||
65b0537f | 630 | unsigned int |
631 | pass_release_ssa_names::execute (function *fun) | |
632 | { | |
633 | unsigned i, j; | |
634 | int n = vec_safe_length (FREE_SSANAMES (fun)); | |
635 | ||
636 | /* Now release the freelist. */ | |
637 | vec_free (FREE_SSANAMES (fun)); | |
638 | ||
639 | /* And compact the SSA number space. We make sure to not change the | |
640 | relative order of SSA versions. */ | |
641 | for (i = 1, j = 1; i < fun->gimple_df->ssa_names->length (); ++i) | |
642 | { | |
643 | tree name = ssa_name (i); | |
644 | if (name) | |
645 | { | |
646 | if (i != j) | |
647 | { | |
648 | SSA_NAME_VERSION (name) = j; | |
649 | (*fun->gimple_df->ssa_names)[j] = name; | |
650 | } | |
651 | j++; | |
652 | } | |
653 | } | |
654 | fun->gimple_df->ssa_names->truncate (j); | |
655 | ||
656 | statistics_counter_event (fun, "SSA names released", n); | |
657 | statistics_counter_event (fun, "SSA name holes removed", i - j); | |
658 | if (dump_file) | |
659 | fprintf (dump_file, "Released %i names, %.2f%%, removed %i holes\n", | |
660 | n, n * 100.0 / num_ssa_names, i - j); | |
661 | return 0; | |
662 | } | |
663 | ||
7620bc82 | 664 | } // anon namespace |
665 | ||
cbe8bda8 | 666 | gimple_opt_pass * |
667 | make_pass_release_ssa_names (gcc::context *ctxt) | |
668 | { | |
669 | return new pass_release_ssa_names (ctxt); | |
670 | } |