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