OSDN Git Service

2007-10-04 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-forwprop.c
1 /* Forward propagation of expressions for single use variables.
2    Copyright (C) 2004, 2005, 2007 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 "tm.h"
24 #include "ggc.h"
25 #include "tree.h"
26 #include "rtl.h"
27 #include "tm_p.h"
28 #include "basic-block.h"
29 #include "timevar.h"
30 #include "diagnostic.h"
31 #include "tree-flow.h"
32 #include "tree-pass.h"
33 #include "tree-dump.h"
34 #include "langhooks.h"
35 #include "flags.h"
36
37 /* This pass propagates the RHS of assignment statements into use
38    sites of the LHS of the assignment.  It's basically a specialized
39    form of tree combination.   It is hoped all of this can disappear
40    when we have a generalized tree combiner.
41
42    Note carefully that after propagation the resulting statement
43    must still be a proper gimple statement.  Right now we simply
44    only perform propagations we know will result in valid gimple
45    code.  One day we'll want to generalize this code.
46
47    One class of common cases we handle is forward propagating a single use
48    variable into a COND_EXPR.  
49
50      bb0:
51        x = a COND b;
52        if (x) goto ... else goto ...
53
54    Will be transformed into:
55
56      bb0:
57        if (a COND b) goto ... else goto ...
58  
59    Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
60
61    Or (assuming c1 and c2 are constants):
62
63      bb0:
64        x = a + c1;  
65        if (x EQ/NEQ c2) goto ... else goto ...
66
67    Will be transformed into:
68
69      bb0:
70         if (a EQ/NEQ (c2 - c1)) goto ... else goto ...
71
72    Similarly for x = a - c1.
73     
74    Or
75
76      bb0:
77        x = !a
78        if (x) goto ... else goto ...
79
80    Will be transformed into:
81
82      bb0:
83         if (a == 0) goto ... else goto ...
84
85    Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
86    For these cases, we propagate A into all, possibly more than one,
87    COND_EXPRs that use X.
88
89    Or
90
91      bb0:
92        x = (typecast) a
93        if (x) goto ... else goto ...
94
95    Will be transformed into:
96
97      bb0:
98         if (a != 0) goto ... else goto ...
99
100    (Assuming a is an integral type and x is a boolean or x is an
101     integral and a is a boolean.)
102
103    Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
104    For these cases, we propagate A into all, possibly more than one,
105    COND_EXPRs that use X.
106
107    In addition to eliminating the variable and the statement which assigns
108    a value to the variable, we may be able to later thread the jump without
109    adding insane complexity in the dominator optimizer.
110
111    Also note these transformations can cascade.  We handle this by having
112    a worklist of COND_EXPR statements to examine.  As we make a change to
113    a statement, we put it back on the worklist to examine on the next
114    iteration of the main loop.
115
116    A second class of propagation opportunities arises for ADDR_EXPR
117    nodes.
118
119      ptr = &x->y->z;
120      res = *ptr;
121
122    Will get turned into
123
124      res = x->y->z;
125
126    Or
127
128      ptr = &x[0];
129      ptr2 = ptr + <constant>;
130
131    Will get turned into
132
133      ptr2 = &x[constant/elementsize];
134
135   Or
136
137      ptr = &x[0];
138      offset = index * element_size;
139      offset_p = (pointer) offset;
140      ptr2 = ptr + offset_p
141
142   Will get turned into:
143
144      ptr2 = &x[index];
145
146   We also propagate casts into SWITCH_EXPR and COND_EXPR conditions to
147   allow us to remove the cast and {NOT_EXPR,NEG_EXPR} into a subsequent
148   {NOT_EXPR,NEG_EXPR}.
149
150    This will (of course) be extended as other needs arise.  */
151
152 static bool forward_propagate_addr_expr (tree name, tree rhs);
153
154 /* Set to true if we delete EH edges during the optimization.  */
155 static bool cfg_changed;
156
157
158 /* Get the next statement we can propagate NAME's value into skipping
159    trivial copies.  Returns the statement that is suitable as a
160    propagation destination or NULL_TREE if there is no such one.
161    This only returns destinations in a single-use chain.  FINAL_NAME_P
162    if non-NULL is written to the ssa name that represents the use.  */
163
164 static tree
165 get_prop_dest_stmt (tree name, tree *final_name_p)
166 {
167   use_operand_p use;
168   tree use_stmt;
169
170   do {
171     /* If name has multiple uses, bail out.  */
172     if (!single_imm_use (name, &use, &use_stmt))
173       return NULL_TREE;
174
175     /* If this is not a trivial copy, we found it.  */
176     if (TREE_CODE (use_stmt) != GIMPLE_MODIFY_STMT
177         || TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 0)) != SSA_NAME
178         || GIMPLE_STMT_OPERAND (use_stmt, 1) != name)
179       break;
180
181     /* Continue searching uses of the copy destination.  */
182     name = GIMPLE_STMT_OPERAND (use_stmt, 0);
183   } while (1);
184
185   if (final_name_p)
186     *final_name_p = name;
187
188   return use_stmt;
189 }
190
191 /* Get the statement we can propagate from into NAME skipping
192    trivial copies.  Returns the statement which defines the
193    propagation source or NULL_TREE if there is no such one.
194    If SINGLE_USE_ONLY is set considers only sources which have
195    a single use chain up to NAME.  If SINGLE_USE_P is non-null,
196    it is set to whether the chain to NAME is a single use chain
197    or not.  SINGLE_USE_P is not written to if SINGLE_USE_ONLY is set.  */
198
199 static tree
200 get_prop_source_stmt (tree name, bool single_use_only, bool *single_use_p)
201 {
202   bool single_use = true;
203
204   do {
205     tree def_stmt = SSA_NAME_DEF_STMT (name);
206
207     if (!has_single_use (name))
208       {
209         single_use = false;
210         if (single_use_only)
211           return NULL_TREE;
212       }
213
214     /* If name is defined by a PHI node or is the default def, bail out.  */
215     if (TREE_CODE (def_stmt) != GIMPLE_MODIFY_STMT)
216       return NULL_TREE;
217
218     /* If name is not a simple copy destination, we found it.  */
219     if (TREE_CODE (GIMPLE_STMT_OPERAND (def_stmt, 1)) != SSA_NAME)
220       {
221         if (!single_use_only && single_use_p)
222           *single_use_p = single_use;
223
224         return def_stmt;
225       }
226
227     /* Continue searching the def of the copy source name.  */
228     name = GIMPLE_STMT_OPERAND (def_stmt, 1);
229   } while (1);
230 }
231
232 /* Checks if the destination ssa name in DEF_STMT can be used as
233    propagation source.  Returns true if so, otherwise false.  */
234
235 static bool
236 can_propagate_from (tree def_stmt)
237 {
238   tree rhs = GIMPLE_STMT_OPERAND (def_stmt, 1);
239
240   /* We cannot propagate ssa names that occur in abnormal phi nodes.  */
241   switch (TREE_CODE_LENGTH (TREE_CODE (rhs)))
242     {
243     case 3:
244       if (TREE_OPERAND (rhs, 2) != NULL_TREE
245           && TREE_CODE (TREE_OPERAND (rhs, 2)) == SSA_NAME
246           && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (rhs, 2)))
247         return false;
248     case 2:
249       if (TREE_OPERAND (rhs, 1) != NULL_TREE
250           && TREE_CODE (TREE_OPERAND (rhs, 1)) == SSA_NAME
251           && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (rhs, 1)))
252         return false;
253     case 1:
254       if (TREE_OPERAND (rhs, 0) != NULL_TREE
255           && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
256           && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (rhs, 0)))
257         return false;
258       break;
259
260     default:
261       return false;
262     }
263
264   /* If the definition is a conversion of a pointer to a function type,
265      then we can not apply optimizations as some targets require function
266      pointers to be canonicalized and in this case this optimization could
267      eliminate a necessary canonicalization.  */
268   if ((TREE_CODE (rhs) == NOP_EXPR
269        || TREE_CODE (rhs) == CONVERT_EXPR)
270       && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (rhs, 0)))
271       && TREE_CODE (TREE_TYPE (TREE_TYPE
272                                 (TREE_OPERAND (rhs, 0)))) == FUNCTION_TYPE)
273     return false;
274
275   return true;
276 }
277
278 /* Remove a copy chain ending in NAME along the defs but not
279    further or including UP_TO_STMT.  If NAME was replaced in
280    its only use then this function can be used to clean up
281    dead stmts.  Returns true if UP_TO_STMT can be removed
282    as well, otherwise false.  */
283
284 static bool
285 remove_prop_source_from_use (tree name, tree up_to_stmt)
286 {
287   block_stmt_iterator bsi;
288   tree stmt;
289
290   do {
291     if (!has_zero_uses (name))
292       return false;
293
294     stmt = SSA_NAME_DEF_STMT (name);
295     if (stmt == up_to_stmt)
296       return true;
297
298     bsi = bsi_for_stmt (stmt);
299     release_defs (stmt);
300     bsi_remove (&bsi, true);
301
302     name = GIMPLE_STMT_OPERAND (stmt, 1);
303   } while (TREE_CODE (name) == SSA_NAME);
304
305   return false;
306 }
307
308 /* Combine OP0 CODE OP1 in the context of a COND_EXPR.  Returns
309    the folded result in a form suitable for COND_EXPR_COND or
310    NULL_TREE, if there is no suitable simplified form.  If
311    INVARIANT_ONLY is true only gimple_min_invariant results are
312    considered simplified.  */
313
314 static tree
315 combine_cond_expr_cond (enum tree_code code, tree type,
316                         tree op0, tree op1, bool invariant_only)
317 {
318   tree t;
319
320   gcc_assert (TREE_CODE_CLASS (code) == tcc_comparison);
321
322   t = fold_binary (code, type, op0, op1);
323   if (!t)
324     return NULL_TREE;
325
326   /* Require that we got a boolean type out if we put one in.  */
327   gcc_assert (TREE_CODE (TREE_TYPE (t)) == TREE_CODE (type));
328
329   /* Canonicalize the combined condition for use in a COND_EXPR.  */
330   t = canonicalize_cond_expr_cond (t);
331
332   /* Bail out if we required an invariant but didn't get one.  */
333   if (!t
334       || (invariant_only
335           && !is_gimple_min_invariant (t)))
336     return NULL_TREE;
337
338   return t;
339 }
340
341 /* Propagate from the ssa name definition statements of COND_EXPR
342    in statement STMT into the conditional if that simplifies it.
343    Returns zero if no statement was changed, one if there were
344    changes and two if cfg_cleanup needs to run.  */
345
346 static int
347 forward_propagate_into_cond (tree cond_expr, tree stmt)
348 {
349   int did_something = 0;
350
351   do {
352     tree tmp = NULL_TREE;
353     tree cond = COND_EXPR_COND (cond_expr);
354     tree name, def_stmt, rhs;
355     bool single_use_p;
356
357     /* We can do tree combining on SSA_NAME and comparison expressions.  */
358     if (COMPARISON_CLASS_P (cond)
359         && TREE_CODE (TREE_OPERAND (cond, 0)) == SSA_NAME)
360       {
361         /* For comparisons use the first operand, that is likely to
362            simplify comparisons against constants.  */
363         name = TREE_OPERAND (cond, 0);
364         def_stmt = get_prop_source_stmt (name, false, &single_use_p);
365         if (def_stmt != NULL_TREE
366             && can_propagate_from (def_stmt))
367           {
368             tree op1 = TREE_OPERAND (cond, 1);
369             rhs = GIMPLE_STMT_OPERAND (def_stmt, 1);
370             tmp = combine_cond_expr_cond (TREE_CODE (cond), boolean_type_node,
371                                           fold_convert (TREE_TYPE (op1), rhs),
372                                           op1, !single_use_p);
373           }
374         /* If that wasn't successful, try the second operand.  */
375         if (tmp == NULL_TREE
376             && TREE_CODE (TREE_OPERAND (cond, 1)) == SSA_NAME)
377           {
378             tree op0 = TREE_OPERAND (cond, 0);
379             name = TREE_OPERAND (cond, 1);
380             def_stmt = get_prop_source_stmt (name, false, &single_use_p);
381             if (def_stmt == NULL_TREE
382                 || !can_propagate_from (def_stmt))
383               return did_something;
384
385             rhs = GIMPLE_STMT_OPERAND (def_stmt, 1);
386             tmp = combine_cond_expr_cond (TREE_CODE (cond), boolean_type_node,
387                                           op0,
388                                           fold_convert (TREE_TYPE (op0), rhs),
389                                           !single_use_p);
390           }
391       }
392     else if (TREE_CODE (cond) == SSA_NAME)
393       {
394         name = cond;
395         def_stmt = get_prop_source_stmt (name, true, NULL);
396         if (def_stmt == NULL_TREE
397             || !can_propagate_from (def_stmt))
398           return did_something;
399
400         rhs = GIMPLE_STMT_OPERAND (def_stmt, 1);
401         tmp = combine_cond_expr_cond (NE_EXPR, boolean_type_node, rhs,
402                                       build_int_cst (TREE_TYPE (rhs), 0),
403                                       false);
404       }
405
406     if (tmp)
407       {
408         if (dump_file && tmp)
409           {
410             fprintf (dump_file, "  Replaced '");
411             print_generic_expr (dump_file, cond, 0);
412             fprintf (dump_file, "' with '");
413             print_generic_expr (dump_file, tmp, 0);
414             fprintf (dump_file, "'\n");
415           }
416
417         COND_EXPR_COND (cond_expr) = unshare_expr (tmp);
418         update_stmt (stmt);
419
420         /* Remove defining statements.  */
421         remove_prop_source_from_use (name, NULL);
422
423         if (is_gimple_min_invariant (tmp))
424           did_something = 2;
425         else if (did_something == 0)
426           did_something = 1;
427
428         /* Continue combining.  */
429         continue;
430       }
431
432     break;
433   } while (1);
434
435   return did_something;
436 }
437
438 /* We've just substituted an ADDR_EXPR into stmt.  Update all the 
439    relevant data structures to match.  */
440
441 static void
442 tidy_after_forward_propagate_addr (tree stmt)
443 {
444   /* We may have turned a trapping insn into a non-trapping insn.  */
445   if (maybe_clean_or_replace_eh_stmt (stmt, stmt)
446       && tree_purge_dead_eh_edges (bb_for_stmt (stmt)))
447     cfg_changed = true;
448
449   if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == ADDR_EXPR)
450      recompute_tree_invariant_for_addr_expr (GIMPLE_STMT_OPERAND (stmt, 1));
451
452   mark_symbols_for_renaming (stmt);
453 }
454
455 /* DEF_RHS contains the address of the 0th element in an array. 
456    USE_STMT uses type of DEF_RHS to compute the address of an
457    arbitrary element within the array.  The (variable) byte offset
458    of the element is contained in OFFSET.
459
460    We walk back through the use-def chains of OFFSET to verify that
461    it is indeed computing the offset of an element within the array
462    and extract the index corresponding to the given byte offset.
463
464    We then try to fold the entire address expression into a form
465    &array[index].
466
467    If we are successful, we replace the right hand side of USE_STMT
468    with the new address computation.  */
469
470 static bool
471 forward_propagate_addr_into_variable_array_index (tree offset,
472                                                   tree def_rhs, tree use_stmt)
473 {
474   tree index;
475
476   /* Try to find an expression for a proper index.  This is either
477      a multiplication expression by the element size or just the
478      ssa name we came along in case the element size is one.  */
479   if (integer_onep (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (def_rhs)))))
480     index = offset;
481   else
482     {
483       /* Get the offset's defining statement.  */
484       offset = SSA_NAME_DEF_STMT (offset);
485
486       /* The statement which defines OFFSET before type conversion
487          must be a simple GIMPLE_MODIFY_STMT.  */
488       if (TREE_CODE (offset) != GIMPLE_MODIFY_STMT)
489         return false;
490
491       /* The RHS of the statement which defines OFFSET must be a
492          multiplication of an object by the size of the array elements. 
493          This implicitly verifies that the size of the array elements
494          is constant.  */
495      offset = GIMPLE_STMT_OPERAND (offset, 1);
496       if (TREE_CODE (offset) != MULT_EXPR
497           || TREE_CODE (TREE_OPERAND (offset, 1)) != INTEGER_CST
498           || !simple_cst_equal (TREE_OPERAND (offset, 1),
499                                 TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (def_rhs)))))
500         return false;
501
502       /* The first operand to the MULT_EXPR is the desired index.  */
503       index = TREE_OPERAND (offset, 0);
504     }
505
506   /* Replace the pointer addition with array indexing.  */
507   GIMPLE_STMT_OPERAND (use_stmt, 1) = unshare_expr (def_rhs);
508   TREE_OPERAND (TREE_OPERAND (GIMPLE_STMT_OPERAND (use_stmt, 1), 0), 1)
509     = index;
510
511   /* That should have created gimple, so there is no need to
512      record information to undo the propagation.  */
513   fold_stmt_inplace (use_stmt);
514   tidy_after_forward_propagate_addr (use_stmt);
515   return true;
516 }
517
518 /* NAME is a SSA_NAME representing DEF_RHS which is of the form
519    ADDR_EXPR <whatever>.
520
521    Try to forward propagate the ADDR_EXPR into the use USE_STMT.
522    Often this will allow for removal of an ADDR_EXPR and INDIRECT_REF
523    node or for recovery of array indexing from pointer arithmetic.
524    
525    Return true if the propagation was successful (the propagation can
526    be not totally successful, yet things may have been changed).  */
527
528 static bool
529 forward_propagate_addr_expr_1 (tree name, tree def_rhs, tree use_stmt,
530                                bool single_use_p)
531 {
532   tree lhs, rhs, array_ref;
533
534   /* Strip away any outer COMPONENT_REF/ARRAY_REF nodes from the LHS. 
535      ADDR_EXPR will not appear on the LHS.  */
536   lhs = GIMPLE_STMT_OPERAND (use_stmt, 0);
537   while (handled_component_p (lhs))
538     lhs = TREE_OPERAND (lhs, 0);
539
540   rhs = GIMPLE_STMT_OPERAND (use_stmt, 1);
541
542   /* Now see if the LHS node is an INDIRECT_REF using NAME.  If so, 
543      propagate the ADDR_EXPR into the use of NAME and fold the result.  */
544   if (TREE_CODE (lhs) == INDIRECT_REF && TREE_OPERAND (lhs, 0) == name)
545     {
546       /* This should always succeed in creating gimple, so there is
547          no need to save enough state to undo this propagation.  */
548       TREE_OPERAND (lhs, 0) = unshare_expr (def_rhs);
549       fold_stmt_inplace (use_stmt);
550       tidy_after_forward_propagate_addr (use_stmt);
551
552       /* Continue propagating into the RHS.  */
553     }
554
555   /* Trivial cases.  The use statement could be a trivial copy or a
556      useless conversion.  Recurse to the uses of the lhs as copyprop does
557      not copy through differen variant pointers and FRE does not catch
558      all useless conversions.  Treat the case of a single-use name and
559      a conversion to def_rhs type separate, though.  */
560   else if (TREE_CODE (lhs) == SSA_NAME
561            && (TREE_CODE (rhs) == NOP_EXPR
562                || TREE_CODE (rhs) == CONVERT_EXPR)
563            && TREE_TYPE (rhs) == TREE_TYPE (def_rhs)
564            && single_use_p)
565     {
566       GIMPLE_STMT_OPERAND (use_stmt, 1) = unshare_expr (def_rhs);
567       return true;
568     }
569   else if ((TREE_CODE (lhs) == SSA_NAME
570             && rhs == name)
571            || ((TREE_CODE (rhs) == NOP_EXPR
572                 || TREE_CODE (rhs) == CONVERT_EXPR)
573                && useless_type_conversion_p (TREE_TYPE (rhs),
574                                             TREE_TYPE (def_rhs))))
575     return forward_propagate_addr_expr (lhs, def_rhs);
576
577   /* Strip away any outer COMPONENT_REF, ARRAY_REF or ADDR_EXPR
578      nodes from the RHS.  */
579   while (handled_component_p (rhs)
580          || TREE_CODE (rhs) == ADDR_EXPR)
581     rhs = TREE_OPERAND (rhs, 0);
582
583   /* Now see if the RHS node is an INDIRECT_REF using NAME.  If so, 
584      propagate the ADDR_EXPR into the use of NAME and fold the result.  */
585   if (TREE_CODE (rhs) == INDIRECT_REF && TREE_OPERAND (rhs, 0) == name)
586     {
587       /* This should always succeed in creating gimple, so there is
588          no need to save enough state to undo this propagation.  */
589       TREE_OPERAND (rhs, 0) = unshare_expr (def_rhs);
590       fold_stmt_inplace (use_stmt);
591       tidy_after_forward_propagate_addr (use_stmt);
592       return true;
593     }
594
595   /* The remaining cases are all for turning pointer arithmetic into
596      array indexing.  They only apply when we have the address of
597      element zero in an array.  If that is not the case then there
598      is nothing to do.  */
599   array_ref = TREE_OPERAND (def_rhs, 0);
600   if (TREE_CODE (array_ref) != ARRAY_REF
601       || TREE_CODE (TREE_TYPE (TREE_OPERAND (array_ref, 0))) != ARRAY_TYPE
602       || !integer_zerop (TREE_OPERAND (array_ref, 1)))
603     return false;
604
605   /* If the use of the ADDR_EXPR is not a POINTER_PLUS_EXPR, there
606      is nothing to do. */
607   if (TREE_CODE (rhs) != POINTER_PLUS_EXPR)
608     return false;
609
610   /* Try to optimize &x[0] p+ C where C is a multiple of the size
611      of the elements in X into &x[C/element size].  */
612   if (TREE_OPERAND (rhs, 0) == name
613       && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST)
614     {
615       tree orig = unshare_expr (rhs);
616       TREE_OPERAND (rhs, 0) = unshare_expr (def_rhs);
617
618       /* If folding succeeds, then we have just exposed new variables
619          in USE_STMT which will need to be renamed.  If folding fails,
620          then we need to put everything back the way it was.  */
621       if (fold_stmt_inplace (use_stmt))
622         {
623           tidy_after_forward_propagate_addr (use_stmt);
624           return true;
625         }
626       else
627         {
628           GIMPLE_STMT_OPERAND (use_stmt, 1) = orig;
629           update_stmt (use_stmt);
630           return false;
631         }
632     }
633
634   /* Try to optimize &x[0] p+ OFFSET where OFFSET is defined by
635      converting a multiplication of an index by the size of the
636      array elements, then the result is converted into the proper
637      type for the arithmetic.  */
638   if (TREE_OPERAND (rhs, 0) == name
639       && TREE_CODE (TREE_OPERAND (rhs, 1)) == SSA_NAME
640       /* Avoid problems with IVopts creating PLUS_EXPRs with a
641          different type than their operands.  */
642       && useless_type_conversion_p (TREE_TYPE (rhs), TREE_TYPE (name)))
643     {
644       bool res;
645       
646       res = forward_propagate_addr_into_variable_array_index (TREE_OPERAND (rhs, 1),
647                                                               def_rhs, use_stmt);
648       return res;
649     }
650   return false;
651 }
652
653 /* STMT is a statement of the form SSA_NAME = ADDR_EXPR <whatever>.
654
655    Try to forward propagate the ADDR_EXPR into all uses of the SSA_NAME.
656    Often this will allow for removal of an ADDR_EXPR and INDIRECT_REF
657    node or for recovery of array indexing from pointer arithmetic.
658    Returns true, if all uses have been propagated into.  */
659
660 static bool
661 forward_propagate_addr_expr (tree name, tree rhs)
662 {
663   int stmt_loop_depth = bb_for_stmt (SSA_NAME_DEF_STMT (name))->loop_depth;
664   imm_use_iterator iter;
665   tree use_stmt;
666   bool all = true;
667   bool single_use_p = has_single_use (name);
668
669   FOR_EACH_IMM_USE_STMT (use_stmt, iter, name)
670     {
671       bool result;
672
673       /* If the use is not in a simple assignment statement, then
674          there is nothing we can do.  */
675       if (TREE_CODE (use_stmt) != GIMPLE_MODIFY_STMT)
676         {
677           all = false;
678           continue;
679         }
680
681       /* If the use is in a deeper loop nest, then we do not want
682         to propagate the ADDR_EXPR into the loop as that is likely
683         adding expression evaluations into the loop.  */
684       if (bb_for_stmt (use_stmt)->loop_depth > stmt_loop_depth)
685         {
686           all = false;
687           continue;
688         }
689
690       push_stmt_changes (&use_stmt);
691
692       result = forward_propagate_addr_expr_1 (name, rhs, use_stmt,
693                                               single_use_p);
694       all &= result;
695
696       pop_stmt_changes (&use_stmt);
697
698       /* Remove intermediate now unused copy and conversion chains.  */
699       if (result
700           && TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 0)) == SSA_NAME
701           && (TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 1)) == SSA_NAME
702               || TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 1)) == NOP_EXPR
703               || TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 1)) == CONVERT_EXPR))
704         {
705           block_stmt_iterator bsi = bsi_for_stmt (use_stmt);
706           release_defs (use_stmt);
707           bsi_remove (&bsi, true);
708         }
709     }
710
711   return all;
712 }
713
714 /* Forward propagate the comparison COND defined in STMT like
715    cond_1 = x CMP y to uses of the form
716      a_1 = (T')cond_1
717      a_1 = !cond_1
718      a_1 = cond_1 != 0
719    Returns true if stmt is now unused.  */
720
721 static bool
722 forward_propagate_comparison (tree cond, tree stmt)
723 {
724   tree name = GIMPLE_STMT_OPERAND (stmt, 0);
725   tree use_stmt, tmp = NULL_TREE;
726
727   /* Don't propagate ssa names that occur in abnormal phis.  */
728   if ((TREE_CODE (TREE_OPERAND (cond, 0)) == SSA_NAME
729        && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (cond, 0)))
730       || (TREE_CODE (TREE_OPERAND (cond, 1)) == SSA_NAME
731           && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (cond, 1))))
732     return false;
733
734   /* Do not un-cse comparisons.  But propagate through copies.  */
735   use_stmt = get_prop_dest_stmt (name, &name);
736   if (use_stmt == NULL_TREE)
737     return false;
738
739   /* Conversion of the condition result to another integral type.  */
740   if (TREE_CODE (use_stmt) == GIMPLE_MODIFY_STMT
741       && (TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 1)) == CONVERT_EXPR
742           || TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 1)) == NOP_EXPR
743           || COMPARISON_CLASS_P (GIMPLE_STMT_OPERAND (use_stmt, 1))
744           || TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 1)) == TRUTH_NOT_EXPR)
745       && INTEGRAL_TYPE_P (TREE_TYPE (GIMPLE_STMT_OPERAND (use_stmt, 0))))
746     {
747       tree lhs = GIMPLE_STMT_OPERAND (use_stmt, 0);
748       tree rhs = GIMPLE_STMT_OPERAND (use_stmt, 1);
749
750       /* We can propagate the condition into a conversion.  */
751       if (TREE_CODE (rhs) == CONVERT_EXPR
752           || TREE_CODE (rhs) == NOP_EXPR)
753         {
754           /* Avoid using fold here as that may create a COND_EXPR with
755              non-boolean condition as canonical form.  */
756           tmp = build2 (TREE_CODE (cond), TREE_TYPE (lhs),
757                         TREE_OPERAND (cond, 0), TREE_OPERAND (cond, 1));
758         }
759       /* We can propagate the condition into X op CST where op
760          is EQ_EXRP or NE_EXPR and CST is either one or zero.  */
761       else if (COMPARISON_CLASS_P (rhs)
762                && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
763                && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST)
764         {
765           enum tree_code code = TREE_CODE (rhs);
766           tree cst = TREE_OPERAND (rhs, 1);
767
768           tmp = combine_cond_expr_cond (code, TREE_TYPE (lhs),
769                                         fold_convert (TREE_TYPE (cst), cond),
770                                         cst, false);
771           if (tmp == NULL_TREE)
772             return false;
773         }
774       /* We can propagate the condition into a statement that
775          computes the logical negation of the comparison result.  */
776       else if (TREE_CODE (rhs) == TRUTH_NOT_EXPR)
777         {
778           tree type = TREE_TYPE (TREE_OPERAND (cond, 0));
779           bool nans = HONOR_NANS (TYPE_MODE (type));
780           enum tree_code code;
781           code = invert_tree_comparison (TREE_CODE (cond), nans);
782           if (code == ERROR_MARK)
783             return false;
784
785           tmp = build2 (code, TREE_TYPE (lhs), TREE_OPERAND (cond, 0),
786                         TREE_OPERAND (cond, 1));
787         }
788       else
789         return false;
790
791       GIMPLE_STMT_OPERAND (use_stmt, 1) = unshare_expr (tmp);
792       update_stmt (use_stmt);
793
794       /* Remove defining statements.  */
795       remove_prop_source_from_use (name, stmt);
796
797       if (dump_file && (dump_flags & TDF_DETAILS))
798         {
799           fprintf (dump_file, "  Replaced '");
800           print_generic_expr (dump_file, rhs, dump_flags);
801           fprintf (dump_file, "' with '");
802           print_generic_expr (dump_file, tmp, dump_flags);
803           fprintf (dump_file, "'\n");
804         }
805
806       return true;
807     }
808
809   return false;
810 }
811
812 /* If we have lhs = ~x (STMT), look and see if earlier we had x = ~y.
813    If so, we can change STMT into lhs = y which can later be copy
814    propagated.  Similarly for negation. 
815
816    This could trivially be formulated as a forward propagation 
817    to immediate uses.  However, we already had an implementation
818    from DOM which used backward propagation via the use-def links.
819
820    It turns out that backward propagation is actually faster as
821    there's less work to do for each NOT/NEG expression we find.
822    Backwards propagation needs to look at the statement in a single
823    backlink.  Forward propagation needs to look at potentially more
824    than one forward link.  */
825
826 static void
827 simplify_not_neg_expr (tree stmt)
828 {
829   tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
830   tree rhs_def_stmt = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 0));
831
832   /* See if the RHS_DEF_STMT has the same form as our statement.  */
833   if (TREE_CODE (rhs_def_stmt) == GIMPLE_MODIFY_STMT
834       && TREE_CODE (GIMPLE_STMT_OPERAND (rhs_def_stmt, 1)) == TREE_CODE (rhs))
835     {
836       tree rhs_def_operand =
837         TREE_OPERAND (GIMPLE_STMT_OPERAND (rhs_def_stmt, 1), 0);
838
839       /* Verify that RHS_DEF_OPERAND is a suitable SSA_NAME.  */
840       if (TREE_CODE (rhs_def_operand) == SSA_NAME
841           && ! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs_def_operand))
842         {
843           GIMPLE_STMT_OPERAND (stmt, 1) = rhs_def_operand;
844           update_stmt (stmt);
845         }
846     }
847 }
848
849 /* STMT is a SWITCH_EXPR for which we attempt to find equivalent forms of
850    the condition which we may be able to optimize better.  */
851
852 static void
853 simplify_switch_expr (tree stmt)
854 {
855   tree cond = SWITCH_COND (stmt);
856   tree def, to, ti;
857
858   /* The optimization that we really care about is removing unnecessary
859      casts.  That will let us do much better in propagating the inferred
860      constant at the switch target.  */
861   if (TREE_CODE (cond) == SSA_NAME)
862     {
863       def = SSA_NAME_DEF_STMT (cond);
864       if (TREE_CODE (def) == GIMPLE_MODIFY_STMT)
865         {
866           def = GIMPLE_STMT_OPERAND (def, 1);
867           if (TREE_CODE (def) == NOP_EXPR)
868             {
869               int need_precision;
870               bool fail;
871
872               def = TREE_OPERAND (def, 0);
873
874 #ifdef ENABLE_CHECKING
875               /* ??? Why was Jeff testing this?  We are gimple...  */
876               gcc_assert (is_gimple_val (def));
877 #endif
878
879               to = TREE_TYPE (cond);
880               ti = TREE_TYPE (def);
881
882               /* If we have an extension that preserves value, then we
883                  can copy the source value into the switch.  */
884
885               need_precision = TYPE_PRECISION (ti);
886               fail = false;
887               if (! INTEGRAL_TYPE_P (ti))
888                 fail = true;
889               else if (TYPE_UNSIGNED (to) && !TYPE_UNSIGNED (ti))
890                 fail = true;
891               else if (!TYPE_UNSIGNED (to) && TYPE_UNSIGNED (ti))
892                 need_precision += 1;
893               if (TYPE_PRECISION (to) < need_precision)
894                 fail = true;
895
896               if (!fail)
897                 {
898                   SWITCH_COND (stmt) = def;
899                   update_stmt (stmt);
900                 }
901             }
902         }
903     }
904 }
905
906 /* Main entry point for the forward propagation optimizer.  */
907
908 static unsigned int
909 tree_ssa_forward_propagate_single_use_vars (void)
910 {
911   basic_block bb;
912   unsigned int todoflags = 0;
913
914   cfg_changed = false;
915
916   FOR_EACH_BB (bb)
917     {
918       block_stmt_iterator bsi;
919
920       /* Note we update BSI within the loop as necessary.  */
921       for (bsi = bsi_start (bb); !bsi_end_p (bsi); )
922         {
923           tree stmt = bsi_stmt (bsi);
924
925           /* If this statement sets an SSA_NAME to an address,
926              try to propagate the address into the uses of the SSA_NAME.  */
927           if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
928             {
929               tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
930               tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
931
932
933               if (TREE_CODE (lhs) != SSA_NAME)
934                 {
935                   bsi_next (&bsi);
936                   continue;
937                 }
938
939               if (TREE_CODE (rhs) == ADDR_EXPR)
940                 {
941                   if (forward_propagate_addr_expr (lhs, rhs))
942                     {
943                       release_defs (stmt);
944                       todoflags |= TODO_remove_unused_locals;
945                       bsi_remove (&bsi, true);
946                     }
947                   else
948                     bsi_next (&bsi);
949                 }
950               else if ((TREE_CODE (rhs) == BIT_NOT_EXPR
951                         || TREE_CODE (rhs) == NEGATE_EXPR)
952                        && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
953                 {
954                   simplify_not_neg_expr (stmt);
955                   bsi_next (&bsi);
956                 }
957               else if (TREE_CODE (rhs) == COND_EXPR)
958                 {
959                   int did_something;
960                   fold_defer_overflow_warnings ();
961                   did_something = forward_propagate_into_cond (rhs, stmt);
962                   if (did_something == 2)
963                     cfg_changed = true;
964                   fold_undefer_overflow_warnings (!TREE_NO_WARNING (rhs)
965                     && did_something, stmt, WARN_STRICT_OVERFLOW_CONDITIONAL);
966                   bsi_next (&bsi);
967                 }
968               else if (COMPARISON_CLASS_P (rhs))
969                 {
970                   if (forward_propagate_comparison (rhs, stmt))
971                     {
972                       release_defs (stmt);
973                       todoflags |= TODO_remove_unused_locals;
974                       bsi_remove (&bsi, true);
975                     }
976                   else
977                     bsi_next (&bsi);
978                 }
979               else
980                 bsi_next (&bsi);
981             }
982           else if (TREE_CODE (stmt) == SWITCH_EXPR)
983             {
984               simplify_switch_expr (stmt);
985               bsi_next (&bsi);
986             }
987           else if (TREE_CODE (stmt) == COND_EXPR)
988             {
989               int did_something;
990               fold_defer_overflow_warnings ();
991               did_something = forward_propagate_into_cond (stmt, stmt);
992               if (did_something == 2)
993                 cfg_changed = true;
994               fold_undefer_overflow_warnings (did_something, stmt,
995                                               WARN_STRICT_OVERFLOW_CONDITIONAL);
996               bsi_next (&bsi);
997             }
998           else
999             bsi_next (&bsi);
1000         }
1001     }
1002
1003   if (cfg_changed)
1004     todoflags |= TODO_cleanup_cfg;
1005   return todoflags;
1006 }
1007
1008
1009 static bool
1010 gate_forwprop (void)
1011 {
1012   return 1;
1013 }
1014
1015 struct tree_opt_pass pass_forwprop = {
1016   "forwprop",                   /* name */
1017   gate_forwprop,                /* gate */
1018   tree_ssa_forward_propagate_single_use_vars,   /* execute */
1019   NULL,                         /* sub */
1020   NULL,                         /* next */
1021   0,                            /* static_pass_number */
1022   TV_TREE_FORWPROP,             /* tv_id */
1023   PROP_cfg | PROP_ssa,          /* properties_required */
1024   0,                            /* properties_provided */
1025   0,                            /* properties_destroyed */
1026   0,                            /* todo_flags_start */
1027   TODO_dump_func
1028   | TODO_ggc_collect
1029   | TODO_update_ssa
1030   | TODO_verify_ssa,            /* todo_flags_finish */
1031   0                             /* letter */
1032 };
1033
1034
1035 /* Structure to keep track of the value of a dereferenced PHI result
1036    and the set of virtual operands used for that dereference.  */
1037
1038 struct phiprop_d
1039 {
1040   tree value;
1041   tree vop_stmt;
1042 };
1043
1044 /* Verify if the value recorded for NAME in PHIVN is still valid at
1045    the start of basic block BB.  */
1046
1047 static bool
1048 phivn_valid_p (struct phiprop_d *phivn, tree name, basic_block bb)
1049 {
1050   tree vop_stmt = phivn[SSA_NAME_VERSION (name)].vop_stmt;
1051   ssa_op_iter ui;
1052   tree vuse;
1053
1054   /* The def stmts of all virtual uses need to be post-dominated
1055      by bb.  */
1056   FOR_EACH_SSA_TREE_OPERAND (vuse, vop_stmt, ui, SSA_OP_VUSE)
1057     {
1058       tree use_stmt;
1059       imm_use_iterator ui2;
1060       bool ok = true;
1061
1062       FOR_EACH_IMM_USE_STMT (use_stmt, ui2, vuse)
1063         {
1064           /* If BB does not dominate a VDEF, the value is invalid.  */
1065           if (((TREE_CODE (use_stmt) == GIMPLE_MODIFY_STMT
1066                 && !ZERO_SSA_OPERANDS (use_stmt, SSA_OP_VDEF))
1067                || TREE_CODE (use_stmt) == PHI_NODE)
1068               && !dominated_by_p (CDI_DOMINATORS, bb_for_stmt (use_stmt), bb))
1069             {
1070               ok = false;
1071               BREAK_FROM_IMM_USE_STMT (ui2);
1072             }
1073         }
1074       if (!ok)
1075         return false;
1076     }
1077
1078   return true;
1079 }
1080
1081 /* Insert a new phi node for the dereference of PHI at basic_block
1082    BB with the virtual operands from USE_STMT.  */
1083
1084 static tree
1085 phiprop_insert_phi (basic_block bb, tree phi, tree use_stmt,
1086                     struct phiprop_d *phivn, size_t n)
1087 {
1088   tree res, new_phi;
1089   edge_iterator ei;
1090   edge e;
1091
1092   /* Build a new PHI node to replace the definition of
1093      the indirect reference lhs.  */
1094   res = GIMPLE_STMT_OPERAND (use_stmt, 0);
1095   SSA_NAME_DEF_STMT (res) = new_phi = create_phi_node (res, bb);
1096
1097   /* Add PHI arguments for each edge inserting loads of the
1098      addressable operands.  */
1099   FOR_EACH_EDGE (e, ei, bb->preds)
1100     {
1101       tree old_arg, new_var, tmp;
1102
1103       old_arg = PHI_ARG_DEF_FROM_EDGE (phi, e);
1104       while (TREE_CODE (old_arg) == SSA_NAME
1105              && (SSA_NAME_VERSION (old_arg) >= n
1106                  || phivn[SSA_NAME_VERSION (old_arg)].value == NULL_TREE))
1107         {
1108           tree def_stmt = SSA_NAME_DEF_STMT (old_arg);
1109           old_arg = GIMPLE_STMT_OPERAND (def_stmt, 1);
1110         }
1111
1112       if (TREE_CODE (old_arg) == SSA_NAME)
1113         /* Reuse a formerly created dereference.  */
1114         new_var = phivn[SSA_NAME_VERSION (old_arg)].value;
1115       else
1116         {
1117           old_arg = TREE_OPERAND (old_arg, 0);
1118           new_var = create_tmp_var (TREE_TYPE (old_arg), NULL);
1119           tmp = build2 (GIMPLE_MODIFY_STMT, void_type_node,
1120                         NULL_TREE, unshare_expr (old_arg));
1121           if (TREE_CODE (TREE_TYPE (old_arg)) == COMPLEX_TYPE
1122               || TREE_CODE (TREE_TYPE (old_arg)) == VECTOR_TYPE)
1123             DECL_GIMPLE_REG_P (new_var) = 1;
1124           add_referenced_var (new_var);
1125           new_var = make_ssa_name (new_var, tmp);
1126           GIMPLE_STMT_OPERAND (tmp, 0) = new_var;
1127
1128           bsi_insert_on_edge (e, tmp);
1129
1130           update_stmt (tmp);
1131           mark_symbols_for_renaming (tmp);
1132         }
1133
1134       add_phi_arg (new_phi, new_var, e);
1135     }
1136
1137   update_stmt (new_phi);
1138
1139   return res;
1140 }
1141
1142 /* Propagate between the phi node arguments of PHI in BB and phi result
1143    users.  For now this matches
1144         # p_2 = PHI <&x, &y>
1145       <Lx>:;
1146         p_3 = p_2;
1147         z_2 = *p_3;
1148    and converts it to
1149         # z_2 = PHI <x, y>
1150       <Lx>:;
1151    Returns true if a transformation was done and edge insertions
1152    need to be committed.  Global data PHIVN and N is used to track
1153    past transformation results.  We need to be especially careful here
1154    with aliasing issues as we are moving memory reads.  */
1155
1156 static bool
1157 propagate_with_phi (basic_block bb, tree phi, struct phiprop_d *phivn, size_t n)
1158 {
1159   tree ptr = PHI_RESULT (phi);
1160   tree use_stmt, res = NULL_TREE;
1161   block_stmt_iterator bsi;
1162   imm_use_iterator ui;
1163   use_operand_p arg_p, use;
1164   ssa_op_iter i;
1165   bool phi_inserted;
1166
1167   if (MTAG_P (SSA_NAME_VAR (ptr))
1168       || !POINTER_TYPE_P (TREE_TYPE (ptr))
1169       || !is_gimple_reg_type (TREE_TYPE (TREE_TYPE (ptr))))
1170     return false;
1171
1172   /* Check if we can "cheaply" dereference all phi arguments.  */
1173   FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_USE)
1174     {
1175       tree arg = USE_FROM_PTR (arg_p);
1176       /* Walk the ssa chain until we reach a ssa name we already
1177          created a value for or we reach a definition of the form
1178          ssa_name_n = &var;  */
1179       while (TREE_CODE (arg) == SSA_NAME
1180              && !SSA_NAME_IS_DEFAULT_DEF (arg)
1181              && (SSA_NAME_VERSION (arg) >= n
1182                  || phivn[SSA_NAME_VERSION (arg)].value == NULL_TREE))
1183         {
1184           tree def_stmt = SSA_NAME_DEF_STMT (arg);
1185           if (TREE_CODE (def_stmt) != GIMPLE_MODIFY_STMT)
1186             return false;
1187           arg = GIMPLE_STMT_OPERAND (def_stmt, 1);
1188         }
1189       if ((TREE_CODE (arg) != ADDR_EXPR
1190            /* Avoid to have to decay *&a to a[0] later.  */
1191            || !is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (arg, 0))))
1192           && !(TREE_CODE (arg) == SSA_NAME
1193                && phivn[SSA_NAME_VERSION (arg)].value != NULL_TREE
1194                && phivn_valid_p (phivn, arg, bb)))
1195         return false;
1196     }
1197
1198   /* Find a dereferencing use.  First follow (single use) ssa
1199      copy chains for ptr.  */
1200   while (single_imm_use (ptr, &use, &use_stmt)
1201          && TREE_CODE (use_stmt) == GIMPLE_MODIFY_STMT
1202          && GIMPLE_STMT_OPERAND (use_stmt, 1) == ptr
1203          && TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 0)) == SSA_NAME)
1204     ptr = GIMPLE_STMT_OPERAND (use_stmt, 0);
1205
1206   /* Replace the first dereference of *ptr if there is one and if we
1207      can move the loads to the place of the ptr phi node.  */
1208   phi_inserted = false;
1209   FOR_EACH_IMM_USE_STMT (use_stmt, ui, ptr)
1210     {
1211       ssa_op_iter ui2;
1212       tree vuse;
1213
1214       /* Check whether this is a load of *ptr.  */
1215       if (!(TREE_CODE (use_stmt) == GIMPLE_MODIFY_STMT
1216             && TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 0)) == SSA_NAME 
1217             && TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 1)) == INDIRECT_REF
1218             && TREE_OPERAND (GIMPLE_STMT_OPERAND (use_stmt, 1), 0) == ptr
1219             /* We cannot replace a load that may throw or is volatile.  */
1220             && !tree_can_throw_internal (use_stmt)))
1221         continue;
1222
1223       /* Check if we can move the loads.  The def stmts of all virtual uses
1224          need to be post-dominated by bb.  */
1225       FOR_EACH_SSA_TREE_OPERAND (vuse, use_stmt, ui2, SSA_OP_VUSE)
1226         {
1227           tree def_stmt = SSA_NAME_DEF_STMT (vuse);
1228           if (!SSA_NAME_IS_DEFAULT_DEF (vuse)
1229               && (bb_for_stmt (def_stmt) == bb
1230                   || !dominated_by_p (CDI_DOMINATORS,
1231                                       bb, bb_for_stmt (def_stmt))))
1232             goto next;
1233         }
1234
1235       /* Found a proper dereference.  Insert a phi node if this
1236          is the first load transformation.  */
1237       if (!phi_inserted)
1238         {
1239           res = phiprop_insert_phi (bb, phi, use_stmt, phivn, n);
1240
1241           /* Remember the value we created for *ptr.  */
1242           phivn[SSA_NAME_VERSION (ptr)].value = res;
1243           phivn[SSA_NAME_VERSION (ptr)].vop_stmt = use_stmt;
1244
1245           /* Remove old stmt.  The phi is taken care of by DCE, if we
1246              want to delete it here we also have to delete all intermediate
1247              copies.  */
1248           bsi = bsi_for_stmt (use_stmt);
1249           bsi_remove (&bsi, 0);
1250
1251           phi_inserted = true;
1252         }
1253       else
1254         {
1255           /* Further replacements are easy, just make a copy out of the
1256              load.  */
1257           GIMPLE_STMT_OPERAND (use_stmt, 1) = res;
1258           update_stmt (use_stmt);
1259         }
1260
1261 next:;
1262       /* Continue searching for a proper dereference.  */
1263     }
1264
1265   return phi_inserted;
1266 }
1267
1268 /* Helper walking the dominator tree starting from BB and processing
1269    phi nodes with global data PHIVN and N.  */
1270
1271 static bool
1272 tree_ssa_phiprop_1 (basic_block bb, struct phiprop_d *phivn, size_t n)
1273 {
1274   bool did_something = false; 
1275   basic_block son;
1276   tree phi;
1277
1278   for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
1279     did_something |= propagate_with_phi (bb, phi, phivn, n);
1280
1281   for (son = first_dom_son (CDI_DOMINATORS, bb);
1282        son;
1283        son = next_dom_son (CDI_DOMINATORS, son))
1284     did_something |= tree_ssa_phiprop_1 (son, phivn, n);
1285
1286   return did_something;
1287 }
1288
1289 /* Main entry for phiprop pass.  */
1290
1291 static unsigned int
1292 tree_ssa_phiprop (void)
1293 {
1294   struct phiprop_d *phivn;
1295
1296   calculate_dominance_info (CDI_DOMINATORS);
1297
1298   phivn = XCNEWVEC (struct phiprop_d, num_ssa_names);
1299
1300   if (tree_ssa_phiprop_1 (ENTRY_BLOCK_PTR, phivn, num_ssa_names))
1301     bsi_commit_edge_inserts ();
1302
1303   free (phivn);
1304
1305   return 0;
1306 }
1307
1308 static bool
1309 gate_phiprop (void)
1310 {
1311   return 1;
1312 }
1313
1314 struct tree_opt_pass pass_phiprop = {
1315   "phiprop",                    /* name */
1316   gate_phiprop,                 /* gate */
1317   tree_ssa_phiprop,             /* execute */
1318   NULL,                         /* sub */
1319   NULL,                         /* next */
1320   0,                            /* static_pass_number */
1321   TV_TREE_FORWPROP,             /* tv_id */
1322   PROP_cfg | PROP_ssa,          /* properties_required */
1323   0,                            /* properties_provided */
1324   0,                            /* properties_destroyed */
1325   0,                            /* todo_flags_start */
1326   TODO_dump_func
1327   | TODO_ggc_collect
1328   | TODO_update_ssa
1329   | TODO_verify_ssa,            /* todo_flags_finish */
1330   0                             /* letter */
1331 };