]>
Commit | Line | Data |
---|---|---|
bdf50f60 | 1 | /* Routines for performing Temporary Expression Replacement (TER) in SSA trees. |
f0b5f617 | 2 | Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, |
3 | Inc. | |
bdf50f60 | 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 | |
8c4c00c1 | 10 | the Free Software Foundation; either version 3, or (at your option) |
bdf50f60 | 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 | |
8c4c00c1 | 19 | along with GCC; see the file COPYING3. If not see |
20 | <http://www.gnu.org/licenses/>. */ | |
bdf50f60 | 21 | |
22 | ||
23 | #include "config.h" | |
24 | #include "system.h" | |
25 | #include "coretypes.h" | |
26 | #include "tm.h" | |
27 | #include "tree.h" | |
bdf50f60 | 28 | #include "diagnostic.h" |
29 | #include "bitmap.h" | |
30 | #include "tree-flow.h" | |
bdf50f60 | 31 | #include "tree-dump.h" |
32 | #include "tree-ssa-live.h" | |
bff4202c | 33 | #include "flags.h" |
bdf50f60 | 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 | |
f0b5f617 | 63 | resulting code which will be passed to the expander looks something like: |
bdf50f60 | 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 | |
f0b5f617 | 75 | problem, i.e., |
bdf50f60 | 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 | ||
7920eed5 | 84 | If b_5, b_8 and b_14 are all coalesced together... |
bdf50f60 | 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 | |
7920eed5 | 87 | and will be assigned the same memory or register location. |
bdf50f60 | 88 | |
89 | TER implements this but stepping through the instructions in a block and | |
7920eed5 | 90 | tracking potential expressions for replacement, and the partitions they are |
bdf50f60 | 91 | dependent on. Expressions are represented by the SSA_NAME_VERSION of the |
75a70cf9 | 92 | DEF on the LHS of a GIMPLE_ASSIGN and the expression is the RHS. |
bdf50f60 | 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 | |
f0b5f617 | 100 | accumulating sequences, i.e., |
101 | ||
bdf50f60 | 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, | |
7920eed5 | 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 | |
bdf50f60 | 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 | |
7920eed5 | 125 | currently have something in their kill list. This is used at the end of |
bdf50f60 | 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 | |
f0b5f617 | 129 | dependencies which will be reused by the current definition. All the uses |
bdf50f60 | 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 | |
f0b5f617 | 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 | |
bdf50f60 | 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. */ | |
75a70cf9 | 162 | gimple *replaceable_expressions; /* Replacement expression table. */ |
bdf50f60 | 163 | bitmap *expr_decl_uids; /* Base uids of exprs. */ |
164 | bitmap *kill_list; /* Expr's killed by a partition. */ | |
7920eed5 | 165 | int virtual_partition; /* Pseudo partition for virtual ops. */ |
166 | bitmap partition_in_use; /* Partitions with kill entries. */ | |
bdf50f60 | 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 | ||
4fb5e5ca | 171 | /* Used to indicate a dependency on VDEFs. */ |
bdf50f60 | 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 | ||
75a70cf9 | 219 | static gimple * |
bdf50f60 | 220 | free_temp_expr_table (temp_expr_table_p t) |
221 | { | |
75a70cf9 | 222 | gimple *ret = NULL; |
bdf50f60 | 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]); | |
464cc29a | 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 | } | |
bdf50f60 | 233 | #endif |
234 | ||
235 | BITMAP_FREE (t->partition_in_use); | |
c2df357d | 236 | BITMAP_FREE (t->new_replaceable_dependencies); |
bdf50f60 | 237 | |
bdf50f60 | 238 | free (t->expr_decl_uids); |
bdf50f60 | 239 | free (t->kill_list); |
240 | free (t->partition_dependencies); | |
c2df357d | 241 | free (t->num_in_part); |
bdf50f60 | 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; | |
75a70cf9 | 258 | return tab->replaceable_expressions[version] != NULL; |
bdf50f60 | 259 | } |
260 | ||
261 | ||
7920eed5 | 262 | /* Add partition P to the list if partitions VERSION is dependent on. TAB is |
bdf50f60 | 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 | |
75a70cf9 | 363 | is_replaceable_p (gimple stmt) |
bdf50f60 | 364 | { |
bdf50f60 | 365 | use_operand_p use_p; |
75a70cf9 | 366 | tree def; |
367 | gimple use_stmt; | |
bff4202c | 368 | location_t locus1, locus2; |
369 | tree block1, block2; | |
bdf50f60 | 370 | |
371 | /* Only consider modify stmts. */ | |
75a70cf9 | 372 | if (!is_gimple_assign (stmt)) |
bdf50f60 | 373 | return false; |
374 | ||
52dfd149 | 375 | /* If the statement may throw an exception, it cannot be replaced. */ |
75a70cf9 | 376 | if (stmt_could_throw_p (stmt)) |
52dfd149 | 377 | return false; |
378 | ||
bdf50f60 | 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. */ | |
75a70cf9 | 389 | if (gimple_bb (use_stmt) != gimple_bb (stmt)) |
bdf50f60 | 390 | return false; |
391 | ||
75a70cf9 | 392 | locus1 = gimple_location (stmt); |
393 | block1 = gimple_block (stmt); | |
394 | ||
395 | if (gimple_code (use_stmt) == GIMPLE_PHI) | |
bff4202c | 396 | { |
397 | locus2 = 0; | |
398 | block2 = NULL_TREE; | |
399 | } | |
400 | else | |
401 | { | |
75a70cf9 | 402 | locus2 = gimple_location (use_stmt); |
403 | block2 = gimple_block (use_stmt); | |
bff4202c | 404 | } |
405 | ||
406 | if (!optimize | |
407 | && ((locus1 && locus1 != locus2) || (block1 && block1 != block2))) | |
408 | return false; | |
409 | ||
bdf50f60 | 410 | /* Used in this block, but at the TOP of the block, not the end. */ |
75a70cf9 | 411 | if (gimple_code (use_stmt) == GIMPLE_PHI) |
bdf50f60 | 412 | return false; |
413 | ||
4fb5e5ca | 414 | /* There must be no VDEFs. */ |
dd277d48 | 415 | if (gimple_vdef (stmt)) |
bdf50f60 | 416 | return false; |
417 | ||
bff4202c | 418 | /* Without alias info we can't move around loads. */ |
75a70cf9 | 419 | if (gimple_references_memory_p (stmt) && !optimize) |
bff4202c | 420 | return false; |
421 | ||
bdf50f60 | 422 | /* Float expressions must go through memory if float-store is on. */ |
423 | if (flag_float_store | |
75a70cf9 | 424 | && FLOAT_TYPE_P (gimple_expr_type (stmt))) |
bdf50f60 | 425 | return false; |
426 | ||
dac21d57 | 427 | /* An assignment with a register variable on the RHS is not |
428 | replaceable. */ | |
75a70cf9 | 429 | if (gimple_assign_rhs_code (stmt) == VAR_DECL |
430 | && DECL_HARD_REGISTER (gimple_assign_rhs1 (stmt))) | |
dac21d57 | 431 | return false; |
432 | ||
abfb4f34 | 433 | /* No function calls can be replaced. */ |
75a70cf9 | 434 | if (is_gimple_call (stmt)) |
abfb4f34 | 435 | return false; |
bdf50f60 | 436 | |
d819917f | 437 | /* Leave any stmt with volatile operands alone as well. */ |
75a70cf9 | 438 | if (gimple_has_volatile_ops (stmt)) |
bdf50f60 | 439 | return false; |
bdf50f60 | 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 | ||
0b7780cd | 468 | /* Create an expression entry for a replaceable expression. */ |
bdf50f60 | 469 | |
470 | static void | |
75a70cf9 | 471 | process_replaceable (temp_expr_table_p tab, gimple stmt) |
bdf50f60 | 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. */ | |
dd277d48 | 507 | if (gimple_vuse (stmt)) |
bdf50f60 | 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 | |
f0b5f617 | 548 | the defining stmt into the partition_dependencies table TAB. If |
bdf50f60 | 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) | |
75a70cf9 | 565 | tab->replaceable_expressions = XCNEWVEC (gimple, num_ssa_names + 1); |
bdf50f60 | 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 | { | |
75a70cf9 | 576 | gimple_stmt_iterator bsi; |
577 | gimple stmt; | |
578 | tree def, use; | |
bdf50f60 | 579 | int partition; |
580 | var_map map = tab->map; | |
581 | ssa_op_iter iter; | |
582 | bool stmt_replaceable; | |
583 | ||
75a70cf9 | 584 | for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) |
bdf50f60 | 585 | { |
75a70cf9 | 586 | stmt = gsi_stmt (bsi); |
bdf50f60 | 587 | |
588 | stmt_replaceable = is_replaceable_p (stmt); | |
75a70cf9 | 589 | |
bdf50f60 | 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. */ | |
75a70cf9 | 618 | if (gimple_has_volatile_ops (stmt) || same_root_var) |
bdf50f60 | 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. */ | |
dd277d48 | 642 | if (gimple_vdef (stmt)) |
bdf50f60 | 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 | ||
75a70cf9 | 656 | extern gimple * |
bdf50f60 | 657 | find_replaceable_exprs (var_map map) |
658 | { | |
659 | basic_block bb; | |
660 | temp_expr_table_p table; | |
75a70cf9 | 661 | gimple *ret; |
bdf50f60 | 662 | |
663 | table = new_temp_expr_table (map); | |
664 | FOR_EACH_BB (bb) | |
665 | { | |
666 | find_replaceable_in_bb (table, bb); | |
bdf50f60 | 667 | #ifdef ENABLE_CHECKING |
464cc29a | 668 | gcc_assert (bitmap_empty_p (table->partition_in_use)); |
bdf50f60 | 669 | #endif |
670 | } | |
671 | ||
672 | ret = free_temp_expr_table (table); | |
673 | return ret; | |
464cc29a | 674 | } |
bdf50f60 | 675 | |
676 | /* Dump TER expression table EXPR to file F. */ | |
677 | ||
75a70cf9 | 678 | void |
679 | dump_replaceable_exprs (FILE *f, gimple *expr) | |
bdf50f60 | 680 | { |
75a70cf9 | 681 | tree var; |
682 | unsigned x; | |
bdf50f60 | 683 | |
684 | fprintf (f, "\nReplacing Expressions\n"); | |
75a70cf9 | 685 | for (x = 0; x < num_ssa_names; x++) |
bdf50f60 | 686 | if (expr[x]) |
687 | { | |
75a70cf9 | 688 | var = ssa_name (x); |
bdf50f60 | 689 | print_generic_expr (f, var, TDF_SLIM); |
690 | fprintf (f, " replace with --> "); | |
75a70cf9 | 691 | print_gimple_stmt (f, expr[x], 0, TDF_SLIM); |
bdf50f60 | 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 | ||
75a70cf9 | 703 | void |
bdf50f60 | 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 |