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