Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-ssa-ter.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* Routines for performing Temporary Expression Replacement (TER) in SSA trees. | 1 /* Routines for performing Temporary Expression Replacement (TER) in SSA trees. |
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 | 2 Copyright (C) 2003-2017 Free Software Foundation, Inc. |
3 Free Software Foundation, Inc. | |
4 Contributed by Andrew MacLeod <amacleod@redhat.com> | 3 Contributed by Andrew MacLeod <amacleod@redhat.com> |
5 | 4 |
6 This file is part of GCC. | 5 This file is part of GCC. |
7 | 6 |
8 GCC is free software; you can redistribute it and/or modify | 7 GCC is free software; you can redistribute it and/or modify |
21 | 20 |
22 | 21 |
23 #include "config.h" | 22 #include "config.h" |
24 #include "system.h" | 23 #include "system.h" |
25 #include "coretypes.h" | 24 #include "coretypes.h" |
26 #include "tm.h" | 25 #include "backend.h" |
27 #include "tree.h" | 26 #include "tree.h" |
28 #include "tree-pretty-print.h" | 27 #include "gimple.h" |
28 #include "ssa.h" | |
29 #include "gimple-pretty-print.h" | 29 #include "gimple-pretty-print.h" |
30 #include "bitmap.h" | 30 #include "gimple-iterator.h" |
31 #include "tree-flow.h" | 31 #include "dumpfile.h" |
32 #include "tree-dump.h" | |
33 #include "tree-ssa-live.h" | 32 #include "tree-ssa-live.h" |
34 #include "flags.h" | 33 #include "tree-ssa-ter.h" |
34 #include "tree-outof-ssa.h" | |
35 #include "gimple-walk.h" | |
35 | 36 |
36 | 37 |
37 /* Temporary Expression Replacement (TER) | 38 /* Temporary Expression Replacement (TER) |
38 | 39 |
39 Replace SSA version variables during out-of-ssa with their defining | 40 Replace SSA version variables during out-of-ssa with their defining |
46 | 47 |
47 A pass is made through the function, one block at a time. No cross block | 48 A pass is made through the function, one block at a time. No cross block |
48 information is tracked. | 49 information is tracked. |
49 | 50 |
50 Variables which only have one use, and whose defining stmt is considered | 51 Variables which only have one use, and whose defining stmt is considered |
51 a replaceable expression (see is_replaceable_p) are tracked to see whether | 52 a replaceable expression (see ssa_is_replaceable_p) are tracked to see whether |
52 they can be replaced at their use location. | 53 they can be replaced at their use location. |
53 | 54 |
54 n_12 = C * 10 | 55 n_12 = C * 10 |
55 a_2 = b_5 + 6 | 56 a_2 = b_5 + 6 |
56 v_9 = a_2 * n_12 | 57 v_9 = a_2 * n_12 |
117 on a virtual operand. | 118 on a virtual operand. |
118 Note that the EXPR_DECL_UID and this bitmap represent very similar | 119 Note that the EXPR_DECL_UID and this bitmap represent very similar |
119 information, but the info in one is not easy to obtain from the other. | 120 information, but the info in one is not easy to obtain from the other. |
120 | 121 |
121 KILL_LIST is yet another bitmap array, this time it is indexed by partition | 122 KILL_LIST is yet another bitmap array, this time it is indexed by partition |
122 number, and represents a list of active expressions which will will no | 123 number, and represents a list of active expressions which will no |
123 longer be valid if a definition into this partition takes place. | 124 longer be valid if a definition into this partition takes place. |
124 | 125 |
125 PARTITION_IN_USE is simply a bitmap which is used to track which partitions | 126 PARTITION_IN_USE is simply a bitmap which is used to track which partitions |
126 currently have something in their kill list. This is used at the end of | 127 currently have something in their kill list. This is used at the end of |
127 a block to clear out the KILL_LIST bitmaps at the end of each block. | 128 a block to clear out the KILL_LIST bitmaps at the end of each block. |
154 before x_9 is used, then x_9 itself is NOT replaceable. */ | 155 before x_9 is used, then x_9 itself is NOT replaceable. */ |
155 | 156 |
156 | 157 |
157 /* Temporary Expression Replacement (TER) table information. */ | 158 /* Temporary Expression Replacement (TER) table information. */ |
158 | 159 |
159 typedef struct temp_expr_table_d | 160 struct temp_expr_table |
160 { | 161 { |
161 var_map map; | 162 var_map map; |
162 bitmap *partition_dependencies; /* Partitions expr is dependent on. */ | 163 bitmap *partition_dependencies; /* Partitions expr is dependent on. */ |
163 bitmap replaceable_expressions; /* Replacement expression table. */ | 164 bitmap replaceable_expressions; /* Replacement expression table. */ |
164 bitmap *expr_decl_uids; /* Base uids of exprs. */ | 165 bitmap *expr_decl_uids; /* Base uids of exprs. */ |
166 int virtual_partition; /* Pseudo partition for virtual ops. */ | 167 int virtual_partition; /* Pseudo partition for virtual ops. */ |
167 bitmap partition_in_use; /* Partitions with kill entries. */ | 168 bitmap partition_in_use; /* Partitions with kill entries. */ |
168 bitmap new_replaceable_dependencies; /* Holding place for pending dep's. */ | 169 bitmap new_replaceable_dependencies; /* Holding place for pending dep's. */ |
169 int *num_in_part; /* # of ssa_names in a partition. */ | 170 int *num_in_part; /* # of ssa_names in a partition. */ |
170 int *call_cnt; /* Call count at definition. */ | 171 int *call_cnt; /* Call count at definition. */ |
171 } *temp_expr_table_p; | 172 int *reg_vars_cnt; /* Number of register variable |
173 definitions encountered. */ | |
174 }; | |
172 | 175 |
173 /* Used to indicate a dependency on VDEFs. */ | 176 /* Used to indicate a dependency on VDEFs. */ |
174 #define VIRTUAL_PARTITION(table) (table->virtual_partition) | 177 #define VIRTUAL_PARTITION(table) (table->virtual_partition) |
175 | 178 |
176 #ifdef ENABLE_CHECKING | 179 /* A place for the many, many bitmaps we create. */ |
177 extern void debug_ter (FILE *, temp_expr_table_p); | 180 static bitmap_obstack ter_bitmap_obstack; |
178 #endif | 181 |
182 extern void debug_ter (FILE *, temp_expr_table *); | |
179 | 183 |
180 | 184 |
181 /* Create a new TER table for MAP. */ | 185 /* Create a new TER table for MAP. */ |
182 | 186 |
183 static temp_expr_table_p | 187 static temp_expr_table * |
184 new_temp_expr_table (var_map map) | 188 new_temp_expr_table (var_map map) |
185 { | 189 { |
186 temp_expr_table_p t; | 190 temp_expr_table *t = XNEW (struct temp_expr_table); |
187 unsigned x; | |
188 | |
189 t = XNEW (struct temp_expr_table_d); | |
190 t->map = map; | 191 t->map = map; |
191 | 192 |
192 t->partition_dependencies = XCNEWVEC (bitmap, num_ssa_names + 1); | 193 t->partition_dependencies = XCNEWVEC (bitmap, num_ssa_names + 1); |
193 t->expr_decl_uids = XCNEWVEC (bitmap, num_ssa_names + 1); | 194 t->expr_decl_uids = XCNEWVEC (bitmap, num_ssa_names + 1); |
194 t->kill_list = XCNEWVEC (bitmap, num_var_partitions (map) + 1); | 195 t->kill_list = XCNEWVEC (bitmap, num_var_partitions (map) + 1); |
195 | 196 |
196 t->partition_in_use = BITMAP_ALLOC (NULL); | 197 t->partition_in_use = BITMAP_ALLOC (&ter_bitmap_obstack); |
197 | 198 |
198 t->virtual_partition = num_var_partitions (map); | 199 t->virtual_partition = num_var_partitions (map); |
199 t->new_replaceable_dependencies = BITMAP_ALLOC (NULL); | 200 t->new_replaceable_dependencies = BITMAP_ALLOC (&ter_bitmap_obstack); |
200 | 201 |
201 t->replaceable_expressions = NULL; | 202 t->replaceable_expressions = NULL; |
202 t->num_in_part = XCNEWVEC (int, num_var_partitions (map)); | 203 t->num_in_part = XCNEWVEC (int, num_var_partitions (map)); |
203 for (x = 1; x < num_ssa_names; x++) | 204 |
205 unsigned x; | |
206 tree name; | |
207 | |
208 FOR_EACH_SSA_NAME (x, name, cfun) | |
204 { | 209 { |
205 int p; | 210 int p; |
206 tree name = ssa_name (x); | |
207 if (!name) | |
208 continue; | |
209 p = var_to_partition (map, name); | 211 p = var_to_partition (map, name); |
210 if (p != NO_PARTITION) | 212 if (p != NO_PARTITION) |
211 t->num_in_part[p]++; | 213 t->num_in_part[p]++; |
212 } | 214 } |
213 t->call_cnt = XCNEWVEC (int, num_ssa_names + 1); | 215 t->call_cnt = XCNEWVEC (int, num_ssa_names + 1); |
216 t->reg_vars_cnt = XCNEWVEC (int, num_ssa_names + 1); | |
214 | 217 |
215 return t; | 218 return t; |
216 } | 219 } |
217 | 220 |
218 | 221 |
219 /* Free TER table T. If there are valid replacements, return the expression | 222 /* Free TER table T. If there are valid replacements, return the expression |
220 vector. */ | 223 vector. */ |
221 | 224 |
222 static bitmap | 225 static bitmap |
223 free_temp_expr_table (temp_expr_table_p t) | 226 free_temp_expr_table (temp_expr_table *t) |
224 { | 227 { |
225 bitmap ret = NULL; | 228 bitmap ret = NULL; |
226 | 229 |
227 #ifdef ENABLE_CHECKING | 230 if (flag_checking) |
228 unsigned x; | 231 { |
229 for (x = 0; x <= num_var_partitions (t->map); x++) | 232 for (unsigned x = 0; x <= num_var_partitions (t->map); x++) |
230 gcc_assert (!t->kill_list[x]); | 233 gcc_assert (!t->kill_list[x]); |
231 for (x = 0; x < num_ssa_names; x++) | 234 for (unsigned x = 0; x < num_ssa_names; x++) |
232 { | 235 { |
233 gcc_assert (t->expr_decl_uids[x] == NULL); | 236 gcc_assert (t->expr_decl_uids[x] == NULL); |
234 gcc_assert (t->partition_dependencies[x] == NULL); | 237 gcc_assert (t->partition_dependencies[x] == NULL); |
235 } | 238 } |
236 #endif | 239 } |
237 | 240 |
238 BITMAP_FREE (t->partition_in_use); | 241 BITMAP_FREE (t->partition_in_use); |
239 BITMAP_FREE (t->new_replaceable_dependencies); | 242 BITMAP_FREE (t->new_replaceable_dependencies); |
240 | 243 |
241 free (t->expr_decl_uids); | 244 free (t->expr_decl_uids); |
242 free (t->kill_list); | 245 free (t->kill_list); |
243 free (t->partition_dependencies); | 246 free (t->partition_dependencies); |
244 free (t->num_in_part); | 247 free (t->num_in_part); |
245 free (t->call_cnt); | 248 free (t->call_cnt); |
249 free (t->reg_vars_cnt); | |
246 | 250 |
247 if (t->replaceable_expressions) | 251 if (t->replaceable_expressions) |
248 ret = t->replaceable_expressions; | 252 ret = t->replaceable_expressions; |
249 | 253 |
250 free (t); | 254 free (t); |
253 | 257 |
254 | 258 |
255 /* Return TRUE if VERSION is to be replaced by an expression in TAB. */ | 259 /* Return TRUE if VERSION is to be replaced by an expression in TAB. */ |
256 | 260 |
257 static inline bool | 261 static inline bool |
258 version_to_be_replaced_p (temp_expr_table_p tab, int version) | 262 version_to_be_replaced_p (temp_expr_table *tab, int version) |
259 { | 263 { |
260 if (!tab->replaceable_expressions) | 264 if (!tab->replaceable_expressions) |
261 return false; | 265 return false; |
262 return bitmap_bit_p (tab->replaceable_expressions, version); | 266 return bitmap_bit_p (tab->replaceable_expressions, version); |
263 } | 267 } |
265 | 269 |
266 /* Add partition P to the list if partitions VERSION is dependent on. TAB is | 270 /* Add partition P to the list if partitions VERSION is dependent on. TAB is |
267 the expression table */ | 271 the expression table */ |
268 | 272 |
269 static inline void | 273 static inline void |
270 make_dependent_on_partition (temp_expr_table_p tab, int version, int p) | 274 make_dependent_on_partition (temp_expr_table *tab, int version, int p) |
271 { | 275 { |
272 if (!tab->partition_dependencies[version]) | 276 if (!tab->partition_dependencies[version]) |
273 tab->partition_dependencies[version] = BITMAP_ALLOC (NULL); | 277 tab->partition_dependencies[version] = BITMAP_ALLOC (&ter_bitmap_obstack); |
274 | 278 |
275 bitmap_set_bit (tab->partition_dependencies[version], p); | 279 bitmap_set_bit (tab->partition_dependencies[version], p); |
276 } | 280 } |
277 | 281 |
278 | 282 |
279 /* Add VER to the kill list for P. TAB is the expression table */ | 283 /* Add VER to the kill list for P. TAB is the expression table */ |
280 | 284 |
281 static inline void | 285 static inline void |
282 add_to_partition_kill_list (temp_expr_table_p tab, int p, int ver) | 286 add_to_partition_kill_list (temp_expr_table *tab, int p, int ver) |
283 { | 287 { |
284 if (!tab->kill_list[p]) | 288 if (!tab->kill_list[p]) |
285 { | 289 { |
286 tab->kill_list[p] = BITMAP_ALLOC (NULL); | 290 tab->kill_list[p] = BITMAP_ALLOC (&ter_bitmap_obstack); |
287 bitmap_set_bit (tab->partition_in_use, p); | 291 bitmap_set_bit (tab->partition_in_use, p); |
288 } | 292 } |
289 bitmap_set_bit (tab->kill_list[p], ver); | 293 bitmap_set_bit (tab->kill_list[p], ver); |
290 } | 294 } |
291 | 295 |
292 | 296 |
293 /* Remove VER from the partition kill list for P. TAB is the expression | 297 /* Remove VER from the partition kill list for P. TAB is the expression |
294 table. */ | 298 table. */ |
295 | 299 |
296 static inline void | 300 static inline void |
297 remove_from_partition_kill_list (temp_expr_table_p tab, int p, int version) | 301 remove_from_partition_kill_list (temp_expr_table *tab, int p, int version) |
298 { | 302 { |
299 gcc_checking_assert (tab->kill_list[p]); | 303 gcc_checking_assert (tab->kill_list[p]); |
300 bitmap_clear_bit (tab->kill_list[p], version); | 304 bitmap_clear_bit (tab->kill_list[p], version); |
301 if (bitmap_empty_p (tab->kill_list[p])) | 305 if (bitmap_empty_p (tab->kill_list[p])) |
302 { | 306 { |
310 replaceable by an expression, add a dependence each of the elements of the | 314 replaceable by an expression, add a dependence each of the elements of the |
311 expression. These are contained in the new_replaceable list. TAB is the | 315 expression. These are contained in the new_replaceable list. TAB is the |
312 expression table. */ | 316 expression table. */ |
313 | 317 |
314 static void | 318 static void |
315 add_dependence (temp_expr_table_p tab, int version, tree var) | 319 add_dependence (temp_expr_table *tab, int version, tree var) |
316 { | 320 { |
317 int i; | 321 int i; |
318 bitmap_iterator bi; | 322 bitmap_iterator bi; |
319 unsigned x; | 323 unsigned x; |
320 | 324 |
329 add_to_partition_kill_list (tab, x, version); | 333 add_to_partition_kill_list (tab, x, version); |
330 | 334 |
331 /* Rather than set partition_dependencies and in_use lists bit by | 335 /* Rather than set partition_dependencies and in_use lists bit by |
332 bit, simply OR in the new_replaceable_dependencies bits. */ | 336 bit, simply OR in the new_replaceable_dependencies bits. */ |
333 if (!tab->partition_dependencies[version]) | 337 if (!tab->partition_dependencies[version]) |
334 tab->partition_dependencies[version] = BITMAP_ALLOC (NULL); | 338 tab->partition_dependencies[version] = |
339 BITMAP_ALLOC (&ter_bitmap_obstack); | |
335 bitmap_ior_into (tab->partition_dependencies[version], | 340 bitmap_ior_into (tab->partition_dependencies[version], |
336 tab->new_replaceable_dependencies); | 341 tab->new_replaceable_dependencies); |
337 bitmap_ior_into (tab->partition_in_use, | 342 bitmap_ior_into (tab->partition_in_use, |
338 tab->new_replaceable_dependencies); | 343 tab->new_replaceable_dependencies); |
339 /* It is only necessary to add these once. */ | 344 /* It is only necessary to add these once. */ |
355 } | 360 } |
356 } | 361 } |
357 } | 362 } |
358 | 363 |
359 | 364 |
360 /* Return TRUE if expression STMT is suitable for replacement. | |
361 TER is true if is_replaceable_p is called from within TER, false | |
362 when used from within stmt_is_replaceable_p, i.e. EXPAND_INITIALIZER | |
363 expansion. The differences are that with !TER some tests are skipped | |
364 to make it more aggressive (doesn't require the same bb, or for -O0 | |
365 same locus and same BLOCK), on the other side never considers memory | |
366 loads as replaceable, because those don't ever lead into constant | |
367 expressions. */ | |
368 | |
369 static inline bool | |
370 is_replaceable_p (gimple stmt, bool ter) | |
371 { | |
372 use_operand_p use_p; | |
373 tree def; | |
374 gimple use_stmt; | |
375 location_t locus1, locus2; | |
376 tree block1, block2; | |
377 | |
378 /* Only consider modify stmts. */ | |
379 if (!is_gimple_assign (stmt)) | |
380 return false; | |
381 | |
382 /* If the statement may throw an exception, it cannot be replaced. */ | |
383 if (stmt_could_throw_p (stmt)) | |
384 return false; | |
385 | |
386 /* Punt if there is more than 1 def. */ | |
387 def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF); | |
388 if (!def) | |
389 return false; | |
390 | |
391 /* Only consider definitions which have a single use. */ | |
392 if (!single_imm_use (def, &use_p, &use_stmt)) | |
393 return false; | |
394 | |
395 /* If the use isn't in this block, it wont be replaced either. */ | |
396 if (ter && gimple_bb (use_stmt) != gimple_bb (stmt)) | |
397 return false; | |
398 | |
399 locus1 = gimple_location (stmt); | |
400 block1 = gimple_block (stmt); | |
401 | |
402 if (gimple_code (use_stmt) == GIMPLE_PHI) | |
403 { | |
404 locus2 = 0; | |
405 block2 = NULL_TREE; | |
406 } | |
407 else | |
408 { | |
409 locus2 = gimple_location (use_stmt); | |
410 block2 = gimple_block (use_stmt); | |
411 } | |
412 | |
413 if (!optimize | |
414 && ter | |
415 && ((locus1 && locus1 != locus2) || (block1 && block1 != block2))) | |
416 return false; | |
417 | |
418 /* Used in this block, but at the TOP of the block, not the end. */ | |
419 if (gimple_code (use_stmt) == GIMPLE_PHI) | |
420 return false; | |
421 | |
422 /* There must be no VDEFs. */ | |
423 if (gimple_vdef (stmt)) | |
424 return false; | |
425 | |
426 /* Without alias info we can't move around loads. */ | |
427 if ((!optimize || !ter) | |
428 && gimple_assign_single_p (stmt) | |
429 && !is_gimple_val (gimple_assign_rhs1 (stmt))) | |
430 return false; | |
431 | |
432 /* Float expressions must go through memory if float-store is on. */ | |
433 if (flag_float_store | |
434 && FLOAT_TYPE_P (gimple_expr_type (stmt))) | |
435 return false; | |
436 | |
437 /* An assignment with a register variable on the RHS is not | |
438 replaceable. */ | |
439 if (gimple_assign_rhs_code (stmt) == VAR_DECL | |
440 && DECL_HARD_REGISTER (gimple_assign_rhs1 (stmt))) | |
441 return false; | |
442 | |
443 /* No function calls can be replaced. */ | |
444 if (is_gimple_call (stmt)) | |
445 return false; | |
446 | |
447 /* Leave any stmt with volatile operands alone as well. */ | |
448 if (gimple_has_volatile_ops (stmt)) | |
449 return false; | |
450 | |
451 return true; | |
452 } | |
453 | |
454 | |
455 /* Variant of is_replaceable_p test for use in EXPAND_INITIALIZER | |
456 expansion. */ | |
457 | |
458 bool | |
459 stmt_is_replaceable_p (gimple stmt) | |
460 { | |
461 return is_replaceable_p (stmt, false); | |
462 } | |
463 | |
464 | |
465 /* This function will remove the expression for VERSION from replacement | 365 /* This function will remove the expression for VERSION from replacement |
466 consideration in table TAB. If FREE_EXPR is true, then remove the | 366 consideration in table TAB. If FREE_EXPR is true, then remove the |
467 expression from consideration as well by freeing the decl uid bitmap. */ | 367 expression from consideration as well by freeing the decl uid bitmap. */ |
468 | 368 |
469 static void | 369 static void |
470 finished_with_expr (temp_expr_table_p tab, int version, bool free_expr) | 370 finished_with_expr (temp_expr_table *tab, int version, bool free_expr) |
471 { | 371 { |
472 unsigned i; | 372 unsigned i; |
473 bitmap_iterator bi; | 373 bitmap_iterator bi; |
474 | 374 |
475 /* Remove this expression from its dependent lists. The partition dependence | 375 /* Remove this expression from its dependent lists. The partition dependence |
476 list is retained and transfered later to whomever uses this version. */ | 376 list is retained and transferred later to whomever uses this version. */ |
477 if (tab->partition_dependencies[version]) | 377 if (tab->partition_dependencies[version]) |
478 { | 378 { |
479 EXECUTE_IF_SET_IN_BITMAP (tab->partition_dependencies[version], 0, i, bi) | 379 EXECUTE_IF_SET_IN_BITMAP (tab->partition_dependencies[version], 0, i, bi) |
480 remove_from_partition_kill_list (tab, i, version); | 380 remove_from_partition_kill_list (tab, i, version); |
481 BITMAP_FREE (tab->partition_dependencies[version]); | 381 BITMAP_FREE (tab->partition_dependencies[version]); |
483 if (free_expr) | 383 if (free_expr) |
484 BITMAP_FREE (tab->expr_decl_uids[version]); | 384 BITMAP_FREE (tab->expr_decl_uids[version]); |
485 } | 385 } |
486 | 386 |
487 | 387 |
388 /* Return TRUE if expression STMT is suitable for replacement. | |
389 In addition to ssa_is_replaceable_p, require the same bb, and for -O0 | |
390 same locus and same BLOCK), Considers memory loads as replaceable if aliasing | |
391 is available. */ | |
392 | |
393 static inline bool | |
394 ter_is_replaceable_p (gimple *stmt) | |
395 { | |
396 | |
397 if (ssa_is_replaceable_p (stmt)) | |
398 { | |
399 use_operand_p use_p; | |
400 tree def; | |
401 gimple *use_stmt; | |
402 location_t locus1, locus2; | |
403 tree block1, block2; | |
404 | |
405 /* Only consider definitions which have a single use. ssa_is_replaceable_p | |
406 already performed this check, but the use stmt pointer is required for | |
407 further checks. */ | |
408 def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF); | |
409 if (!single_imm_use (def, &use_p, &use_stmt)) | |
410 return false; | |
411 | |
412 /* If the use isn't in this block, it wont be replaced either. */ | |
413 if (gimple_bb (use_stmt) != gimple_bb (stmt)) | |
414 return false; | |
415 | |
416 locus1 = gimple_location (stmt); | |
417 block1 = LOCATION_BLOCK (locus1); | |
418 locus1 = LOCATION_LOCUS (locus1); | |
419 | |
420 if (gphi *phi = dyn_cast <gphi *> (use_stmt)) | |
421 locus2 = gimple_phi_arg_location (phi, | |
422 PHI_ARG_INDEX_FROM_USE (use_p)); | |
423 else | |
424 locus2 = gimple_location (use_stmt); | |
425 block2 = LOCATION_BLOCK (locus2); | |
426 locus2 = LOCATION_LOCUS (locus2); | |
427 | |
428 if ((!optimize || optimize_debug) | |
429 && ((locus1 != UNKNOWN_LOCATION && locus1 != locus2) | |
430 || (block1 != NULL_TREE && block1 != block2))) | |
431 return false; | |
432 | |
433 return true; | |
434 } | |
435 return false; | |
436 } | |
437 | |
438 | |
488 /* Create an expression entry for a replaceable expression. */ | 439 /* Create an expression entry for a replaceable expression. */ |
489 | 440 |
490 static void | 441 static void |
491 process_replaceable (temp_expr_table_p tab, gimple stmt, int call_cnt) | 442 process_replaceable (temp_expr_table *tab, gimple *stmt, int call_cnt, |
443 int reg_vars_cnt) | |
492 { | 444 { |
493 tree var, def, basevar; | 445 tree var, def, basevar; |
494 int version; | 446 int version; |
495 ssa_op_iter iter; | 447 ssa_op_iter iter; |
496 bitmap def_vars, use_vars; | 448 bitmap def_vars, use_vars; |
497 | 449 |
498 gcc_checking_assert (is_replaceable_p (stmt, true)); | 450 gcc_checking_assert (ter_is_replaceable_p (stmt)); |
499 | 451 |
500 def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF); | 452 def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF); |
501 version = SSA_NAME_VERSION (def); | 453 version = SSA_NAME_VERSION (def); |
454 def_vars = BITMAP_ALLOC (&ter_bitmap_obstack); | |
455 | |
502 basevar = SSA_NAME_VAR (def); | 456 basevar = SSA_NAME_VAR (def); |
503 def_vars = BITMAP_ALLOC (NULL); | 457 if (basevar) |
504 | 458 bitmap_set_bit (def_vars, DECL_UID (basevar)); |
505 bitmap_set_bit (def_vars, DECL_UID (basevar)); | |
506 | 459 |
507 /* Add this expression to the dependency list for each use partition. */ | 460 /* Add this expression to the dependency list for each use partition. */ |
508 FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE) | 461 FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE) |
509 { | 462 { |
510 int var_version = SSA_NAME_VERSION (var); | 463 int var_version = SSA_NAME_VERSION (var); |
514 if (use_vars) | 467 if (use_vars) |
515 { | 468 { |
516 bitmap_ior_into (def_vars, use_vars); | 469 bitmap_ior_into (def_vars, use_vars); |
517 BITMAP_FREE (tab->expr_decl_uids[var_version]); | 470 BITMAP_FREE (tab->expr_decl_uids[var_version]); |
518 } | 471 } |
519 else | 472 else if (SSA_NAME_VAR (var)) |
520 bitmap_set_bit (def_vars, DECL_UID (SSA_NAME_VAR (var))); | 473 bitmap_set_bit (def_vars, DECL_UID (SSA_NAME_VAR (var))); |
521 } | 474 } |
522 tab->expr_decl_uids[version] = def_vars; | 475 tab->expr_decl_uids[version] = def_vars; |
523 | 476 |
524 /* If there are VUSES, add a dependence on virtual defs. */ | 477 /* If there are VUSES, add a dependence on virtual defs. */ |
527 make_dependent_on_partition (tab, version, VIRTUAL_PARTITION (tab)); | 480 make_dependent_on_partition (tab, version, VIRTUAL_PARTITION (tab)); |
528 add_to_partition_kill_list (tab, VIRTUAL_PARTITION (tab), version); | 481 add_to_partition_kill_list (tab, VIRTUAL_PARTITION (tab), version); |
529 } | 482 } |
530 | 483 |
531 tab->call_cnt[version] = call_cnt; | 484 tab->call_cnt[version] = call_cnt; |
485 tab->reg_vars_cnt[version] = reg_vars_cnt; | |
532 } | 486 } |
533 | 487 |
534 | 488 |
535 /* This function removes any expression in TAB which is dependent on PARTITION | 489 /* This function removes any expression in TAB which is dependent on PARTITION |
536 from consideration, making it not replaceable. */ | 490 from consideration, making it not replaceable. */ |
537 | 491 |
538 static inline void | 492 static inline void |
539 kill_expr (temp_expr_table_p tab, int partition) | 493 kill_expr (temp_expr_table *tab, int partition) |
540 { | 494 { |
541 unsigned version; | 495 unsigned version; |
542 | 496 |
543 /* Mark every active expr dependent on this var as not replaceable. | 497 /* Mark every active expr dependent on this var as not replaceable. |
544 finished_with_expr can modify the bitmap, so we can't execute over it. */ | 498 finished_with_expr can modify the bitmap, so we can't execute over it. */ |
554 | 508 |
555 /* This function kills all expressions in TAB which are dependent on virtual | 509 /* This function kills all expressions in TAB which are dependent on virtual |
556 partitions. */ | 510 partitions. */ |
557 | 511 |
558 static inline void | 512 static inline void |
559 kill_virtual_exprs (temp_expr_table_p tab) | 513 kill_virtual_exprs (temp_expr_table *tab) |
560 { | 514 { |
561 kill_expr (tab, VIRTUAL_PARTITION (tab)); | 515 kill_expr (tab, VIRTUAL_PARTITION (tab)); |
562 } | 516 } |
563 | 517 |
564 | 518 |
565 /* Mark the expression associated with VAR as replaceable, and enter | 519 /* Mark the expression associated with VAR as replaceable, and enter |
566 the defining stmt into the partition_dependencies table TAB. If | 520 the defining stmt into the partition_dependencies table TAB. If |
567 MORE_REPLACING is true, accumulate the pending partition dependencies. */ | 521 MORE_REPLACING is true, accumulate the pending partition dependencies. */ |
568 | 522 |
569 static void | 523 static void |
570 mark_replaceable (temp_expr_table_p tab, tree var, bool more_replacing) | 524 mark_replaceable (temp_expr_table *tab, tree var, bool more_replacing) |
571 { | 525 { |
572 int version = SSA_NAME_VERSION (var); | 526 int version = SSA_NAME_VERSION (var); |
573 | 527 |
574 /* Move the dependence list to the pending listpending. */ | 528 /* Move the dependence list to the pending listpending. */ |
575 if (more_replacing && tab->partition_dependencies[version]) | 529 if (more_replacing && tab->partition_dependencies[version]) |
576 bitmap_ior_into (tab->new_replaceable_dependencies, | 530 bitmap_ior_into (tab->new_replaceable_dependencies, |
577 tab->partition_dependencies[version]); | 531 tab->partition_dependencies[version]); |
578 | 532 |
579 finished_with_expr (tab, version, !more_replacing); | 533 finished_with_expr (tab, version, !more_replacing); |
580 | 534 |
581 /* Set the replaceable expression. */ | 535 /* Set the replaceable expression. |
536 The bitmap for this "escapes" from this file so it's allocated | |
537 on the default obstack. */ | |
582 if (!tab->replaceable_expressions) | 538 if (!tab->replaceable_expressions) |
583 tab->replaceable_expressions = BITMAP_ALLOC (NULL); | 539 tab->replaceable_expressions = BITMAP_ALLOC (NULL); |
584 bitmap_set_bit (tab->replaceable_expressions, version); | 540 bitmap_set_bit (tab->replaceable_expressions, version); |
585 } | 541 } |
586 | 542 |
587 | 543 |
544 /* Helper function for find_ssaname_in_stores. Called via walk_tree to | |
545 find a SSA_NAME DATA somewhere in *TP. */ | |
546 | |
547 static tree | |
548 find_ssaname (tree *tp, int *walk_subtrees, void *data) | |
549 { | |
550 tree var = (tree) data; | |
551 if (*tp == var) | |
552 return var; | |
553 else if (IS_TYPE_OR_DECL_P (*tp)) | |
554 *walk_subtrees = 0; | |
555 return NULL_TREE; | |
556 } | |
557 | |
558 /* Helper function for find_replaceable_in_bb. Return true if SSA_NAME DATA | |
559 is used somewhere in T, which is a store in the statement. Called via | |
560 walk_stmt_load_store_addr_ops. */ | |
561 | |
562 static bool | |
563 find_ssaname_in_store (gimple *, tree, tree t, void *data) | |
564 { | |
565 return walk_tree (&t, find_ssaname, data, NULL) != NULL_TREE; | |
566 } | |
567 | |
588 /* This function processes basic block BB, and looks for variables which can | 568 /* This function processes basic block BB, and looks for variables which can |
589 be replaced by their expressions. Results are stored in the table TAB. */ | 569 be replaced by their expressions. Results are stored in the table TAB. */ |
590 | 570 |
591 static void | 571 static void |
592 find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb) | 572 find_replaceable_in_bb (temp_expr_table *tab, basic_block bb) |
593 { | 573 { |
594 gimple_stmt_iterator bsi; | 574 gimple_stmt_iterator bsi; |
595 gimple stmt; | 575 gimple *stmt; |
596 tree def, use, fndecl; | 576 tree def, use, fndecl; |
597 int partition; | 577 int partition; |
598 var_map map = tab->map; | 578 var_map map = tab->map; |
599 ssa_op_iter iter; | 579 ssa_op_iter iter; |
600 bool stmt_replaceable; | 580 bool stmt_replaceable; |
601 int cur_call_cnt = 0; | 581 int cur_call_cnt = 0; |
582 int cur_reg_vars_cnt = 0; | |
602 | 583 |
603 for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) | 584 for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) |
604 { | 585 { |
605 stmt = gsi_stmt (bsi); | 586 stmt = gsi_stmt (bsi); |
606 | 587 |
607 if (is_gimple_debug (stmt)) | 588 if (is_gimple_debug (stmt)) |
608 continue; | 589 continue; |
609 | 590 |
610 stmt_replaceable = is_replaceable_p (stmt, true); | 591 stmt_replaceable = ter_is_replaceable_p (stmt); |
611 | 592 |
612 /* Determine if this stmt finishes an existing expression. */ | 593 /* Determine if this stmt finishes an existing expression. */ |
613 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE) | 594 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE) |
614 { | 595 { |
615 unsigned ver = SSA_NAME_VERSION (use); | 596 unsigned ver = SSA_NAME_VERSION (use); |
625 do not want to do the replacement to avoid problems with | 606 do not want to do the replacement to avoid problems with |
626 code size, see PR tree-optimization/17549. */ | 607 code size, see PR tree-optimization/17549. */ |
627 if (!bitmap_empty_p (vars)) | 608 if (!bitmap_empty_p (vars)) |
628 FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter2, SSA_OP_DEF) | 609 FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter2, SSA_OP_DEF) |
629 { | 610 { |
630 if (bitmap_bit_p (vars, DECL_UID (SSA_NAME_VAR (def)))) | 611 if (SSA_NAME_VAR (def) |
612 && bitmap_bit_p (vars, DECL_UID (SSA_NAME_VAR (def)))) | |
631 { | 613 { |
632 same_root_var = true; | 614 same_root_var = true; |
633 break; | 615 break; |
634 } | 616 } |
635 } | 617 } |
636 | 618 |
637 /* If the stmt does a memory store and the replacement | 619 /* If the stmt does a memory store and the replacement |
638 is a load aliasing it avoid creating overlapping | 620 is a load aliasing it avoid creating overlapping |
639 assignments which we cannot expand correctly. */ | 621 assignments which we cannot expand correctly. */ |
640 if (gimple_vdef (stmt) | 622 if (gimple_vdef (stmt)) |
641 && gimple_assign_single_p (stmt)) | |
642 { | 623 { |
643 gimple def_stmt = SSA_NAME_DEF_STMT (use); | 624 gimple *def_stmt = SSA_NAME_DEF_STMT (use); |
644 while (is_gimple_assign (def_stmt) | 625 while (is_gimple_assign (def_stmt) |
645 && gimple_assign_rhs_code (def_stmt) == SSA_NAME) | 626 && gimple_assign_rhs_code (def_stmt) == SSA_NAME) |
646 def_stmt | 627 def_stmt |
647 = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def_stmt)); | 628 = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def_stmt)); |
648 if (gimple_vuse (def_stmt) | 629 if (gimple_vuse (def_stmt) |
649 && gimple_assign_single_p (def_stmt) | 630 && gimple_assign_single_p (def_stmt) |
650 && refs_may_alias_p (gimple_assign_lhs (stmt), | 631 && stmt_may_clobber_ref_p (stmt, |
651 gimple_assign_rhs1 (def_stmt))) | 632 gimple_assign_rhs1 (def_stmt))) |
652 same_root_var = true; | 633 { |
634 /* For calls, it is not a problem if USE is among | |
635 call's arguments or say OBJ_TYPE_REF argument, | |
636 all those necessarily need to be evaluated before | |
637 the call that may clobber the memory. But if | |
638 LHS of the call refers to USE, expansion might | |
639 evaluate it after the call, prevent TER in that | |
640 case. | |
641 For inline asm, allow TER of loads into input | |
642 arguments, but disallow TER for USEs that occur | |
643 somewhere in outputs. */ | |
644 if (is_gimple_call (stmt) | |
645 || gimple_code (stmt) == GIMPLE_ASM) | |
646 { | |
647 if (walk_stmt_load_store_ops (stmt, use, NULL, | |
648 find_ssaname_in_store)) | |
649 same_root_var = true; | |
650 } | |
651 else | |
652 same_root_var = true; | |
653 } | |
653 } | 654 } |
654 | 655 |
655 /* Mark expression as replaceable unless stmt is volatile, or the | 656 /* Mark expression as replaceable unless stmt is volatile, or the |
656 def variable has the same root variable as something in the | 657 def variable has the same root variable as something in the |
657 substitution list, or the def and use span a call such that | 658 substitution list, or the def and use span a call such that |
658 we'll expand lifetimes across a call. */ | 659 we'll expand lifetimes across a call. We also don't want to |
660 replace across these expressions that may call libcalls that | |
661 clobber the register involved. See PR 70184. */ | |
659 if (gimple_has_volatile_ops (stmt) || same_root_var | 662 if (gimple_has_volatile_ops (stmt) || same_root_var |
660 || (tab->call_cnt[ver] != cur_call_cnt | 663 || (tab->call_cnt[ver] != cur_call_cnt |
661 && SINGLE_SSA_USE_OPERAND (SSA_NAME_DEF_STMT (use), SSA_OP_USE) | 664 && SINGLE_SSA_USE_OPERAND (SSA_NAME_DEF_STMT (use), SSA_OP_USE) |
662 == NULL_USE_OPERAND_P)) | 665 == NULL_USE_OPERAND_P) |
666 || tab->reg_vars_cnt[ver] != cur_reg_vars_cnt) | |
663 finished_with_expr (tab, ver, true); | 667 finished_with_expr (tab, ver, true); |
664 else | 668 else |
665 mark_replaceable (tab, use, stmt_replaceable); | 669 mark_replaceable (tab, use, stmt_replaceable); |
666 } | 670 } |
667 } | 671 } |
680 if (is_gimple_call (stmt) | 684 if (is_gimple_call (stmt) |
681 && !((fndecl = gimple_call_fndecl (stmt)) | 685 && !((fndecl = gimple_call_fndecl (stmt)) |
682 && DECL_BUILT_IN (fndecl))) | 686 && DECL_BUILT_IN (fndecl))) |
683 cur_call_cnt++; | 687 cur_call_cnt++; |
684 | 688 |
689 /* Increment counter if this statement sets a local | |
690 register variable. */ | |
691 if (gimple_assign_single_p (stmt) | |
692 && (TREE_CODE (gimple_assign_lhs (stmt)) == VAR_DECL | |
693 && DECL_HARD_REGISTER (gimple_assign_lhs (stmt)))) | |
694 cur_reg_vars_cnt++; | |
695 | |
685 /* Now see if we are creating a new expression or not. */ | 696 /* Now see if we are creating a new expression or not. */ |
686 if (stmt_replaceable) | 697 if (stmt_replaceable) |
687 process_replaceable (tab, stmt, cur_call_cnt); | 698 process_replaceable (tab, stmt, cur_call_cnt, cur_reg_vars_cnt); |
688 | 699 |
689 /* Free any unused dependency lists. */ | 700 /* Free any unused dependency lists. */ |
690 bitmap_clear (tab->new_replaceable_dependencies); | 701 bitmap_clear (tab->new_replaceable_dependencies); |
691 | 702 |
692 /* A V_{MAY,MUST}_DEF kills any expression using a virtual operand, | 703 /* A V_{MAY,MUST}_DEF kills any expression using a virtual operand, |
703 expressions they should be replaced with. A NULL_TREE indicates no | 714 expressions they should be replaced with. A NULL_TREE indicates no |
704 replacement should take place. If there are no replacements at all, | 715 replacement should take place. If there are no replacements at all, |
705 NULL is returned by the function, otherwise an expression vector indexed | 716 NULL is returned by the function, otherwise an expression vector indexed |
706 by SSA_NAME version numbers. */ | 717 by SSA_NAME version numbers. */ |
707 | 718 |
708 extern bitmap | 719 bitmap |
709 find_replaceable_exprs (var_map map) | 720 find_replaceable_exprs (var_map map) |
710 { | 721 { |
711 basic_block bb; | 722 basic_block bb; |
712 temp_expr_table_p table; | 723 temp_expr_table *table; |
713 bitmap ret; | 724 bitmap ret; |
714 | 725 |
726 bitmap_obstack_initialize (&ter_bitmap_obstack); | |
715 table = new_temp_expr_table (map); | 727 table = new_temp_expr_table (map); |
716 FOR_EACH_BB (bb) | 728 FOR_EACH_BB_FN (bb, cfun) |
717 { | 729 { |
718 find_replaceable_in_bb (table, bb); | 730 find_replaceable_in_bb (table, bb); |
719 gcc_checking_assert (bitmap_empty_p (table->partition_in_use)); | 731 gcc_checking_assert (bitmap_empty_p (table->partition_in_use)); |
720 } | 732 } |
721 | |
722 ret = free_temp_expr_table (table); | 733 ret = free_temp_expr_table (table); |
734 bitmap_obstack_release (&ter_bitmap_obstack); | |
723 return ret; | 735 return ret; |
724 } | 736 } |
725 | 737 |
726 /* Dump TER expression table EXPR to file F. */ | 738 /* Dump TER expression table EXPR to file F. */ |
727 | 739 |
743 } | 755 } |
744 fprintf (f, "\n"); | 756 fprintf (f, "\n"); |
745 } | 757 } |
746 | 758 |
747 | 759 |
748 #ifdef ENABLE_CHECKING | |
749 /* Dump the status of the various tables in the expression table. This is used | 760 /* Dump the status of the various tables in the expression table. This is used |
750 exclusively to debug TER. F is the place to send debug info and T is the | 761 exclusively to debug TER. F is the place to send debug info and T is the |
751 table being debugged. */ | 762 table being debugged. */ |
752 | 763 |
753 DEBUG_FUNCTION void | 764 DEBUG_FUNCTION void |
754 debug_ter (FILE *f, temp_expr_table_p t) | 765 debug_ter (FILE *f, temp_expr_table *t) |
755 { | 766 { |
756 unsigned x, y; | 767 unsigned x, y; |
757 bitmap_iterator bi; | 768 bitmap_iterator bi; |
758 | 769 |
759 fprintf (f, "\nDumping current state of TER\n virtual partition = %d\n", | 770 fprintf (f, "\nDumping current state of TER\n virtual partition = %d\n", |
791 fprintf (f, "_%d ",y); | 802 fprintf (f, "_%d ",y); |
792 } | 803 } |
793 | 804 |
794 fprintf (f, "\n----------\n"); | 805 fprintf (f, "\n----------\n"); |
795 } | 806 } |
796 #endif |