]>
Commit | Line | Data |
---|---|---|
4ee9c684 | 1 | /* Generic routines for manipulating PHIs |
d353bf18 | 2 | Copyright (C) 2003-2015 Free Software Foundation, Inc. |
de5f9bd2 | 3 | |
4ee9c684 | 4 | This file is part of GCC. |
de5f9bd2 | 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. |
de5f9bd2 | 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. | |
de5f9bd2 | 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/>. */ | |
de5f9bd2 | 19 | |
4ee9c684 | 20 | #include "config.h" |
21 | #include "system.h" | |
22 | #include "coretypes.h" | |
23 | #include "tm.h" | |
24 | #include "tree.h" | |
94ea8568 | 25 | #include "predict.h" |
26 | #include "vec.h" | |
27 | #include "hashtab.h" | |
28 | #include "hash-set.h" | |
29 | #include "machmode.h" | |
30 | #include "hard-reg-set.h" | |
31 | #include "input.h" | |
32 | #include "function.h" | |
4ee9c684 | 33 | #include "basic-block.h" |
bc61cadb | 34 | #include "tree-ssa-alias.h" |
35 | #include "internal-fn.h" | |
36 | #include "gimple-expr.h" | |
37 | #include "is-a.h" | |
073c1fd5 | 38 | #include "gimple.h" |
dcf1a1ec | 39 | #include "gimple-iterator.h" |
073c1fd5 | 40 | #include "gimple-ssa.h" |
41 | #include "tree-phinodes.h" | |
42 | #include "ssa-iterators.h" | |
9ed99284 | 43 | #include "stringpool.h" |
073c1fd5 | 44 | #include "tree-ssanames.h" |
69ee5dbb | 45 | #include "tree-ssa.h" |
0b205f4c | 46 | #include "diagnostic-core.h" |
4ee9c684 | 47 | |
48 | /* Rewriting a function into SSA form can create a huge number of PHIs | |
49 | many of which may be thrown away shortly after their creation if jumps | |
de5f9bd2 | 50 | were threaded through PHI nodes. |
4ee9c684 | 51 | |
52 | While our garbage collection mechanisms will handle this situation, it | |
53 | is extremely wasteful to create nodes and throw them away, especially | |
54 | when the nodes can be reused. | |
55 | ||
56 | For PR 8361, we can significantly reduce the number of nodes allocated | |
57 | and thus the total amount of memory allocated by managing PHIs a | |
58 | little. This additionally helps reduce the amount of work done by the | |
59 | garbage collector. Similar results have been seen on a wider variety | |
60 | of tests (such as the compiler itself). | |
61 | ||
4ee9c684 | 62 | PHI nodes have different sizes, so we can't have a single list of all |
63 | the PHI nodes as it would be too expensive to walk down that list to | |
64 | find a PHI of a suitable size. | |
65 | ||
66 | Instead we have an array of lists of free PHI nodes. The array is | |
67 | indexed by the number of PHI alternatives that PHI node can hold. | |
68 | Except for the last array member, which holds all remaining PHI | |
69 | nodes. | |
70 | ||
71 | So to find a free PHI node, we compute its index into the free PHI | |
72 | node array and see if there are any elements with an exact match. | |
73 | If so, then we are done. Otherwise, we test the next larger size | |
74 | up and continue until we are in the last array element. | |
75 | ||
76 | We do not actually walk members of the last array element. While it | |
77 | might allow us to pick up a few reusable PHI nodes, it could potentially | |
78 | be very expensive if the program has released a bunch of large PHI nodes, | |
79 | but keeps asking for even larger PHI nodes. Experiments have shown that | |
80 | walking the elements of the last array entry would result in finding less | |
de5f9bd2 | 81 | than .1% additional reusable PHI nodes. |
4ee9c684 | 82 | |
83 | Note that we can never have less than two PHI argument slots. Thus, | |
84 | the -2 on all the calculations below. */ | |
85 | ||
86 | #define NUM_BUCKETS 10 | |
f1f41a6c | 87 | static GTY ((deletable (""))) vec<gimple, va_gc> *free_phinodes[NUM_BUCKETS - 2]; |
4ee9c684 | 88 | static unsigned long free_phinode_count; |
89 | ||
90 | static int ideal_phi_node_len (int); | |
4ee9c684 | 91 | |
4ee9c684 | 92 | unsigned int phi_nodes_reused; |
93 | unsigned int phi_nodes_created; | |
4ee9c684 | 94 | |
4ee9c684 | 95 | /* Dump some simple statistics regarding the re-use of PHI nodes. */ |
96 | ||
4ee9c684 | 97 | void |
98 | phinodes_print_statistics (void) | |
99 | { | |
100 | fprintf (stderr, "PHI nodes allocated: %u\n", phi_nodes_created); | |
101 | fprintf (stderr, "PHI nodes reused: %u\n", phi_nodes_reused); | |
102 | } | |
4ee9c684 | 103 | |
c1ba1d09 | 104 | /* Allocate a PHI node with at least LEN arguments. If the free list |
105 | happens to contain a PHI node with LEN arguments or more, return | |
106 | that one. */ | |
107 | ||
1a91d914 | 108 | static inline gphi * |
75a70cf9 | 109 | allocate_phi_node (size_t len) |
c1ba1d09 | 110 | { |
1a91d914 | 111 | gphi *phi; |
75a70cf9 | 112 | size_t bucket = NUM_BUCKETS - 2; |
1a91d914 | 113 | size_t size = sizeof (struct gphi) |
75a70cf9 | 114 | + (len - 1) * sizeof (struct phi_arg_d); |
c1ba1d09 | 115 | |
116 | if (free_phinode_count) | |
117 | for (bucket = len - 2; bucket < NUM_BUCKETS - 2; bucket++) | |
118 | if (free_phinodes[bucket]) | |
119 | break; | |
120 | ||
121 | /* If our free list has an element, then use it. */ | |
122 | if (bucket < NUM_BUCKETS - 2 | |
f1f41a6c | 123 | && gimple_phi_capacity ((*free_phinodes[bucket])[0]) >= len) |
c1ba1d09 | 124 | { |
125 | free_phinode_count--; | |
1a91d914 | 126 | phi = as_a <gphi *> (free_phinodes[bucket]->pop ()); |
f1f41a6c | 127 | if (free_phinodes[bucket]->is_empty ()) |
128 | vec_free (free_phinodes[bucket]); | |
ecd52ea9 | 129 | if (GATHER_STATISTICS) |
130 | phi_nodes_reused++; | |
c1ba1d09 | 131 | } |
132 | else | |
133 | { | |
1a91d914 | 134 | phi = static_cast <gphi *> (ggc_internal_alloc (size)); |
ecd52ea9 | 135 | if (GATHER_STATISTICS) |
75a70cf9 | 136 | { |
137 | enum gimple_alloc_kind kind = gimple_alloc_kind (GIMPLE_PHI); | |
ecd52ea9 | 138 | phi_nodes_created++; |
139 | gimple_alloc_counts[(int) kind]++; | |
140 | gimple_alloc_sizes[(int) kind] += size; | |
75a70cf9 | 141 | } |
c1ba1d09 | 142 | } |
143 | ||
144 | return phi; | |
145 | } | |
146 | ||
4ee9c684 | 147 | /* Given LEN, the original number of requested PHI arguments, return |
148 | a new, "ideal" length for the PHI node. The "ideal" length rounds | |
149 | the total size of the PHI node up to the next power of two bytes. | |
150 | ||
151 | Rounding up will not result in wasting any memory since the size request | |
152 | will be rounded up by the GC system anyway. [ Note this is not entirely | |
153 | true since the original length might have fit on one of the special | |
154 | GC pages. ] By rounding up, we may avoid the need to reallocate the | |
155 | PHI node later if we increase the number of arguments for the PHI. */ | |
156 | ||
157 | static int | |
158 | ideal_phi_node_len (int len) | |
159 | { | |
160 | size_t size, new_size; | |
161 | int log2, new_len; | |
162 | ||
163 | /* We do not support allocations of less than two PHI argument slots. */ | |
164 | if (len < 2) | |
165 | len = 2; | |
166 | ||
167 | /* Compute the number of bytes of the original request. */ | |
1a91d914 | 168 | size = sizeof (struct gphi) |
75a70cf9 | 169 | + (len - 1) * sizeof (struct phi_arg_d); |
4ee9c684 | 170 | |
171 | /* Round it up to the next power of two. */ | |
172 | log2 = ceil_log2 (size); | |
173 | new_size = 1 << log2; | |
de5f9bd2 | 174 | |
175 | /* Now compute and return the number of PHI argument slots given an | |
4ee9c684 | 176 | ideal size allocation. */ |
177 | new_len = len + (new_size - size) / sizeof (struct phi_arg_d); | |
178 | return new_len; | |
179 | } | |
180 | ||
88dbf20f | 181 | /* Return a PHI node with LEN argument slots for variable VAR. */ |
4ee9c684 | 182 | |
1a91d914 | 183 | static gphi * |
4ee9c684 | 184 | make_phi_node (tree var, int len) |
185 | { | |
1a91d914 | 186 | gphi *phi; |
22aa74c4 | 187 | int capacity, i; |
4ee9c684 | 188 | |
08d1df96 | 189 | capacity = ideal_phi_node_len (len); |
4ee9c684 | 190 | |
08d1df96 | 191 | phi = allocate_phi_node (capacity); |
4ee9c684 | 192 | |
cc890649 | 193 | /* We need to clear the entire PHI node, including the argument |
194 | portion, because we represent a "missing PHI argument" by placing | |
195 | NULL_TREE in PHI_ARG_DEF. */ | |
1a91d914 | 196 | memset (phi, 0, (sizeof (struct gphi) |
75a70cf9 | 197 | - sizeof (struct phi_arg_d) |
cc890649 | 198 | + sizeof (struct phi_arg_d) * len)); |
de6bd75e | 199 | phi->code = GIMPLE_PHI; |
e3a19533 | 200 | gimple_init_singleton (phi); |
de6bd75e | 201 | phi->nargs = len; |
202 | phi->capacity = capacity; | |
9c06f260 | 203 | if (!var) |
204 | ; | |
205 | else if (TREE_CODE (var) == SSA_NAME) | |
75a70cf9 | 206 | gimple_phi_set_result (phi, var); |
4ee9c684 | 207 | else |
75a70cf9 | 208 | gimple_phi_set_result (phi, make_ssa_name (var, phi)); |
4ee9c684 | 209 | |
22aa74c4 | 210 | for (i = 0; i < capacity; i++) |
211 | { | |
b66731e8 | 212 | use_operand_p imm; |
efbcb6de | 213 | |
214 | gimple_phi_arg_set_location (phi, i, UNKNOWN_LOCATION); | |
75a70cf9 | 215 | imm = gimple_phi_arg_imm_use_ptr (phi, i); |
216 | imm->use = gimple_phi_arg_def_ptr (phi, i); | |
22aa74c4 | 217 | imm->prev = NULL; |
218 | imm->next = NULL; | |
75a70cf9 | 219 | imm->loc.stmt = phi; |
22aa74c4 | 220 | } |
17889f9d | 221 | |
4ee9c684 | 222 | return phi; |
223 | } | |
224 | ||
225 | /* We no longer need PHI, release it so that it may be reused. */ | |
226 | ||
227 | void | |
75a70cf9 | 228 | release_phi_node (gimple phi) |
4ee9c684 | 229 | { |
75a70cf9 | 230 | size_t bucket; |
231 | size_t len = gimple_phi_capacity (phi); | |
232 | size_t x; | |
22aa74c4 | 233 | |
75a70cf9 | 234 | for (x = 0; x < gimple_phi_num_args (phi); x++) |
22aa74c4 | 235 | { |
b66731e8 | 236 | use_operand_p imm; |
75a70cf9 | 237 | imm = gimple_phi_arg_imm_use_ptr (phi, x); |
22aa74c4 | 238 | delink_imm_use (imm); |
239 | } | |
4ee9c684 | 240 | |
241 | bucket = len > NUM_BUCKETS - 1 ? NUM_BUCKETS - 1 : len; | |
242 | bucket -= 2; | |
f1f41a6c | 243 | vec_safe_push (free_phinodes[bucket], phi); |
4ee9c684 | 244 | free_phinode_count++; |
245 | } | |
246 | ||
75a70cf9 | 247 | |
4ee9c684 | 248 | /* Resize an existing PHI node. The only way is up. Return the |
249 | possibly relocated phi. */ | |
de5f9bd2 | 250 | |
1a91d914 | 251 | static gphi * |
252 | resize_phi_node (gphi *phi, size_t len) | |
4ee9c684 | 253 | { |
75a70cf9 | 254 | size_t old_size, i; |
1a91d914 | 255 | gphi *new_phi; |
8c0963c4 | 256 | |
e3a19533 | 257 | gcc_assert (len > gimple_phi_capacity (phi)); |
8c0963c4 | 258 | |
ee98f167 | 259 | /* The garbage collector will not look at the PHI node beyond the |
260 | first PHI_NUM_ARGS elements. Therefore, all we have to copy is a | |
261 | portion of the PHI node currently in use. */ | |
1a91d914 | 262 | old_size = sizeof (struct gphi) |
e3a19533 | 263 | + (gimple_phi_num_args (phi) - 1) * sizeof (struct phi_arg_d); |
4ee9c684 | 264 | |
c1ba1d09 | 265 | new_phi = allocate_phi_node (len); |
4ee9c684 | 266 | |
e3a19533 | 267 | memcpy (new_phi, phi, old_size); |
4ee9c684 | 268 | |
75a70cf9 | 269 | for (i = 0; i < gimple_phi_num_args (new_phi); i++) |
22aa74c4 | 270 | { |
b66731e8 | 271 | use_operand_p imm, old_imm; |
75a70cf9 | 272 | imm = gimple_phi_arg_imm_use_ptr (new_phi, i); |
e3a19533 | 273 | old_imm = gimple_phi_arg_imm_use_ptr (phi, i); |
75a70cf9 | 274 | imm->use = gimple_phi_arg_def_ptr (new_phi, i); |
22aa74c4 | 275 | relink_imm_use_stmt (imm, old_imm, new_phi); |
276 | } | |
277 | ||
de6bd75e | 278 | new_phi->capacity = len; |
de5f9bd2 | 279 | |
75a70cf9 | 280 | for (i = gimple_phi_num_args (new_phi); i < len; i++) |
22aa74c4 | 281 | { |
b66731e8 | 282 | use_operand_p imm; |
efbcb6de | 283 | |
284 | gimple_phi_arg_set_location (new_phi, i, UNKNOWN_LOCATION); | |
75a70cf9 | 285 | imm = gimple_phi_arg_imm_use_ptr (new_phi, i); |
286 | imm->use = gimple_phi_arg_def_ptr (new_phi, i); | |
22aa74c4 | 287 | imm->prev = NULL; |
288 | imm->next = NULL; | |
75a70cf9 | 289 | imm->loc.stmt = new_phi; |
22aa74c4 | 290 | } |
291 | ||
e3a19533 | 292 | return new_phi; |
4ee9c684 | 293 | } |
294 | ||
a77b4cde | 295 | /* Reserve PHI arguments for a new edge to basic block BB. */ |
296 | ||
297 | void | |
298 | reserve_phi_args_for_new_edge (basic_block bb) | |
299 | { | |
75a70cf9 | 300 | size_t len = EDGE_COUNT (bb->preds); |
301 | size_t cap = ideal_phi_node_len (len + 4); | |
1a91d914 | 302 | gphi_iterator gsi; |
a77b4cde | 303 | |
75a70cf9 | 304 | for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) |
a77b4cde | 305 | { |
1a91d914 | 306 | gphi *stmt = gsi.phi (); |
75a70cf9 | 307 | |
e3a19533 | 308 | if (len > gimple_phi_capacity (stmt)) |
a77b4cde | 309 | { |
1a91d914 | 310 | gphi *new_phi = resize_phi_node (stmt, cap); |
a77b4cde | 311 | |
75a70cf9 | 312 | /* The result of the PHI is defined by this PHI node. */ |
e3a19533 | 313 | SSA_NAME_DEF_STMT (gimple_phi_result (new_phi)) = new_phi; |
314 | gsi_set_stmt (&gsi, new_phi); | |
a77b4cde | 315 | |
e3a19533 | 316 | release_phi_node (stmt); |
317 | stmt = new_phi; | |
a77b4cde | 318 | } |
cc890649 | 319 | |
320 | /* We represent a "missing PHI argument" by placing NULL_TREE in | |
321 | the corresponding slot. If PHI arguments were added | |
322 | immediately after an edge is created, this zeroing would not | |
323 | be necessary, but unfortunately this is not the case. For | |
324 | example, the loop optimizer duplicates several basic blocks, | |
325 | redirects edges, and then fixes up PHI arguments later in | |
326 | batch. */ | |
e3a19533 | 327 | SET_PHI_ARG_DEF (stmt, len - 1, NULL_TREE); |
16f02f09 | 328 | gimple_phi_arg_set_location (stmt, len - 1, UNKNOWN_LOCATION); |
cc890649 | 329 | |
de6bd75e | 330 | stmt->nargs++; |
a77b4cde | 331 | } |
332 | } | |
333 | ||
255b6be7 | 334 | /* Adds PHI to BB. */ |
17889f9d | 335 | |
48e1416a | 336 | void |
1a91d914 | 337 | add_phi_node_to_bb (gphi *phi, basic_block bb) |
4ee9c684 | 338 | { |
e3a19533 | 339 | gimple_seq seq = phi_nodes (bb); |
4ee9c684 | 340 | /* Add the new PHI node to the list of PHI nodes for block BB. */ |
e3a19533 | 341 | if (seq == NULL) |
342 | set_phi_nodes (bb, gimple_seq_alloc_with_stmt (phi)); | |
343 | else | |
344 | { | |
345 | gimple_seq_add_stmt (&seq, phi); | |
346 | gcc_assert (seq == phi_nodes (bb)); | |
347 | } | |
4ee9c684 | 348 | |
349 | /* Associate BB to the PHI node. */ | |
75a70cf9 | 350 | gimple_set_bb (phi, bb); |
4ee9c684 | 351 | |
255b6be7 | 352 | } |
353 | ||
354 | /* Create a new PHI node for variable VAR at basic block BB. */ | |
355 | ||
1a91d914 | 356 | gphi * |
255b6be7 | 357 | create_phi_node (tree var, basic_block bb) |
358 | { | |
1a91d914 | 359 | gphi *phi = make_phi_node (var, EDGE_COUNT (bb->preds)); |
255b6be7 | 360 | |
361 | add_phi_node_to_bb (phi, bb); | |
4ee9c684 | 362 | return phi; |
363 | } | |
364 | ||
17889f9d | 365 | |
4ee9c684 | 366 | /* Add a new argument to PHI node PHI. DEF is the incoming reaching |
367 | definition and E is the edge through which DEF reaches PHI. The new | |
368 | argument is added at the end of the argument list. | |
369 | If PHI has reached its maximum capacity, add a few slots. In this case, | |
370 | PHI points to the reallocated phi node when we return. */ | |
371 | ||
372 | void | |
1a91d914 | 373 | add_phi_arg (gphi *phi, tree def, edge e, source_location locus) |
4ee9c684 | 374 | { |
2a6e956a | 375 | basic_block bb = e->dest; |
4ee9c684 | 376 | |
75a70cf9 | 377 | gcc_assert (bb == gimple_bb (phi)); |
2a6e956a | 378 | |
a77b4cde | 379 | /* We resize PHI nodes upon edge creation. We should always have |
380 | enough room at this point. */ | |
75a70cf9 | 381 | gcc_assert (gimple_phi_num_args (phi) <= gimple_phi_capacity (phi)); |
cc890649 | 382 | |
383 | /* We resize PHI nodes upon edge creation. We should always have | |
384 | enough room at this point. */ | |
75a70cf9 | 385 | gcc_assert (e->dest_idx < gimple_phi_num_args (phi)); |
4ee9c684 | 386 | |
387 | /* Copy propagation needs to know what object occur in abnormal | |
388 | PHI nodes. This is a convenient place to record such information. */ | |
389 | if (e->flags & EDGE_ABNORMAL) | |
390 | { | |
391 | SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def) = 1; | |
04cd6268 | 392 | SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi)) = 1; |
4ee9c684 | 393 | } |
394 | ||
04cd6268 | 395 | SET_PHI_ARG_DEF (phi, e->dest_idx, def); |
efbcb6de | 396 | gimple_phi_arg_set_location (phi, e->dest_idx, locus); |
4ee9c684 | 397 | } |
398 | ||
17889f9d | 399 | |
519d40d1 | 400 | /* Remove the Ith argument from PHI's argument list. This routine |
401 | implements removal by swapping the last alternative with the | |
402 | alternative we want to delete and then shrinking the vector, which | |
403 | is consistent with how we remove an edge from the edge vector. */ | |
4ee9c684 | 404 | |
a632e132 | 405 | static void |
1a91d914 | 406 | remove_phi_arg_num (gphi *phi, int i) |
4ee9c684 | 407 | { |
75a70cf9 | 408 | int num_elem = gimple_phi_num_args (phi); |
4ee9c684 | 409 | |
13e51728 | 410 | gcc_assert (i < num_elem); |
411 | ||
66c8f3a9 | 412 | /* Delink the item which is being removed. */ |
75a70cf9 | 413 | delink_imm_use (gimple_phi_arg_imm_use_ptr (phi, i)); |
66c8f3a9 | 414 | |
415 | /* If it is not the last element, move the last element | |
416 | to the element we want to delete, resetting all the links. */ | |
4ee9c684 | 417 | if (i != num_elem - 1) |
418 | { | |
66c8f3a9 | 419 | use_operand_p old_p, new_p; |
75a70cf9 | 420 | old_p = gimple_phi_arg_imm_use_ptr (phi, num_elem - 1); |
421 | new_p = gimple_phi_arg_imm_use_ptr (phi, i); | |
9fdf9cf6 | 422 | /* Set use on new node, and link into last element's place. */ |
66c8f3a9 | 423 | *(new_p->use) = *(old_p->use); |
424 | relink_imm_use (new_p, old_p); | |
efbcb6de | 425 | /* Move the location as well. */ |
48e1416a | 426 | gimple_phi_arg_set_location (phi, i, |
efbcb6de | 427 | gimple_phi_arg_location (phi, num_elem - 1)); |
4ee9c684 | 428 | } |
429 | ||
36fddb4b | 430 | /* Shrink the vector and return. Note that we do not have to clear |
6b34676b | 431 | PHI_ARG_DEF because the garbage collector will not look at those |
432 | elements beyond the first PHI_NUM_ARGS elements of the array. */ | |
de6bd75e | 433 | phi->nargs--; |
4ee9c684 | 434 | } |
435 | ||
17889f9d | 436 | |
1af6dc83 | 437 | /* Remove all PHI arguments associated with edge E. */ |
438 | ||
439 | void | |
440 | remove_phi_args (edge e) | |
441 | { | |
1a91d914 | 442 | gphi_iterator gsi; |
1af6dc83 | 443 | |
75a70cf9 | 444 | for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi)) |
1a91d914 | 445 | remove_phi_arg_num (gsi.phi (), |
de6bd75e | 446 | e->dest_idx); |
1af6dc83 | 447 | } |
448 | ||
17889f9d | 449 | |
75a70cf9 | 450 | /* Remove the PHI node pointed-to by iterator GSI from basic block BB. After |
451 | removal, iterator GSI is updated to point to the next PHI node in the | |
452 | sequence. If RELEASE_LHS_P is true, the LHS of this PHI node is released | |
453 | into the free pool of SSA names. */ | |
4ee9c684 | 454 | |
455 | void | |
75a70cf9 | 456 | remove_phi_node (gimple_stmt_iterator *gsi, bool release_lhs_p) |
4ee9c684 | 457 | { |
75a70cf9 | 458 | gimple phi = gsi_stmt (*gsi); |
41ad616d | 459 | |
460 | if (release_lhs_p) | |
461 | insert_debug_temps_for_defs (gsi); | |
462 | ||
75a70cf9 | 463 | gsi_remove (gsi, false); |
1e49fef2 | 464 | |
465 | /* If we are deleting the PHI node, then we should release the | |
466 | SSA_NAME node so that it can be reused. */ | |
1e49fef2 | 467 | release_phi_node (phi); |
17889f9d | 468 | if (release_lhs_p) |
75a70cf9 | 469 | release_ssa_name (gimple_phi_result (phi)); |
214ed29c | 470 | } |
4ee9c684 | 471 | |
899e6126 | 472 | /* Remove all the phi nodes from BB. */ |
473 | ||
474 | void | |
475 | remove_phi_nodes (basic_block bb) | |
476 | { | |
1a91d914 | 477 | gphi_iterator gsi; |
899e6126 | 478 | |
479 | for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); ) | |
480 | remove_phi_node (&gsi, true); | |
481 | ||
482 | set_phi_nodes (bb, NULL); | |
483 | } | |
484 | ||
424a4a92 | 485 | /* Given PHI, return its RHS if the PHI is a degenerate, otherwise return |
486 | NULL. */ | |
487 | ||
488 | tree | |
1a91d914 | 489 | degenerate_phi_result (gphi *phi) |
424a4a92 | 490 | { |
491 | tree lhs = gimple_phi_result (phi); | |
492 | tree val = NULL; | |
493 | size_t i; | |
494 | ||
495 | /* Ignoring arguments which are the same as LHS, if all the remaining | |
496 | arguments are the same, then the PHI is a degenerate and has the | |
497 | value of that common argument. */ | |
498 | for (i = 0; i < gimple_phi_num_args (phi); i++) | |
499 | { | |
500 | tree arg = gimple_phi_arg_def (phi, i); | |
501 | ||
502 | if (arg == lhs) | |
503 | continue; | |
504 | else if (!arg) | |
505 | break; | |
506 | else if (!val) | |
507 | val = arg; | |
508 | else if (arg == val) | |
509 | continue; | |
510 | /* We bring in some of operand_equal_p not only to speed things | |
511 | up, but also to avoid crashing when dereferencing the type of | |
512 | a released SSA name. */ | |
513 | else if (TREE_CODE (val) != TREE_CODE (arg) | |
514 | || TREE_CODE (val) == SSA_NAME | |
515 | || !operand_equal_p (arg, val, 0)) | |
516 | break; | |
517 | } | |
518 | return (i == gimple_phi_num_args (phi) ? val : NULL); | |
519 | } | |
520 | ||
dcf1a1ec | 521 | /* Set PHI nodes of a basic block BB to SEQ. */ |
522 | ||
523 | void | |
524 | set_phi_nodes (basic_block bb, gimple_seq seq) | |
525 | { | |
526 | gimple_stmt_iterator i; | |
527 | ||
528 | gcc_checking_assert (!(bb->flags & BB_RTL)); | |
529 | bb->il.gimple.phi_nodes = seq; | |
530 | if (seq) | |
531 | for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i)) | |
532 | gimple_set_bb (gsi_stmt (i), bb); | |
533 | } | |
424a4a92 | 534 | |
4ee9c684 | 535 | #include "gt-tree-phinodes.h" |