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