Mercurial > hg > CbC > CbC_gcc
annotate gcc/tree-ssanames.c @ 158:494b0b89df80 default tip
...
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 25 May 2020 18:13:55 +0900 |
parents | 1830386684a0 |
children |
rev | line source |
---|---|
0 | 1 /* Generic routines for manipulating SSA_NAME expressions |
145 | 2 Copyright (C) 2003-2020 Free Software Foundation, Inc. |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
3 |
0 | 4 This file is part of GCC. |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
5 |
0 | 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 | |
8 the Free Software Foundation; either version 3, or (at your option) | |
9 any later version. | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
10 |
0 | 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. | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
15 |
0 | 16 You should have received a copy of the GNU General Public License |
17 along with GCC; see the file COPYING3. If not see | |
18 <http://www.gnu.org/licenses/>. */ | |
19 | |
20 #include "config.h" | |
21 #include "system.h" | |
22 #include "coretypes.h" | |
111 | 23 #include "backend.h" |
0 | 24 #include "tree.h" |
111 | 25 #include "gimple.h" |
0 | 26 #include "tree-pass.h" |
111 | 27 #include "ssa.h" |
28 #include "gimple-iterator.h" | |
29 #include "stor-layout.h" | |
30 #include "tree-into-ssa.h" | |
31 #include "tree-ssa.h" | |
131 | 32 #include "cfgloop.h" |
33 #include "tree-scalar-evolution.h" | |
0 | 34 |
35 /* Rewriting a function into SSA form can create a huge number of SSA_NAMEs, | |
36 many of which may be thrown away shortly after their creation if jumps | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
37 were threaded through PHI nodes. |
0 | 38 |
39 While our garbage collection mechanisms will handle this situation, it | |
40 is extremely wasteful to create nodes and throw them away, especially | |
41 when the nodes can be reused. | |
42 | |
43 For PR 8361, we can significantly reduce the number of nodes allocated | |
44 and thus the total amount of memory allocated by managing SSA_NAMEs a | |
45 little. This additionally helps reduce the amount of work done by the | |
46 garbage collector. Similar results have been seen on a wider variety | |
47 of tests (such as the compiler itself). | |
48 | |
49 Right now we maintain our free list on a per-function basis. It may | |
50 or may not make sense to maintain the free list for the duration of | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
51 a compilation unit. |
0 | 52 |
53 External code should rely solely upon HIGHEST_SSA_VERSION and the | |
54 externally defined functions. External code should not know about | |
55 the details of the free list management. | |
56 | |
57 External code should also not assume the version number on nodes is | |
58 monotonically increasing. We reuse the version number when we | |
59 reuse an SSA_NAME expression. This helps keep arrays and bitmaps | |
111 | 60 more compact. */ |
0 | 61 |
62 | |
63 /* Version numbers with special meanings. We start allocating new version | |
64 numbers after the special ones. */ | |
65 #define UNUSED_NAME_VERSION 0 | |
66 | |
67 unsigned int ssa_name_nodes_reused; | |
68 unsigned int ssa_name_nodes_created; | |
111 | 69 |
70 #define FREE_SSANAMES(fun) (fun)->gimple_df->free_ssanames | |
71 #define FREE_SSANAMES_QUEUE(fun) (fun)->gimple_df->free_ssanames_queue | |
72 | |
0 | 73 |
74 /* Initialize management of SSA_NAMEs to default SIZE. If SIZE is | |
75 zero use default. */ | |
76 | |
77 void | |
78 init_ssanames (struct function *fn, int size) | |
79 { | |
80 if (size < 50) | |
81 size = 50; | |
82 | |
111 | 83 vec_alloc (SSANAMES (fn), size); |
0 | 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 | |
88 large. | |
89 | |
111 | 90 We use vec::quick_push here because we know that SSA_NAMES has at |
0 | 91 least 50 elements reserved in it. */ |
111 | 92 SSANAMES (fn)->quick_push (NULL_TREE); |
0 | 93 FREE_SSANAMES (fn) = NULL; |
111 | 94 FREE_SSANAMES_QUEUE (fn) = NULL; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
95 |
111 | 96 fn->gimple_df->ssa_renaming_needed = 0; |
97 fn->gimple_df->rename_vops = 0; | |
0 | 98 } |
99 | |
100 /* Finalize management of SSA_NAMEs. */ | |
101 | |
102 void | |
111 | 103 fini_ssanames (struct function *fn) |
0 | 104 { |
111 | 105 vec_free (SSANAMES (fn)); |
106 vec_free (FREE_SSANAMES (fn)); | |
107 vec_free (FREE_SSANAMES_QUEUE (fn)); | |
0 | 108 } |
109 | |
110 /* Dump some simple statistics regarding the re-use of SSA_NAME nodes. */ | |
111 | |
112 void | |
113 ssanames_print_statistics (void) | |
114 { | |
145 | 115 fprintf (stderr, "%-32s" PRsa (11) "\n", "SSA_NAME nodes allocated:", |
116 SIZE_AMOUNT (ssa_name_nodes_created)); | |
117 fprintf (stderr, "%-32s" PRsa (11) "\n", "SSA_NAME nodes reused:", | |
118 SIZE_AMOUNT (ssa_name_nodes_reused)); | |
0 | 119 } |
111 | 120 |
121 /* Verify the state of the SSA_NAME lists. | |
122 | |
123 There must be no duplicates on the free list. | |
124 Every name on the free list must be marked as on the free list. | |
125 Any name on the free list must not appear in the IL. | |
126 No names can be leaked. */ | |
127 | |
128 DEBUG_FUNCTION void | |
129 verify_ssaname_freelists (struct function *fun) | |
130 { | |
131 if (!gimple_in_ssa_p (fun)) | |
132 return; | |
133 | |
134 auto_bitmap names_in_il; | |
135 | |
136 /* Walk the entire IL noting every SSA_NAME we see. */ | |
137 basic_block bb; | |
138 FOR_EACH_BB_FN (bb, fun) | |
139 { | |
140 tree t; | |
141 /* First note the result and arguments of PHI nodes. */ | |
142 for (gphi_iterator gsi = gsi_start_phis (bb); | |
143 !gsi_end_p (gsi); | |
144 gsi_next (&gsi)) | |
145 { | |
146 gphi *phi = gsi.phi (); | |
147 t = gimple_phi_result (phi); | |
148 bitmap_set_bit (names_in_il, SSA_NAME_VERSION (t)); | |
149 | |
150 for (unsigned int i = 0; i < gimple_phi_num_args (phi); i++) | |
151 { | |
152 t = gimple_phi_arg_def (phi, i); | |
153 if (TREE_CODE (t) == SSA_NAME) | |
154 bitmap_set_bit (names_in_il, SSA_NAME_VERSION (t)); | |
155 } | |
156 } | |
157 | |
158 /* Then note the operands of each statement. */ | |
159 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); | |
160 !gsi_end_p (gsi); | |
161 gsi_next (&gsi)) | |
162 { | |
163 ssa_op_iter iter; | |
164 gimple *stmt = gsi_stmt (gsi); | |
165 FOR_EACH_SSA_TREE_OPERAND (t, stmt, iter, SSA_OP_ALL_OPERANDS) | |
166 bitmap_set_bit (names_in_il, SSA_NAME_VERSION (t)); | |
167 } | |
168 } | |
169 | |
170 /* Now walk the free list noting what we find there and verifying | |
171 there are no duplicates. */ | |
172 auto_bitmap names_in_freelists; | |
173 if (FREE_SSANAMES (fun)) | |
174 { | |
175 for (unsigned int i = 0; i < FREE_SSANAMES (fun)->length (); i++) | |
176 { | |
177 tree t = (*FREE_SSANAMES (fun))[i]; | |
178 | |
179 /* Verify that the name is marked as being in the free list. */ | |
180 gcc_assert (SSA_NAME_IN_FREE_LIST (t)); | |
181 | |
182 /* Verify the name has not already appeared in the free list and | |
183 note it in the list of names found in the free list. */ | |
184 gcc_assert (!bitmap_bit_p (names_in_freelists, SSA_NAME_VERSION (t))); | |
185 bitmap_set_bit (names_in_freelists, SSA_NAME_VERSION (t)); | |
186 } | |
187 } | |
188 | |
189 /* Similarly for the names in the pending free list. */ | |
190 if (FREE_SSANAMES_QUEUE (fun)) | |
191 { | |
192 for (unsigned int i = 0; i < FREE_SSANAMES_QUEUE (fun)->length (); i++) | |
193 { | |
194 tree t = (*FREE_SSANAMES_QUEUE (fun))[i]; | |
195 | |
196 /* Verify that the name is marked as being in the free list. */ | |
197 gcc_assert (SSA_NAME_IN_FREE_LIST (t)); | |
198 | |
199 /* Verify the name has not already appeared in the free list and | |
200 note it in the list of names found in the free list. */ | |
201 gcc_assert (!bitmap_bit_p (names_in_freelists, SSA_NAME_VERSION (t))); | |
202 bitmap_set_bit (names_in_freelists, SSA_NAME_VERSION (t)); | |
203 } | |
204 } | |
205 | |
206 /* If any name appears in both the IL and the freelists, then | |
207 something horrible has happened. */ | |
208 bool intersect_p = bitmap_intersect_p (names_in_il, names_in_freelists); | |
209 gcc_assert (!intersect_p); | |
210 | |
211 /* Names can be queued up for release if there is an ssa update | |
212 pending. Pretend we saw them in the IL. */ | |
213 if (names_to_release) | |
214 bitmap_ior_into (names_in_il, names_to_release); | |
215 | |
216 /* Function splitting can "lose" SSA_NAMEs in an effort to ensure that | |
217 debug/non-debug compilations have the same SSA_NAMEs. So for each | |
218 lost SSA_NAME, see if it's likely one from that wart. These will always | |
219 be marked as default definitions. So we loosely assume that anything | |
220 marked as a default definition isn't leaked by pretending they are | |
221 in the IL. */ | |
222 for (unsigned int i = UNUSED_NAME_VERSION + 1; i < num_ssa_names; i++) | |
223 if (ssa_name (i) && SSA_NAME_IS_DEFAULT_DEF (ssa_name (i))) | |
224 bitmap_set_bit (names_in_il, i); | |
225 | |
226 unsigned int i; | |
227 bitmap_iterator bi; | |
228 auto_bitmap all_names; | |
229 bitmap_set_range (all_names, UNUSED_NAME_VERSION + 1, num_ssa_names - 1); | |
230 bitmap_ior_into (names_in_il, names_in_freelists); | |
231 | |
232 /* Any name not mentioned in the IL and not in the feelists | |
233 has been leaked. */ | |
234 EXECUTE_IF_AND_COMPL_IN_BITMAP(all_names, names_in_il, | |
235 UNUSED_NAME_VERSION + 1, i, bi) | |
236 gcc_assert (!ssa_name (i)); | |
237 } | |
238 | |
239 /* Move all SSA_NAMEs from FREE_SSA_NAMES_QUEUE to FREE_SSA_NAMES. | |
240 | |
241 We do not, but should have a mode to verify the state of the SSA_NAMEs | |
242 lists. In particular at this point every name must be in the IL, | |
243 on the free list or in the queue. Anything else is an error. */ | |
244 | |
245 void | |
246 flush_ssaname_freelist (void) | |
247 { | |
131 | 248 /* If there were any SSA names released reset the SCEV cache. */ |
249 if (! vec_safe_is_empty (FREE_SSANAMES_QUEUE (cfun))) | |
250 scev_reset_htab (); | |
111 | 251 vec_safe_splice (FREE_SSANAMES (cfun), FREE_SSANAMES_QUEUE (cfun)); |
252 vec_safe_truncate (FREE_SSANAMES_QUEUE (cfun), 0); | |
253 } | |
0 | 254 |
145 | 255 /* Initialize SSA_NAME_IMM_USE_NODE of a SSA NAME. */ |
256 | |
257 void | |
258 init_ssa_name_imm_use (tree name) | |
259 { | |
260 use_operand_p imm; | |
261 imm = &(SSA_NAME_IMM_USE_NODE (name)); | |
262 imm->use = NULL; | |
263 imm->prev = imm; | |
264 imm->next = imm; | |
265 imm->loc.ssa_name = name; | |
266 } | |
267 | |
0 | 268 /* Return an SSA_NAME node for variable VAR defined in statement STMT |
269 in function FN. STMT may be an empty statement for artificial | |
270 references (e.g., default definitions created when a variable is | |
111 | 271 used without a preceding definition). If VERISON is not zero then |
272 allocate the SSA name with that version. */ | |
0 | 273 |
274 tree | |
111 | 275 make_ssa_name_fn (struct function *fn, tree var, gimple *stmt, |
276 unsigned int version) | |
0 | 277 { |
278 tree t; | |
111 | 279 gcc_assert (VAR_P (var) |
280 || TREE_CODE (var) == PARM_DECL | |
281 || TREE_CODE (var) == RESULT_DECL | |
282 || (TYPE_P (var) && is_gimple_reg_type (var))); | |
0 | 283 |
111 | 284 /* Get the specified SSA name version. */ |
285 if (version != 0) | |
0 | 286 { |
111 | 287 t = make_node (SSA_NAME); |
288 SSA_NAME_VERSION (t) = version; | |
289 if (version >= SSANAMES (fn)->length ()) | |
290 vec_safe_grow_cleared (SSANAMES (fn), version + 1); | |
291 gcc_assert ((*SSANAMES (fn))[version] == NULL); | |
292 (*SSANAMES (fn))[version] = t; | |
293 ssa_name_nodes_created++; | |
294 } | |
295 /* If our free list has an element, then use it. */ | |
296 else if (!vec_safe_is_empty (FREE_SSANAMES (fn))) | |
297 { | |
298 t = FREE_SSANAMES (fn)->pop (); | |
0 | 299 ssa_name_nodes_reused++; |
300 | |
301 /* The node was cleared out when we put it on the free list, so | |
302 there is no need to do so again here. */ | |
111 | 303 gcc_assert ((*SSANAMES (fn))[SSA_NAME_VERSION (t)] == NULL); |
304 (*SSANAMES (fn))[SSA_NAME_VERSION (t)] = t; | |
0 | 305 } |
306 else | |
307 { | |
308 t = make_node (SSA_NAME); | |
111 | 309 SSA_NAME_VERSION (t) = SSANAMES (fn)->length (); |
310 vec_safe_push (SSANAMES (fn), t); | |
0 | 311 ssa_name_nodes_created++; |
312 } | |
313 | |
111 | 314 if (TYPE_P (var)) |
315 { | |
316 TREE_TYPE (t) = TYPE_MAIN_VARIANT (var); | |
317 SET_SSA_NAME_VAR_OR_IDENTIFIER (t, NULL_TREE); | |
318 } | |
319 else | |
320 { | |
321 TREE_TYPE (t) = TREE_TYPE (var); | |
322 SET_SSA_NAME_VAR_OR_IDENTIFIER (t, var); | |
323 } | |
0 | 324 SSA_NAME_DEF_STMT (t) = stmt; |
111 | 325 if (POINTER_TYPE_P (TREE_TYPE (t))) |
326 SSA_NAME_PTR_INFO (t) = NULL; | |
327 else | |
328 SSA_NAME_RANGE_INFO (t) = NULL; | |
329 | |
0 | 330 SSA_NAME_IN_FREE_LIST (t) = 0; |
331 SSA_NAME_IS_DEFAULT_DEF (t) = 0; | |
145 | 332 init_ssa_name_imm_use (t); |
0 | 333 |
334 return t; | |
335 } | |
336 | |
111 | 337 /* Helper function for set_range_info. |
338 | |
339 Store range information RANGE_TYPE, MIN, and MAX to tree ssa_name | |
340 NAME. */ | |
341 | |
342 void | |
131 | 343 set_range_info_raw (tree name, enum value_range_kind range_type, |
111 | 344 const wide_int_ref &min, const wide_int_ref &max) |
345 { | |
346 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name))); | |
347 gcc_assert (range_type == VR_RANGE || range_type == VR_ANTI_RANGE); | |
348 range_info_def *ri = SSA_NAME_RANGE_INFO (name); | |
349 unsigned int precision = TYPE_PRECISION (TREE_TYPE (name)); | |
350 | |
351 /* Allocate if not available. */ | |
352 if (ri == NULL) | |
353 { | |
354 size_t size = (sizeof (range_info_def) | |
355 + trailing_wide_ints <3>::extra_size (precision)); | |
356 ri = static_cast<range_info_def *> (ggc_internal_alloc (size)); | |
357 ri->ints.set_precision (precision); | |
358 SSA_NAME_RANGE_INFO (name) = ri; | |
359 ri->set_nonzero_bits (wi::shwi (-1, precision)); | |
360 } | |
361 | |
362 /* Record the range type. */ | |
363 if (SSA_NAME_RANGE_TYPE (name) != range_type) | |
364 SSA_NAME_ANTI_RANGE_P (name) = (range_type == VR_ANTI_RANGE); | |
365 | |
366 /* Set the values. */ | |
367 ri->set_min (min); | |
368 ri->set_max (max); | |
369 | |
370 /* If it is a range, try to improve nonzero_bits from the min/max. */ | |
371 if (range_type == VR_RANGE) | |
372 { | |
373 wide_int xorv = ri->get_min () ^ ri->get_max (); | |
374 if (xorv != 0) | |
375 xorv = wi::mask (precision - wi::clz (xorv), false, precision); | |
376 ri->set_nonzero_bits (ri->get_nonzero_bits () & (ri->get_min () | xorv)); | |
377 } | |
378 } | |
379 | |
380 /* Store range information RANGE_TYPE, MIN, and MAX to tree ssa_name | |
381 NAME while making sure we don't store useless range info. */ | |
382 | |
383 void | |
131 | 384 set_range_info (tree name, enum value_range_kind range_type, |
111 | 385 const wide_int_ref &min, const wide_int_ref &max) |
386 { | |
387 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name))); | |
388 | |
389 /* A range of the entire domain is really no range at all. */ | |
390 tree type = TREE_TYPE (name); | |
391 if (min == wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type)) | |
392 && max == wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type))) | |
393 { | |
394 range_info_def *ri = SSA_NAME_RANGE_INFO (name); | |
395 if (ri == NULL) | |
396 return; | |
397 if (ri->get_nonzero_bits () == -1) | |
398 { | |
399 ggc_free (ri); | |
400 SSA_NAME_RANGE_INFO (name) = NULL; | |
401 return; | |
402 } | |
403 } | |
404 | |
405 set_range_info_raw (name, range_type, min, max); | |
406 } | |
407 | |
145 | 408 /* Store range information for NAME from a value_range. */ |
409 | |
410 void | |
411 set_range_info (tree name, const value_range &vr) | |
412 { | |
413 wide_int min = wi::to_wide (vr.min ()); | |
414 wide_int max = wi::to_wide (vr.max ()); | |
415 set_range_info (name, vr.kind (), min, max); | |
416 } | |
111 | 417 |
131 | 418 /* Gets range information MIN, MAX and returns enum value_range_kind |
419 corresponding to tree ssa_name NAME. enum value_range_kind returned | |
111 | 420 is used to determine if MIN and MAX are valid values. */ |
421 | |
131 | 422 enum value_range_kind |
111 | 423 get_range_info (const_tree name, wide_int *min, wide_int *max) |
424 { | |
425 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name))); | |
426 gcc_assert (min && max); | |
427 range_info_def *ri = SSA_NAME_RANGE_INFO (name); | |
428 | |
429 /* Return VR_VARYING for SSA_NAMEs with NULL RANGE_INFO or SSA_NAMEs | |
430 with integral types width > 2 * HOST_BITS_PER_WIDE_INT precision. */ | |
431 if (!ri || (GET_MODE_PRECISION (SCALAR_INT_TYPE_MODE (TREE_TYPE (name))) | |
432 > 2 * HOST_BITS_PER_WIDE_INT)) | |
433 return VR_VARYING; | |
434 | |
435 *min = ri->get_min (); | |
436 *max = ri->get_max (); | |
437 return SSA_NAME_RANGE_TYPE (name); | |
438 } | |
439 | |
145 | 440 /* Gets range information corresponding to ssa_name NAME and stores it |
441 in a value_range VR. Returns the value_range_kind. */ | |
442 | |
443 enum value_range_kind | |
444 get_range_info (const_tree name, value_range &vr) | |
445 { | |
446 tree min, max; | |
447 wide_int wmin, wmax; | |
448 enum value_range_kind kind = get_range_info (name, &wmin, &wmax); | |
449 | |
450 if (kind == VR_VARYING) | |
451 vr.set_varying (TREE_TYPE (name)); | |
452 else if (kind == VR_UNDEFINED) | |
453 vr.set_undefined (); | |
454 else | |
455 { | |
456 min = wide_int_to_tree (TREE_TYPE (name), wmin); | |
457 max = wide_int_to_tree (TREE_TYPE (name), wmax); | |
458 vr.set (min, max, kind); | |
459 } | |
460 return kind; | |
461 } | |
462 | |
111 | 463 /* Set nonnull attribute to pointer NAME. */ |
464 | |
465 void | |
466 set_ptr_nonnull (tree name) | |
467 { | |
468 gcc_assert (POINTER_TYPE_P (TREE_TYPE (name))); | |
469 struct ptr_info_def *pi = get_ptr_info (name); | |
470 pi->pt.null = 0; | |
471 } | |
472 | |
473 /* Return nonnull attribute of pointer NAME. */ | |
474 bool | |
475 get_ptr_nonnull (const_tree name) | |
476 { | |
477 gcc_assert (POINTER_TYPE_P (TREE_TYPE (name))); | |
478 struct ptr_info_def *pi = SSA_NAME_PTR_INFO (name); | |
479 if (pi == NULL) | |
480 return false; | |
481 /* TODO Now pt->null is conservatively set to true in PTA | |
482 analysis. vrp is the only pass (including ipa-vrp) | |
483 that clears pt.null via set_ptr_nonull when it knows | |
484 for sure. PTA will preserves the pt.null value set by VRP. | |
485 | |
486 When PTA analysis is improved, pt.anything, pt.nonlocal | |
487 and pt.escaped may also has to be considered before | |
488 deciding that pointer cannot point to NULL. */ | |
489 return !pi->pt.null; | |
490 } | |
491 | |
492 /* Change non-zero bits bitmask of NAME. */ | |
493 | |
494 void | |
495 set_nonzero_bits (tree name, const wide_int_ref &mask) | |
496 { | |
497 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name))); | |
498 if (SSA_NAME_RANGE_INFO (name) == NULL) | |
499 { | |
500 if (mask == -1) | |
501 return; | |
502 set_range_info_raw (name, VR_RANGE, | |
503 wi::to_wide (TYPE_MIN_VALUE (TREE_TYPE (name))), | |
504 wi::to_wide (TYPE_MAX_VALUE (TREE_TYPE (name)))); | |
505 } | |
506 range_info_def *ri = SSA_NAME_RANGE_INFO (name); | |
507 ri->set_nonzero_bits (mask); | |
508 } | |
509 | |
510 /* Return a widest_int with potentially non-zero bits in SSA_NAME | |
511 NAME, the constant for INTEGER_CST, or -1 if unknown. */ | |
512 | |
513 wide_int | |
514 get_nonzero_bits (const_tree name) | |
515 { | |
516 if (TREE_CODE (name) == INTEGER_CST) | |
517 return wi::to_wide (name); | |
518 | |
519 /* Use element_precision instead of TYPE_PRECISION so complex and | |
520 vector types get a non-zero precision. */ | |
521 unsigned int precision = element_precision (TREE_TYPE (name)); | |
522 if (POINTER_TYPE_P (TREE_TYPE (name))) | |
523 { | |
524 struct ptr_info_def *pi = SSA_NAME_PTR_INFO (name); | |
525 if (pi && pi->align) | |
526 return wi::shwi (-(HOST_WIDE_INT) pi->align | |
527 | (HOST_WIDE_INT) pi->misalign, precision); | |
528 return wi::shwi (-1, precision); | |
529 } | |
530 | |
531 range_info_def *ri = SSA_NAME_RANGE_INFO (name); | |
532 if (!ri) | |
533 return wi::shwi (-1, precision); | |
534 | |
535 return ri->get_nonzero_bits (); | |
536 } | |
537 | |
538 /* Return TRUE is OP, an SSA_NAME has a range of values [0..1], false | |
539 otherwise. | |
540 | |
541 This can be because it is a boolean type, any unsigned integral | |
542 type with a single bit of precision, or has known range of [0..1] | |
543 via VRP analysis. */ | |
544 | |
545 bool | |
546 ssa_name_has_boolean_range (tree op) | |
547 { | |
548 gcc_assert (TREE_CODE (op) == SSA_NAME); | |
549 | |
550 /* Boolean types always have a range [0..1]. */ | |
551 if (TREE_CODE (TREE_TYPE (op)) == BOOLEAN_TYPE) | |
552 return true; | |
553 | |
554 /* An integral type with a single bit of precision. */ | |
555 if (INTEGRAL_TYPE_P (TREE_TYPE (op)) | |
556 && TYPE_UNSIGNED (TREE_TYPE (op)) | |
557 && TYPE_PRECISION (TREE_TYPE (op)) == 1) | |
558 return true; | |
559 | |
560 /* An integral type with more precision, but the object | |
561 only takes on values [0..1] as determined by VRP | |
562 analysis. */ | |
563 if (INTEGRAL_TYPE_P (TREE_TYPE (op)) | |
564 && (TYPE_PRECISION (TREE_TYPE (op)) > 1) | |
565 && wi::eq_p (get_nonzero_bits (op), 1)) | |
566 return true; | |
567 | |
568 return false; | |
569 } | |
0 | 570 |
571 /* We no longer need the SSA_NAME expression VAR, release it so that | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
572 it may be reused. |
0 | 573 |
574 Note it is assumed that no calls to make_ssa_name will be made | |
575 until all uses of the ssa name are released and that the only | |
576 use of the SSA_NAME expression is to check its SSA_NAME_VAR. All | |
577 other fields must be assumed clobbered. */ | |
578 | |
579 void | |
111 | 580 release_ssa_name_fn (struct function *fn, tree var) |
0 | 581 { |
582 if (!var) | |
583 return; | |
584 | |
585 /* Never release the default definition for a symbol. It's a | |
586 special SSA name that should always exist once it's created. */ | |
587 if (SSA_NAME_IS_DEFAULT_DEF (var)) | |
588 return; | |
589 | |
590 /* If VAR has been registered for SSA updating, don't remove it. | |
591 After update_ssa has run, the name will be released. */ | |
592 if (name_registered_for_update_p (var)) | |
593 { | |
594 release_ssa_name_after_update_ssa (var); | |
595 return; | |
596 } | |
597 | |
598 /* release_ssa_name can be called multiple times on a single SSA_NAME. | |
599 However, it should only end up on our free list one time. We | |
600 keep a status bit in the SSA_NAME node itself to indicate it has | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
601 been put on the free list. |
0 | 602 |
145 | 603 Note that once on the freelist you cannot reference the SSA_NAME's |
0 | 604 defining statement. */ |
605 if (! SSA_NAME_IN_FREE_LIST (var)) | |
606 { | |
607 int saved_ssa_name_version = SSA_NAME_VERSION (var); | |
608 use_operand_p imm = &(SSA_NAME_IMM_USE_NODE (var)); | |
609 | |
131 | 610 if (MAY_HAVE_DEBUG_BIND_STMTS) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
611 insert_debug_temp_for_var_def (NULL, var); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
612 |
111 | 613 if (flag_checking) |
614 verify_imm_links (stderr, var); | |
0 | 615 while (imm->next != imm) |
616 delink_imm_use (imm->next); | |
617 | |
111 | 618 (*SSANAMES (fn))[SSA_NAME_VERSION (var)] = NULL_TREE; |
0 | 619 memset (var, 0, tree_size (var)); |
620 | |
621 imm->prev = imm; | |
622 imm->next = imm; | |
623 imm->loc.ssa_name = var; | |
624 | |
625 /* First put back the right tree node so that the tree checking | |
626 macros do not complain. */ | |
627 TREE_SET_CODE (var, SSA_NAME); | |
628 | |
629 /* Restore the version number. */ | |
630 SSA_NAME_VERSION (var) = saved_ssa_name_version; | |
631 | |
632 /* Note this SSA_NAME is now in the first list. */ | |
633 SSA_NAME_IN_FREE_LIST (var) = 1; | |
634 | |
145 | 635 /* Put in a non-NULL TREE_TYPE so dumping code will not ICE |
636 if it happens to come along a released SSA name and tries | |
637 to inspect its type. */ | |
638 TREE_TYPE (var) = error_mark_node; | |
639 | |
111 | 640 /* And finally queue it so that it will be put on the free list. */ |
641 vec_safe_push (FREE_SSANAMES_QUEUE (fn), var); | |
0 | 642 } |
643 } | |
644 | |
111 | 645 /* If the alignment of the pointer described by PI is known, return true and |
646 store the alignment and the deviation from it into *ALIGNP and *MISALIGNP | |
647 respectively. Otherwise return false. */ | |
648 | |
649 bool | |
650 get_ptr_info_alignment (struct ptr_info_def *pi, unsigned int *alignp, | |
651 unsigned int *misalignp) | |
652 { | |
653 if (pi->align) | |
654 { | |
655 *alignp = pi->align; | |
656 *misalignp = pi->misalign; | |
657 return true; | |
658 } | |
659 else | |
660 return false; | |
661 } | |
662 | |
663 /* State that the pointer described by PI has unknown alignment. */ | |
664 | |
665 void | |
666 mark_ptr_info_alignment_unknown (struct ptr_info_def *pi) | |
667 { | |
668 pi->align = 0; | |
669 pi->misalign = 0; | |
670 } | |
671 | |
672 /* Store the power-of-two byte alignment and the deviation from that | |
673 alignment of pointer described by PI to ALIOGN and MISALIGN | |
674 respectively. */ | |
675 | |
676 void | |
677 set_ptr_info_alignment (struct ptr_info_def *pi, unsigned int align, | |
678 unsigned int misalign) | |
679 { | |
680 gcc_checking_assert (align != 0); | |
681 gcc_assert ((align & (align - 1)) == 0); | |
682 gcc_assert ((misalign & ~(align - 1)) == 0); | |
683 | |
684 pi->align = align; | |
685 pi->misalign = misalign; | |
686 } | |
687 | |
688 /* If pointer described by PI has known alignment, increase its known | |
689 misalignment by INCREMENT modulo its current alignment. */ | |
690 | |
691 void | |
131 | 692 adjust_ptr_info_misalignment (struct ptr_info_def *pi, poly_uint64 increment) |
111 | 693 { |
694 if (pi->align != 0) | |
695 { | |
131 | 696 increment += pi->misalign; |
697 if (!known_misalignment (increment, pi->align, &pi->misalign)) | |
698 { | |
699 pi->align = known_alignment (increment); | |
700 pi->misalign = 0; | |
701 } | |
111 | 702 } |
703 } | |
0 | 704 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
705 /* Return the alias information associated with pointer T. It creates a |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
706 new instance if none existed. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
707 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
708 struct ptr_info_def * |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
709 get_ptr_info (tree t) |
0 | 710 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
711 struct ptr_info_def *pi; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
712 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
713 gcc_assert (POINTER_TYPE_P (TREE_TYPE (t))); |
0 | 714 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
715 pi = SSA_NAME_PTR_INFO (t); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
716 if (pi == NULL) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
717 { |
111 | 718 pi = ggc_cleared_alloc<ptr_info_def> (); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
719 pt_solution_reset (&pi->pt); |
111 | 720 mark_ptr_info_alignment_unknown (pi); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
721 SSA_NAME_PTR_INFO (t) = pi; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
722 } |
0 | 723 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
724 return pi; |
0 | 725 } |
726 | |
111 | 727 |
728 /* Creates a new SSA name using the template NAME tobe defined by | |
729 statement STMT in function FN. */ | |
730 | |
731 tree | |
732 copy_ssa_name_fn (struct function *fn, tree name, gimple *stmt) | |
733 { | |
734 tree new_name; | |
735 | |
736 if (SSA_NAME_VAR (name)) | |
737 new_name = make_ssa_name_fn (fn, SSA_NAME_VAR (name), stmt); | |
738 else | |
739 { | |
740 new_name = make_ssa_name_fn (fn, TREE_TYPE (name), stmt); | |
741 SET_SSA_NAME_VAR_OR_IDENTIFIER (new_name, SSA_NAME_IDENTIFIER (name)); | |
742 } | |
743 | |
744 return new_name; | |
745 } | |
746 | |
747 | |
0 | 748 /* Creates a duplicate of the ptr_info_def at PTR_INFO for use by |
749 the SSA name NAME. */ | |
750 | |
751 void | |
752 duplicate_ssa_name_ptr_info (tree name, struct ptr_info_def *ptr_info) | |
753 { | |
754 struct ptr_info_def *new_ptr_info; | |
755 | |
756 gcc_assert (POINTER_TYPE_P (TREE_TYPE (name))); | |
757 gcc_assert (!SSA_NAME_PTR_INFO (name)); | |
758 | |
759 if (!ptr_info) | |
760 return; | |
761 | |
111 | 762 new_ptr_info = ggc_alloc<ptr_info_def> (); |
0 | 763 *new_ptr_info = *ptr_info; |
764 | |
765 SSA_NAME_PTR_INFO (name) = new_ptr_info; | |
766 } | |
767 | |
111 | 768 /* Creates a duplicate of the range_info_def at RANGE_INFO of type |
769 RANGE_TYPE for use by the SSA name NAME. */ | |
770 void | |
131 | 771 duplicate_ssa_name_range_info (tree name, enum value_range_kind range_type, |
111 | 772 struct range_info_def *range_info) |
773 { | |
774 struct range_info_def *new_range_info; | |
0 | 775 |
111 | 776 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name))); |
777 gcc_assert (!SSA_NAME_RANGE_INFO (name)); | |
778 | |
779 if (!range_info) | |
780 return; | |
781 | |
782 unsigned int precision = TYPE_PRECISION (TREE_TYPE (name)); | |
783 size_t size = (sizeof (range_info_def) | |
784 + trailing_wide_ints <3>::extra_size (precision)); | |
785 new_range_info = static_cast<range_info_def *> (ggc_internal_alloc (size)); | |
786 memcpy (new_range_info, range_info, size); | |
787 | |
788 gcc_assert (range_type == VR_RANGE || range_type == VR_ANTI_RANGE); | |
789 SSA_NAME_ANTI_RANGE_P (name) = (range_type == VR_ANTI_RANGE); | |
790 SSA_NAME_RANGE_INFO (name) = new_range_info; | |
791 } | |
792 | |
793 | |
794 | |
795 /* Creates a duplicate of a ssa name NAME tobe defined by statement STMT | |
796 in function FN. */ | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
797 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
798 tree |
111 | 799 duplicate_ssa_name_fn (struct function *fn, tree name, gimple *stmt) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
800 { |
111 | 801 tree new_name = copy_ssa_name_fn (fn, name, stmt); |
802 if (POINTER_TYPE_P (TREE_TYPE (name))) | |
803 { | |
804 struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
805 |
111 | 806 if (old_ptr_info) |
807 duplicate_ssa_name_ptr_info (new_name, old_ptr_info); | |
808 } | |
809 else | |
810 { | |
811 struct range_info_def *old_range_info = SSA_NAME_RANGE_INFO (name); | |
812 | |
813 if (old_range_info) | |
814 duplicate_ssa_name_range_info (new_name, SSA_NAME_RANGE_TYPE (name), | |
815 old_range_info); | |
816 } | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
817 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
818 return new_name; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
819 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
820 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
821 |
111 | 822 /* Reset all flow sensitive data on NAME such as range-info, nonzero |
823 bits and alignment. */ | |
824 | |
825 void | |
826 reset_flow_sensitive_info (tree name) | |
827 { | |
828 if (POINTER_TYPE_P (TREE_TYPE (name))) | |
829 { | |
830 /* points-to info is not flow-sensitive. */ | |
831 if (SSA_NAME_PTR_INFO (name)) | |
145 | 832 { |
833 /* [E]VRP can derive context sensitive alignment info and | |
834 non-nullness properties. We must reset both. */ | |
835 mark_ptr_info_alignment_unknown (SSA_NAME_PTR_INFO (name)); | |
836 SSA_NAME_PTR_INFO (name)->pt.null = 1; | |
837 } | |
111 | 838 } |
839 else | |
840 SSA_NAME_RANGE_INFO (name) = NULL; | |
841 } | |
842 | |
843 /* Clear all flow sensitive data from all statements and PHI definitions | |
844 in BB. */ | |
845 | |
846 void | |
847 reset_flow_sensitive_info_in_bb (basic_block bb) | |
848 { | |
849 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); | |
850 gsi_next (&gsi)) | |
851 { | |
852 gimple *stmt = gsi_stmt (gsi); | |
853 ssa_op_iter i; | |
854 tree op; | |
855 FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_DEF) | |
856 reset_flow_sensitive_info (op); | |
857 } | |
858 | |
859 for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi); | |
860 gsi_next (&gsi)) | |
861 { | |
862 tree phi_def = gimple_phi_result (gsi.phi ()); | |
863 reset_flow_sensitive_info (phi_def); | |
864 } | |
865 } | |
866 | |
0 | 867 /* Release all the SSA_NAMEs created by STMT. */ |
868 | |
869 void | |
111 | 870 release_defs (gimple *stmt) |
0 | 871 { |
872 tree def; | |
873 ssa_op_iter iter; | |
874 | |
875 FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS) | |
876 if (TREE_CODE (def) == SSA_NAME) | |
877 release_ssa_name (def); | |
878 } | |
879 | |
880 | |
881 /* Replace the symbol associated with SSA_NAME with SYM. */ | |
882 | |
883 void | |
884 replace_ssa_name_symbol (tree ssa_name, tree sym) | |
885 { | |
111 | 886 SET_SSA_NAME_VAR_OR_IDENTIFIER (ssa_name, sym); |
0 | 887 TREE_TYPE (ssa_name) = TREE_TYPE (sym); |
888 } | |
889 | |
111 | 890 /* Release the vector of free SSA_NAMEs and compact the vector of SSA_NAMEs |
891 that are live. */ | |
892 | |
893 static void | |
894 release_free_names_and_compact_live_names (function *fun) | |
0 | 895 { |
111 | 896 unsigned i, j; |
897 int n = vec_safe_length (FREE_SSANAMES (fun)); | |
0 | 898 |
899 /* Now release the freelist. */ | |
111 | 900 vec_free (FREE_SSANAMES (fun)); |
901 | |
902 /* And compact the SSA number space. We make sure to not change the | |
903 relative order of SSA versions. */ | |
904 for (i = 1, j = 1; i < fun->gimple_df->ssa_names->length (); ++i) | |
0 | 905 { |
111 | 906 tree name = ssa_name (i); |
907 if (name) | |
908 { | |
909 if (i != j) | |
910 { | |
911 SSA_NAME_VERSION (name) = j; | |
912 (*fun->gimple_df->ssa_names)[j] = name; | |
913 } | |
914 j++; | |
915 } | |
0 | 916 } |
111 | 917 fun->gimple_df->ssa_names->truncate (j); |
918 | |
919 statistics_counter_event (fun, "SSA names released", n); | |
920 statistics_counter_event (fun, "SSA name holes removed", i - j); | |
921 if (dump_file) | |
922 fprintf (dump_file, "Released %i names, %.2f%%, removed %i holes\n", | |
923 n, n * 100.0 / num_ssa_names, i - j); | |
924 } | |
925 | |
926 /* Return SSA names that are unused to GGC memory and compact the SSA | |
927 version namespace. This is used to keep footprint of compiler during | |
928 interprocedural optimization. */ | |
929 | |
930 namespace { | |
0 | 931 |
111 | 932 const pass_data pass_data_release_ssa_names = |
933 { | |
934 GIMPLE_PASS, /* type */ | |
935 "release_ssa", /* name */ | |
936 OPTGROUP_NONE, /* optinfo_flags */ | |
937 TV_TREE_SSA_OTHER, /* tv_id */ | |
938 PROP_ssa, /* properties_required */ | |
939 0, /* properties_provided */ | |
940 0, /* properties_destroyed */ | |
941 TODO_remove_unused_locals, /* todo_flags_start */ | |
942 0, /* todo_flags_finish */ | |
943 }; | |
944 | |
945 class pass_release_ssa_names : public gimple_opt_pass | |
946 { | |
947 public: | |
948 pass_release_ssa_names (gcc::context *ctxt) | |
949 : gimple_opt_pass (pass_data_release_ssa_names, ctxt) | |
950 {} | |
951 | |
952 /* opt_pass methods: */ | |
953 virtual unsigned int execute (function *); | |
954 | |
955 }; // class pass_release_ssa_names | |
956 | |
957 unsigned int | |
958 pass_release_ssa_names::execute (function *fun) | |
959 { | |
960 release_free_names_and_compact_live_names (fun); | |
0 | 961 return 0; |
962 } | |
963 | |
111 | 964 } // anon namespace |
965 | |
966 gimple_opt_pass * | |
967 make_pass_release_ssa_names (gcc::context *ctxt) | |
0 | 968 { |
111 | 969 return new pass_release_ssa_names (ctxt); |
970 } |