]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/tree-ssa-copy.c
Merger of git branch "gimple-classes-v2-option-3"
[thirdparty/gcc.git] / gcc / tree-ssa-copy.c
CommitLineData
88dbf20f 1/* Copy propagation and SSA_NAME replacement support routines.
3aea1f79 2 Copyright (C) 2004-2014 Free Software Foundation, Inc.
4ee9c684 3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8c4c00c1 8the Free Software Foundation; either version 3, or (at your option)
4ee9c684 9any later version.
10
11GCC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
8c4c00c1 17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
4ee9c684 19
20#include "config.h"
21#include "system.h"
22#include "coretypes.h"
23#include "tm.h"
24#include "tree.h"
25#include "flags.h"
4ee9c684 26#include "tm_p.h"
94ea8568 27#include "predict.h"
28#include "vec.h"
a3020f2f 29#include "hashtab.h"
30#include "hash-set.h"
a3020f2f 31#include "machmode.h"
32#include "hard-reg-set.h"
33#include "input.h"
4ee9c684 34#include "function.h"
94ea8568 35#include "dominance.h"
36#include "cfg.h"
37#include "basic-block.h"
ce084dfc 38#include "gimple-pretty-print.h"
bc61cadb 39#include "tree-ssa-alias.h"
40#include "internal-fn.h"
41#include "gimple-expr.h"
42#include "is-a.h"
073c1fd5 43#include "gimple.h"
dcf1a1ec 44#include "gimple-iterator.h"
073c1fd5 45#include "gimple-ssa.h"
46#include "tree-cfg.h"
47#include "tree-phinodes.h"
48#include "ssa-iterators.h"
9ed99284 49#include "stringpool.h"
073c1fd5 50#include "tree-ssanames.h"
4ee9c684 51#include "tree-pass.h"
88dbf20f 52#include "tree-ssa-propagate.h"
4ee9c684 53#include "langhooks.h"
23a3430d 54#include "cfgloop.h"
f6568ea4 55#include "tree-scalar-evolution.h"
424a4a92 56#include "tree-ssa-dom.h"
c919e493 57#include "tree-ssa-loop-niter.h"
58
4ee9c684 59
88dbf20f 60/* This file implements the copy propagation pass and provides a
61 handful of interfaces for performing const/copy propagation and
62 simple expression replacement which keep variable annotations
63 up-to-date.
4ee9c684 64
65 We require that for any copy operation where the RHS and LHS have
f7406879 66 a non-null memory tag the memory tag be the same. It is OK
4ee9c684 67 for one or both of the memory tags to be NULL.
68
69 We also require tracking if a variable is dereferenced in a load or
70 store operation.
71
72 We enforce these requirements by having all copy propagation and
73 replacements of one SSA_NAME with a different SSA_NAME to use the
74 APIs defined in this file. */
75
88dbf20f 76/*---------------------------------------------------------------------------
77 Copy propagation
78---------------------------------------------------------------------------*/
6ecedef2 79/* Lattice for copy-propagation. The lattice is initialized to
80 UNDEFINED (value == NULL) for SSA names that can become a copy
81 of something or VARYING (value == self) if not (see get_copy_of_val
82 and stmt_may_generate_copy). Other values make the name a COPY
83 of that value.
88dbf20f 84
6ecedef2 85 When visiting a statement or PHI node the lattice value for an
86 SSA name can transition from UNDEFINED to COPY to VARYING. */
14f101cf 87
9908fe4d 88struct prop_value_t {
14f101cf 89 /* Copy-of value. */
90 tree value;
91};
14f101cf 92
88dbf20f 93static prop_value_t *copy_of;
285df01b 94static unsigned n_copy_of;
88dbf20f 95
88dbf20f 96
97/* Return true if this statement may generate a useful copy. */
98
99static bool
75a70cf9 100stmt_may_generate_copy (gimple stmt)
88dbf20f 101{
75a70cf9 102 if (gimple_code (stmt) == GIMPLE_PHI)
103 return !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_phi_result (stmt));
88dbf20f 104
75a70cf9 105 if (gimple_code (stmt) != GIMPLE_ASSIGN)
88dbf20f 106 return false;
107
88dbf20f 108 /* If the statement has volatile operands, it won't generate a
109 useful copy. */
75a70cf9 110 if (gimple_has_volatile_ops (stmt))
88dbf20f 111 return false;
112
317d3b82 113 /* Statements with loads and/or stores will never generate a useful copy. */
dd277d48 114 if (gimple_vuse (stmt))
88dbf20f 115 return false;
116
117 /* Otherwise, the only statements that generate useful copies are
118 assignments whose RHS is just an SSA name that doesn't flow
119 through abnormal edges. */
f82efd77 120 return ((gimple_assign_rhs_code (stmt) == SSA_NAME
121 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (stmt)))
122 || is_gimple_min_invariant (gimple_assign_rhs1 (stmt)));
88dbf20f 123}
124
125
126/* Return the copy-of value for VAR. */
127
128static inline prop_value_t *
129get_copy_of_val (tree var)
130{
131 prop_value_t *val = &copy_of[SSA_NAME_VERSION (var)];
132
133 if (val->value == NULL_TREE
134 && !stmt_may_generate_copy (SSA_NAME_DEF_STMT (var)))
135 {
136 /* If the variable will never generate a useful copy relation,
137 make it its own copy. */
138 val->value = var;
88dbf20f 139 }
140
141 return val;
142}
143
6ecedef2 144/* Return the variable VAR is a copy of or VAR if VAR isn't the result
145 of a copy. */
88dbf20f 146
6ecedef2 147static inline tree
148valueize_val (tree var)
88dbf20f 149{
6ecedef2 150 if (TREE_CODE (var) == SSA_NAME)
88dbf20f 151 {
6ecedef2 152 tree val = get_copy_of_val (var)->value;
153 if (val)
154 return val;
88dbf20f 155 }
6ecedef2 156 return var;
88dbf20f 157}
158
6ecedef2 159/* Set VAL to be the copy of VAR. If that changed return true. */
88dbf20f 160
161static inline bool
6ecedef2 162set_copy_of_val (tree var, tree val)
88dbf20f 163{
6ecedef2 164 unsigned int ver = SSA_NAME_VERSION (var);
165 tree old;
48e1416a 166
88dbf20f 167 /* Set FIRST to be the first link in COPY_OF[DEST]. If that
168 changed, return true. */
6ecedef2 169 old = copy_of[ver].value;
170 copy_of[ver].value = val;
88dbf20f 171
82f6f8b4 172 if (old != val
173 || (val && !operand_equal_p (old, val, 0)))
88dbf20f 174 return true;
175
6ecedef2 176 return false;
88dbf20f 177}
178
179
3f5be5f4 180/* Dump the copy-of value for variable VAR to FILE. */
88dbf20f 181
182static void
3f5be5f4 183dump_copy_of (FILE *file, tree var)
88dbf20f 184{
185 tree val;
186
3f5be5f4 187 print_generic_expr (file, var, dump_flags);
88dbf20f 188 if (TREE_CODE (var) != SSA_NAME)
189 return;
48e1416a 190
6ecedef2 191 val = copy_of[SSA_NAME_VERSION (var)].value;
3f5be5f4 192 fprintf (file, " copy-of chain: ");
6ecedef2 193 print_generic_expr (file, var, 0);
3f5be5f4 194 fprintf (file, " ");
6ecedef2 195 if (!val)
196 fprintf (file, "[UNDEFINED]");
197 else if (val == var)
198 fprintf (file, "[NOT A COPY]");
199 else
88dbf20f 200 {
3f5be5f4 201 fprintf (file, "-> ");
3f5be5f4 202 print_generic_expr (file, val, 0);
203 fprintf (file, " ");
6ecedef2 204 fprintf (file, "[COPY]");
88dbf20f 205 }
88dbf20f 206}
207
208
209/* Evaluate the RHS of STMT. If it produces a valid copy, set the LHS
6ecedef2 210 value and store the LHS into *RESULT_P. */
88dbf20f 211
212static enum ssa_prop_result
75a70cf9 213copy_prop_visit_assignment (gimple stmt, tree *result_p)
88dbf20f 214{
215 tree lhs, rhs;
88dbf20f 216
75a70cf9 217 lhs = gimple_assign_lhs (stmt);
82f6f8b4 218 rhs = valueize_val (gimple_assign_rhs1 (stmt));
88dbf20f 219
220 if (TREE_CODE (lhs) == SSA_NAME)
221 {
222 /* Straight copy between two SSA names. First, make sure that
223 we can propagate the RHS into uses of LHS. */
224 if (!may_propagate_copy (lhs, rhs))
225 return SSA_PROP_VARYING;
226
88dbf20f 227 *result_p = lhs;
82f6f8b4 228 if (set_copy_of_val (*result_p, rhs))
88dbf20f 229 return SSA_PROP_INTERESTING;
230 else
231 return SSA_PROP_NOT_INTERESTING;
232 }
233
88dbf20f 234 return SSA_PROP_VARYING;
235}
236
237
75a70cf9 238/* Visit the GIMPLE_COND STMT. Return SSA_PROP_INTERESTING
88dbf20f 239 if it can determine which edge will be taken. Otherwise, return
240 SSA_PROP_VARYING. */
241
242static enum ssa_prop_result
75a70cf9 243copy_prop_visit_cond_stmt (gimple stmt, edge *taken_edge_p)
88dbf20f 244{
75a70cf9 245 enum ssa_prop_result retval = SSA_PROP_VARYING;
389dd41b 246 location_t loc = gimple_location (stmt);
88dbf20f 247
06a06ab5 248 tree op0 = valueize_val (gimple_cond_lhs (stmt));
249 tree op1 = valueize_val (gimple_cond_rhs (stmt));
88dbf20f 250
06a06ab5 251 /* See if we can determine the predicate's value. */
252 if (dump_file && (dump_flags & TDF_DETAILS))
88dbf20f 253 {
06a06ab5 254 fprintf (dump_file, "Trying to determine truth value of ");
255 fprintf (dump_file, "predicate ");
256 print_gimple_stmt (dump_file, stmt, 0, 0);
257 }
258
259 /* Fold COND and see whether we get a useful result. */
260 tree folded_cond = fold_binary_loc (loc, gimple_cond_code (stmt),
261 boolean_type_node, op0, op1);
262 if (folded_cond)
263 {
264 basic_block bb = gimple_bb (stmt);
265 *taken_edge_p = find_taken_edge (bb, folded_cond);
266 if (*taken_edge_p)
267 retval = SSA_PROP_INTERESTING;
88dbf20f 268 }
269
270 if (dump_file && (dump_flags & TDF_DETAILS) && *taken_edge_p)
271 fprintf (dump_file, "\nConditional will always take edge %d->%d\n",
272 (*taken_edge_p)->src->index, (*taken_edge_p)->dest->index);
273
274 return retval;
275}
276
277
278/* Evaluate statement STMT. If the statement produces a new output
279 value, return SSA_PROP_INTERESTING and store the SSA_NAME holding
280 the new value in *RESULT_P.
281
282 If STMT is a conditional branch and we can determine its truth
283 value, set *TAKEN_EDGE_P accordingly.
284
285 If the new value produced by STMT is varying, return
286 SSA_PROP_VARYING. */
287
288static enum ssa_prop_result
75a70cf9 289copy_prop_visit_stmt (gimple stmt, edge *taken_edge_p, tree *result_p)
88dbf20f 290{
88dbf20f 291 enum ssa_prop_result retval;
292
293 if (dump_file && (dump_flags & TDF_DETAILS))
294 {
295 fprintf (dump_file, "\nVisiting statement:\n");
75a70cf9 296 print_gimple_stmt (dump_file, stmt, 0, dump_flags);
88dbf20f 297 fprintf (dump_file, "\n");
298 }
299
75a70cf9 300 if (gimple_assign_single_p (stmt)
301 && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
82f6f8b4 302 && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
303 || is_gimple_min_invariant (gimple_assign_rhs1 (stmt))))
88dbf20f 304 {
305 /* If the statement is a copy assignment, evaluate its RHS to
306 see if the lattice value of its output has changed. */
307 retval = copy_prop_visit_assignment (stmt, result_p);
308 }
75a70cf9 309 else if (gimple_code (stmt) == GIMPLE_COND)
88dbf20f 310 {
311 /* See if we can determine which edge goes out of a conditional
312 jump. */
313 retval = copy_prop_visit_cond_stmt (stmt, taken_edge_p);
314 }
315 else
316 retval = SSA_PROP_VARYING;
317
318 if (retval == SSA_PROP_VARYING)
319 {
320 tree def;
321 ssa_op_iter i;
322
323 /* Any other kind of statement is not interesting for constant
324 propagation and, therefore, not worth simulating. */
325 if (dump_file && (dump_flags & TDF_DETAILS))
326 fprintf (dump_file, "No interesting values produced.\n");
327
328 /* The assignment is not a copy operation. Don't visit this
329 statement again and mark all the definitions in the statement
330 to be copies of nothing. */
331 FOR_EACH_SSA_TREE_OPERAND (def, stmt, i, SSA_OP_ALL_DEFS)
317d3b82 332 set_copy_of_val (def, def);
88dbf20f 333 }
334
335 return retval;
336}
337
338
339/* Visit PHI node PHI. If all the arguments produce the same value,
340 set it to be the value of the LHS of PHI. */
341
342static enum ssa_prop_result
1a91d914 343copy_prop_visit_phi_node (gphi *phi)
88dbf20f 344{
345 enum ssa_prop_result retval;
75a70cf9 346 unsigned i;
14f101cf 347 prop_value_t phi_val = { NULL_TREE };
88dbf20f 348
75a70cf9 349 tree lhs = gimple_phi_result (phi);
88dbf20f 350
351 if (dump_file && (dump_flags & TDF_DETAILS))
352 {
353 fprintf (dump_file, "\nVisiting PHI node: ");
75a70cf9 354 print_gimple_stmt (dump_file, phi, 0, dump_flags);
88dbf20f 355 }
356
75a70cf9 357 for (i = 0; i < gimple_phi_num_args (phi); i++)
88dbf20f 358 {
359 prop_value_t *arg_val;
abb08aa8 360 tree arg_value;
75a70cf9 361 tree arg = gimple_phi_arg_def (phi, i);
362 edge e = gimple_phi_arg_edge (phi, i);
88dbf20f 363
364 /* We don't care about values flowing through non-executable
365 edges. */
366 if (!(e->flags & EDGE_EXECUTABLE))
367 continue;
368
abb08aa8 369 /* Names that flow through abnormal edges cannot be used to
370 derive copies. */
371 if (TREE_CODE (arg) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (arg))
88dbf20f 372 {
373 phi_val.value = lhs;
374 break;
375 }
376
88dbf20f 377 if (dump_file && (dump_flags & TDF_DETAILS))
378 {
379 fprintf (dump_file, "\tArgument #%d: ", i);
380 dump_copy_of (dump_file, arg);
381 fprintf (dump_file, "\n");
382 }
383
abb08aa8 384 if (TREE_CODE (arg) == SSA_NAME)
385 {
386 arg_val = get_copy_of_val (arg);
387
388 /* If we didn't visit the definition of arg yet treat it as
389 UNDEFINED. This also handles PHI arguments that are the
390 same as lhs. We'll come here again. */
391 if (!arg_val->value)
392 continue;
88dbf20f 393
abb08aa8 394 arg_value = arg_val->value;
395 }
396 else
397 arg_value = valueize_val (arg);
398
3beff0e1 399 /* In loop-closed SSA form do not copy-propagate SSA-names across
400 loop exit edges. */
401 if (loops_state_satisfies_p (LOOP_CLOSED_SSA)
402 && TREE_CODE (arg_value) == SSA_NAME
403 && loop_exit_edge_p (e->src->loop_father, e))
abb08aa8 404 {
405 phi_val.value = lhs;
406 break;
407 }
6ecedef2 408
88dbf20f 409 /* If the LHS didn't have a value yet, make it a copy of the
6ecedef2 410 first argument we find. */
88dbf20f 411 if (phi_val.value == NULL_TREE)
412 {
abb08aa8 413 phi_val.value = arg_value;
88dbf20f 414 continue;
415 }
416
417 /* If PHI_VAL and ARG don't have a common copy-of chain, then
6ecedef2 418 this PHI node cannot be a copy operation. */
abb08aa8 419 if (phi_val.value != arg_value
420 && !operand_equal_p (phi_val.value, arg_value, 0))
88dbf20f 421 {
422 phi_val.value = lhs;
423 break;
424 }
425 }
426
6ecedef2 427 if (phi_val.value
428 && may_propagate_copy (lhs, phi_val.value)
b87f0847 429 && set_copy_of_val (lhs, phi_val.value))
88dbf20f 430 retval = (phi_val.value != lhs) ? SSA_PROP_INTERESTING : SSA_PROP_VARYING;
431 else
432 retval = SSA_PROP_NOT_INTERESTING;
433
434 if (dump_file && (dump_flags & TDF_DETAILS))
435 {
6ecedef2 436 fprintf (dump_file, "PHI node ");
88dbf20f 437 dump_copy_of (dump_file, lhs);
438 fprintf (dump_file, "\nTelling the propagator to ");
439 if (retval == SSA_PROP_INTERESTING)
440 fprintf (dump_file, "add SSA edges out of this PHI and continue.");
441 else if (retval == SSA_PROP_VARYING)
442 fprintf (dump_file, "add SSA edges out of this PHI and never visit again.");
443 else
444 fprintf (dump_file, "do nothing with SSA edges and keep iterating.");
445 fprintf (dump_file, "\n\n");
446 }
447
448 return retval;
449}
450
451
6ecedef2 452/* Initialize structures used for copy propagation. */
88dbf20f 453
454static void
d1d2af7d 455init_copy_prop (void)
88dbf20f 456{
457 basic_block bb;
458
285df01b 459 n_copy_of = num_ssa_names;
460 copy_of = XCNEWVEC (prop_value_t, n_copy_of);
88dbf20f 461
fc00614f 462 FOR_EACH_BB_FN (bb, cfun)
88dbf20f 463 {
1a91d914 464 for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si);
465 gsi_next (&si))
88dbf20f 466 {
75a70cf9 467 gimple stmt = gsi_stmt (si);
2166ab0e 468 ssa_op_iter iter;
75a70cf9 469 tree def;
88dbf20f 470
471 /* The only statements that we care about are those that may
472 generate useful copies. We also need to mark conditional
473 jumps so that their outgoing edges are added to the work
3beff0e1 474 lists of the propagator. */
88dbf20f 475 if (stmt_ends_bb_p (stmt))
75a70cf9 476 prop_set_simulate_again (stmt, true);
3beff0e1 477 else if (stmt_may_generate_copy (stmt))
75a70cf9 478 prop_set_simulate_again (stmt, true);
88dbf20f 479 else
75a70cf9 480 prop_set_simulate_again (stmt, false);
2166ab0e 481
482 /* Mark all the outputs of this statement as not being
483 the copy of anything. */
484 FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
75a70cf9 485 if (!prop_simulate_again_p (stmt))
317d3b82 486 set_copy_of_val (def, def);
88dbf20f 487 }
488
1a91d914 489 for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
490 gsi_next (&si))
2166ab0e 491 {
1a91d914 492 gphi *phi = si.phi ();
75a70cf9 493 tree def;
494
495 def = gimple_phi_result (phi);
7c782c9b 496 if (virtual_operand_p (def))
75a70cf9 497 prop_set_simulate_again (phi, false);
2166ab0e 498 else
75a70cf9 499 prop_set_simulate_again (phi, true);
2166ab0e 500
75a70cf9 501 if (!prop_simulate_again_p (phi))
317d3b82 502 set_copy_of_val (def, def);
2166ab0e 503 }
88dbf20f 504 }
505}
506
14f101cf 507/* Callback for substitute_and_fold to get at the final copy-of values. */
508
509static tree
510get_value (tree name)
511{
285df01b 512 tree val;
513 if (SSA_NAME_VERSION (name) >= n_copy_of)
514 return NULL_TREE;
515 val = copy_of[SSA_NAME_VERSION (name)].value;
14f101cf 516 if (val && val != name)
517 return val;
518 return NULL_TREE;
519}
88dbf20f 520
521/* Deallocate memory used in copy propagation and do final
522 substitution. */
523
c919e493 524static bool
88dbf20f 525fini_copy_prop (void)
526{
14f101cf 527 unsigned i;
48e1416a 528
88dbf20f 529 /* Set the final copy-of value for each variable by traversing the
530 copy-of chains. */
531 for (i = 1; i < num_ssa_names; i++)
532 {
533 tree var = ssa_name (i);
ba3f9c71 534 if (!var
535 || !copy_of[i].value
536 || copy_of[i].value == var)
537 continue;
538
ba3f9c71 539 /* In theory the points-to solution of all members of the
540 copy chain is their intersection. For now we do not bother
541 to compute this but only make sure we do not lose points-to
542 information completely by setting the points-to solution
543 of the representative to the first solution we find if
544 it doesn't have one already. */
14f101cf 545 if (copy_of[i].value != var
0cf78115 546 && TREE_CODE (copy_of[i].value) == SSA_NAME)
547 {
64243ab0 548 basic_block copy_of_bb
549 = gimple_bb (SSA_NAME_DEF_STMT (copy_of[i].value));
550 basic_block var_bb = gimple_bb (SSA_NAME_DEF_STMT (var));
0cf78115 551 if (POINTER_TYPE_P (TREE_TYPE (var))
552 && SSA_NAME_PTR_INFO (var)
553 && !SSA_NAME_PTR_INFO (copy_of[i].value))
64243ab0 554 {
555 duplicate_ssa_name_ptr_info (copy_of[i].value,
556 SSA_NAME_PTR_INFO (var));
557 /* Points-to information is cfg insensitive,
558 but alignment info might be cfg sensitive, if it
559 e.g. is derived from VRP derived non-zero bits.
560 So, do not copy alignment info if the two SSA_NAMEs
561 aren't defined in the same basic block. */
562 if (var_bb != copy_of_bb)
563 mark_ptr_info_alignment_unknown
564 (SSA_NAME_PTR_INFO (copy_of[i].value));
565 }
0cf78115 566 else if (!POINTER_TYPE_P (TREE_TYPE (var))
567 && SSA_NAME_RANGE_INFO (var)
64243ab0 568 && !SSA_NAME_RANGE_INFO (copy_of[i].value)
569 && var_bb == copy_of_bb)
0cf78115 570 duplicate_ssa_name_range_info (copy_of[i].value,
c6a711c3 571 SSA_NAME_RANGE_TYPE (var),
0cf78115 572 SSA_NAME_RANGE_INFO (var));
573 }
88dbf20f 574 }
575
c919e493 576 bool changed = substitute_and_fold (get_value, NULL, true);
577 if (changed)
578 {
579 free_numbers_of_iterations_estimates ();
580 if (scev_initialized_p ())
581 scev_reset ();
582 }
88dbf20f 583
584 free (copy_of);
c919e493 585
586 return changed;
88dbf20f 587}
588
589
421828b0 590/* Main entry point to the copy propagator.
591
592 PHIS_ONLY is true if we should only consider PHI nodes as generating
48e1416a 593 copy propagation opportunities.
421828b0 594
595 The algorithm propagates the value COPY-OF using ssa_propagate. For
596 every variable X_i, COPY-OF(X_i) indicates which variable is X_i created
597 from. The following example shows how the algorithm proceeds at a
598 high level:
88dbf20f 599
600 1 a_24 = x_1
601 2 a_2 = PHI <a_24, x_1>
602 3 a_5 = PHI <a_2>
603 4 x_1 = PHI <x_298, a_5, a_2>
604
605 The end result should be that a_2, a_5, a_24 and x_1 are a copy of
606 x_298. Propagation proceeds as follows.
607
608 Visit #1: a_24 is copy-of x_1. Value changed.
609 Visit #2: a_2 is copy-of x_1. Value changed.
610 Visit #3: a_5 is copy-of x_1. Value changed.
611 Visit #4: x_1 is copy-of x_298. Value changed.
612 Visit #1: a_24 is copy-of x_298. Value changed.
613 Visit #2: a_2 is copy-of x_298. Value changed.
614 Visit #3: a_5 is copy-of x_298. Value changed.
615 Visit #4: x_1 is copy-of x_298. Stable state reached.
48e1416a 616
88dbf20f 617 When visiting PHI nodes, we only consider arguments that flow
618 through edges marked executable by the propagation engine. So,
619 when visiting statement #2 for the first time, we will only look at
620 the first argument (a_24) and optimistically assume that its value
6ecedef2 621 is the copy of a_24 (x_1). */
88dbf20f 622
317d3b82 623static unsigned int
624execute_copy_prop (void)
88dbf20f 625{
d1d2af7d 626 init_copy_prop ();
88dbf20f 627 ssa_propagate (copy_prop_visit_stmt, copy_prop_visit_phi_node);
c919e493 628 if (fini_copy_prop ())
629 return TODO_cleanup_cfg;
317d3b82 630 return 0;
88dbf20f 631}
632
cbe8bda8 633namespace {
634
635const pass_data pass_data_copy_prop =
88dbf20f 636{
cbe8bda8 637 GIMPLE_PASS, /* type */
638 "copyprop", /* name */
639 OPTGROUP_NONE, /* optinfo_flags */
cbe8bda8 640 TV_TREE_COPY_PROP, /* tv_id */
641 ( PROP_ssa | PROP_cfg ), /* properties_required */
642 0, /* properties_provided */
643 0, /* properties_destroyed */
644 0, /* todo_flags_start */
c919e493 645 0, /* todo_flags_finish */
88dbf20f 646};
cbe8bda8 647
648class pass_copy_prop : public gimple_opt_pass
649{
650public:
9af5ce0c 651 pass_copy_prop (gcc::context *ctxt)
652 : gimple_opt_pass (pass_data_copy_prop, ctxt)
cbe8bda8 653 {}
654
655 /* opt_pass methods: */
ae84f584 656 opt_pass * clone () { return new pass_copy_prop (m_ctxt); }
31315c24 657 virtual bool gate (function *) { return flag_tree_copy_prop != 0; }
65b0537f 658 virtual unsigned int execute (function *) { return execute_copy_prop (); }
cbe8bda8 659
660}; // class pass_copy_prop
661
662} // anon namespace
663
664gimple_opt_pass *
665make_pass_copy_prop (gcc::context *ctxt)
666{
667 return new pass_copy_prop (ctxt);
668}