Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-ssa-ter.c @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children | 77e2b8dfacca |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
1 /* Routines for performing Temporary Expression Replacement (TER) in SSA trees. | |
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, | |
3 Inc. | |
4 Contributed by Andrew MacLeod <amacleod@redhat.com> | |
5 | |
6 This file is part of GCC. | |
7 | |
8 GCC is free software; you can redistribute it and/or modify | |
9 it under the terms of the GNU General Public License as published by | |
10 the Free Software Foundation; either version 3, or (at your option) | |
11 any later version. | |
12 | |
13 GCC is distributed in the hope that it will be useful, | |
14 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 GNU General Public License for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with GCC; see the file COPYING3. If not see | |
20 <http://www.gnu.org/licenses/>. */ | |
21 | |
22 | |
23 #include "config.h" | |
24 #include "system.h" | |
25 #include "coretypes.h" | |
26 #include "tm.h" | |
27 #include "tree.h" | |
28 #include "diagnostic.h" | |
29 #include "bitmap.h" | |
30 #include "tree-flow.h" | |
31 #include "tree-dump.h" | |
32 #include "tree-ssa-live.h" | |
33 #include "flags.h" | |
34 | |
35 | |
36 /* Temporary Expression Replacement (TER) | |
37 | |
38 Replace SSA version variables during out-of-ssa with their defining | |
39 expression if there is only one use of the variable. | |
40 | |
41 This pass is required in order for the RTL expansion pass to see larger | |
42 chunks of code. This allows it to make better choices on RTL pattern | |
43 selection. When expand is rewritten and merged with out-of-ssa, and | |
44 understands SSA, this should be eliminated. | |
45 | |
46 A pass is made through the function, one block at a time. No cross block | |
47 information is tracked. | |
48 | |
49 Variables which only have one use, and whose defining stmt is considered | |
50 a replaceable expression (see is_replaceable_p) are tracked to see whether | |
51 they can be replaced at their use location. | |
52 | |
53 n_12 = C * 10 | |
54 a_2 = b_5 + 6 | |
55 v_9 = a_2 * n_12 | |
56 | |
57 if there are the only use of n_12 and a_2, TER will substitute in their | |
58 expressions in v_9, and end up with: | |
59 | |
60 v_9 = (b_5 + 6) * (C * 10) | |
61 | |
62 which will then have the ssa_name assigned to regular variables, and the | |
63 resulting code which will be passed to the expander looks something like: | |
64 | |
65 v = (b + 6) * (C * 10) | |
66 | |
67 | |
68 This requires ensuring that none of the variables used by the expression | |
69 change between the def point and where it is used. Furthermore, if any | |
70 of the ssa_names used in this expression are themselves replaceable, we | |
71 have to ensure none of that expressions' arguments change either. | |
72 Although SSA_NAMES themselves don't change, this pass is performed after | |
73 coalescing has coalesced different SSA_NAMES together, so there could be a | |
74 definition of an SSA_NAME which is coalesced with a use that causes a | |
75 problem, i.e., | |
76 | |
77 PHI b_5 = <b_8(2), b_14(1)> | |
78 <...> | |
79 a_2 = b_5 + 6 | |
80 b_8 = c_4 + 4 | |
81 v_9 = a_2 * n_12 | |
82 <...> | |
83 | |
84 If b_5, b_8 and b_14 are all coalesced together... | |
85 The expression b_5 + 6 CANNOT replace the use in the statement defining v_9 | |
86 because b_8 is in fact killing the value of b_5 since they share a partition | |
87 and will be assigned the same memory or register location. | |
88 | |
89 TER implements this but stepping through the instructions in a block and | |
90 tracking potential expressions for replacement, and the partitions they are | |
91 dependent on. Expressions are represented by the SSA_NAME_VERSION of the | |
92 DEF on the LHS of a GIMPLE_ASSIGN and the expression is the RHS. | |
93 | |
94 When a stmt is determined to be a possible replacement expression, the | |
95 following steps are taken: | |
96 | |
97 EXPR_DECL_UID bitmap is allocated and set to the base variable UID of the | |
98 def and any uses in the expression. non-NULL means the expression is being | |
99 tracked. The UID's themselves are used to prevent TER substitution into | |
100 accumulating sequences, i.e., | |
101 | |
102 x = x + y | |
103 x = x + z | |
104 x = x + w | |
105 etc. | |
106 this can result in very large expressions which don't accomplish anything | |
107 see PR tree-optimization/17549. | |
108 | |
109 PARTITION_DEPENDENCIES is another bitmap array, and it has a bit set for any | |
110 partition which is used in the expression. This is primarily used to remove | |
111 an expression from the partition kill lists when a decision is made whether | |
112 to replace it or not. This is indexed by ssa version number as well, and | |
113 indicates a partition number. virtual operands are not tracked individually, | |
114 but they are summarized by an artificial partition called VIRTUAL_PARTITION. | |
115 This means a MAY or MUST def will kill *ALL* expressions that are dependent | |
116 on a virtual operand. | |
117 Note that the EXPR_DECL_UID and this bitmap represent very similar | |
118 information, but the info in one is not easy to obtain from the other. | |
119 | |
120 KILL_LIST is yet another bitmap array, this time it is indexed by partition | |
121 number, and represents a list of active expressions which will will no | |
122 longer be valid if a definition into this partition takes place. | |
123 | |
124 PARTITION_IN_USE is simply a bitmap which is used to track which partitions | |
125 currently have something in their kill list. This is used at the end of | |
126 a block to clear out the KILL_LIST bitmaps at the end of each block. | |
127 | |
128 NEW_REPLACEABLE_DEPENDENCIES is used as a temporary place to store | |
129 dependencies which will be reused by the current definition. All the uses | |
130 on an expression are processed before anything else is done. If a use is | |
131 determined to be a replaceable expression AND the current stmt is also going | |
132 to be replaceable, all the dependencies of this replaceable use will be | |
133 picked up by the current stmt's expression. Rather than recreate them, they | |
134 are simply copied here and then copied into the new expression when it is | |
135 processed. | |
136 | |
137 a_2 = b_5 + 6 | |
138 v_8 = a_2 + c_4 | |
139 | |
140 a_2's expression 'b_5 + 6' is determined to be replaceable at the use | |
141 location. It is dependent on the partition 'b_5' is in. This is cached into | |
142 the NEW_REPLACEABLE_DEPENDENCIES bitmap, and when v_8 is examined for | |
143 replaceability, it is a candidate, and it is dependent on the partition | |
144 b_5 is in *NOT* a_2, as well as c_4's partition. | |
145 | |
146 if v_8 is also replaceable: | |
147 | |
148 x_9 = v_8 * 5 | |
149 | |
150 x_9 is dependent on partitions b_5, and c_4 | |
151 | |
152 if a statement is found which has either of those partitions written to | |
153 before x_9 is used, then x_9 itself is NOT replaceable. */ | |
154 | |
155 | |
156 /* Temporary Expression Replacement (TER) table information. */ | |
157 | |
158 typedef struct temp_expr_table_d | |
159 { | |
160 var_map map; | |
161 bitmap *partition_dependencies; /* Partitions expr is dependent on. */ | |
162 gimple *replaceable_expressions; /* Replacement expression table. */ | |
163 bitmap *expr_decl_uids; /* Base uids of exprs. */ | |
164 bitmap *kill_list; /* Expr's killed by a partition. */ | |
165 int virtual_partition; /* Pseudo partition for virtual ops. */ | |
166 bitmap partition_in_use; /* Partitions with kill entries. */ | |
167 bitmap new_replaceable_dependencies; /* Holding place for pending dep's. */ | |
168 int *num_in_part; /* # of ssa_names in a partition. */ | |
169 } *temp_expr_table_p; | |
170 | |
171 /* Used to indicate a dependency on VDEFs. */ | |
172 #define VIRTUAL_PARTITION(table) (table->virtual_partition) | |
173 | |
174 #ifdef ENABLE_CHECKING | |
175 extern void debug_ter (FILE *, temp_expr_table_p); | |
176 #endif | |
177 | |
178 | |
179 /* Create a new TER table for MAP. */ | |
180 | |
181 static temp_expr_table_p | |
182 new_temp_expr_table (var_map map) | |
183 { | |
184 temp_expr_table_p t; | |
185 unsigned x; | |
186 | |
187 t = XNEW (struct temp_expr_table_d); | |
188 t->map = map; | |
189 | |
190 t->partition_dependencies = XCNEWVEC (bitmap, num_ssa_names + 1); | |
191 t->expr_decl_uids = XCNEWVEC (bitmap, num_ssa_names + 1); | |
192 t->kill_list = XCNEWVEC (bitmap, num_var_partitions (map) + 1); | |
193 | |
194 t->partition_in_use = BITMAP_ALLOC (NULL); | |
195 | |
196 t->virtual_partition = num_var_partitions (map); | |
197 t->new_replaceable_dependencies = BITMAP_ALLOC (NULL); | |
198 | |
199 t->replaceable_expressions = NULL; | |
200 t->num_in_part = XCNEWVEC (int, num_var_partitions (map)); | |
201 for (x = 1; x < num_ssa_names; x++) | |
202 { | |
203 int p; | |
204 tree name = ssa_name (x); | |
205 if (!name) | |
206 continue; | |
207 p = var_to_partition (map, name); | |
208 if (p != NO_PARTITION) | |
209 t->num_in_part[p]++; | |
210 } | |
211 | |
212 return t; | |
213 } | |
214 | |
215 | |
216 /* Free TER table T. If there are valid replacements, return the expression | |
217 vector. */ | |
218 | |
219 static gimple * | |
220 free_temp_expr_table (temp_expr_table_p t) | |
221 { | |
222 gimple *ret = NULL; | |
223 | |
224 #ifdef ENABLE_CHECKING | |
225 unsigned x; | |
226 for (x = 0; x <= num_var_partitions (t->map); x++) | |
227 gcc_assert (!t->kill_list[x]); | |
228 for (x = 0; x < num_ssa_names + 1; x++) | |
229 { | |
230 gcc_assert (t->expr_decl_uids[x] == NULL); | |
231 gcc_assert (t->partition_dependencies[x] == NULL); | |
232 } | |
233 #endif | |
234 | |
235 BITMAP_FREE (t->partition_in_use); | |
236 BITMAP_FREE (t->new_replaceable_dependencies); | |
237 | |
238 free (t->expr_decl_uids); | |
239 free (t->kill_list); | |
240 free (t->partition_dependencies); | |
241 free (t->num_in_part); | |
242 | |
243 if (t->replaceable_expressions) | |
244 ret = t->replaceable_expressions; | |
245 | |
246 free (t); | |
247 return ret; | |
248 } | |
249 | |
250 | |
251 /* Return TRUE if VERSION is to be replaced by an expression in TAB. */ | |
252 | |
253 static inline bool | |
254 version_to_be_replaced_p (temp_expr_table_p tab, int version) | |
255 { | |
256 if (!tab->replaceable_expressions) | |
257 return false; | |
258 return tab->replaceable_expressions[version] != NULL; | |
259 } | |
260 | |
261 | |
262 /* Add partition P to the list if partitions VERSION is dependent on. TAB is | |
263 the expression table */ | |
264 | |
265 static inline void | |
266 make_dependent_on_partition (temp_expr_table_p tab, int version, int p) | |
267 { | |
268 if (!tab->partition_dependencies[version]) | |
269 tab->partition_dependencies[version] = BITMAP_ALLOC (NULL); | |
270 | |
271 bitmap_set_bit (tab->partition_dependencies[version], p); | |
272 } | |
273 | |
274 | |
275 /* Add VER to the kill list for P. TAB is the expression table */ | |
276 | |
277 static inline void | |
278 add_to_partition_kill_list (temp_expr_table_p tab, int p, int ver) | |
279 { | |
280 if (!tab->kill_list[p]) | |
281 { | |
282 tab->kill_list[p] = BITMAP_ALLOC (NULL); | |
283 bitmap_set_bit (tab->partition_in_use, p); | |
284 } | |
285 bitmap_set_bit (tab->kill_list[p], ver); | |
286 } | |
287 | |
288 | |
289 /* Remove VER from the partition kill list for P. TAB is the expression | |
290 table. */ | |
291 | |
292 static inline void | |
293 remove_from_partition_kill_list (temp_expr_table_p tab, int p, int version) | |
294 { | |
295 #ifdef ENABLE_CHECKING | |
296 gcc_assert (tab->kill_list[p]); | |
297 #endif | |
298 bitmap_clear_bit (tab->kill_list[p], version); | |
299 if (bitmap_empty_p (tab->kill_list[p])) | |
300 { | |
301 bitmap_clear_bit (tab->partition_in_use, p); | |
302 BITMAP_FREE (tab->kill_list[p]); | |
303 } | |
304 } | |
305 | |
306 | |
307 /* Add a dependency between the def of ssa VERSION and VAR. If VAR is | |
308 replaceable by an expression, add a dependence each of the elements of the | |
309 expression. These are contained in the new_replaceable list. TAB is the | |
310 expression table. */ | |
311 | |
312 static void | |
313 add_dependence (temp_expr_table_p tab, int version, tree var) | |
314 { | |
315 int i; | |
316 bitmap_iterator bi; | |
317 unsigned x; | |
318 | |
319 i = SSA_NAME_VERSION (var); | |
320 if (version_to_be_replaced_p (tab, i)) | |
321 { | |
322 if (!bitmap_empty_p (tab->new_replaceable_dependencies)) | |
323 { | |
324 /* Version will now be killed by a write to any partition the | |
325 substituted expression would have been killed by. */ | |
326 EXECUTE_IF_SET_IN_BITMAP (tab->new_replaceable_dependencies, 0, x, bi) | |
327 add_to_partition_kill_list (tab, x, version); | |
328 | |
329 /* Rather than set partition_dependencies and in_use lists bit by | |
330 bit, simply OR in the new_replaceable_dependencies bits. */ | |
331 if (!tab->partition_dependencies[version]) | |
332 tab->partition_dependencies[version] = BITMAP_ALLOC (NULL); | |
333 bitmap_ior_into (tab->partition_dependencies[version], | |
334 tab->new_replaceable_dependencies); | |
335 bitmap_ior_into (tab->partition_in_use, | |
336 tab->new_replaceable_dependencies); | |
337 /* It is only necessary to add these once. */ | |
338 bitmap_clear (tab->new_replaceable_dependencies); | |
339 } | |
340 } | |
341 else | |
342 { | |
343 i = var_to_partition (tab->map, var); | |
344 #ifdef ENABLE_CHECKING | |
345 gcc_assert (i != NO_PARTITION); | |
346 gcc_assert (tab->num_in_part[i] != 0); | |
347 #endif | |
348 /* Only dependencies on ssa_names which are coalesced with something need | |
349 to be tracked. Partitions with containing only a single SSA_NAME | |
350 *cannot* have their value changed. */ | |
351 if (tab->num_in_part[i] > 1) | |
352 { | |
353 add_to_partition_kill_list (tab, i, version); | |
354 make_dependent_on_partition (tab, version, i); | |
355 } | |
356 } | |
357 } | |
358 | |
359 | |
360 /* Return TRUE if expression STMT is suitable for replacement. */ | |
361 | |
362 static inline bool | |
363 is_replaceable_p (gimple stmt) | |
364 { | |
365 use_operand_p use_p; | |
366 tree def; | |
367 gimple use_stmt; | |
368 location_t locus1, locus2; | |
369 tree block1, block2; | |
370 | |
371 /* Only consider modify stmts. */ | |
372 if (!is_gimple_assign (stmt)) | |
373 return false; | |
374 | |
375 /* If the statement may throw an exception, it cannot be replaced. */ | |
376 if (stmt_could_throw_p (stmt)) | |
377 return false; | |
378 | |
379 /* Punt if there is more than 1 def. */ | |
380 def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF); | |
381 if (!def) | |
382 return false; | |
383 | |
384 /* Only consider definitions which have a single use. */ | |
385 if (!single_imm_use (def, &use_p, &use_stmt)) | |
386 return false; | |
387 | |
388 /* If the use isn't in this block, it wont be replaced either. */ | |
389 if (gimple_bb (use_stmt) != gimple_bb (stmt)) | |
390 return false; | |
391 | |
392 locus1 = gimple_location (stmt); | |
393 block1 = gimple_block (stmt); | |
394 | |
395 if (gimple_code (use_stmt) == GIMPLE_PHI) | |
396 { | |
397 locus2 = 0; | |
398 block2 = NULL_TREE; | |
399 } | |
400 else | |
401 { | |
402 locus2 = gimple_location (use_stmt); | |
403 block2 = gimple_block (use_stmt); | |
404 } | |
405 | |
406 if (!optimize | |
407 && ((locus1 && locus1 != locus2) || (block1 && block1 != block2))) | |
408 return false; | |
409 | |
410 /* Used in this block, but at the TOP of the block, not the end. */ | |
411 if (gimple_code (use_stmt) == GIMPLE_PHI) | |
412 return false; | |
413 | |
414 /* There must be no VDEFs. */ | |
415 if (!(ZERO_SSA_OPERANDS (stmt, SSA_OP_VDEF))) | |
416 return false; | |
417 | |
418 /* Without alias info we can't move around loads. */ | |
419 if (gimple_references_memory_p (stmt) && !optimize) | |
420 return false; | |
421 | |
422 /* Float expressions must go through memory if float-store is on. */ | |
423 if (flag_float_store | |
424 && FLOAT_TYPE_P (gimple_expr_type (stmt))) | |
425 return false; | |
426 | |
427 /* An assignment with a register variable on the RHS is not | |
428 replaceable. */ | |
429 if (gimple_assign_rhs_code (stmt) == VAR_DECL | |
430 && DECL_HARD_REGISTER (gimple_assign_rhs1 (stmt))) | |
431 return false; | |
432 | |
433 /* No function calls can be replaced. */ | |
434 if (is_gimple_call (stmt)) | |
435 return false; | |
436 | |
437 /* Leave any stmt with volatile operands alone as well. */ | |
438 if (gimple_has_volatile_ops (stmt)) | |
439 return false; | |
440 | |
441 return true; | |
442 } | |
443 | |
444 | |
445 /* This function will remove the expression for VERSION from replacement | |
446 consideration in table TAB. If FREE_EXPR is true, then remove the | |
447 expression from consideration as well by freeing the decl uid bitmap. */ | |
448 | |
449 static void | |
450 finished_with_expr (temp_expr_table_p tab, int version, bool free_expr) | |
451 { | |
452 unsigned i; | |
453 bitmap_iterator bi; | |
454 | |
455 /* Remove this expression from its dependent lists. The partition dependence | |
456 list is retained and transfered later to whomever uses this version. */ | |
457 if (tab->partition_dependencies[version]) | |
458 { | |
459 EXECUTE_IF_SET_IN_BITMAP (tab->partition_dependencies[version], 0, i, bi) | |
460 remove_from_partition_kill_list (tab, i, version); | |
461 BITMAP_FREE (tab->partition_dependencies[version]); | |
462 } | |
463 if (free_expr) | |
464 BITMAP_FREE (tab->expr_decl_uids[version]); | |
465 } | |
466 | |
467 | |
468 /* Create an expression entry for a replaceable expression. */ | |
469 | |
470 static void | |
471 process_replaceable (temp_expr_table_p tab, gimple stmt) | |
472 { | |
473 tree var, def, basevar; | |
474 int version; | |
475 ssa_op_iter iter; | |
476 bitmap def_vars, use_vars; | |
477 | |
478 #ifdef ENABLE_CHECKING | |
479 gcc_assert (is_replaceable_p (stmt)); | |
480 #endif | |
481 | |
482 def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF); | |
483 version = SSA_NAME_VERSION (def); | |
484 basevar = SSA_NAME_VAR (def); | |
485 def_vars = BITMAP_ALLOC (NULL); | |
486 | |
487 bitmap_set_bit (def_vars, DECL_UID (basevar)); | |
488 | |
489 /* Add this expression to the dependency list for each use partition. */ | |
490 FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE) | |
491 { | |
492 int var_version = SSA_NAME_VERSION (var); | |
493 | |
494 use_vars = tab->expr_decl_uids[var_version]; | |
495 add_dependence (tab, version, var); | |
496 if (use_vars) | |
497 { | |
498 bitmap_ior_into (def_vars, use_vars); | |
499 BITMAP_FREE (tab->expr_decl_uids[var_version]); | |
500 } | |
501 else | |
502 bitmap_set_bit (def_vars, DECL_UID (SSA_NAME_VAR (var))); | |
503 } | |
504 tab->expr_decl_uids[version] = def_vars; | |
505 | |
506 /* If there are VUSES, add a dependence on virtual defs. */ | |
507 if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VUSE)) | |
508 { | |
509 make_dependent_on_partition (tab, version, VIRTUAL_PARTITION (tab)); | |
510 add_to_partition_kill_list (tab, VIRTUAL_PARTITION (tab), version); | |
511 } | |
512 } | |
513 | |
514 | |
515 /* This function removes any expression in TAB which is dependent on PARTITION | |
516 from consideration, making it not replaceable. */ | |
517 | |
518 static inline void | |
519 kill_expr (temp_expr_table_p tab, int partition) | |
520 { | |
521 unsigned version; | |
522 | |
523 /* Mark every active expr dependent on this var as not replaceable. | |
524 finished_with_expr can modify the bitmap, so we can't execute over it. */ | |
525 while (tab->kill_list[partition]) | |
526 { | |
527 version = bitmap_first_set_bit (tab->kill_list[partition]); | |
528 finished_with_expr (tab, version, true); | |
529 } | |
530 | |
531 #ifdef ENABLE_CHECKING | |
532 gcc_assert (!tab->kill_list[partition]); | |
533 #endif | |
534 } | |
535 | |
536 | |
537 /* This function kills all expressions in TAB which are dependent on virtual | |
538 partitions. */ | |
539 | |
540 static inline void | |
541 kill_virtual_exprs (temp_expr_table_p tab) | |
542 { | |
543 kill_expr (tab, VIRTUAL_PARTITION (tab)); | |
544 } | |
545 | |
546 | |
547 /* Mark the expression associated with VAR as replaceable, and enter | |
548 the defining stmt into the partition_dependencies table TAB. If | |
549 MORE_REPLACING is true, accumulate the pending partition dependencies. */ | |
550 | |
551 static void | |
552 mark_replaceable (temp_expr_table_p tab, tree var, bool more_replacing) | |
553 { | |
554 int version = SSA_NAME_VERSION (var); | |
555 | |
556 /* Move the dependence list to the pending listpending. */ | |
557 if (more_replacing && tab->partition_dependencies[version]) | |
558 bitmap_ior_into (tab->new_replaceable_dependencies, | |
559 tab->partition_dependencies[version]); | |
560 | |
561 finished_with_expr (tab, version, !more_replacing); | |
562 | |
563 /* Set the replaceable expression. */ | |
564 if (!tab->replaceable_expressions) | |
565 tab->replaceable_expressions = XCNEWVEC (gimple, num_ssa_names + 1); | |
566 tab->replaceable_expressions[version] = SSA_NAME_DEF_STMT (var); | |
567 } | |
568 | |
569 | |
570 /* This function processes basic block BB, and looks for variables which can | |
571 be replaced by their expressions. Results are stored in the table TAB. */ | |
572 | |
573 static void | |
574 find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb) | |
575 { | |
576 gimple_stmt_iterator bsi; | |
577 gimple stmt; | |
578 tree def, use; | |
579 int partition; | |
580 var_map map = tab->map; | |
581 ssa_op_iter iter; | |
582 bool stmt_replaceable; | |
583 | |
584 for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) | |
585 { | |
586 stmt = gsi_stmt (bsi); | |
587 | |
588 stmt_replaceable = is_replaceable_p (stmt); | |
589 | |
590 /* Determine if this stmt finishes an existing expression. */ | |
591 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE) | |
592 { | |
593 unsigned ver = SSA_NAME_VERSION (use); | |
594 | |
595 /* If this use is a potential replacement variable, process it. */ | |
596 if (tab->expr_decl_uids[ver]) | |
597 { | |
598 bool same_root_var = false; | |
599 ssa_op_iter iter2; | |
600 bitmap vars = tab->expr_decl_uids[ver]; | |
601 | |
602 /* See if the root variables are the same. If they are, we | |
603 do not want to do the replacement to avoid problems with | |
604 code size, see PR tree-optimization/17549. */ | |
605 if (!bitmap_empty_p (vars)) | |
606 FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter2, SSA_OP_DEF) | |
607 { | |
608 if (bitmap_bit_p (vars, DECL_UID (SSA_NAME_VAR (def)))) | |
609 { | |
610 same_root_var = true; | |
611 break; | |
612 } | |
613 } | |
614 | |
615 /* Mark expression as replaceable unless stmt is volatile or the | |
616 def variable has the same root variable as something in the | |
617 substitution list. */ | |
618 if (gimple_has_volatile_ops (stmt) || same_root_var) | |
619 finished_with_expr (tab, ver, true); | |
620 else | |
621 mark_replaceable (tab, use, stmt_replaceable); | |
622 } | |
623 } | |
624 | |
625 /* Next, see if this stmt kills off an active expression. */ | |
626 FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF) | |
627 { | |
628 partition = var_to_partition (map, def); | |
629 if (partition != NO_PARTITION && tab->kill_list[partition]) | |
630 kill_expr (tab, partition); | |
631 } | |
632 | |
633 /* Now see if we are creating a new expression or not. */ | |
634 if (stmt_replaceable) | |
635 process_replaceable (tab, stmt); | |
636 | |
637 /* Free any unused dependency lists. */ | |
638 bitmap_clear (tab->new_replaceable_dependencies); | |
639 | |
640 /* A V_{MAY,MUST}_DEF kills any expression using a virtual operand, | |
641 including the current stmt. */ | |
642 if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS)) | |
643 kill_virtual_exprs (tab); | |
644 } | |
645 } | |
646 | |
647 | |
648 /* This function is the driver routine for replacement of temporary expressions | |
649 in the SSA->normal phase, operating on MAP. If there are replaceable | |
650 expressions, a table is returned which maps SSA versions to the | |
651 expressions they should be replaced with. A NULL_TREE indicates no | |
652 replacement should take place. If there are no replacements at all, | |
653 NULL is returned by the function, otherwise an expression vector indexed | |
654 by SSA_NAME version numbers. */ | |
655 | |
656 extern gimple * | |
657 find_replaceable_exprs (var_map map) | |
658 { | |
659 basic_block bb; | |
660 temp_expr_table_p table; | |
661 gimple *ret; | |
662 | |
663 table = new_temp_expr_table (map); | |
664 FOR_EACH_BB (bb) | |
665 { | |
666 find_replaceable_in_bb (table, bb); | |
667 #ifdef ENABLE_CHECKING | |
668 gcc_assert (bitmap_empty_p (table->partition_in_use)); | |
669 #endif | |
670 } | |
671 | |
672 ret = free_temp_expr_table (table); | |
673 return ret; | |
674 } | |
675 | |
676 /* Dump TER expression table EXPR to file F. */ | |
677 | |
678 void | |
679 dump_replaceable_exprs (FILE *f, gimple *expr) | |
680 { | |
681 tree var; | |
682 unsigned x; | |
683 | |
684 fprintf (f, "\nReplacing Expressions\n"); | |
685 for (x = 0; x < num_ssa_names; x++) | |
686 if (expr[x]) | |
687 { | |
688 var = ssa_name (x); | |
689 print_generic_expr (f, var, TDF_SLIM); | |
690 fprintf (f, " replace with --> "); | |
691 print_gimple_stmt (f, expr[x], 0, TDF_SLIM); | |
692 fprintf (f, "\n"); | |
693 } | |
694 fprintf (f, "\n"); | |
695 } | |
696 | |
697 | |
698 #ifdef ENABLE_CHECKING | |
699 /* Dump the status of the various tables in the expression table. This is used | |
700 exclusively to debug TER. F is the place to send debug info and T is the | |
701 table being debugged. */ | |
702 | |
703 void | |
704 debug_ter (FILE *f, temp_expr_table_p t) | |
705 { | |
706 unsigned x, y; | |
707 bitmap_iterator bi; | |
708 | |
709 fprintf (f, "\nDumping current state of TER\n virtual partition = %d\n", | |
710 VIRTUAL_PARTITION (t)); | |
711 if (t->replaceable_expressions) | |
712 dump_replaceable_exprs (f, t->replaceable_expressions); | |
713 fprintf (f, "Currently tracking the following expressions:\n"); | |
714 | |
715 for (x = 1; x < num_ssa_names; x++) | |
716 if (t->expr_decl_uids[x]) | |
717 { | |
718 print_generic_expr (stderr, ssa_name (x), TDF_SLIM); | |
719 fprintf (f, " dep-parts : "); | |
720 if (t->partition_dependencies[x] | |
721 && !bitmap_empty_p (t->partition_dependencies[x])) | |
722 { | |
723 EXECUTE_IF_SET_IN_BITMAP (t->partition_dependencies[x], 0, y, bi) | |
724 fprintf (f, "P%d ",y); | |
725 } | |
726 fprintf (stderr, " basedecls: "); | |
727 EXECUTE_IF_SET_IN_BITMAP (t->expr_decl_uids[x], 0, y, bi) | |
728 fprintf (f, "%d ",y); | |
729 fprintf (stderr, "\n"); | |
730 } | |
731 | |
732 bitmap_print (f, t->partition_in_use, "Partitions in use ", | |
733 "\npartition KILL lists:\n"); | |
734 | |
735 for (x = 0; x <= num_var_partitions (t->map); x++) | |
736 if (t->kill_list[x]) | |
737 { | |
738 fprintf (f, "Partition %d : ", x); | |
739 EXECUTE_IF_SET_IN_BITMAP (t->kill_list[x], 0, y, bi) | |
740 fprintf (f, "_%d ",y); | |
741 } | |
742 | |
743 fprintf (f, "\n----------\n"); | |
744 } | |
745 #endif |