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