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