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