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