]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/tree-ssa-copy.c
remove has_execute
[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
75a70cf9 240 tree op0 = gimple_cond_lhs (stmt);
241 tree op1 = gimple_cond_rhs (stmt);
88dbf20f 242
243 /* The only conditionals that we may be able to compute statically
20bd2b8f 244 are predicates involving two SSA_NAMEs. */
75a70cf9 245 if (TREE_CODE (op0) == SSA_NAME && TREE_CODE (op1) == SSA_NAME)
88dbf20f 246 {
6ecedef2 247 op0 = valueize_val (op0);
248 op1 = valueize_val (op1);
88dbf20f 249
250 /* See if we can determine the predicate's value. */
251 if (dump_file && (dump_flags & TDF_DETAILS))
252 {
253 fprintf (dump_file, "Trying to determine truth value of ");
254 fprintf (dump_file, "predicate ");
75a70cf9 255 print_gimple_stmt (dump_file, stmt, 0, 0);
88dbf20f 256 }
257
20bd2b8f 258 /* We can fold COND and get a useful result only when we have
259 the same SSA_NAME on both sides of a comparison operator. */
260 if (op0 == op1)
f21dcb28 261 {
389dd41b 262 tree folded_cond = fold_binary_loc (loc, gimple_cond_code (stmt),
75a70cf9 263 boolean_type_node, op0, op1);
20bd2b8f 264 if (folded_cond)
265 {
75a70cf9 266 basic_block bb = gimple_bb (stmt);
20bd2b8f 267 *taken_edge_p = find_taken_edge (bb, folded_cond);
268 if (*taken_edge_p)
269 retval = SSA_PROP_INTERESTING;
270 }
f21dcb28 271 }
88dbf20f 272 }
273
274 if (dump_file && (dump_flags & TDF_DETAILS) && *taken_edge_p)
275 fprintf (dump_file, "\nConditional will always take edge %d->%d\n",
276 (*taken_edge_p)->src->index, (*taken_edge_p)->dest->index);
277
278 return retval;
279}
280
281
282/* Evaluate statement STMT. If the statement produces a new output
283 value, return SSA_PROP_INTERESTING and store the SSA_NAME holding
284 the new value in *RESULT_P.
285
286 If STMT is a conditional branch and we can determine its truth
287 value, set *TAKEN_EDGE_P accordingly.
288
289 If the new value produced by STMT is varying, return
290 SSA_PROP_VARYING. */
291
292static enum ssa_prop_result
75a70cf9 293copy_prop_visit_stmt (gimple stmt, edge *taken_edge_p, tree *result_p)
88dbf20f 294{
88dbf20f 295 enum ssa_prop_result retval;
296
297 if (dump_file && (dump_flags & TDF_DETAILS))
298 {
299 fprintf (dump_file, "\nVisiting statement:\n");
75a70cf9 300 print_gimple_stmt (dump_file, stmt, 0, dump_flags);
88dbf20f 301 fprintf (dump_file, "\n");
302 }
303
75a70cf9 304 if (gimple_assign_single_p (stmt)
305 && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
82f6f8b4 306 && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
307 || is_gimple_min_invariant (gimple_assign_rhs1 (stmt))))
88dbf20f 308 {
309 /* If the statement is a copy assignment, evaluate its RHS to
310 see if the lattice value of its output has changed. */
311 retval = copy_prop_visit_assignment (stmt, result_p);
312 }
75a70cf9 313 else if (gimple_code (stmt) == GIMPLE_COND)
88dbf20f 314 {
315 /* See if we can determine which edge goes out of a conditional
316 jump. */
317 retval = copy_prop_visit_cond_stmt (stmt, taken_edge_p);
318 }
319 else
320 retval = SSA_PROP_VARYING;
321
322 if (retval == SSA_PROP_VARYING)
323 {
324 tree def;
325 ssa_op_iter i;
326
327 /* Any other kind of statement is not interesting for constant
328 propagation and, therefore, not worth simulating. */
329 if (dump_file && (dump_flags & TDF_DETAILS))
330 fprintf (dump_file, "No interesting values produced.\n");
331
332 /* The assignment is not a copy operation. Don't visit this
333 statement again and mark all the definitions in the statement
334 to be copies of nothing. */
335 FOR_EACH_SSA_TREE_OPERAND (def, stmt, i, SSA_OP_ALL_DEFS)
317d3b82 336 set_copy_of_val (def, def);
88dbf20f 337 }
338
339 return retval;
340}
341
342
343/* Visit PHI node PHI. If all the arguments produce the same value,
344 set it to be the value of the LHS of PHI. */
345
346static enum ssa_prop_result
75a70cf9 347copy_prop_visit_phi_node (gimple phi)
88dbf20f 348{
349 enum ssa_prop_result retval;
75a70cf9 350 unsigned i;
14f101cf 351 prop_value_t phi_val = { NULL_TREE };
88dbf20f 352
75a70cf9 353 tree lhs = gimple_phi_result (phi);
88dbf20f 354
355 if (dump_file && (dump_flags & TDF_DETAILS))
356 {
357 fprintf (dump_file, "\nVisiting PHI node: ");
75a70cf9 358 print_gimple_stmt (dump_file, phi, 0, dump_flags);
88dbf20f 359 }
360
75a70cf9 361 for (i = 0; i < gimple_phi_num_args (phi); i++)
88dbf20f 362 {
363 prop_value_t *arg_val;
abb08aa8 364 tree arg_value;
75a70cf9 365 tree arg = gimple_phi_arg_def (phi, i);
366 edge e = gimple_phi_arg_edge (phi, i);
88dbf20f 367
368 /* We don't care about values flowing through non-executable
369 edges. */
370 if (!(e->flags & EDGE_EXECUTABLE))
371 continue;
372
abb08aa8 373 /* Names that flow through abnormal edges cannot be used to
374 derive copies. */
375 if (TREE_CODE (arg) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (arg))
88dbf20f 376 {
377 phi_val.value = lhs;
378 break;
379 }
380
88dbf20f 381 if (dump_file && (dump_flags & TDF_DETAILS))
382 {
383 fprintf (dump_file, "\tArgument #%d: ", i);
384 dump_copy_of (dump_file, arg);
385 fprintf (dump_file, "\n");
386 }
387
abb08aa8 388 if (TREE_CODE (arg) == SSA_NAME)
389 {
390 arg_val = get_copy_of_val (arg);
391
392 /* If we didn't visit the definition of arg yet treat it as
393 UNDEFINED. This also handles PHI arguments that are the
394 same as lhs. We'll come here again. */
395 if (!arg_val->value)
396 continue;
88dbf20f 397
abb08aa8 398 arg_value = arg_val->value;
399 }
400 else
401 arg_value = valueize_val (arg);
402
3beff0e1 403 /* In loop-closed SSA form do not copy-propagate SSA-names across
404 loop exit edges. */
405 if (loops_state_satisfies_p (LOOP_CLOSED_SSA)
406 && TREE_CODE (arg_value) == SSA_NAME
407 && loop_exit_edge_p (e->src->loop_father, e))
abb08aa8 408 {
409 phi_val.value = lhs;
410 break;
411 }
6ecedef2 412
88dbf20f 413 /* If the LHS didn't have a value yet, make it a copy of the
6ecedef2 414 first argument we find. */
88dbf20f 415 if (phi_val.value == NULL_TREE)
416 {
abb08aa8 417 phi_val.value = arg_value;
88dbf20f 418 continue;
419 }
420
421 /* If PHI_VAL and ARG don't have a common copy-of chain, then
6ecedef2 422 this PHI node cannot be a copy operation. */
abb08aa8 423 if (phi_val.value != arg_value
424 && !operand_equal_p (phi_val.value, arg_value, 0))
88dbf20f 425 {
426 phi_val.value = lhs;
427 break;
428 }
429 }
430
6ecedef2 431 if (phi_val.value
432 && may_propagate_copy (lhs, phi_val.value)
b87f0847 433 && set_copy_of_val (lhs, phi_val.value))
88dbf20f 434 retval = (phi_val.value != lhs) ? SSA_PROP_INTERESTING : SSA_PROP_VARYING;
435 else
436 retval = SSA_PROP_NOT_INTERESTING;
437
438 if (dump_file && (dump_flags & TDF_DETAILS))
439 {
6ecedef2 440 fprintf (dump_file, "PHI node ");
88dbf20f 441 dump_copy_of (dump_file, lhs);
442 fprintf (dump_file, "\nTelling the propagator to ");
443 if (retval == SSA_PROP_INTERESTING)
444 fprintf (dump_file, "add SSA edges out of this PHI and continue.");
445 else if (retval == SSA_PROP_VARYING)
446 fprintf (dump_file, "add SSA edges out of this PHI and never visit again.");
447 else
448 fprintf (dump_file, "do nothing with SSA edges and keep iterating.");
449 fprintf (dump_file, "\n\n");
450 }
451
452 return retval;
453}
454
455
6ecedef2 456/* Initialize structures used for copy propagation. */
88dbf20f 457
458static void
d1d2af7d 459init_copy_prop (void)
88dbf20f 460{
461 basic_block bb;
462
285df01b 463 n_copy_of = num_ssa_names;
464 copy_of = XCNEWVEC (prop_value_t, n_copy_of);
88dbf20f 465
fc00614f 466 FOR_EACH_BB_FN (bb, cfun)
88dbf20f 467 {
75a70cf9 468 gimple_stmt_iterator si;
88dbf20f 469
75a70cf9 470 for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
88dbf20f 471 {
75a70cf9 472 gimple stmt = gsi_stmt (si);
2166ab0e 473 ssa_op_iter iter;
75a70cf9 474 tree def;
88dbf20f 475
476 /* The only statements that we care about are those that may
477 generate useful copies. We also need to mark conditional
478 jumps so that their outgoing edges are added to the work
3beff0e1 479 lists of the propagator. */
88dbf20f 480 if (stmt_ends_bb_p (stmt))
75a70cf9 481 prop_set_simulate_again (stmt, true);
3beff0e1 482 else if (stmt_may_generate_copy (stmt))
75a70cf9 483 prop_set_simulate_again (stmt, true);
88dbf20f 484 else
75a70cf9 485 prop_set_simulate_again (stmt, false);
2166ab0e 486
487 /* Mark all the outputs of this statement as not being
488 the copy of anything. */
489 FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
75a70cf9 490 if (!prop_simulate_again_p (stmt))
317d3b82 491 set_copy_of_val (def, def);
88dbf20f 492 }
493
75a70cf9 494 for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
2166ab0e 495 {
75a70cf9 496 gimple phi = gsi_stmt (si);
497 tree def;
498
499 def = gimple_phi_result (phi);
7c782c9b 500 if (virtual_operand_p (def))
75a70cf9 501 prop_set_simulate_again (phi, false);
2166ab0e 502 else
75a70cf9 503 prop_set_simulate_again (phi, true);
2166ab0e 504
75a70cf9 505 if (!prop_simulate_again_p (phi))
317d3b82 506 set_copy_of_val (def, def);
2166ab0e 507 }
88dbf20f 508 }
509}
510
14f101cf 511/* Callback for substitute_and_fold to get at the final copy-of values. */
512
513static tree
514get_value (tree name)
515{
285df01b 516 tree val;
517 if (SSA_NAME_VERSION (name) >= n_copy_of)
518 return NULL_TREE;
519 val = copy_of[SSA_NAME_VERSION (name)].value;
14f101cf 520 if (val && val != name)
521 return val;
522 return NULL_TREE;
523}
88dbf20f 524
525/* Deallocate memory used in copy propagation and do final
526 substitution. */
527
c919e493 528static bool
88dbf20f 529fini_copy_prop (void)
530{
14f101cf 531 unsigned i;
48e1416a 532
88dbf20f 533 /* Set the final copy-of value for each variable by traversing the
534 copy-of chains. */
535 for (i = 1; i < num_ssa_names; i++)
536 {
537 tree var = ssa_name (i);
ba3f9c71 538 if (!var
539 || !copy_of[i].value
540 || copy_of[i].value == var)
541 continue;
542
ba3f9c71 543 /* In theory the points-to solution of all members of the
544 copy chain is their intersection. For now we do not bother
545 to compute this but only make sure we do not lose points-to
546 information completely by setting the points-to solution
547 of the representative to the first solution we find if
548 it doesn't have one already. */
14f101cf 549 if (copy_of[i].value != var
0cf78115 550 && TREE_CODE (copy_of[i].value) == SSA_NAME)
551 {
64243ab0 552 basic_block copy_of_bb
553 = gimple_bb (SSA_NAME_DEF_STMT (copy_of[i].value));
554 basic_block var_bb = gimple_bb (SSA_NAME_DEF_STMT (var));
0cf78115 555 if (POINTER_TYPE_P (TREE_TYPE (var))
556 && SSA_NAME_PTR_INFO (var)
557 && !SSA_NAME_PTR_INFO (copy_of[i].value))
64243ab0 558 {
559 duplicate_ssa_name_ptr_info (copy_of[i].value,
560 SSA_NAME_PTR_INFO (var));
561 /* Points-to information is cfg insensitive,
562 but alignment info might be cfg sensitive, if it
563 e.g. is derived from VRP derived non-zero bits.
564 So, do not copy alignment info if the two SSA_NAMEs
565 aren't defined in the same basic block. */
566 if (var_bb != copy_of_bb)
567 mark_ptr_info_alignment_unknown
568 (SSA_NAME_PTR_INFO (copy_of[i].value));
569 }
0cf78115 570 else if (!POINTER_TYPE_P (TREE_TYPE (var))
571 && SSA_NAME_RANGE_INFO (var)
64243ab0 572 && !SSA_NAME_RANGE_INFO (copy_of[i].value)
573 && var_bb == copy_of_bb)
0cf78115 574 duplicate_ssa_name_range_info (copy_of[i].value,
c6a711c3 575 SSA_NAME_RANGE_TYPE (var),
0cf78115 576 SSA_NAME_RANGE_INFO (var));
577 }
88dbf20f 578 }
579
c919e493 580 bool changed = substitute_and_fold (get_value, NULL, true);
581 if (changed)
582 {
583 free_numbers_of_iterations_estimates ();
584 if (scev_initialized_p ())
585 scev_reset ();
586 }
88dbf20f 587
588 free (copy_of);
c919e493 589
590 return changed;
88dbf20f 591}
592
593
421828b0 594/* Main entry point to the copy propagator.
595
596 PHIS_ONLY is true if we should only consider PHI nodes as generating
48e1416a 597 copy propagation opportunities.
421828b0 598
599 The algorithm propagates the value COPY-OF using ssa_propagate. For
600 every variable X_i, COPY-OF(X_i) indicates which variable is X_i created
601 from. The following example shows how the algorithm proceeds at a
602 high level:
88dbf20f 603
604 1 a_24 = x_1
605 2 a_2 = PHI <a_24, x_1>
606 3 a_5 = PHI <a_2>
607 4 x_1 = PHI <x_298, a_5, a_2>
608
609 The end result should be that a_2, a_5, a_24 and x_1 are a copy of
610 x_298. Propagation proceeds as follows.
611
612 Visit #1: a_24 is copy-of x_1. Value changed.
613 Visit #2: a_2 is copy-of x_1. Value changed.
614 Visit #3: a_5 is copy-of x_1. Value changed.
615 Visit #4: x_1 is copy-of x_298. Value changed.
616 Visit #1: a_24 is copy-of x_298. Value changed.
617 Visit #2: a_2 is copy-of x_298. Value changed.
618 Visit #3: a_5 is copy-of x_298. Value changed.
619 Visit #4: x_1 is copy-of x_298. Stable state reached.
48e1416a 620
88dbf20f 621 When visiting PHI nodes, we only consider arguments that flow
622 through edges marked executable by the propagation engine. So,
623 when visiting statement #2 for the first time, we will only look at
624 the first argument (a_24) and optimistically assume that its value
6ecedef2 625 is the copy of a_24 (x_1). */
88dbf20f 626
317d3b82 627static unsigned int
628execute_copy_prop (void)
88dbf20f 629{
d1d2af7d 630 init_copy_prop ();
88dbf20f 631 ssa_propagate (copy_prop_visit_stmt, copy_prop_visit_phi_node);
c919e493 632 if (fini_copy_prop ())
633 return TODO_cleanup_cfg;
317d3b82 634 return 0;
88dbf20f 635}
636
cbe8bda8 637namespace {
638
639const pass_data pass_data_copy_prop =
88dbf20f 640{
cbe8bda8 641 GIMPLE_PASS, /* type */
642 "copyprop", /* name */
643 OPTGROUP_NONE, /* optinfo_flags */
cbe8bda8 644 TV_TREE_COPY_PROP, /* tv_id */
645 ( PROP_ssa | PROP_cfg ), /* properties_required */
646 0, /* properties_provided */
647 0, /* properties_destroyed */
648 0, /* todo_flags_start */
c919e493 649 0, /* todo_flags_finish */
88dbf20f 650};
cbe8bda8 651
652class pass_copy_prop : public gimple_opt_pass
653{
654public:
9af5ce0c 655 pass_copy_prop (gcc::context *ctxt)
656 : gimple_opt_pass (pass_data_copy_prop, ctxt)
cbe8bda8 657 {}
658
659 /* opt_pass methods: */
ae84f584 660 opt_pass * clone () { return new pass_copy_prop (m_ctxt); }
31315c24 661 virtual bool gate (function *) { return flag_tree_copy_prop != 0; }
65b0537f 662 virtual unsigned int execute (function *) { return execute_copy_prop (); }
cbe8bda8 663
664}; // class pass_copy_prop
665
666} // anon namespace
667
668gimple_opt_pass *
669make_pass_copy_prop (gcc::context *ctxt)
670{
671 return new pass_copy_prop (ctxt);
672}