comparison gcc/tree-phinodes.c @ 16:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents f6334be47118
children 84e7813d76e9
comparison
equal deleted inserted replaced
15:561a7518be6b 16:04ced10e8804
1 /* Generic routines for manipulating PHIs 1 /* Generic routines for manipulating PHIs
2 Copyright (C) 2003, 2005, 2007, 2008, 2009, 2010 2 Copyright (C) 2003-2017 Free Software Foundation, Inc.
3 Free Software Foundation, Inc.
4 3
5 This file is part of GCC. 4 This file is part of GCC.
6 5
7 GCC is free software; you can redistribute it and/or modify 6 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 7 it under the terms of the GNU General Public License as published by
19 <http://www.gnu.org/licenses/>. */ 18 <http://www.gnu.org/licenses/>. */
20 19
21 #include "config.h" 20 #include "config.h"
22 #include "system.h" 21 #include "system.h"
23 #include "coretypes.h" 22 #include "coretypes.h"
24 #include "tm.h" 23 #include "backend.h"
25 #include "tree.h" 24 #include "tree.h"
26 #include "rtl.h" /* FIXME: Only for ceil_log2, of all things... */
27 #include "ggc.h"
28 #include "basic-block.h"
29 #include "tree-flow.h"
30 #include "diagnostic-core.h"
31 #include "gimple.h" 25 #include "gimple.h"
26 #include "ssa.h"
27 #include "fold-const.h"
28 #include "gimple-iterator.h"
29 #include "tree-ssa.h"
32 30
33 /* Rewriting a function into SSA form can create a huge number of PHIs 31 /* Rewriting a function into SSA form can create a huge number of PHIs
34 many of which may be thrown away shortly after their creation if jumps 32 many of which may be thrown away shortly after their creation if jumps
35 were threaded through PHI nodes. 33 were threaded through PHI nodes.
36 34
41 For PR 8361, we can significantly reduce the number of nodes allocated 39 For PR 8361, we can significantly reduce the number of nodes allocated
42 and thus the total amount of memory allocated by managing PHIs a 40 and thus the total amount of memory allocated by managing PHIs a
43 little. This additionally helps reduce the amount of work done by the 41 little. This additionally helps reduce the amount of work done by the
44 garbage collector. Similar results have been seen on a wider variety 42 garbage collector. Similar results have been seen on a wider variety
45 of tests (such as the compiler itself). 43 of tests (such as the compiler itself).
46
47 Right now we maintain our free list on a per-function basis. It may
48 or may not make sense to maintain the free list for the duration of
49 a compilation unit.
50
51 We could also use a zone allocator for these objects since they have
52 a very well defined lifetime. If someone wants to experiment with that
53 this is the place to try it.
54 44
55 PHI nodes have different sizes, so we can't have a single list of all 45 PHI nodes have different sizes, so we can't have a single list of all
56 the PHI nodes as it would be too expensive to walk down that list to 46 the PHI nodes as it would be too expensive to walk down that list to
57 find a PHI of a suitable size. 47 find a PHI of a suitable size.
58 48
75 65
76 Note that we can never have less than two PHI argument slots. Thus, 66 Note that we can never have less than two PHI argument slots. Thus,
77 the -2 on all the calculations below. */ 67 the -2 on all the calculations below. */
78 68
79 #define NUM_BUCKETS 10 69 #define NUM_BUCKETS 10
80 static GTY ((deletable (""))) VEC(gimple,gc) *free_phinodes[NUM_BUCKETS - 2]; 70 static GTY ((deletable (""))) vec<gimple *, va_gc> *free_phinodes[NUM_BUCKETS - 2];
81 static unsigned long free_phinode_count; 71 static unsigned long free_phinode_count;
82 72
83 static int ideal_phi_node_len (int); 73 static int ideal_phi_node_len (int);
84 74
85 #ifdef GATHER_STATISTICS
86 unsigned int phi_nodes_reused; 75 unsigned int phi_nodes_reused;
87 unsigned int phi_nodes_created; 76 unsigned int phi_nodes_created;
88 #endif
89
90 /* Initialize management of PHIs. */
91
92 void
93 init_phinodes (void)
94 {
95 int i;
96
97 for (i = 0; i < NUM_BUCKETS - 2; i++)
98 free_phinodes[i] = NULL;
99 free_phinode_count = 0;
100 }
101
102 /* Finalize management of PHIs. */
103
104 void
105 fini_phinodes (void)
106 {
107 int i;
108
109 for (i = 0; i < NUM_BUCKETS - 2; i++)
110 free_phinodes[i] = NULL;
111 free_phinode_count = 0;
112 }
113 77
114 /* Dump some simple statistics regarding the re-use of PHI nodes. */ 78 /* Dump some simple statistics regarding the re-use of PHI nodes. */
115 79
116 #ifdef GATHER_STATISTICS
117 void 80 void
118 phinodes_print_statistics (void) 81 phinodes_print_statistics (void)
119 { 82 {
120 fprintf (stderr, "PHI nodes allocated: %u\n", phi_nodes_created); 83 fprintf (stderr, "PHI nodes allocated: %u\n", phi_nodes_created);
121 fprintf (stderr, "PHI nodes reused: %u\n", phi_nodes_reused); 84 fprintf (stderr, "PHI nodes reused: %u\n", phi_nodes_reused);
122 } 85 }
123 #endif
124 86
125 /* Allocate a PHI node with at least LEN arguments. If the free list 87 /* Allocate a PHI node with at least LEN arguments. If the free list
126 happens to contain a PHI node with LEN arguments or more, return 88 happens to contain a PHI node with LEN arguments or more, return
127 that one. */ 89 that one. */
128 90
129 static inline gimple 91 static inline gphi *
130 allocate_phi_node (size_t len) 92 allocate_phi_node (size_t len)
131 { 93 {
132 gimple phi; 94 gphi *phi;
133 size_t bucket = NUM_BUCKETS - 2; 95 size_t bucket = NUM_BUCKETS - 2;
134 size_t size = sizeof (struct gimple_statement_phi) 96 size_t size = sizeof (struct gphi)
135 + (len - 1) * sizeof (struct phi_arg_d); 97 + (len - 1) * sizeof (struct phi_arg_d);
136 98
137 if (free_phinode_count) 99 if (free_phinode_count)
138 for (bucket = len - 2; bucket < NUM_BUCKETS - 2; bucket++) 100 for (bucket = len - 2; bucket < NUM_BUCKETS - 2; bucket++)
139 if (free_phinodes[bucket]) 101 if (free_phinodes[bucket])
140 break; 102 break;
141 103
142 /* If our free list has an element, then use it. */ 104 /* If our free list has an element, then use it. */
143 if (bucket < NUM_BUCKETS - 2 105 if (bucket < NUM_BUCKETS - 2
144 && gimple_phi_capacity (VEC_index (gimple, free_phinodes[bucket], 0)) 106 && gimple_phi_capacity ((*free_phinodes[bucket])[0]) >= len)
145 >= len)
146 { 107 {
147 free_phinode_count--; 108 free_phinode_count--;
148 phi = VEC_pop (gimple, free_phinodes[bucket]); 109 phi = as_a <gphi *> (free_phinodes[bucket]->pop ());
149 if (VEC_empty (gimple, free_phinodes[bucket])) 110 if (free_phinodes[bucket]->is_empty ())
150 VEC_free (gimple, gc, free_phinodes[bucket]); 111 vec_free (free_phinodes[bucket]);
151 #ifdef GATHER_STATISTICS 112 if (GATHER_STATISTICS)
152 phi_nodes_reused++; 113 phi_nodes_reused++;
153 #endif
154 } 114 }
155 else 115 else
156 { 116 {
157 phi = ggc_alloc_gimple_statement_d (size); 117 phi = static_cast <gphi *> (ggc_internal_alloc (size));
158 #ifdef GATHER_STATISTICS 118 if (GATHER_STATISTICS)
159 phi_nodes_created++;
160 { 119 {
161 enum gimple_alloc_kind kind = gimple_alloc_kind (GIMPLE_PHI); 120 enum gimple_alloc_kind kind = gimple_alloc_kind (GIMPLE_PHI);
162 gimple_alloc_counts[(int) kind]++; 121 phi_nodes_created++;
163 gimple_alloc_sizes[(int) kind] += size; 122 gimple_alloc_counts[(int) kind]++;
123 gimple_alloc_sizes[(int) kind] += size;
164 } 124 }
165 #endif
166 } 125 }
167 126
168 return phi; 127 return phi;
169 } 128 }
170 129
187 /* We do not support allocations of less than two PHI argument slots. */ 146 /* We do not support allocations of less than two PHI argument slots. */
188 if (len < 2) 147 if (len < 2)
189 len = 2; 148 len = 2;
190 149
191 /* Compute the number of bytes of the original request. */ 150 /* Compute the number of bytes of the original request. */
192 size = sizeof (struct gimple_statement_phi) 151 size = sizeof (struct gphi)
193 + (len - 1) * sizeof (struct phi_arg_d); 152 + (len - 1) * sizeof (struct phi_arg_d);
194 153
195 /* Round it up to the next power of two. */ 154 /* Round it up to the next power of two. */
196 log2 = ceil_log2 (size); 155 log2 = ceil_log2 (size);
197 new_size = 1 << log2; 156 new_size = 1 << log2;
202 return new_len; 161 return new_len;
203 } 162 }
204 163
205 /* Return a PHI node with LEN argument slots for variable VAR. */ 164 /* Return a PHI node with LEN argument slots for variable VAR. */
206 165
207 gimple 166 static gphi *
208 make_phi_node (tree var, int len) 167 make_phi_node (tree var, int len)
209 { 168 {
210 gimple phi; 169 gphi *phi;
211 int capacity, i; 170 int capacity, i;
212 171
213 capacity = ideal_phi_node_len (len); 172 capacity = ideal_phi_node_len (len);
214 173
215 phi = allocate_phi_node (capacity); 174 phi = allocate_phi_node (capacity);
216 175
217 /* We need to clear the entire PHI node, including the argument 176 /* We need to clear the entire PHI node, including the argument
218 portion, because we represent a "missing PHI argument" by placing 177 portion, because we represent a "missing PHI argument" by placing
219 NULL_TREE in PHI_ARG_DEF. */ 178 NULL_TREE in PHI_ARG_DEF. */
220 memset (phi, 0, (sizeof (struct gimple_statement_phi) 179 memset (phi, 0, (sizeof (struct gphi)
221 - sizeof (struct phi_arg_d) 180 - sizeof (struct phi_arg_d)
222 + sizeof (struct phi_arg_d) * len)); 181 + sizeof (struct phi_arg_d) * len));
223 phi->gsbase.code = GIMPLE_PHI; 182 phi->code = GIMPLE_PHI;
224 phi->gimple_phi.nargs = len; 183 gimple_init_singleton (phi);
225 phi->gimple_phi.capacity = capacity; 184 phi->nargs = len;
226 if (TREE_CODE (var) == SSA_NAME) 185 phi->capacity = capacity;
186 if (!var)
187 ;
188 else if (TREE_CODE (var) == SSA_NAME)
227 gimple_phi_set_result (phi, var); 189 gimple_phi_set_result (phi, var);
228 else 190 else
229 gimple_phi_set_result (phi, make_ssa_name (var, phi)); 191 gimple_phi_set_result (phi, make_ssa_name (var, phi));
230 192
231 for (i = 0; i < capacity; i++) 193 for (i = 0; i < len; i++)
232 { 194 {
233 use_operand_p imm; 195 use_operand_p imm;
234 196
235 gimple_phi_arg_set_location (phi, i, UNKNOWN_LOCATION); 197 gimple_phi_arg_set_location (phi, i, UNKNOWN_LOCATION);
236 imm = gimple_phi_arg_imm_use_ptr (phi, i); 198 imm = gimple_phi_arg_imm_use_ptr (phi, i);
243 return phi; 205 return phi;
244 } 206 }
245 207
246 /* We no longer need PHI, release it so that it may be reused. */ 208 /* We no longer need PHI, release it so that it may be reused. */
247 209
248 void 210 static void
249 release_phi_node (gimple phi) 211 release_phi_node (gimple *phi)
250 { 212 {
251 size_t bucket; 213 size_t bucket;
252 size_t len = gimple_phi_capacity (phi); 214 size_t len = gimple_phi_capacity (phi);
253 size_t x; 215 size_t x;
254 216
259 delink_imm_use (imm); 221 delink_imm_use (imm);
260 } 222 }
261 223
262 bucket = len > NUM_BUCKETS - 1 ? NUM_BUCKETS - 1 : len; 224 bucket = len > NUM_BUCKETS - 1 ? NUM_BUCKETS - 1 : len;
263 bucket -= 2; 225 bucket -= 2;
264 VEC_safe_push (gimple, gc, free_phinodes[bucket], phi); 226 vec_safe_push (free_phinodes[bucket], phi);
265 free_phinode_count++; 227 free_phinode_count++;
266 } 228 }
267 229
268 230
269 /* Resize an existing PHI node. The only way is up. Return the 231 /* Resize an existing PHI node. The only way is up. Return the
270 possibly relocated phi. */ 232 possibly relocated phi. */
271 233
272 static void 234 static gphi *
273 resize_phi_node (gimple *phi, size_t len) 235 resize_phi_node (gphi *phi, size_t len)
274 { 236 {
275 size_t old_size, i; 237 size_t old_size, i;
276 gimple new_phi; 238 gphi *new_phi;
277 239
278 gcc_assert (len > gimple_phi_capacity (*phi)); 240 gcc_assert (len > gimple_phi_capacity (phi));
279 241
280 /* The garbage collector will not look at the PHI node beyond the 242 /* The garbage collector will not look at the PHI node beyond the
281 first PHI_NUM_ARGS elements. Therefore, all we have to copy is a 243 first PHI_NUM_ARGS elements. Therefore, all we have to copy is a
282 portion of the PHI node currently in use. */ 244 portion of the PHI node currently in use. */
283 old_size = sizeof (struct gimple_statement_phi) 245 old_size = sizeof (struct gphi)
284 + (gimple_phi_num_args (*phi) - 1) * sizeof (struct phi_arg_d); 246 + (gimple_phi_num_args (phi) - 1) * sizeof (struct phi_arg_d);
285 247
286 new_phi = allocate_phi_node (len); 248 new_phi = allocate_phi_node (len);
287 249
288 memcpy (new_phi, *phi, old_size); 250 memcpy (new_phi, phi, old_size);
251 memset ((char *)new_phi + old_size, 0,
252 (sizeof (struct gphi)
253 - sizeof (struct phi_arg_d)
254 + sizeof (struct phi_arg_d) * len) - old_size);
289 255
290 for (i = 0; i < gimple_phi_num_args (new_phi); i++) 256 for (i = 0; i < gimple_phi_num_args (new_phi); i++)
291 { 257 {
292 use_operand_p imm, old_imm; 258 use_operand_p imm, old_imm;
293 imm = gimple_phi_arg_imm_use_ptr (new_phi, i); 259 imm = gimple_phi_arg_imm_use_ptr (new_phi, i);
294 old_imm = gimple_phi_arg_imm_use_ptr (*phi, i); 260 old_imm = gimple_phi_arg_imm_use_ptr (phi, i);
295 imm->use = gimple_phi_arg_def_ptr (new_phi, i); 261 imm->use = gimple_phi_arg_def_ptr (new_phi, i);
296 relink_imm_use_stmt (imm, old_imm, new_phi); 262 relink_imm_use_stmt (imm, old_imm, new_phi);
297 } 263 }
298 264
299 new_phi->gimple_phi.capacity = len; 265 new_phi->capacity = len;
300 266
301 for (i = gimple_phi_num_args (new_phi); i < len; i++) 267 return new_phi;
302 {
303 use_operand_p imm;
304
305 gimple_phi_arg_set_location (new_phi, i, UNKNOWN_LOCATION);
306 imm = gimple_phi_arg_imm_use_ptr (new_phi, i);
307 imm->use = gimple_phi_arg_def_ptr (new_phi, i);
308 imm->prev = NULL;
309 imm->next = NULL;
310 imm->loc.stmt = new_phi;
311 }
312
313 *phi = new_phi;
314 } 268 }
315 269
316 /* Reserve PHI arguments for a new edge to basic block BB. */ 270 /* Reserve PHI arguments for a new edge to basic block BB. */
317 271
318 void 272 void
319 reserve_phi_args_for_new_edge (basic_block bb) 273 reserve_phi_args_for_new_edge (basic_block bb)
320 { 274 {
321 size_t len = EDGE_COUNT (bb->preds); 275 size_t len = EDGE_COUNT (bb->preds);
322 size_t cap = ideal_phi_node_len (len + 4); 276 size_t cap = ideal_phi_node_len (len + 4);
323 gimple_stmt_iterator gsi; 277 gphi_iterator gsi;
324 278
325 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) 279 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
326 { 280 {
327 gimple *loc = gsi_stmt_ptr (&gsi); 281 gphi *stmt = gsi.phi ();
328 282
329 if (len > gimple_phi_capacity (*loc)) 283 if (len > gimple_phi_capacity (stmt))
330 { 284 {
331 gimple old_phi = *loc; 285 gphi *new_phi = resize_phi_node (stmt, cap);
332
333 resize_phi_node (loc, cap);
334 286
335 /* The result of the PHI is defined by this PHI node. */ 287 /* The result of the PHI is defined by this PHI node. */
336 SSA_NAME_DEF_STMT (gimple_phi_result (*loc)) = *loc; 288 SSA_NAME_DEF_STMT (gimple_phi_result (new_phi)) = new_phi;
337 289 gsi_set_stmt (&gsi, new_phi);
338 release_phi_node (old_phi); 290
291 release_phi_node (stmt);
292 stmt = new_phi;
339 } 293 }
294
295 stmt->nargs++;
340 296
341 /* We represent a "missing PHI argument" by placing NULL_TREE in 297 /* We represent a "missing PHI argument" by placing NULL_TREE in
342 the corresponding slot. If PHI arguments were added 298 the corresponding slot. If PHI arguments were added
343 immediately after an edge is created, this zeroing would not 299 immediately after an edge is created, this zeroing would not
344 be necessary, but unfortunately this is not the case. For 300 be necessary, but unfortunately this is not the case. For
345 example, the loop optimizer duplicates several basic blocks, 301 example, the loop optimizer duplicates several basic blocks,
346 redirects edges, and then fixes up PHI arguments later in 302 redirects edges, and then fixes up PHI arguments later in
347 batch. */ 303 batch. */
348 SET_PHI_ARG_DEF (*loc, len - 1, NULL_TREE); 304 use_operand_p imm = gimple_phi_arg_imm_use_ptr (stmt, len - 1);
349 305 imm->use = gimple_phi_arg_def_ptr (stmt, len - 1);
350 (*loc)->gimple_phi.nargs++; 306 imm->prev = NULL;
307 imm->next = NULL;
308 imm->loc.stmt = stmt;
309 SET_PHI_ARG_DEF (stmt, len - 1, NULL_TREE);
310 gimple_phi_arg_set_location (stmt, len - 1, UNKNOWN_LOCATION);
351 } 311 }
352 } 312 }
353 313
354 /* Adds PHI to BB. */ 314 /* Adds PHI to BB. */
355 315
356 void 316 void
357 add_phi_node_to_bb (gimple phi, basic_block bb) 317 add_phi_node_to_bb (gphi *phi, basic_block bb)
358 { 318 {
359 gimple_stmt_iterator gsi; 319 gimple_seq seq = phi_nodes (bb);
360 /* Add the new PHI node to the list of PHI nodes for block BB. */ 320 /* Add the new PHI node to the list of PHI nodes for block BB. */
361 if (phi_nodes (bb) == NULL) 321 if (seq == NULL)
362 set_phi_nodes (bb, gimple_seq_alloc ()); 322 set_phi_nodes (bb, gimple_seq_alloc_with_stmt (phi));
363 323 else
364 gsi = gsi_last (phi_nodes (bb)); 324 {
365 gsi_insert_after (&gsi, phi, GSI_NEW_STMT); 325 gimple_seq_add_stmt (&seq, phi);
326 gcc_assert (seq == phi_nodes (bb));
327 }
366 328
367 /* Associate BB to the PHI node. */ 329 /* Associate BB to the PHI node. */
368 gimple_set_bb (phi, bb); 330 gimple_set_bb (phi, bb);
369 331
370 } 332 }
371 333
372 /* Create a new PHI node for variable VAR at basic block BB. */ 334 /* Create a new PHI node for variable VAR at basic block BB. */
373 335
374 gimple 336 gphi *
375 create_phi_node (tree var, basic_block bb) 337 create_phi_node (tree var, basic_block bb)
376 { 338 {
377 gimple phi = make_phi_node (var, EDGE_COUNT (bb->preds)); 339 gphi *phi = make_phi_node (var, EDGE_COUNT (bb->preds));
378 340
379 add_phi_node_to_bb (phi, bb); 341 add_phi_node_to_bb (phi, bb);
380 return phi; 342 return phi;
381 } 343 }
382 344
386 argument is added at the end of the argument list. 348 argument is added at the end of the argument list.
387 If PHI has reached its maximum capacity, add a few slots. In this case, 349 If PHI has reached its maximum capacity, add a few slots. In this case,
388 PHI points to the reallocated phi node when we return. */ 350 PHI points to the reallocated phi node when we return. */
389 351
390 void 352 void
391 add_phi_arg (gimple phi, tree def, edge e, source_location locus) 353 add_phi_arg (gphi *phi, tree def, edge e, source_location locus)
392 { 354 {
393 basic_block bb = e->dest; 355 basic_block bb = e->dest;
394 356
395 gcc_assert (bb == gimple_bb (phi)); 357 gcc_assert (bb == gimple_bb (phi));
396 358
419 implements removal by swapping the last alternative with the 381 implements removal by swapping the last alternative with the
420 alternative we want to delete and then shrinking the vector, which 382 alternative we want to delete and then shrinking the vector, which
421 is consistent with how we remove an edge from the edge vector. */ 383 is consistent with how we remove an edge from the edge vector. */
422 384
423 static void 385 static void
424 remove_phi_arg_num (gimple phi, int i) 386 remove_phi_arg_num (gphi *phi, int i)
425 { 387 {
426 int num_elem = gimple_phi_num_args (phi); 388 int num_elem = gimple_phi_num_args (phi);
427 389
428 gcc_assert (i < num_elem); 390 gcc_assert (i < num_elem);
429 391
446 } 408 }
447 409
448 /* Shrink the vector and return. Note that we do not have to clear 410 /* Shrink the vector and return. Note that we do not have to clear
449 PHI_ARG_DEF because the garbage collector will not look at those 411 PHI_ARG_DEF because the garbage collector will not look at those
450 elements beyond the first PHI_NUM_ARGS elements of the array. */ 412 elements beyond the first PHI_NUM_ARGS elements of the array. */
451 phi->gimple_phi.nargs--; 413 phi->nargs--;
452 } 414 }
453 415
454 416
455 /* Remove all PHI arguments associated with edge E. */ 417 /* Remove all PHI arguments associated with edge E. */
456 418
457 void 419 void
458 remove_phi_args (edge e) 420 remove_phi_args (edge e)
459 { 421 {
460 gimple_stmt_iterator gsi; 422 gphi_iterator gsi;
461 423
462 for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi)) 424 for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
463 remove_phi_arg_num (gsi_stmt (gsi), e->dest_idx); 425 remove_phi_arg_num (gsi.phi (),
426 e->dest_idx);
464 } 427 }
465 428
466 429
467 /* Remove the PHI node pointed-to by iterator GSI from basic block BB. After 430 /* Remove the PHI node pointed-to by iterator GSI from basic block BB. After
468 removal, iterator GSI is updated to point to the next PHI node in the 431 removal, iterator GSI is updated to point to the next PHI node in the
470 into the free pool of SSA names. */ 433 into the free pool of SSA names. */
471 434
472 void 435 void
473 remove_phi_node (gimple_stmt_iterator *gsi, bool release_lhs_p) 436 remove_phi_node (gimple_stmt_iterator *gsi, bool release_lhs_p)
474 { 437 {
475 gimple phi = gsi_stmt (*gsi); 438 gimple *phi = gsi_stmt (*gsi);
476 439
477 if (release_lhs_p) 440 if (release_lhs_p)
478 insert_debug_temps_for_defs (gsi); 441 insert_debug_temps_for_defs (gsi);
479 442
480 gsi_remove (gsi, false); 443 gsi_remove (gsi, false);
489 /* Remove all the phi nodes from BB. */ 452 /* Remove all the phi nodes from BB. */
490 453
491 void 454 void
492 remove_phi_nodes (basic_block bb) 455 remove_phi_nodes (basic_block bb)
493 { 456 {
494 gimple_stmt_iterator gsi; 457 gphi_iterator gsi;
495 458
496 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); ) 459 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); )
497 remove_phi_node (&gsi, true); 460 remove_phi_node (&gsi, true);
498 461
499 set_phi_nodes (bb, NULL); 462 set_phi_nodes (bb, NULL);
500 } 463 }
501 464
465 /* Given PHI, return its RHS if the PHI is a degenerate, otherwise return
466 NULL. */
467
468 tree
469 degenerate_phi_result (gphi *phi)
470 {
471 tree lhs = gimple_phi_result (phi);
472 tree val = NULL;
473 size_t i;
474
475 /* Ignoring arguments which are the same as LHS, if all the remaining
476 arguments are the same, then the PHI is a degenerate and has the
477 value of that common argument. */
478 for (i = 0; i < gimple_phi_num_args (phi); i++)
479 {
480 tree arg = gimple_phi_arg_def (phi, i);
481
482 if (arg == lhs)
483 continue;
484 else if (!arg)
485 break;
486 else if (!val)
487 val = arg;
488 else if (arg == val)
489 continue;
490 /* We bring in some of operand_equal_p not only to speed things
491 up, but also to avoid crashing when dereferencing the type of
492 a released SSA name. */
493 else if (TREE_CODE (val) != TREE_CODE (arg)
494 || TREE_CODE (val) == SSA_NAME
495 || !operand_equal_p (arg, val, 0))
496 break;
497 }
498 return (i == gimple_phi_num_args (phi) ? val : NULL);
499 }
500
501 /* Set PHI nodes of a basic block BB to SEQ. */
502
503 void
504 set_phi_nodes (basic_block bb, gimple_seq seq)
505 {
506 gimple_stmt_iterator i;
507
508 gcc_checking_assert (!(bb->flags & BB_RTL));
509 bb->il.gimple.phi_nodes = seq;
510 if (seq)
511 for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
512 gimple_set_bb (gsi_stmt (i), bb);
513 }
514
502 #include "gt-tree-phinodes.h" 515 #include "gt-tree-phinodes.h"