OSDN Git Service

2011-07-19 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, 2008, 2009, 2010, 2011
3    Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "tree.h"
26 #include "tm_p.h"
27 #include "basic-block.h"
28 #include "timevar.h"
29 #include "tree-pretty-print.h"
30 #include "tree-flow.h"
31 #include "tree-pass.h"
32 #include "tree-dump.h"
33 #include "langhooks.h"
34 #include "flags.h"
35 #include "gimple.h"
36 #include "expr.h"
37
38 /* This pass propagates the RHS of assignment statements into use
39    sites of the LHS of the assignment.  It's basically a specialized
40    form of tree combination.   It is hoped all of this can disappear
41    when we have a generalized tree combiner.
42
43    One class of common cases we handle is forward propagating a single use
44    variable into a COND_EXPR.
45
46      bb0:
47        x = a COND b;
48        if (x) goto ... else goto ...
49
50    Will be transformed into:
51
52      bb0:
53        if (a COND b) goto ... else goto ...
54
55    Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
56
57    Or (assuming c1 and c2 are constants):
58
59      bb0:
60        x = a + c1;
61        if (x EQ/NEQ c2) goto ... else goto ...
62
63    Will be transformed into:
64
65      bb0:
66         if (a EQ/NEQ (c2 - c1)) goto ... else goto ...
67
68    Similarly for x = a - c1.
69
70    Or
71
72      bb0:
73        x = !a
74        if (x) goto ... else goto ...
75
76    Will be transformed into:
77
78      bb0:
79         if (a == 0) goto ... else goto ...
80
81    Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
82    For these cases, we propagate A into all, possibly more than one,
83    COND_EXPRs that use X.
84
85    Or
86
87      bb0:
88        x = (typecast) a
89        if (x) goto ... else goto ...
90
91    Will be transformed into:
92
93      bb0:
94         if (a != 0) goto ... else goto ...
95
96    (Assuming a is an integral type and x is a boolean or x is an
97     integral and a is a boolean.)
98
99    Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
100    For these cases, we propagate A into all, possibly more than one,
101    COND_EXPRs that use X.
102
103    In addition to eliminating the variable and the statement which assigns
104    a value to the variable, we may be able to later thread the jump without
105    adding insane complexity in the dominator optimizer.
106
107    Also note these transformations can cascade.  We handle this by having
108    a worklist of COND_EXPR statements to examine.  As we make a change to
109    a statement, we put it back on the worklist to examine on the next
110    iteration of the main loop.
111
112    A second class of propagation opportunities arises for ADDR_EXPR
113    nodes.
114
115      ptr = &x->y->z;
116      res = *ptr;
117
118    Will get turned into
119
120      res = x->y->z;
121
122    Or
123      ptr = (type1*)&type2var;
124      res = *ptr
125
126    Will get turned into (if type1 and type2 are the same size
127    and neither have volatile on them):
128      res = VIEW_CONVERT_EXPR<type1>(type2var)
129
130    Or
131
132      ptr = &x[0];
133      ptr2 = ptr + <constant>;
134
135    Will get turned into
136
137      ptr2 = &x[constant/elementsize];
138
139   Or
140
141      ptr = &x[0];
142      offset = index * element_size;
143      offset_p = (pointer) offset;
144      ptr2 = ptr + offset_p
145
146   Will get turned into:
147
148      ptr2 = &x[index];
149
150   Or
151     ssa = (int) decl
152     res = ssa & 1
153
154   Provided that decl has known alignment >= 2, will get turned into
155
156     res = 0
157
158   We also propagate casts into SWITCH_EXPR and COND_EXPR conditions to
159   allow us to remove the cast and {NOT_EXPR,NEG_EXPR} into a subsequent
160   {NOT_EXPR,NEG_EXPR}.
161
162    This will (of course) be extended as other needs arise.  */
163
164 static bool forward_propagate_addr_expr (tree name, tree rhs);
165
166 /* Set to true if we delete EH edges during the optimization.  */
167 static bool cfg_changed;
168
169 static tree rhs_to_tree (tree type, gimple stmt);
170
171 /* Get the next statement we can propagate NAME's value into skipping
172    trivial copies.  Returns the statement that is suitable as a
173    propagation destination or NULL_TREE if there is no such one.
174    This only returns destinations in a single-use chain.  FINAL_NAME_P
175    if non-NULL is written to the ssa name that represents the use.  */
176
177 static gimple
178 get_prop_dest_stmt (tree name, tree *final_name_p)
179 {
180   use_operand_p use;
181   gimple use_stmt;
182
183   do {
184     /* If name has multiple uses, bail out.  */
185     if (!single_imm_use (name, &use, &use_stmt))
186       return NULL;
187
188     /* If this is not a trivial copy, we found it.  */
189     if (!gimple_assign_ssa_name_copy_p (use_stmt)
190         || gimple_assign_rhs1 (use_stmt) != name)
191       break;
192
193     /* Continue searching uses of the copy destination.  */
194     name = gimple_assign_lhs (use_stmt);
195   } while (1);
196
197   if (final_name_p)
198     *final_name_p = name;
199
200   return use_stmt;
201 }
202
203 /* Get the statement we can propagate from into NAME skipping
204    trivial copies.  Returns the statement which defines the
205    propagation source or NULL_TREE if there is no such one.
206    If SINGLE_USE_ONLY is set considers only sources which have
207    a single use chain up to NAME.  If SINGLE_USE_P is non-null,
208    it is set to whether the chain to NAME is a single use chain
209    or not.  SINGLE_USE_P is not written to if SINGLE_USE_ONLY is set.  */
210
211 static gimple
212 get_prop_source_stmt (tree name, bool single_use_only, bool *single_use_p)
213 {
214   bool single_use = true;
215
216   do {
217     gimple def_stmt = SSA_NAME_DEF_STMT (name);
218
219     if (!has_single_use (name))
220       {
221         single_use = false;
222         if (single_use_only)
223           return NULL;
224       }
225
226     /* If name is defined by a PHI node or is the default def, bail out.  */
227     if (!is_gimple_assign (def_stmt))
228       return NULL;
229
230     /* If def_stmt is not a simple copy, we possibly found it.  */
231     if (!gimple_assign_ssa_name_copy_p (def_stmt))
232       {
233         tree rhs;
234
235         if (!single_use_only && single_use_p)
236           *single_use_p = single_use;
237
238         /* We can look through pointer conversions in the search
239            for a useful stmt for the comparison folding.  */
240         rhs = gimple_assign_rhs1 (def_stmt);
241         if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt))
242             && TREE_CODE (rhs) == SSA_NAME
243             && POINTER_TYPE_P (TREE_TYPE (gimple_assign_lhs (def_stmt)))
244             && POINTER_TYPE_P (TREE_TYPE (rhs)))
245           name = rhs;
246         else
247           return def_stmt;
248       }
249     else
250       {
251         /* Continue searching the def of the copy source name.  */
252         name = gimple_assign_rhs1 (def_stmt);
253       }
254   } while (1);
255 }
256
257 /* Checks if the destination ssa name in DEF_STMT can be used as
258    propagation source.  Returns true if so, otherwise false.  */
259
260 static bool
261 can_propagate_from (gimple def_stmt)
262 {
263   gcc_assert (is_gimple_assign (def_stmt));
264
265   /* If the rhs has side-effects we cannot propagate from it.  */
266   if (gimple_has_volatile_ops (def_stmt))
267     return false;
268
269   /* If the rhs is a load we cannot propagate from it.  */
270   if (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) == tcc_reference
271       || TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) == tcc_declaration)
272     return false;
273
274   /* Constants can be always propagated.  */
275   if (gimple_assign_single_p (def_stmt)
276       && is_gimple_min_invariant (gimple_assign_rhs1 (def_stmt)))
277     return true;
278
279   /* We cannot propagate ssa names that occur in abnormal phi nodes.  */
280   if (stmt_references_abnormal_ssa_name (def_stmt))
281     return false;
282
283   /* If the definition is a conversion of a pointer to a function type,
284      then we can not apply optimizations as some targets require
285      function pointers to be canonicalized and in this case this
286      optimization could eliminate a necessary canonicalization.  */
287   if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
288     {
289       tree rhs = gimple_assign_rhs1 (def_stmt);
290       if (POINTER_TYPE_P (TREE_TYPE (rhs))
291           && TREE_CODE (TREE_TYPE (TREE_TYPE (rhs))) == FUNCTION_TYPE)
292         return false;
293     }
294
295   return true;
296 }
297
298 /* Remove a copy chain ending in NAME along the defs.
299    If NAME was replaced in its only use then this function can be used
300    to clean up dead stmts.  Returns true if cleanup-cfg has to run.  */
301
302 static bool
303 remove_prop_source_from_use (tree name)
304 {
305   gimple_stmt_iterator gsi;
306   gimple stmt;
307   bool cfg_changed = false;
308
309   do {
310     basic_block bb;
311
312     if (!has_zero_uses (name))
313       return cfg_changed;
314
315     stmt = SSA_NAME_DEF_STMT (name);
316     gsi = gsi_for_stmt (stmt);
317     bb = gimple_bb (stmt);
318     release_defs (stmt);
319     gsi_remove (&gsi, true);
320     cfg_changed |= gimple_purge_dead_eh_edges (bb);
321
322     name = (gimple_assign_copy_p (stmt)) ? gimple_assign_rhs1 (stmt) : NULL;
323   } while (name && TREE_CODE (name) == SSA_NAME);
324
325   return cfg_changed;
326 }
327
328 /* Return the rhs of a gimple_assign STMT in a form of a single tree,
329    converted to type TYPE.
330
331    This should disappear, but is needed so we can combine expressions and use
332    the fold() interfaces. Long term, we need to develop folding and combine
333    routines that deal with gimple exclusively . */
334
335 static tree
336 rhs_to_tree (tree type, gimple stmt)
337 {
338   location_t loc = gimple_location (stmt);
339   enum tree_code code = gimple_assign_rhs_code (stmt);
340   if (get_gimple_rhs_class (code) == GIMPLE_TERNARY_RHS)
341     return fold_build3_loc (loc, code, type, gimple_assign_rhs1 (stmt),
342                             gimple_assign_rhs2 (stmt),
343                             gimple_assign_rhs3 (stmt));
344   else if (get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS)
345     return fold_build2_loc (loc, code, type, gimple_assign_rhs1 (stmt),
346                         gimple_assign_rhs2 (stmt));
347   else if (get_gimple_rhs_class (code) == GIMPLE_UNARY_RHS)
348     return build1 (code, type, gimple_assign_rhs1 (stmt));
349   else if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS)
350     return gimple_assign_rhs1 (stmt);
351   else
352     gcc_unreachable ();
353 }
354
355 /* Combine OP0 CODE OP1 in the context of a COND_EXPR.  Returns
356    the folded result in a form suitable for COND_EXPR_COND or
357    NULL_TREE, if there is no suitable simplified form.  If
358    INVARIANT_ONLY is true only gimple_min_invariant results are
359    considered simplified.  */
360
361 static tree
362 combine_cond_expr_cond (location_t loc, enum tree_code code, tree type,
363                         tree op0, tree op1, bool invariant_only)
364 {
365   tree t;
366
367   gcc_assert (TREE_CODE_CLASS (code) == tcc_comparison);
368
369   t = fold_binary_loc (loc, code, type, op0, op1);
370   if (!t)
371     return NULL_TREE;
372
373   /* Require that we got a boolean type out if we put one in.  */
374   gcc_assert (TREE_CODE (TREE_TYPE (t)) == TREE_CODE (type));
375
376   /* Canonicalize the combined condition for use in a COND_EXPR.  */
377   t = canonicalize_cond_expr_cond (t);
378
379   /* Bail out if we required an invariant but didn't get one.  */
380   if (!t || (invariant_only && !is_gimple_min_invariant (t)))
381     return NULL_TREE;
382
383   return t;
384 }
385
386 /* Combine the comparison OP0 CODE OP1 at LOC with the defining statements
387    of its operand.  Return a new comparison tree or NULL_TREE if there
388    were no simplifying combines.  */
389
390 static tree
391 forward_propagate_into_comparison_1 (location_t loc,
392                                      enum tree_code code, tree type,
393                                      tree op0, tree op1)
394 {
395   tree tmp = NULL_TREE;
396   tree rhs0 = NULL_TREE, rhs1 = NULL_TREE;
397   bool single_use0_p = false, single_use1_p = false;
398
399   /* For comparisons use the first operand, that is likely to
400      simplify comparisons against constants.  */
401   if (TREE_CODE (op0) == SSA_NAME)
402     {
403       gimple def_stmt = get_prop_source_stmt (op0, false, &single_use0_p);
404       if (def_stmt && can_propagate_from (def_stmt))
405         {
406           rhs0 = rhs_to_tree (TREE_TYPE (op1), def_stmt);
407           tmp = combine_cond_expr_cond (loc, code, type,
408                                         rhs0, op1, !single_use0_p);
409           if (tmp)
410             return tmp;
411         }
412     }
413
414   /* If that wasn't successful, try the second operand.  */
415   if (TREE_CODE (op1) == SSA_NAME)
416     {
417       gimple def_stmt = get_prop_source_stmt (op1, false, &single_use1_p);
418       if (def_stmt && can_propagate_from (def_stmt))
419         {
420           rhs1 = rhs_to_tree (TREE_TYPE (op0), def_stmt);
421           tmp = combine_cond_expr_cond (loc, code, type,
422                                         op0, rhs1, !single_use1_p);
423           if (tmp)
424             return tmp;
425         }
426     }
427
428   /* If that wasn't successful either, try both operands.  */
429   if (rhs0 != NULL_TREE
430       && rhs1 != NULL_TREE)
431     tmp = combine_cond_expr_cond (loc, code, type,
432                                   rhs0, rhs1,
433                                   !(single_use0_p && single_use1_p));
434
435   return tmp;
436 }
437
438 /* Propagate from the ssa name definition statements of the assignment
439    from a comparison at *GSI into the conditional if that simplifies it.
440    Returns true if the stmt was modified, false if not.  */
441
442 static bool
443 forward_propagate_into_comparison (gimple_stmt_iterator *gsi)
444 {
445   gimple stmt = gsi_stmt (*gsi);
446   tree tmp;
447
448   /* Combine the comparison with defining statements.  */
449   tmp = forward_propagate_into_comparison_1 (gimple_location (stmt),
450                                              gimple_assign_rhs_code (stmt),
451                                              TREE_TYPE
452                                                (gimple_assign_lhs (stmt)),
453                                              gimple_assign_rhs1 (stmt),
454                                              gimple_assign_rhs2 (stmt));
455   if (tmp)
456     {
457       gimple_assign_set_rhs_from_tree (gsi, tmp);
458       update_stmt (stmt);
459       return true;
460     }
461
462   return false;
463 }
464
465 /* Propagate from the ssa name definition statements of COND_EXPR
466    in GIMPLE_COND statement STMT into the conditional if that simplifies it.
467    Returns zero if no statement was changed, one if there were
468    changes and two if cfg_cleanup needs to run.
469
470    This must be kept in sync with forward_propagate_into_cond.  */
471
472 static int
473 forward_propagate_into_gimple_cond (gimple stmt)
474 {
475   int did_something = 0;
476   location_t loc = gimple_location (stmt);
477   tree tmp;
478   enum tree_code code = gimple_cond_code (stmt);
479
480   /* We can do tree combining on SSA_NAME and comparison expressions.  */
481   if (TREE_CODE_CLASS (gimple_cond_code (stmt)) != tcc_comparison)
482     return 0;
483
484   tmp = forward_propagate_into_comparison_1 (loc, code,
485                                              boolean_type_node,
486                                              gimple_cond_lhs (stmt),
487                                              gimple_cond_rhs (stmt));
488   if (tmp)
489     {
490       if (dump_file && tmp)
491         {
492           tree cond = build2 (gimple_cond_code (stmt),
493                               boolean_type_node,
494                               gimple_cond_lhs (stmt),
495                               gimple_cond_rhs (stmt));
496           fprintf (dump_file, "  Replaced '");
497           print_generic_expr (dump_file, cond, 0);
498           fprintf (dump_file, "' with '");
499           print_generic_expr (dump_file, tmp, 0);
500           fprintf (dump_file, "'\n");
501         }
502
503       gimple_cond_set_condition_from_tree (stmt, unshare_expr (tmp));
504       update_stmt (stmt);
505
506       /* Remove defining statements.  */
507       if (is_gimple_min_invariant (tmp))
508         did_something = 2;
509       else if (did_something == 0)
510         did_something = 1;
511     }
512
513   return did_something;
514 }
515
516
517 /* Propagate from the ssa name definition statements of COND_EXPR
518    in the rhs of statement STMT into the conditional if that simplifies it.
519    Returns zero if no statement was changed, one if there were
520    changes and two if cfg_cleanup needs to run.
521
522    This must be kept in sync with forward_propagate_into_gimple_cond.  */
523
524 static int
525 forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
526 {
527   gimple stmt = gsi_stmt (*gsi_p);
528   location_t loc = gimple_location (stmt);
529   int did_something = 0;
530   tree tmp = NULL_TREE;
531   tree cond = gimple_assign_rhs1 (stmt);
532
533   /* We can do tree combining on SSA_NAME and comparison expressions.  */
534   if (COMPARISON_CLASS_P (cond))
535     tmp = forward_propagate_into_comparison_1 (loc, TREE_CODE (cond),
536                                                boolean_type_node,
537                                                TREE_OPERAND (cond, 0),
538                                                TREE_OPERAND (cond, 1));
539   else if (TREE_CODE (cond) == SSA_NAME)
540     {
541       tree name = cond, rhs0;
542       gimple def_stmt = get_prop_source_stmt (name, true, NULL);
543       if (!def_stmt || !can_propagate_from (def_stmt))
544         return did_something;
545
546       rhs0 = gimple_assign_rhs1 (def_stmt);
547       tmp = combine_cond_expr_cond (loc, NE_EXPR, boolean_type_node, rhs0,
548                                     build_int_cst (TREE_TYPE (rhs0), 0),
549                                     false);
550     }
551
552   if (tmp)
553     {
554       if (dump_file && tmp)
555         {
556           fprintf (dump_file, "  Replaced '");
557           print_generic_expr (dump_file, cond, 0);
558           fprintf (dump_file, "' with '");
559           print_generic_expr (dump_file, tmp, 0);
560           fprintf (dump_file, "'\n");
561         }
562
563       gimple_assign_set_rhs_from_tree (gsi_p, unshare_expr (tmp));
564       stmt = gsi_stmt (*gsi_p);
565       update_stmt (stmt);
566
567       /* Remove defining statements.  */
568       if (is_gimple_min_invariant (tmp))
569         did_something = 2;
570       else if (did_something == 0)
571         did_something = 1;
572     }
573
574   return did_something;
575 }
576
577 /* We've just substituted an ADDR_EXPR into stmt.  Update all the
578    relevant data structures to match.  */
579
580 static void
581 tidy_after_forward_propagate_addr (gimple stmt)
582 {
583   /* We may have turned a trapping insn into a non-trapping insn.  */
584   if (maybe_clean_or_replace_eh_stmt (stmt, stmt)
585       && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
586     cfg_changed = true;
587
588   if (TREE_CODE (gimple_assign_rhs1 (stmt)) == ADDR_EXPR)
589      recompute_tree_invariant_for_addr_expr (gimple_assign_rhs1 (stmt));
590 }
591
592 /* DEF_RHS contains the address of the 0th element in an array.
593    USE_STMT uses type of DEF_RHS to compute the address of an
594    arbitrary element within the array.  The (variable) byte offset
595    of the element is contained in OFFSET.
596
597    We walk back through the use-def chains of OFFSET to verify that
598    it is indeed computing the offset of an element within the array
599    and extract the index corresponding to the given byte offset.
600
601    We then try to fold the entire address expression into a form
602    &array[index].
603
604    If we are successful, we replace the right hand side of USE_STMT
605    with the new address computation.  */
606
607 static bool
608 forward_propagate_addr_into_variable_array_index (tree offset,
609                                                   tree def_rhs,
610                                                   gimple_stmt_iterator *use_stmt_gsi)
611 {
612   tree index, tunit;
613   gimple offset_def, use_stmt = gsi_stmt (*use_stmt_gsi);
614   tree new_rhs, tmp;
615
616   if (TREE_CODE (TREE_OPERAND (def_rhs, 0)) == ARRAY_REF)
617     tunit = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (def_rhs)));
618   else if (TREE_CODE (TREE_TYPE (TREE_OPERAND (def_rhs, 0))) == ARRAY_TYPE)
619     tunit = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (TREE_TYPE (def_rhs))));
620   else
621     return false;
622   if (!host_integerp (tunit, 1))
623     return false;
624
625   /* Get the offset's defining statement.  */
626   offset_def = SSA_NAME_DEF_STMT (offset);
627
628   /* Try to find an expression for a proper index.  This is either a
629      multiplication expression by the element size or just the ssa name we came
630      along in case the element size is one. In that case, however, we do not
631      allow multiplications because they can be computing index to a higher
632      level dimension (PR 37861). */
633   if (integer_onep (tunit))
634     {
635       if (is_gimple_assign (offset_def)
636           && gimple_assign_rhs_code (offset_def) == MULT_EXPR)
637         return false;
638
639       index = offset;
640     }
641   else
642     {
643       /* The statement which defines OFFSET before type conversion
644          must be a simple GIMPLE_ASSIGN.  */
645       if (!is_gimple_assign (offset_def))
646         return false;
647
648       /* The RHS of the statement which defines OFFSET must be a
649          multiplication of an object by the size of the array elements.
650          This implicitly verifies that the size of the array elements
651          is constant.  */
652      if (gimple_assign_rhs_code (offset_def) == MULT_EXPR
653          && TREE_CODE (gimple_assign_rhs2 (offset_def)) == INTEGER_CST
654          && tree_int_cst_equal (gimple_assign_rhs2 (offset_def), tunit))
655        {
656          /* The first operand to the MULT_EXPR is the desired index.  */
657          index = gimple_assign_rhs1 (offset_def);
658        }
659      /* If we have idx * tunit + CST * tunit re-associate that.  */
660      else if ((gimple_assign_rhs_code (offset_def) == PLUS_EXPR
661                || gimple_assign_rhs_code (offset_def) == MINUS_EXPR)
662               && TREE_CODE (gimple_assign_rhs1 (offset_def)) == SSA_NAME
663               && TREE_CODE (gimple_assign_rhs2 (offset_def)) == INTEGER_CST
664               && (tmp = div_if_zero_remainder (EXACT_DIV_EXPR,
665                                                gimple_assign_rhs2 (offset_def),
666                                                tunit)) != NULL_TREE)
667        {
668          gimple offset_def2 = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (offset_def));
669          if (is_gimple_assign (offset_def2)
670              && gimple_assign_rhs_code (offset_def2) == MULT_EXPR
671              && TREE_CODE (gimple_assign_rhs2 (offset_def2)) == INTEGER_CST
672              && tree_int_cst_equal (gimple_assign_rhs2 (offset_def2), tunit))
673            {
674              index = fold_build2 (gimple_assign_rhs_code (offset_def),
675                                   TREE_TYPE (offset),
676                                   gimple_assign_rhs1 (offset_def2), tmp);
677            }
678          else
679            return false;
680        }
681      else
682         return false;
683     }
684
685   /* Replace the pointer addition with array indexing.  */
686   index = force_gimple_operand_gsi (use_stmt_gsi, index, true, NULL_TREE,
687                                     true, GSI_SAME_STMT);
688   if (TREE_CODE (TREE_OPERAND (def_rhs, 0)) == ARRAY_REF)
689     {
690       new_rhs = unshare_expr (def_rhs);
691       TREE_OPERAND (TREE_OPERAND (new_rhs, 0), 1) = index;
692     }
693   else
694     {
695       new_rhs = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (TREE_TYPE (def_rhs))),
696                         unshare_expr (TREE_OPERAND (def_rhs, 0)),
697                         index, integer_zero_node, NULL_TREE);
698       new_rhs = build_fold_addr_expr (new_rhs);
699       if (!useless_type_conversion_p (TREE_TYPE (gimple_assign_lhs (use_stmt)),
700                                       TREE_TYPE (new_rhs)))
701         {
702           new_rhs = force_gimple_operand_gsi (use_stmt_gsi, new_rhs, true,
703                                               NULL_TREE, true, GSI_SAME_STMT);
704           new_rhs = fold_convert (TREE_TYPE (gimple_assign_lhs (use_stmt)),
705                                   new_rhs);
706         }
707     }
708   gimple_assign_set_rhs_from_tree (use_stmt_gsi, new_rhs);
709   use_stmt = gsi_stmt (*use_stmt_gsi);
710
711   /* That should have created gimple, so there is no need to
712      record information to undo the propagation.  */
713   fold_stmt_inplace (use_stmt);
714   tidy_after_forward_propagate_addr (use_stmt);
715   return true;
716 }
717
718 /* NAME is a SSA_NAME representing DEF_RHS which is of the form
719    ADDR_EXPR <whatever>.
720
721    Try to forward propagate the ADDR_EXPR into the use USE_STMT.
722    Often this will allow for removal of an ADDR_EXPR and INDIRECT_REF
723    node or for recovery of array indexing from pointer arithmetic.
724
725    Return true if the propagation was successful (the propagation can
726    be not totally successful, yet things may have been changed).  */
727
728 static bool
729 forward_propagate_addr_expr_1 (tree name, tree def_rhs,
730                                gimple_stmt_iterator *use_stmt_gsi,
731                                bool single_use_p)
732 {
733   tree lhs, rhs, rhs2, array_ref;
734   gimple use_stmt = gsi_stmt (*use_stmt_gsi);
735   enum tree_code rhs_code;
736   bool res = true;
737
738   gcc_assert (TREE_CODE (def_rhs) == ADDR_EXPR);
739
740   lhs = gimple_assign_lhs (use_stmt);
741   rhs_code = gimple_assign_rhs_code (use_stmt);
742   rhs = gimple_assign_rhs1 (use_stmt);
743
744   /* Trivial cases.  The use statement could be a trivial copy or a
745      useless conversion.  Recurse to the uses of the lhs as copyprop does
746      not copy through different variant pointers and FRE does not catch
747      all useless conversions.  Treat the case of a single-use name and
748      a conversion to def_rhs type separate, though.  */
749   if (TREE_CODE (lhs) == SSA_NAME
750       && ((rhs_code == SSA_NAME && rhs == name)
751           || CONVERT_EXPR_CODE_P (rhs_code)))
752     {
753       /* Only recurse if we don't deal with a single use or we cannot
754          do the propagation to the current statement.  In particular
755          we can end up with a conversion needed for a non-invariant
756          address which we cannot do in a single statement.  */
757       if (!single_use_p
758           || (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (def_rhs))
759               && (!is_gimple_min_invariant (def_rhs)
760                   || (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
761                       && POINTER_TYPE_P (TREE_TYPE (def_rhs))
762                       && (TYPE_PRECISION (TREE_TYPE (lhs))
763                           > TYPE_PRECISION (TREE_TYPE (def_rhs)))))))
764         return forward_propagate_addr_expr (lhs, def_rhs);
765
766       gimple_assign_set_rhs1 (use_stmt, unshare_expr (def_rhs));
767       if (useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (def_rhs)))
768         gimple_assign_set_rhs_code (use_stmt, TREE_CODE (def_rhs));
769       else
770         gimple_assign_set_rhs_code (use_stmt, NOP_EXPR);
771       return true;
772     }
773
774   /* Propagate through constant pointer adjustments.  */
775   if (TREE_CODE (lhs) == SSA_NAME
776       && rhs_code == POINTER_PLUS_EXPR
777       && rhs == name
778       && TREE_CODE (gimple_assign_rhs2 (use_stmt)) == INTEGER_CST)
779     {
780       tree new_def_rhs;
781       /* As we come here with non-invariant addresses in def_rhs we need
782          to make sure we can build a valid constant offsetted address
783          for further propagation.  Simply rely on fold building that
784          and check after the fact.  */
785       new_def_rhs = fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (rhs)),
786                                  def_rhs,
787                                  fold_convert (ptr_type_node,
788                                                gimple_assign_rhs2 (use_stmt)));
789       if (TREE_CODE (new_def_rhs) == MEM_REF
790           && !is_gimple_mem_ref_addr (TREE_OPERAND (new_def_rhs, 0)))
791         return false;
792       new_def_rhs = build_fold_addr_expr_with_type (new_def_rhs,
793                                                     TREE_TYPE (rhs));
794
795       /* Recurse.  If we could propagate into all uses of lhs do not
796          bother to replace into the current use but just pretend we did.  */
797       if (TREE_CODE (new_def_rhs) == ADDR_EXPR
798           && forward_propagate_addr_expr (lhs, new_def_rhs))
799         return true;
800
801       if (useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (new_def_rhs)))
802         gimple_assign_set_rhs_with_ops (use_stmt_gsi, TREE_CODE (new_def_rhs),
803                                         new_def_rhs, NULL_TREE);
804       else if (is_gimple_min_invariant (new_def_rhs))
805         gimple_assign_set_rhs_with_ops (use_stmt_gsi, NOP_EXPR,
806                                         new_def_rhs, NULL_TREE);
807       else
808         return false;
809       gcc_assert (gsi_stmt (*use_stmt_gsi) == use_stmt);
810       update_stmt (use_stmt);
811       return true;
812     }
813
814   /* Now strip away any outer COMPONENT_REF/ARRAY_REF nodes from the LHS.
815      ADDR_EXPR will not appear on the LHS.  */
816   lhs = gimple_assign_lhs (use_stmt);
817   while (handled_component_p (lhs))
818     lhs = TREE_OPERAND (lhs, 0);
819
820   /* Now see if the LHS node is a MEM_REF using NAME.  If so,
821      propagate the ADDR_EXPR into the use of NAME and fold the result.  */
822   if (TREE_CODE (lhs) == MEM_REF
823       && TREE_OPERAND (lhs, 0) == name)
824     {
825       tree def_rhs_base;
826       HOST_WIDE_INT def_rhs_offset;
827       /* If the address is invariant we can always fold it.  */
828       if ((def_rhs_base = get_addr_base_and_unit_offset (TREE_OPERAND (def_rhs, 0),
829                                                          &def_rhs_offset)))
830         {
831           double_int off = mem_ref_offset (lhs);
832           tree new_ptr;
833           off = double_int_add (off,
834                                 shwi_to_double_int (def_rhs_offset));
835           if (TREE_CODE (def_rhs_base) == MEM_REF)
836             {
837               off = double_int_add (off, mem_ref_offset (def_rhs_base));
838               new_ptr = TREE_OPERAND (def_rhs_base, 0);
839             }
840           else
841             new_ptr = build_fold_addr_expr (def_rhs_base);
842           TREE_OPERAND (lhs, 0) = new_ptr;
843           TREE_OPERAND (lhs, 1)
844             = double_int_to_tree (TREE_TYPE (TREE_OPERAND (lhs, 1)), off);
845           tidy_after_forward_propagate_addr (use_stmt);
846           /* Continue propagating into the RHS if this was not the only use.  */
847           if (single_use_p)
848             return true;
849         }
850       /* If the LHS is a plain dereference and the value type is the same as
851          that of the pointed-to type of the address we can put the
852          dereferenced address on the LHS preserving the original alias-type.  */
853       else if (gimple_assign_lhs (use_stmt) == lhs
854                && useless_type_conversion_p
855                     (TREE_TYPE (TREE_OPERAND (def_rhs, 0)),
856                      TREE_TYPE (gimple_assign_rhs1 (use_stmt))))
857         {
858           tree *def_rhs_basep = &TREE_OPERAND (def_rhs, 0);
859           tree new_offset, new_base, saved;
860           while (handled_component_p (*def_rhs_basep))
861             def_rhs_basep = &TREE_OPERAND (*def_rhs_basep, 0);
862           saved = *def_rhs_basep;
863           if (TREE_CODE (*def_rhs_basep) == MEM_REF)
864             {
865               new_base = TREE_OPERAND (*def_rhs_basep, 0);
866               new_offset
867                 = int_const_binop (PLUS_EXPR, TREE_OPERAND (lhs, 1),
868                                    TREE_OPERAND (*def_rhs_basep, 1));
869             }
870           else
871             {
872               new_base = build_fold_addr_expr (*def_rhs_basep);
873               new_offset = TREE_OPERAND (lhs, 1);
874             }
875           *def_rhs_basep = build2 (MEM_REF, TREE_TYPE (*def_rhs_basep),
876                                    new_base, new_offset);
877           gimple_assign_set_lhs (use_stmt,
878                                  unshare_expr (TREE_OPERAND (def_rhs, 0)));
879           *def_rhs_basep = saved;
880           tidy_after_forward_propagate_addr (use_stmt);
881           /* Continue propagating into the RHS if this was not the
882              only use.  */
883           if (single_use_p)
884             return true;
885         }
886       else
887         /* We can have a struct assignment dereferencing our name twice.
888            Note that we didn't propagate into the lhs to not falsely
889            claim we did when propagating into the rhs.  */
890         res = false;
891     }
892
893   /* Strip away any outer COMPONENT_REF, ARRAY_REF or ADDR_EXPR
894      nodes from the RHS.  */
895   rhs = gimple_assign_rhs1 (use_stmt);
896   if (TREE_CODE (rhs) == ADDR_EXPR)
897     rhs = TREE_OPERAND (rhs, 0);
898   while (handled_component_p (rhs))
899     rhs = TREE_OPERAND (rhs, 0);
900
901   /* Now see if the RHS node is a MEM_REF using NAME.  If so,
902      propagate the ADDR_EXPR into the use of NAME and fold the result.  */
903   if (TREE_CODE (rhs) == MEM_REF
904       && TREE_OPERAND (rhs, 0) == name)
905     {
906       tree def_rhs_base;
907       HOST_WIDE_INT def_rhs_offset;
908       if ((def_rhs_base = get_addr_base_and_unit_offset (TREE_OPERAND (def_rhs, 0),
909                                                          &def_rhs_offset)))
910         {
911           double_int off = mem_ref_offset (rhs);
912           tree new_ptr;
913           off = double_int_add (off,
914                                 shwi_to_double_int (def_rhs_offset));
915           if (TREE_CODE (def_rhs_base) == MEM_REF)
916             {
917               off = double_int_add (off, mem_ref_offset (def_rhs_base));
918               new_ptr = TREE_OPERAND (def_rhs_base, 0);
919             }
920           else
921             new_ptr = build_fold_addr_expr (def_rhs_base);
922           TREE_OPERAND (rhs, 0) = new_ptr;
923           TREE_OPERAND (rhs, 1)
924             = double_int_to_tree (TREE_TYPE (TREE_OPERAND (rhs, 1)), off);
925           fold_stmt_inplace (use_stmt);
926           tidy_after_forward_propagate_addr (use_stmt);
927           return res;
928         }
929       /* If the LHS is a plain dereference and the value type is the same as
930          that of the pointed-to type of the address we can put the
931          dereferenced address on the LHS preserving the original alias-type.  */
932       else if (gimple_assign_rhs1 (use_stmt) == rhs
933                && useless_type_conversion_p
934                     (TREE_TYPE (gimple_assign_lhs (use_stmt)),
935                      TREE_TYPE (TREE_OPERAND (def_rhs, 0))))
936         {
937           tree *def_rhs_basep = &TREE_OPERAND (def_rhs, 0);
938           tree new_offset, new_base, saved;
939           while (handled_component_p (*def_rhs_basep))
940             def_rhs_basep = &TREE_OPERAND (*def_rhs_basep, 0);
941           saved = *def_rhs_basep;
942           if (TREE_CODE (*def_rhs_basep) == MEM_REF)
943             {
944               new_base = TREE_OPERAND (*def_rhs_basep, 0);
945               new_offset
946                 = int_const_binop (PLUS_EXPR, TREE_OPERAND (rhs, 1),
947                                    TREE_OPERAND (*def_rhs_basep, 1));
948             }
949           else
950             {
951               new_base = build_fold_addr_expr (*def_rhs_basep);
952               new_offset = TREE_OPERAND (rhs, 1);
953             }
954           *def_rhs_basep = build2 (MEM_REF, TREE_TYPE (*def_rhs_basep),
955                                    new_base, new_offset);
956           gimple_assign_set_rhs1 (use_stmt,
957                                   unshare_expr (TREE_OPERAND (def_rhs, 0)));
958           *def_rhs_basep = saved;
959           fold_stmt_inplace (use_stmt);
960           tidy_after_forward_propagate_addr (use_stmt);
961           return res;
962         }
963     }
964
965   /* If the use of the ADDR_EXPR is not a POINTER_PLUS_EXPR, there
966      is nothing to do. */
967   if (gimple_assign_rhs_code (use_stmt) != POINTER_PLUS_EXPR
968       || gimple_assign_rhs1 (use_stmt) != name)
969     return false;
970
971   /* The remaining cases are all for turning pointer arithmetic into
972      array indexing.  They only apply when we have the address of
973      element zero in an array.  If that is not the case then there
974      is nothing to do.  */
975   array_ref = TREE_OPERAND (def_rhs, 0);
976   if ((TREE_CODE (array_ref) != ARRAY_REF
977        || TREE_CODE (TREE_TYPE (TREE_OPERAND (array_ref, 0))) != ARRAY_TYPE
978        || TREE_CODE (TREE_OPERAND (array_ref, 1)) != INTEGER_CST)
979       && TREE_CODE (TREE_TYPE (array_ref)) != ARRAY_TYPE)
980     return false;
981
982   rhs2 = gimple_assign_rhs2 (use_stmt);
983   /* Try to optimize &x[C1] p+ C2 where C2 is a multiple of the size
984      of the elements in X into &x[C1 + C2/element size].  */
985   if (TREE_CODE (rhs2) == INTEGER_CST)
986     {
987       tree new_rhs = maybe_fold_stmt_addition (gimple_location (use_stmt),
988                                                TREE_TYPE (def_rhs),
989                                                def_rhs, rhs2);
990       if (new_rhs)
991         {
992           tree type = TREE_TYPE (gimple_assign_lhs (use_stmt));
993           new_rhs = unshare_expr (new_rhs);
994           if (!useless_type_conversion_p (type, TREE_TYPE (new_rhs)))
995             {
996               if (!is_gimple_min_invariant (new_rhs))
997                 new_rhs = force_gimple_operand_gsi (use_stmt_gsi, new_rhs,
998                                                     true, NULL_TREE,
999                                                     true, GSI_SAME_STMT);
1000               new_rhs = fold_convert (type, new_rhs);
1001             }
1002           gimple_assign_set_rhs_from_tree (use_stmt_gsi, new_rhs);
1003           use_stmt = gsi_stmt (*use_stmt_gsi);
1004           update_stmt (use_stmt);
1005           tidy_after_forward_propagate_addr (use_stmt);
1006           return true;
1007         }
1008     }
1009
1010   /* Try to optimize &x[0] p+ OFFSET where OFFSET is defined by
1011      converting a multiplication of an index by the size of the
1012      array elements, then the result is converted into the proper
1013      type for the arithmetic.  */
1014   if (TREE_CODE (rhs2) == SSA_NAME
1015       && (TREE_CODE (array_ref) != ARRAY_REF
1016           || integer_zerop (TREE_OPERAND (array_ref, 1)))
1017       && useless_type_conversion_p (TREE_TYPE (name), TREE_TYPE (def_rhs))
1018       /* Avoid problems with IVopts creating PLUS_EXPRs with a
1019          different type than their operands.  */
1020       && useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (def_rhs)))
1021     return forward_propagate_addr_into_variable_array_index (rhs2, def_rhs,
1022                                                              use_stmt_gsi);
1023   return false;
1024 }
1025
1026 /* STMT is a statement of the form SSA_NAME = ADDR_EXPR <whatever>.
1027
1028    Try to forward propagate the ADDR_EXPR into all uses of the SSA_NAME.
1029    Often this will allow for removal of an ADDR_EXPR and INDIRECT_REF
1030    node or for recovery of array indexing from pointer arithmetic.
1031    Returns true, if all uses have been propagated into.  */
1032
1033 static bool
1034 forward_propagate_addr_expr (tree name, tree rhs)
1035 {
1036   int stmt_loop_depth = gimple_bb (SSA_NAME_DEF_STMT (name))->loop_depth;
1037   imm_use_iterator iter;
1038   gimple use_stmt;
1039   bool all = true;
1040   bool single_use_p = has_single_use (name);
1041
1042   FOR_EACH_IMM_USE_STMT (use_stmt, iter, name)
1043     {
1044       bool result;
1045       tree use_rhs;
1046
1047       /* If the use is not in a simple assignment statement, then
1048          there is nothing we can do.  */
1049       if (gimple_code (use_stmt) != GIMPLE_ASSIGN)
1050         {
1051           if (!is_gimple_debug (use_stmt))
1052             all = false;
1053           continue;
1054         }
1055
1056       /* If the use is in a deeper loop nest, then we do not want
1057          to propagate non-invariant ADDR_EXPRs into the loop as that
1058          is likely adding expression evaluations into the loop.  */
1059       if (gimple_bb (use_stmt)->loop_depth > stmt_loop_depth
1060           && !is_gimple_min_invariant (rhs))
1061         {
1062           all = false;
1063           continue;
1064         }
1065
1066       {
1067         gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
1068         result = forward_propagate_addr_expr_1 (name, rhs, &gsi,
1069                                                 single_use_p);
1070         /* If the use has moved to a different statement adjust
1071            the update machinery for the old statement too.  */
1072         if (use_stmt != gsi_stmt (gsi))
1073           {
1074             update_stmt (use_stmt);
1075             use_stmt = gsi_stmt (gsi);
1076           }
1077
1078         update_stmt (use_stmt);
1079       }
1080       all &= result;
1081
1082       /* Remove intermediate now unused copy and conversion chains.  */
1083       use_rhs = gimple_assign_rhs1 (use_stmt);
1084       if (result
1085           && TREE_CODE (gimple_assign_lhs (use_stmt)) == SSA_NAME
1086           && TREE_CODE (use_rhs) == SSA_NAME
1087           && has_zero_uses (gimple_assign_lhs (use_stmt)))
1088         {
1089           gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
1090           release_defs (use_stmt);
1091           gsi_remove (&gsi, true);
1092         }
1093     }
1094
1095   return all && has_zero_uses (name);
1096 }
1097
1098
1099 /* Forward propagate the comparison defined in STMT like
1100    cond_1 = x CMP y to uses of the form
1101      a_1 = (T')cond_1
1102      a_1 = !cond_1
1103      a_1 = cond_1 != 0
1104    Returns true if stmt is now unused.  */
1105
1106 static bool
1107 forward_propagate_comparison (gimple stmt)
1108 {
1109   tree name = gimple_assign_lhs (stmt);
1110   gimple use_stmt;
1111   tree tmp = NULL_TREE;
1112
1113   /* Don't propagate ssa names that occur in abnormal phis.  */
1114   if ((TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
1115        && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (stmt)))
1116       || (TREE_CODE (gimple_assign_rhs2 (stmt)) == SSA_NAME
1117         && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs2 (stmt))))
1118     return false;
1119
1120   /* Do not un-cse comparisons.  But propagate through copies.  */
1121   use_stmt = get_prop_dest_stmt (name, &name);
1122   if (!use_stmt)
1123     return false;
1124
1125   /* Conversion of the condition result to another integral type.  */
1126   if (is_gimple_assign (use_stmt)
1127       && (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (use_stmt))
1128           || TREE_CODE_CLASS (gimple_assign_rhs_code (use_stmt))
1129              == tcc_comparison
1130           || gimple_assign_rhs_code (use_stmt) == BIT_NOT_EXPR
1131           || gimple_assign_rhs_code (use_stmt) == BIT_XOR_EXPR)
1132       && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (use_stmt))))
1133     {
1134       tree lhs = gimple_assign_lhs (use_stmt);
1135
1136       /* We can propagate the condition into a conversion.  */
1137       if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (use_stmt)))
1138         {
1139           /* Avoid using fold here as that may create a COND_EXPR with
1140              non-boolean condition as canonical form.  */
1141           tmp = build2 (gimple_assign_rhs_code (stmt), TREE_TYPE (lhs),
1142                         gimple_assign_rhs1 (stmt), gimple_assign_rhs2 (stmt));
1143         }
1144       /* We can propagate the condition into X op CST where op
1145          is EQ_EXPR or NE_EXPR and CST is either one or zero.  */
1146       else if (TREE_CODE_CLASS (gimple_assign_rhs_code (use_stmt))
1147               == tcc_comparison
1148              && TREE_CODE (gimple_assign_rhs1 (use_stmt)) == SSA_NAME
1149              && TREE_CODE (gimple_assign_rhs2 (use_stmt)) == INTEGER_CST)
1150       {
1151         enum tree_code code = gimple_assign_rhs_code (use_stmt);
1152         tree cst = gimple_assign_rhs2 (use_stmt);
1153         tree cond;
1154
1155         cond = build2 (gimple_assign_rhs_code (stmt),
1156                        TREE_TYPE (cst),
1157                        gimple_assign_rhs1 (stmt),
1158                        gimple_assign_rhs2 (stmt));
1159
1160         tmp = combine_cond_expr_cond (gimple_location (use_stmt),
1161                                       code, TREE_TYPE (lhs),
1162                                       cond, cst, false);
1163         if (tmp == NULL_TREE)
1164           return false;
1165       }
1166       /* We can propagate the condition into a statement that
1167          computes the logical negation of the comparison result.  */
1168       else if ((gimple_assign_rhs_code (use_stmt) == BIT_NOT_EXPR
1169                 && TYPE_PRECISION (TREE_TYPE (lhs)) == 1)
1170                || (gimple_assign_rhs_code (use_stmt) == BIT_XOR_EXPR
1171                    && integer_onep (gimple_assign_rhs2 (use_stmt))))
1172         {
1173           tree type = TREE_TYPE (gimple_assign_rhs1 (stmt));
1174           bool nans = HONOR_NANS (TYPE_MODE (type));
1175           enum tree_code code;
1176           code = invert_tree_comparison (gimple_assign_rhs_code (stmt), nans);
1177           if (code == ERROR_MARK)
1178             return false;
1179
1180           tmp = build2 (code, TREE_TYPE (lhs), gimple_assign_rhs1 (stmt),
1181                         gimple_assign_rhs2 (stmt));
1182         }
1183       else
1184         return false;
1185
1186       {
1187         gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
1188         gimple_assign_set_rhs_from_tree (&gsi, unshare_expr (tmp));
1189         use_stmt = gsi_stmt (gsi);
1190         update_stmt (use_stmt);
1191       }
1192
1193       if (dump_file && (dump_flags & TDF_DETAILS))
1194         {
1195           tree old_rhs = rhs_to_tree (TREE_TYPE (gimple_assign_lhs (stmt)),
1196                                       stmt);
1197           fprintf (dump_file, "  Replaced '");
1198           print_generic_expr (dump_file, old_rhs, dump_flags);
1199           fprintf (dump_file, "' with '");
1200           print_generic_expr (dump_file, tmp, dump_flags);
1201           fprintf (dump_file, "'\n");
1202         }
1203
1204       /* Remove defining statements.  */
1205       return remove_prop_source_from_use (name);
1206     }
1207
1208   return false;
1209 }
1210
1211
1212 /* If we have lhs = ~x (STMT), look and see if earlier we had x = ~y.
1213    If so, we can change STMT into lhs = y which can later be copy
1214    propagated.  Similarly for negation.
1215
1216    This could trivially be formulated as a forward propagation
1217    to immediate uses.  However, we already had an implementation
1218    from DOM which used backward propagation via the use-def links.
1219
1220    It turns out that backward propagation is actually faster as
1221    there's less work to do for each NOT/NEG expression we find.
1222    Backwards propagation needs to look at the statement in a single
1223    backlink.  Forward propagation needs to look at potentially more
1224    than one forward link.
1225
1226    Returns true when the statement was changed.  */
1227
1228 static bool 
1229 simplify_not_neg_expr (gimple_stmt_iterator *gsi_p)
1230 {
1231   gimple stmt = gsi_stmt (*gsi_p);
1232   tree rhs = gimple_assign_rhs1 (stmt);
1233   gimple rhs_def_stmt = SSA_NAME_DEF_STMT (rhs);
1234
1235   /* See if the RHS_DEF_STMT has the same form as our statement.  */
1236   if (is_gimple_assign (rhs_def_stmt)
1237       && gimple_assign_rhs_code (rhs_def_stmt) == gimple_assign_rhs_code (stmt))
1238     {
1239       tree rhs_def_operand = gimple_assign_rhs1 (rhs_def_stmt);
1240
1241       /* Verify that RHS_DEF_OPERAND is a suitable SSA_NAME.  */
1242       if (TREE_CODE (rhs_def_operand) == SSA_NAME
1243           && ! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs_def_operand))
1244         {
1245           gimple_assign_set_rhs_from_tree (gsi_p, rhs_def_operand);
1246           stmt = gsi_stmt (*gsi_p);
1247           update_stmt (stmt);
1248           return true;
1249         }
1250     }
1251
1252   return false;
1253 }
1254
1255 /* STMT is a SWITCH_EXPR for which we attempt to find equivalent forms of
1256    the condition which we may be able to optimize better.  */
1257
1258 static bool
1259 simplify_gimple_switch (gimple stmt)
1260 {
1261   tree cond = gimple_switch_index (stmt);
1262   tree def, to, ti;
1263   gimple def_stmt;
1264
1265   /* The optimization that we really care about is removing unnecessary
1266      casts.  That will let us do much better in propagating the inferred
1267      constant at the switch target.  */
1268   if (TREE_CODE (cond) == SSA_NAME)
1269     {
1270       def_stmt = SSA_NAME_DEF_STMT (cond);
1271       if (is_gimple_assign (def_stmt))
1272         {
1273           if (gimple_assign_rhs_code (def_stmt) == NOP_EXPR)
1274             {
1275               int need_precision;
1276               bool fail;
1277
1278               def = gimple_assign_rhs1 (def_stmt);
1279
1280               /* ??? Why was Jeff testing this?  We are gimple...  */
1281               gcc_checking_assert (is_gimple_val (def));
1282
1283               to = TREE_TYPE (cond);
1284               ti = TREE_TYPE (def);
1285
1286               /* If we have an extension that preserves value, then we
1287                  can copy the source value into the switch.  */
1288
1289               need_precision = TYPE_PRECISION (ti);
1290               fail = false;
1291               if (! INTEGRAL_TYPE_P (ti))
1292                 fail = true;
1293               else if (TYPE_UNSIGNED (to) && !TYPE_UNSIGNED (ti))
1294                 fail = true;
1295               else if (!TYPE_UNSIGNED (to) && TYPE_UNSIGNED (ti))
1296                 need_precision += 1;
1297               if (TYPE_PRECISION (to) < need_precision)
1298                 fail = true;
1299
1300               if (!fail)
1301                 {
1302                   gimple_switch_set_index (stmt, def);
1303                   update_stmt (stmt);
1304                   return true;
1305                 }
1306             }
1307         }
1308     }
1309
1310   return false;
1311 }
1312
1313 /* For pointers p2 and p1 return p2 - p1 if the
1314    difference is known and constant, otherwise return NULL.  */
1315
1316 static tree
1317 constant_pointer_difference (tree p1, tree p2)
1318 {
1319   int i, j;
1320 #define CPD_ITERATIONS 5
1321   tree exps[2][CPD_ITERATIONS];
1322   tree offs[2][CPD_ITERATIONS];
1323   int cnt[2];
1324
1325   for (i = 0; i < 2; i++)
1326     {
1327       tree p = i ? p1 : p2;
1328       tree off = size_zero_node;
1329       gimple stmt;
1330       enum tree_code code;
1331
1332       /* For each of p1 and p2 we need to iterate at least
1333          twice, to handle ADDR_EXPR directly in p1/p2,
1334          SSA_NAME with ADDR_EXPR or POINTER_PLUS_EXPR etc.
1335          on definition's stmt RHS.  Iterate a few extra times.  */
1336       j = 0;
1337       do
1338         {
1339           if (!POINTER_TYPE_P (TREE_TYPE (p)))
1340             break;
1341           if (TREE_CODE (p) == ADDR_EXPR)
1342             {
1343               tree q = TREE_OPERAND (p, 0);
1344               HOST_WIDE_INT offset;
1345               tree base = get_addr_base_and_unit_offset (q, &offset);
1346               if (base)
1347                 {
1348                   q = base;
1349                   if (offset)
1350                     off = size_binop (PLUS_EXPR, off, size_int (offset));
1351                 }
1352               if (TREE_CODE (q) == MEM_REF
1353                   && TREE_CODE (TREE_OPERAND (q, 0)) == SSA_NAME)
1354                 {
1355                   p = TREE_OPERAND (q, 0);
1356                   off = size_binop (PLUS_EXPR, off,
1357                                     double_int_to_tree (sizetype,
1358                                                         mem_ref_offset (q)));
1359                 }
1360               else
1361                 {
1362                   exps[i][j] = q;
1363                   offs[i][j++] = off;
1364                   break;
1365                 }
1366             }
1367           if (TREE_CODE (p) != SSA_NAME)
1368             break;
1369           exps[i][j] = p;
1370           offs[i][j++] = off;
1371           if (j == CPD_ITERATIONS)
1372             break;
1373           stmt = SSA_NAME_DEF_STMT (p);
1374           if (!is_gimple_assign (stmt) || gimple_assign_lhs (stmt) != p)
1375             break;
1376           code = gimple_assign_rhs_code (stmt);
1377           if (code == POINTER_PLUS_EXPR)
1378             {
1379               if (TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST)
1380                 break;
1381               off = size_binop (PLUS_EXPR, off, gimple_assign_rhs2 (stmt));
1382               p = gimple_assign_rhs1 (stmt);
1383             }
1384           else if (code == ADDR_EXPR || code == NOP_EXPR)
1385             p = gimple_assign_rhs1 (stmt);
1386           else
1387             break;
1388         }
1389       while (1);
1390       cnt[i] = j;
1391     }
1392
1393   for (i = 0; i < cnt[0]; i++)
1394     for (j = 0; j < cnt[1]; j++)
1395       if (exps[0][i] == exps[1][j])
1396         return size_binop (MINUS_EXPR, offs[0][i], offs[1][j]);
1397
1398   return NULL_TREE;
1399 }
1400
1401 /* *GSI_P is a GIMPLE_CALL to a builtin function.
1402    Optimize
1403    memcpy (p, "abcd", 4);
1404    memset (p + 4, ' ', 3);
1405    into
1406    memcpy (p, "abcd   ", 7);
1407    call if the latter can be stored by pieces during expansion.  */
1408
1409 static bool
1410 simplify_builtin_call (gimple_stmt_iterator *gsi_p, tree callee2)
1411 {
1412   gimple stmt1, stmt2 = gsi_stmt (*gsi_p);
1413   tree vuse = gimple_vuse (stmt2);
1414   if (vuse == NULL)
1415     return false;
1416   stmt1 = SSA_NAME_DEF_STMT (vuse);
1417
1418   switch (DECL_FUNCTION_CODE (callee2))
1419     {
1420     case BUILT_IN_MEMSET:
1421       if (gimple_call_num_args (stmt2) != 3
1422           || gimple_call_lhs (stmt2)
1423           || CHAR_BIT != 8
1424           || BITS_PER_UNIT != 8)
1425         break;
1426       else
1427         {
1428           tree callee1;
1429           tree ptr1, src1, str1, off1, len1, lhs1;
1430           tree ptr2 = gimple_call_arg (stmt2, 0);
1431           tree val2 = gimple_call_arg (stmt2, 1);
1432           tree len2 = gimple_call_arg (stmt2, 2);
1433           tree diff, vdef, new_str_cst;
1434           gimple use_stmt;
1435           unsigned int ptr1_align;
1436           unsigned HOST_WIDE_INT src_len;
1437           char *src_buf;
1438           use_operand_p use_p;
1439
1440           if (!host_integerp (val2, 0)
1441               || !host_integerp (len2, 1))
1442             break;
1443           if (is_gimple_call (stmt1))
1444             {
1445               /* If first stmt is a call, it needs to be memcpy
1446                  or mempcpy, with string literal as second argument and
1447                  constant length.  */
1448               callee1 = gimple_call_fndecl (stmt1);
1449               if (callee1 == NULL_TREE
1450                   || DECL_BUILT_IN_CLASS (callee1) != BUILT_IN_NORMAL
1451                   || gimple_call_num_args (stmt1) != 3)
1452                 break;
1453               if (DECL_FUNCTION_CODE (callee1) != BUILT_IN_MEMCPY
1454                   && DECL_FUNCTION_CODE (callee1) != BUILT_IN_MEMPCPY)
1455                 break;
1456               ptr1 = gimple_call_arg (stmt1, 0);
1457               src1 = gimple_call_arg (stmt1, 1);
1458               len1 = gimple_call_arg (stmt1, 2);
1459               lhs1 = gimple_call_lhs (stmt1);
1460               if (!host_integerp (len1, 1))
1461                 break;
1462               str1 = string_constant (src1, &off1);
1463               if (str1 == NULL_TREE)
1464                 break;
1465               if (!host_integerp (off1, 1)
1466                   || compare_tree_int (off1, TREE_STRING_LENGTH (str1) - 1) > 0
1467                   || compare_tree_int (len1, TREE_STRING_LENGTH (str1)
1468                                              - tree_low_cst (off1, 1)) > 0
1469                   || TREE_CODE (TREE_TYPE (str1)) != ARRAY_TYPE
1470                   || TYPE_MODE (TREE_TYPE (TREE_TYPE (str1)))
1471                      != TYPE_MODE (char_type_node))
1472                 break;
1473             }
1474           else if (gimple_assign_single_p (stmt1))
1475             {
1476               /* Otherwise look for length 1 memcpy optimized into
1477                  assignment.  */
1478               ptr1 = gimple_assign_lhs (stmt1);
1479               src1 = gimple_assign_rhs1 (stmt1);
1480               if (TREE_CODE (ptr1) != MEM_REF
1481                   || TYPE_MODE (TREE_TYPE (ptr1)) != TYPE_MODE (char_type_node)
1482                   || !host_integerp (src1, 0))
1483                 break;
1484               ptr1 = build_fold_addr_expr (ptr1);
1485               callee1 = NULL_TREE;
1486               len1 = size_one_node;
1487               lhs1 = NULL_TREE;
1488               off1 = size_zero_node;
1489               str1 = NULL_TREE;
1490             }
1491           else
1492             break;
1493
1494           diff = constant_pointer_difference (ptr1, ptr2);
1495           if (diff == NULL && lhs1 != NULL)
1496             {
1497               diff = constant_pointer_difference (lhs1, ptr2);
1498               if (DECL_FUNCTION_CODE (callee1) == BUILT_IN_MEMPCPY
1499                   && diff != NULL)
1500                 diff = size_binop (PLUS_EXPR, diff,
1501                                    fold_convert (sizetype, len1));
1502             }
1503           /* If the difference between the second and first destination pointer
1504              is not constant, or is bigger than memcpy length, bail out.  */
1505           if (diff == NULL
1506               || !host_integerp (diff, 1)
1507               || tree_int_cst_lt (len1, diff))
1508             break;
1509
1510           /* Use maximum of difference plus memset length and memcpy length
1511              as the new memcpy length, if it is too big, bail out.  */
1512           src_len = tree_low_cst (diff, 1);
1513           src_len += tree_low_cst (len2, 1);
1514           if (src_len < (unsigned HOST_WIDE_INT) tree_low_cst (len1, 1))
1515             src_len = tree_low_cst (len1, 1);
1516           if (src_len > 1024)
1517             break;
1518
1519           /* If mempcpy value is used elsewhere, bail out, as mempcpy
1520              with bigger length will return different result.  */
1521           if (lhs1 != NULL_TREE
1522               && DECL_FUNCTION_CODE (callee1) == BUILT_IN_MEMPCPY
1523               && (TREE_CODE (lhs1) != SSA_NAME
1524                   || !single_imm_use (lhs1, &use_p, &use_stmt)
1525                   || use_stmt != stmt2))
1526             break;
1527
1528           /* If anything reads memory in between memcpy and memset
1529              call, the modified memcpy call might change it.  */
1530           vdef = gimple_vdef (stmt1);
1531           if (vdef != NULL
1532               && (!single_imm_use (vdef, &use_p, &use_stmt)
1533                   || use_stmt != stmt2))
1534             break;
1535
1536           ptr1_align = get_pointer_alignment (ptr1, BIGGEST_ALIGNMENT);
1537           /* Construct the new source string literal.  */
1538           src_buf = XALLOCAVEC (char, src_len + 1);
1539           if (callee1)
1540             memcpy (src_buf,
1541                     TREE_STRING_POINTER (str1) + tree_low_cst (off1, 1),
1542                     tree_low_cst (len1, 1));
1543           else
1544             src_buf[0] = tree_low_cst (src1, 0);
1545           memset (src_buf + tree_low_cst (diff, 1),
1546                   tree_low_cst (val2, 1), tree_low_cst (len2, 1));
1547           src_buf[src_len] = '\0';
1548           /* Neither builtin_strncpy_read_str nor builtin_memcpy_read_str
1549              handle embedded '\0's.  */
1550           if (strlen (src_buf) != src_len)
1551             break;
1552           rtl_profile_for_bb (gimple_bb (stmt2));
1553           /* If the new memcpy wouldn't be emitted by storing the literal
1554              by pieces, this optimization might enlarge .rodata too much,
1555              as commonly used string literals couldn't be shared any
1556              longer.  */
1557           if (!can_store_by_pieces (src_len,
1558                                     builtin_strncpy_read_str,
1559                                     src_buf, ptr1_align, false))
1560             break;
1561
1562           new_str_cst = build_string_literal (src_len, src_buf);
1563           if (callee1)
1564             {
1565               /* If STMT1 is a mem{,p}cpy call, adjust it and remove
1566                  memset call.  */
1567               if (lhs1 && DECL_FUNCTION_CODE (callee1) == BUILT_IN_MEMPCPY)
1568                 gimple_call_set_lhs (stmt1, NULL_TREE);
1569               gimple_call_set_arg (stmt1, 1, new_str_cst);
1570               gimple_call_set_arg (stmt1, 2,
1571                                    build_int_cst (TREE_TYPE (len1), src_len));
1572               update_stmt (stmt1);
1573               unlink_stmt_vdef (stmt2);
1574               gsi_remove (gsi_p, true);
1575               release_defs (stmt2);
1576               if (lhs1 && DECL_FUNCTION_CODE (callee1) == BUILT_IN_MEMPCPY)
1577                 release_ssa_name (lhs1);
1578               return true;
1579             }
1580           else
1581             {
1582               /* Otherwise, if STMT1 is length 1 memcpy optimized into
1583                  assignment, remove STMT1 and change memset call into
1584                  memcpy call.  */
1585               gimple_stmt_iterator gsi = gsi_for_stmt (stmt1);
1586
1587               if (!is_gimple_val (ptr1))
1588                 ptr1 = force_gimple_operand_gsi (gsi_p, ptr1, true, NULL_TREE,
1589                                                  true, GSI_SAME_STMT);
1590               gimple_call_set_fndecl (stmt2, built_in_decls [BUILT_IN_MEMCPY]);
1591               gimple_call_set_arg (stmt2, 0, ptr1);
1592               gimple_call_set_arg (stmt2, 1, new_str_cst);
1593               gimple_call_set_arg (stmt2, 2,
1594                                    build_int_cst (TREE_TYPE (len2), src_len));
1595               unlink_stmt_vdef (stmt1);
1596               gsi_remove (&gsi, true);
1597               release_defs (stmt1);
1598               update_stmt (stmt2);
1599               return false;
1600             }
1601         }
1602       break;
1603     default:
1604       break;
1605     }
1606   return false;
1607 }
1608
1609 /* Checks if expression has type of one-bit precision, or is a known
1610    truth-valued expression.  */
1611 static bool
1612 truth_valued_ssa_name (tree name)
1613 {
1614   gimple def;
1615   tree type = TREE_TYPE (name);
1616
1617   if (!INTEGRAL_TYPE_P (type))
1618     return false;
1619   /* Don't check here for BOOLEAN_TYPE as the precision isn't
1620      necessarily one and so ~X is not equal to !X.  */
1621   if (TYPE_PRECISION (type) == 1)
1622     return true;
1623   def = SSA_NAME_DEF_STMT (name);
1624   if (is_gimple_assign (def))
1625     return truth_value_p (gimple_assign_rhs_code (def));
1626   return false;
1627 }
1628
1629 /* Helper routine for simplify_bitwise_binary_1 function.
1630    Return for the SSA name NAME the expression X if it mets condition
1631    NAME = !X. Otherwise return NULL_TREE.
1632    Detected patterns for NAME = !X are:
1633      !X and X == 0 for X with integral type.
1634      X ^ 1, X != 1,or ~X for X with integral type with precision of one.  */
1635 static tree
1636 lookup_logical_inverted_value (tree name)
1637 {
1638   tree op1, op2;
1639   enum tree_code code;
1640   gimple def;
1641
1642   /* If name has none-intergal type, or isn't a SSA_NAME, then
1643      return.  */
1644   if (TREE_CODE (name) != SSA_NAME
1645       || !INTEGRAL_TYPE_P (TREE_TYPE (name)))
1646     return NULL_TREE;
1647   def = SSA_NAME_DEF_STMT (name);
1648   if (!is_gimple_assign (def))
1649     return NULL_TREE;
1650
1651   code = gimple_assign_rhs_code (def);
1652   op1 = gimple_assign_rhs1 (def);
1653   op2 = NULL_TREE;
1654
1655   /* Get for EQ_EXPR or BIT_XOR_EXPR operation the second operand.
1656      If CODE isn't an EQ_EXPR, BIT_XOR_EXPR, TRUTH_NOT_EXPR,
1657      or BIT_NOT_EXPR, then return.  */
1658   if (code == EQ_EXPR || code == NE_EXPR
1659       || code == BIT_XOR_EXPR)
1660     op2 = gimple_assign_rhs2 (def);
1661
1662   switch (code)
1663     {
1664     case TRUTH_NOT_EXPR:
1665       return op1;
1666     case BIT_NOT_EXPR:
1667       if (truth_valued_ssa_name (name))
1668         return op1;
1669       break;
1670     case EQ_EXPR:
1671       /* Check if we have X == 0 and X has an integral type.  */
1672       if (!INTEGRAL_TYPE_P (TREE_TYPE (op1)))
1673         break;
1674       if (integer_zerop (op2))
1675         return op1;
1676       break;
1677     case NE_EXPR:
1678       /* Check if we have X != 1 and X is a truth-valued.  */
1679       if (!INTEGRAL_TYPE_P (TREE_TYPE (op1)))
1680         break;
1681       if (integer_onep (op2) && truth_valued_ssa_name (op1))
1682         return op1;
1683       break;
1684     case BIT_XOR_EXPR:
1685       /* Check if we have X ^ 1 and X is truth valued.  */
1686       if (integer_onep (op2) && truth_valued_ssa_name (op1))
1687         return op1;
1688       break;
1689     default:
1690       break;
1691     }
1692
1693   return NULL_TREE;
1694 }
1695
1696 /* Optimize ARG1 CODE ARG2 to a constant for bitwise binary
1697    operations CODE, if one operand has the logically inverted
1698    value of the other.  */
1699 static tree
1700 simplify_bitwise_binary_1 (enum tree_code code, tree type,
1701                            tree arg1, tree arg2)
1702 {
1703   tree anot;
1704
1705   /* If CODE isn't a bitwise binary operation, return NULL_TREE.  */
1706   if (code != BIT_AND_EXPR && code != BIT_IOR_EXPR
1707       && code != BIT_XOR_EXPR)
1708     return NULL_TREE;
1709
1710   /* First check if operands ARG1 and ARG2 are equal.  If so
1711      return NULL_TREE as this optimization is handled fold_stmt.  */
1712   if (arg1 == arg2)
1713     return NULL_TREE;
1714   /* See if we have in arguments logical-not patterns.  */
1715   if (((anot = lookup_logical_inverted_value (arg1)) == NULL_TREE
1716        || anot != arg2)
1717       && ((anot = lookup_logical_inverted_value (arg2)) == NULL_TREE
1718           || anot != arg1))
1719     return NULL_TREE;
1720
1721   /* X & !X -> 0.  */
1722   if (code == BIT_AND_EXPR)
1723     return fold_convert (type, integer_zero_node);
1724   /* X | !X -> 1 and X ^ !X -> 1, if X is truth-valued.  */
1725   if (truth_valued_ssa_name (anot))
1726     return fold_convert (type, integer_one_node);
1727
1728   /* ??? Otherwise result is (X != 0 ? X : 1).  not handled.  */
1729   return NULL_TREE;
1730 }
1731
1732 /* Simplify bitwise binary operations.
1733    Return true if a transformation applied, otherwise return false.  */
1734
1735 static bool
1736 simplify_bitwise_binary (gimple_stmt_iterator *gsi)
1737 {
1738   gimple stmt = gsi_stmt (*gsi);
1739   tree arg1 = gimple_assign_rhs1 (stmt);
1740   tree arg2 = gimple_assign_rhs2 (stmt);
1741   enum tree_code code = gimple_assign_rhs_code (stmt);
1742   tree res;
1743   gimple def1 = NULL, def2 = NULL;
1744   tree def1_arg1, def2_arg1;
1745   enum tree_code def1_code, def2_code;
1746
1747   /* If the first argument is an SSA name that is itself a result of a
1748      typecast of an ADDR_EXPR to an integer, feed the ADDR_EXPR to the
1749      folder rather than the ssa name.  */
1750   if (code == BIT_AND_EXPR
1751       && TREE_CODE (arg2) == INTEGER_CST
1752       && TREE_CODE (arg1) == SSA_NAME)
1753     {
1754       gimple def = SSA_NAME_DEF_STMT (arg1);
1755       tree op = arg1;
1756
1757       /* ???  This looks bogus - the conversion could be truncating.  */
1758       if (is_gimple_assign (def)
1759           && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def))
1760           && INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
1761         {
1762           tree opp = gimple_assign_rhs1 (def);
1763           if (TREE_CODE (opp) == ADDR_EXPR)
1764             op = opp;
1765         }
1766
1767       res = fold_binary_loc (gimple_location (stmt),
1768                              BIT_AND_EXPR, TREE_TYPE (gimple_assign_lhs (stmt)),
1769                              op, arg2);
1770       if (res && is_gimple_min_invariant (res))
1771         {
1772           gimple_assign_set_rhs_from_tree (gsi, res);
1773           update_stmt (stmt);
1774           return true;
1775         }
1776     }
1777
1778   def1_code = TREE_CODE (arg1);
1779   def1_arg1 = arg1;
1780   if (TREE_CODE (arg1) == SSA_NAME)
1781     {
1782       def1 = SSA_NAME_DEF_STMT (arg1);
1783       if (is_gimple_assign (def1))
1784         {
1785           def1_code = gimple_assign_rhs_code (def1);
1786           def1_arg1 = gimple_assign_rhs1 (def1);
1787         }
1788     }
1789
1790   def2_code = TREE_CODE (arg2);
1791   def2_arg1 = arg2;
1792   if (TREE_CODE (arg2) == SSA_NAME)
1793     {
1794       def2 = SSA_NAME_DEF_STMT (arg2);
1795       if (is_gimple_assign (def2))
1796         {
1797           def2_code = gimple_assign_rhs_code (def2);
1798           def2_arg1 = gimple_assign_rhs1 (def2);
1799         }
1800     }
1801
1802   /* Try to fold (type) X op CST -> (type) (X op ((type-x) CST)).  */
1803   if (TREE_CODE (arg2) == INTEGER_CST
1804       && CONVERT_EXPR_CODE_P (def1_code)
1805       && INTEGRAL_TYPE_P (TREE_TYPE (def1_arg1))
1806       && int_fits_type_p (arg2, TREE_TYPE (def1_arg1)))
1807     {
1808       gimple newop;
1809       tree tem = create_tmp_reg (TREE_TYPE (def1_arg1), NULL);
1810       newop =
1811         gimple_build_assign_with_ops (code, tem, def1_arg1,
1812                                       fold_convert_loc (gimple_location (stmt),
1813                                                         TREE_TYPE (def1_arg1),
1814                                                         arg2));
1815       tem = make_ssa_name (tem, newop);
1816       gimple_assign_set_lhs (newop, tem);
1817       gsi_insert_before (gsi, newop, GSI_SAME_STMT);
1818       gimple_assign_set_rhs_with_ops_1 (gsi, NOP_EXPR,
1819                                         tem, NULL_TREE, NULL_TREE);
1820       update_stmt (gsi_stmt (*gsi));
1821       return true;
1822     }
1823
1824   /* For bitwise binary operations apply operand conversions to the
1825      binary operation result instead of to the operands.  This allows
1826      to combine successive conversions and bitwise binary operations.  */
1827   if (CONVERT_EXPR_CODE_P (def1_code)
1828       && CONVERT_EXPR_CODE_P (def2_code)
1829       && types_compatible_p (TREE_TYPE (def1_arg1), TREE_TYPE (def2_arg1))
1830       /* Make sure that the conversion widens the operands, or has same
1831          precision,  or that it changes the operation to a bitfield
1832          precision.  */
1833       && ((TYPE_PRECISION (TREE_TYPE (def1_arg1))
1834            <= TYPE_PRECISION (TREE_TYPE (arg1)))
1835           || (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (arg1)))
1836               != MODE_INT)
1837           || (TYPE_PRECISION (TREE_TYPE (arg1))
1838               != GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (arg1))))))
1839     {
1840       gimple newop;
1841       tree tem = create_tmp_reg (TREE_TYPE (def1_arg1),
1842                                  NULL);
1843       newop = gimple_build_assign_with_ops (code, tem, def1_arg1, def2_arg1);
1844       tem = make_ssa_name (tem, newop);
1845       gimple_assign_set_lhs (newop, tem);
1846       gsi_insert_before (gsi, newop, GSI_SAME_STMT);
1847       gimple_assign_set_rhs_with_ops_1 (gsi, NOP_EXPR,
1848                                         tem, NULL_TREE, NULL_TREE);
1849       update_stmt (gsi_stmt (*gsi));
1850       return true;
1851     }
1852
1853   /* (a | CST1) & CST2  ->  (a & CST2) | (CST1 & CST2).  */
1854   if (code == BIT_AND_EXPR
1855       && def1_code == BIT_IOR_EXPR
1856       && TREE_CODE (arg2) == INTEGER_CST
1857       && TREE_CODE (gimple_assign_rhs2 (def1)) == INTEGER_CST)
1858     {
1859       tree cst = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg2),
1860                               arg2, gimple_assign_rhs2 (def1));
1861       tree tem;
1862       gimple newop;
1863       if (integer_zerop (cst))
1864         {
1865           gimple_assign_set_rhs1 (stmt, def1_arg1);
1866           update_stmt (stmt);
1867           return true;
1868         }
1869       tem = create_tmp_reg (TREE_TYPE (arg2), NULL);
1870       newop = gimple_build_assign_with_ops (BIT_AND_EXPR,
1871                                             tem, def1_arg1, arg2);
1872       tem = make_ssa_name (tem, newop);
1873       gimple_assign_set_lhs (newop, tem);
1874       /* Make sure to re-process the new stmt as it's walking upwards.  */
1875       gsi_insert_before (gsi, newop, GSI_NEW_STMT);
1876       gimple_assign_set_rhs1 (stmt, tem);
1877       gimple_assign_set_rhs2 (stmt, cst);
1878       gimple_assign_set_rhs_code (stmt, BIT_IOR_EXPR);
1879       update_stmt (stmt);
1880       return true;
1881     }
1882
1883   /* Combine successive equal operations with constants.  */
1884   if ((code == BIT_AND_EXPR
1885        || code == BIT_IOR_EXPR
1886        || code == BIT_XOR_EXPR)
1887       && def1_code == code 
1888       && TREE_CODE (arg2) == INTEGER_CST
1889       && TREE_CODE (gimple_assign_rhs2 (def1)) == INTEGER_CST)
1890     {
1891       tree cst = fold_build2 (code, TREE_TYPE (arg2),
1892                               arg2, gimple_assign_rhs2 (def1));
1893       gimple_assign_set_rhs1 (stmt, def1_arg1);
1894       gimple_assign_set_rhs2 (stmt, cst);
1895       update_stmt (stmt);
1896       return true;
1897     }
1898
1899   /* Try simple folding for X op !X, and X op X.  */
1900   res = simplify_bitwise_binary_1 (code, TREE_TYPE (arg1), arg1, arg2);
1901   if (res != NULL_TREE)
1902     {
1903       gimple_assign_set_rhs_from_tree (gsi, res);
1904       update_stmt (gsi_stmt (*gsi));
1905       return true;
1906     }
1907
1908   return false;
1909 }
1910
1911
1912 /* Perform re-associations of the plus or minus statement STMT that are
1913    always permitted.  Returns true if the CFG was changed.  */
1914
1915 static bool
1916 associate_plusminus (gimple stmt)
1917 {
1918   tree rhs1 = gimple_assign_rhs1 (stmt);
1919   tree rhs2 = gimple_assign_rhs2 (stmt);
1920   enum tree_code code = gimple_assign_rhs_code (stmt);
1921   gimple_stmt_iterator gsi;
1922   bool changed;
1923
1924   /* We can't reassociate at all for saturating types.  */
1925   if (TYPE_SATURATING (TREE_TYPE (rhs1)))
1926     return false;
1927
1928   /* First contract negates.  */
1929   do
1930     {
1931       changed = false;
1932
1933       /* A +- (-B) -> A -+ B.  */
1934       if (TREE_CODE (rhs2) == SSA_NAME)
1935         {
1936           gimple def_stmt = SSA_NAME_DEF_STMT (rhs2);
1937           if (is_gimple_assign (def_stmt)
1938               && gimple_assign_rhs_code (def_stmt) == NEGATE_EXPR
1939               && can_propagate_from (def_stmt))
1940             {
1941               code = (code == MINUS_EXPR) ? PLUS_EXPR : MINUS_EXPR;
1942               gimple_assign_set_rhs_code (stmt, code);
1943               rhs2 = gimple_assign_rhs1 (def_stmt);
1944               gimple_assign_set_rhs2 (stmt, rhs2);
1945               gimple_set_modified (stmt, true);
1946               changed = true;
1947             }
1948         }
1949
1950       /* (-A) + B -> B - A.  */
1951       if (TREE_CODE (rhs1) == SSA_NAME
1952           && code == PLUS_EXPR)
1953         {
1954           gimple def_stmt = SSA_NAME_DEF_STMT (rhs1);
1955           if (is_gimple_assign (def_stmt)
1956               && gimple_assign_rhs_code (def_stmt) == NEGATE_EXPR
1957               && can_propagate_from (def_stmt))
1958             {
1959               code = MINUS_EXPR;
1960               gimple_assign_set_rhs_code (stmt, code);
1961               rhs1 = rhs2;
1962               gimple_assign_set_rhs1 (stmt, rhs1);
1963               rhs2 = gimple_assign_rhs1 (def_stmt);
1964               gimple_assign_set_rhs2 (stmt, rhs2);
1965               gimple_set_modified (stmt, true);
1966               changed = true;
1967             }
1968         }
1969     }
1970   while (changed);
1971
1972   /* We can't reassociate floating-point or fixed-point plus or minus
1973      because of saturation to +-Inf.  */
1974   if (FLOAT_TYPE_P (TREE_TYPE (rhs1))
1975       || FIXED_POINT_TYPE_P (TREE_TYPE (rhs1)))
1976     goto out;
1977
1978   /* Second match patterns that allow contracting a plus-minus pair
1979      irrespective of overflow issues.
1980
1981         (A +- B) - A       ->  +- B
1982         (A +- B) -+ B      ->  A
1983         (CST +- A) +- CST  ->  CST +- A
1984         (A + CST) +- CST   ->  A + CST
1985         ~A + A             ->  -1
1986         ~A + 1             ->  -A 
1987         A - (A +- B)       ->  -+ B
1988         A +- (B +- A)      ->  +- B
1989         CST +- (CST +- A)  ->  CST +- A
1990         CST +- (A +- CST)  ->  CST +- A
1991         A + ~A             ->  -1
1992
1993      via commutating the addition and contracting operations to zero
1994      by reassociation.  */
1995
1996   gsi = gsi_for_stmt (stmt);
1997   if (TREE_CODE (rhs1) == SSA_NAME)
1998     {
1999       gimple def_stmt = SSA_NAME_DEF_STMT (rhs1);
2000       if (is_gimple_assign (def_stmt) && can_propagate_from (def_stmt))
2001         {
2002           enum tree_code def_code = gimple_assign_rhs_code (def_stmt);
2003           if (def_code == PLUS_EXPR
2004               || def_code == MINUS_EXPR)
2005             {
2006               tree def_rhs1 = gimple_assign_rhs1 (def_stmt);
2007               tree def_rhs2 = gimple_assign_rhs2 (def_stmt);
2008               if (operand_equal_p (def_rhs1, rhs2, 0)
2009                   && code == MINUS_EXPR)
2010                 {
2011                   /* (A +- B) - A -> +- B.  */
2012                   code = ((def_code == PLUS_EXPR)
2013                           ? TREE_CODE (def_rhs2) : NEGATE_EXPR);
2014                   rhs1 = def_rhs2;
2015                   rhs2 = NULL_TREE;
2016                   gimple_assign_set_rhs_with_ops (&gsi, code, rhs1, NULL_TREE);
2017                   gcc_assert (gsi_stmt (gsi) == stmt);
2018                   gimple_set_modified (stmt, true);
2019                 }
2020               else if (operand_equal_p (def_rhs2, rhs2, 0)
2021                        && code != def_code)
2022                 {
2023                   /* (A +- B) -+ B -> A.  */
2024                   code = TREE_CODE (def_rhs1);
2025                   rhs1 = def_rhs1;
2026                   rhs2 = NULL_TREE;
2027                   gimple_assign_set_rhs_with_ops (&gsi, code, rhs1, NULL_TREE);
2028                   gcc_assert (gsi_stmt (gsi) == stmt);
2029                   gimple_set_modified (stmt, true);
2030                 }
2031               else if (TREE_CODE (rhs2) == INTEGER_CST
2032                        && TREE_CODE (def_rhs1) == INTEGER_CST)
2033                 {
2034                   /* (CST +- A) +- CST -> CST +- A.  */
2035                   tree cst = fold_binary (code, TREE_TYPE (rhs1),
2036                                           def_rhs1, rhs2);
2037                   if (cst && !TREE_OVERFLOW (cst))
2038                     {
2039                       code = def_code;
2040                       gimple_assign_set_rhs_code (stmt, code);
2041                       rhs1 = cst;
2042                       gimple_assign_set_rhs1 (stmt, rhs1);
2043                       rhs2 = def_rhs2;
2044                       gimple_assign_set_rhs2 (stmt, rhs2);
2045                       gimple_set_modified (stmt, true);
2046                     }
2047                 }
2048               else if (TREE_CODE (rhs2) == INTEGER_CST
2049                        && TREE_CODE (def_rhs2) == INTEGER_CST
2050                        && def_code == PLUS_EXPR)
2051                 {
2052                   /* (A + CST) +- CST -> A + CST.  */
2053                   tree cst = fold_binary (code, TREE_TYPE (rhs1),
2054                                           def_rhs2, rhs2);
2055                   if (cst && !TREE_OVERFLOW (cst))
2056                     {
2057                       code = PLUS_EXPR;
2058                       gimple_assign_set_rhs_code (stmt, code);
2059                       rhs1 = def_rhs1;
2060                       gimple_assign_set_rhs1 (stmt, rhs1);
2061                       rhs2 = cst;
2062                       gimple_assign_set_rhs2 (stmt, rhs2);
2063                       gimple_set_modified (stmt, true);
2064                     }
2065                 }
2066             }
2067           else if (def_code == BIT_NOT_EXPR
2068                    && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
2069             {
2070               tree def_rhs1 = gimple_assign_rhs1 (def_stmt);
2071               if (code == PLUS_EXPR
2072                   && operand_equal_p (def_rhs1, rhs2, 0))
2073                 {
2074                   /* ~A + A -> -1.  */
2075                   code = INTEGER_CST;
2076                   rhs1 = build_int_cst_type (TREE_TYPE (rhs2), -1);
2077                   rhs2 = NULL_TREE;
2078                   gimple_assign_set_rhs_with_ops (&gsi, code, rhs1, NULL_TREE);
2079                   gcc_assert (gsi_stmt (gsi) == stmt);
2080                   gimple_set_modified (stmt, true);
2081                 }
2082               else if (code == PLUS_EXPR
2083                        && integer_onep (rhs1))
2084                 {
2085                   /* ~A + 1 -> -A.  */
2086                   code = NEGATE_EXPR;
2087                   rhs1 = def_rhs1;
2088                   rhs2 = NULL_TREE;
2089                   gimple_assign_set_rhs_with_ops (&gsi, code, rhs1, NULL_TREE);
2090                   gcc_assert (gsi_stmt (gsi) == stmt);
2091                   gimple_set_modified (stmt, true);
2092                 }
2093             }
2094         }
2095     }
2096
2097   if (rhs2 && TREE_CODE (rhs2) == SSA_NAME)
2098     {
2099       gimple def_stmt = SSA_NAME_DEF_STMT (rhs2);
2100       if (is_gimple_assign (def_stmt) && can_propagate_from (def_stmt))
2101         {
2102           enum tree_code def_code = gimple_assign_rhs_code (def_stmt);
2103           if (def_code == PLUS_EXPR
2104               || def_code == MINUS_EXPR)
2105             {
2106               tree def_rhs1 = gimple_assign_rhs1 (def_stmt);
2107               tree def_rhs2 = gimple_assign_rhs2 (def_stmt);
2108               if (operand_equal_p (def_rhs1, rhs1, 0)
2109                   && code == MINUS_EXPR)
2110                 {
2111                   /* A - (A +- B) -> -+ B.  */
2112                   code = ((def_code == PLUS_EXPR)
2113                           ? NEGATE_EXPR : TREE_CODE (def_rhs2));
2114                   rhs1 = def_rhs2;
2115                   rhs2 = NULL_TREE;
2116                   gimple_assign_set_rhs_with_ops (&gsi, code, rhs1, NULL_TREE);
2117                   gcc_assert (gsi_stmt (gsi) == stmt);
2118                   gimple_set_modified (stmt, true);
2119                 }
2120               else if (operand_equal_p (def_rhs2, rhs1, 0)
2121                        && code != def_code)
2122                 {
2123                   /* A +- (B +- A) -> +- B.  */
2124                   code = ((code == PLUS_EXPR)
2125                           ? TREE_CODE (def_rhs1) : NEGATE_EXPR);
2126                   rhs1 = def_rhs1;
2127                   rhs2 = NULL_TREE;
2128                   gimple_assign_set_rhs_with_ops (&gsi, code, rhs1, NULL_TREE);
2129                   gcc_assert (gsi_stmt (gsi) == stmt);
2130                   gimple_set_modified (stmt, true);
2131                 }
2132               else if (TREE_CODE (rhs1) == INTEGER_CST
2133                        && TREE_CODE (def_rhs1) == INTEGER_CST)
2134                 {
2135                   /* CST +- (CST +- A) -> CST +- A.  */
2136                   tree cst = fold_binary (code, TREE_TYPE (rhs2),
2137                                           rhs1, def_rhs1);
2138                   if (cst && !TREE_OVERFLOW (cst))
2139                     {
2140                       code = (code == def_code ? PLUS_EXPR : MINUS_EXPR);
2141                       gimple_assign_set_rhs_code (stmt, code);
2142                       rhs1 = cst;
2143                       gimple_assign_set_rhs1 (stmt, rhs1);
2144                       rhs2 = def_rhs2;
2145                       gimple_assign_set_rhs2 (stmt, rhs2);
2146                       gimple_set_modified (stmt, true);
2147                     }
2148                 }
2149               else if (TREE_CODE (rhs1) == INTEGER_CST
2150                        && TREE_CODE (def_rhs2) == INTEGER_CST)
2151                 {
2152                   /* CST +- (A +- CST) -> CST +- A.  */
2153                   tree cst = fold_binary (def_code == code
2154                                           ? PLUS_EXPR : MINUS_EXPR,
2155                                           TREE_TYPE (rhs2),
2156                                           rhs1, def_rhs2);
2157                   if (cst && !TREE_OVERFLOW (cst))
2158                     {
2159                       rhs1 = cst;
2160                       gimple_assign_set_rhs1 (stmt, rhs1);
2161                       rhs2 = def_rhs1;
2162                       gimple_assign_set_rhs2 (stmt, rhs2);
2163                       gimple_set_modified (stmt, true);
2164                     }
2165                 }
2166             }
2167           else if (def_code == BIT_NOT_EXPR
2168                    && INTEGRAL_TYPE_P (TREE_TYPE (rhs2)))
2169             {
2170               tree def_rhs1 = gimple_assign_rhs1 (def_stmt);
2171               if (code == PLUS_EXPR
2172                   && operand_equal_p (def_rhs1, rhs1, 0))
2173                 {
2174                   /* A + ~A -> -1.  */
2175                   code = INTEGER_CST;
2176                   rhs1 = build_int_cst_type (TREE_TYPE (rhs1), -1);
2177                   rhs2 = NULL_TREE;
2178                   gimple_assign_set_rhs_with_ops (&gsi, code, rhs1, NULL_TREE);
2179                   gcc_assert (gsi_stmt (gsi) == stmt);
2180                   gimple_set_modified (stmt, true);
2181                 }
2182             }
2183         }
2184     }
2185
2186 out:
2187   if (gimple_modified_p (stmt))
2188     {
2189       fold_stmt_inplace (stmt);
2190       update_stmt (stmt);
2191       if (maybe_clean_or_replace_eh_stmt (stmt, stmt)
2192           && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
2193         return true;
2194     }
2195
2196   return false;
2197 }
2198
2199 /* Combine two conversions in a row for the second conversion at *GSI.
2200    Returns true if there were any changes made.  */
2201  
2202 static bool
2203 combine_conversions (gimple_stmt_iterator *gsi)
2204 {
2205   gimple stmt = gsi_stmt (*gsi);
2206   gimple def_stmt;
2207   tree op0, lhs;
2208   enum tree_code code = gimple_assign_rhs_code (stmt);
2209
2210   gcc_checking_assert (CONVERT_EXPR_CODE_P (code)
2211                        || code == FLOAT_EXPR
2212                        || code == FIX_TRUNC_EXPR);
2213
2214   lhs = gimple_assign_lhs (stmt);
2215   op0 = gimple_assign_rhs1 (stmt);
2216   if (useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (op0)))
2217     {
2218       gimple_assign_set_rhs_code (stmt, TREE_CODE (op0));
2219       return true;
2220     }
2221
2222   if (TREE_CODE (op0) != SSA_NAME)
2223     return false;
2224
2225   def_stmt = SSA_NAME_DEF_STMT (op0);
2226   if (!is_gimple_assign (def_stmt))
2227     return false;
2228
2229   if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
2230     {
2231       tree defop0 = gimple_assign_rhs1 (def_stmt);
2232       tree type = TREE_TYPE (lhs);
2233       tree inside_type = TREE_TYPE (defop0);
2234       tree inter_type = TREE_TYPE (op0);
2235       int inside_int = INTEGRAL_TYPE_P (inside_type);
2236       int inside_ptr = POINTER_TYPE_P (inside_type);
2237       int inside_float = FLOAT_TYPE_P (inside_type);
2238       int inside_vec = TREE_CODE (inside_type) == VECTOR_TYPE;
2239       unsigned int inside_prec = TYPE_PRECISION (inside_type);
2240       int inside_unsignedp = TYPE_UNSIGNED (inside_type);
2241       int inter_int = INTEGRAL_TYPE_P (inter_type);
2242       int inter_ptr = POINTER_TYPE_P (inter_type);
2243       int inter_float = FLOAT_TYPE_P (inter_type);
2244       int inter_vec = TREE_CODE (inter_type) == VECTOR_TYPE;
2245       unsigned int inter_prec = TYPE_PRECISION (inter_type);
2246       int inter_unsignedp = TYPE_UNSIGNED (inter_type);
2247       int final_int = INTEGRAL_TYPE_P (type);
2248       int final_ptr = POINTER_TYPE_P (type);
2249       int final_float = FLOAT_TYPE_P (type);
2250       int final_vec = TREE_CODE (type) == VECTOR_TYPE;
2251       unsigned int final_prec = TYPE_PRECISION (type);
2252       int final_unsignedp = TYPE_UNSIGNED (type);
2253
2254       /* In addition to the cases of two conversions in a row
2255          handled below, if we are converting something to its own
2256          type via an object of identical or wider precision, neither
2257          conversion is needed.  */
2258       if (useless_type_conversion_p (type, inside_type)
2259           && (((inter_int || inter_ptr) && final_int)
2260               || (inter_float && final_float))
2261           && inter_prec >= final_prec)
2262         {
2263           gimple_assign_set_rhs1 (stmt, unshare_expr (defop0));
2264           gimple_assign_set_rhs_code (stmt, TREE_CODE (defop0));
2265           update_stmt (stmt);
2266           return true;
2267         }
2268
2269       /* Likewise, if the intermediate and initial types are either both
2270          float or both integer, we don't need the middle conversion if the
2271          former is wider than the latter and doesn't change the signedness
2272          (for integers).  Avoid this if the final type is a pointer since
2273          then we sometimes need the middle conversion.  Likewise if the
2274          final type has a precision not equal to the size of its mode.  */
2275       if (((inter_int && inside_int)
2276            || (inter_float && inside_float)
2277            || (inter_vec && inside_vec))
2278           && inter_prec >= inside_prec
2279           && (inter_float || inter_vec
2280               || inter_unsignedp == inside_unsignedp)
2281           && ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (type))
2282                 && TYPE_MODE (type) == TYPE_MODE (inter_type))
2283           && ! final_ptr
2284           && (! final_vec || inter_prec == inside_prec))
2285         {
2286           gimple_assign_set_rhs1 (stmt, defop0);
2287           update_stmt (stmt);
2288           return true;
2289         }
2290
2291       /* If we have a sign-extension of a zero-extended value, we can
2292          replace that by a single zero-extension.  */
2293       if (inside_int && inter_int && final_int
2294           && inside_prec < inter_prec && inter_prec < final_prec
2295           && inside_unsignedp && !inter_unsignedp)
2296         {
2297           gimple_assign_set_rhs1 (stmt, defop0);
2298           update_stmt (stmt);
2299           return true;
2300         }
2301
2302       /* Two conversions in a row are not needed unless:
2303          - some conversion is floating-point (overstrict for now), or
2304          - some conversion is a vector (overstrict for now), or
2305          - the intermediate type is narrower than both initial and
2306          final, or
2307          - the intermediate type and innermost type differ in signedness,
2308          and the outermost type is wider than the intermediate, or
2309          - the initial type is a pointer type and the precisions of the
2310          intermediate and final types differ, or
2311          - the final type is a pointer type and the precisions of the
2312          initial and intermediate types differ.  */
2313       if (! inside_float && ! inter_float && ! final_float
2314           && ! inside_vec && ! inter_vec && ! final_vec
2315           && (inter_prec >= inside_prec || inter_prec >= final_prec)
2316           && ! (inside_int && inter_int
2317                 && inter_unsignedp != inside_unsignedp
2318                 && inter_prec < final_prec)
2319           && ((inter_unsignedp && inter_prec > inside_prec)
2320               == (final_unsignedp && final_prec > inter_prec))
2321           && ! (inside_ptr && inter_prec != final_prec)
2322           && ! (final_ptr && inside_prec != inter_prec)
2323           && ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (type))
2324                 && TYPE_MODE (type) == TYPE_MODE (inter_type)))
2325         {
2326           gimple_assign_set_rhs1 (stmt, defop0);
2327           update_stmt (stmt);
2328           return true;
2329         }
2330
2331       /* A truncation to an unsigned type should be canonicalized as
2332          bitwise and of a mask.  */
2333       if (final_int && inter_int && inside_int
2334           && final_prec == inside_prec
2335           && final_prec > inter_prec
2336           && inter_unsignedp)
2337         {
2338           tree tem;
2339           tem = fold_build2 (BIT_AND_EXPR, inside_type,
2340                              defop0,
2341                              double_int_to_tree
2342                                (inside_type, double_int_mask (inter_prec)));
2343           if (!useless_type_conversion_p (type, inside_type))
2344             {
2345               tem = force_gimple_operand_gsi (gsi, tem, true, NULL_TREE, true,
2346                                               GSI_SAME_STMT);
2347               gimple_assign_set_rhs1 (stmt, tem);
2348             }
2349           else
2350             gimple_assign_set_rhs_from_tree (gsi, tem);
2351           update_stmt (gsi_stmt (*gsi));
2352           return true;
2353         }
2354     }
2355
2356   return false;
2357 }
2358
2359 /* Main entry point for the forward propagation and statement combine
2360    optimizer.  */
2361
2362 static unsigned int
2363 ssa_forward_propagate_and_combine (void)
2364 {
2365   basic_block bb;
2366   unsigned int todoflags = 0;
2367
2368   cfg_changed = false;
2369
2370   FOR_EACH_BB (bb)
2371     {
2372       gimple_stmt_iterator gsi, prev;
2373       bool prev_initialized;
2374
2375       /* Apply forward propagation to all stmts in the basic-block.
2376          Note we update GSI within the loop as necessary.  */
2377       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
2378         {
2379           gimple stmt = gsi_stmt (gsi);
2380           tree lhs, rhs;
2381           enum tree_code code;
2382
2383           if (!is_gimple_assign (stmt))
2384             {
2385               gsi_next (&gsi);
2386               continue;
2387             }
2388
2389           lhs = gimple_assign_lhs (stmt);
2390           rhs = gimple_assign_rhs1 (stmt);
2391           code = gimple_assign_rhs_code (stmt);
2392           if (TREE_CODE (lhs) != SSA_NAME
2393               || has_zero_uses (lhs))
2394             {
2395               gsi_next (&gsi);
2396               continue;
2397             }
2398
2399           /* If this statement sets an SSA_NAME to an address,
2400              try to propagate the address into the uses of the SSA_NAME.  */
2401           if (code == ADDR_EXPR
2402               /* Handle pointer conversions on invariant addresses
2403                  as well, as this is valid gimple.  */
2404               || (CONVERT_EXPR_CODE_P (code)
2405                   && TREE_CODE (rhs) == ADDR_EXPR
2406                   && POINTER_TYPE_P (TREE_TYPE (lhs))))
2407             {
2408               tree base = get_base_address (TREE_OPERAND (rhs, 0));
2409               if ((!base
2410                    || !DECL_P (base)
2411                    || decl_address_invariant_p (base))
2412                   && !stmt_references_abnormal_ssa_name (stmt)
2413                   && forward_propagate_addr_expr (lhs, rhs))
2414                 {
2415                   release_defs (stmt);
2416                   todoflags |= TODO_remove_unused_locals;
2417                   gsi_remove (&gsi, true);
2418                 }
2419               else
2420                 gsi_next (&gsi);
2421             }
2422           else if (code == POINTER_PLUS_EXPR && can_propagate_from (stmt))
2423             {
2424               if (TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST
2425                   /* ???  Better adjust the interface to that function
2426                      instead of building new trees here.  */
2427                   && forward_propagate_addr_expr
2428                   (lhs,
2429                    build1 (ADDR_EXPR,
2430                            TREE_TYPE (rhs),
2431                            fold_build2 (MEM_REF,
2432                                         TREE_TYPE (TREE_TYPE (rhs)),
2433                                         rhs,
2434                                         fold_convert
2435                                         (ptr_type_node,
2436                                          gimple_assign_rhs2 (stmt))))))
2437                 {
2438                   release_defs (stmt);
2439                   todoflags |= TODO_remove_unused_locals;
2440                   gsi_remove (&gsi, true);
2441                 }
2442               else if (is_gimple_min_invariant (rhs))
2443                 {
2444                   /* Make sure to fold &a[0] + off_1 here.  */
2445                   fold_stmt_inplace (stmt);
2446                   update_stmt (stmt);
2447                   if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
2448                     gsi_next (&gsi);
2449                 }
2450               else
2451                 gsi_next (&gsi);
2452             }
2453           else if (TREE_CODE_CLASS (code) == tcc_comparison)
2454             {
2455               forward_propagate_comparison (stmt);
2456               gsi_next (&gsi);
2457             }
2458           else
2459             gsi_next (&gsi);
2460         }
2461
2462       /* Combine stmts with the stmts defining their operands.
2463          Note we update GSI within the loop as necessary.  */
2464       prev_initialized = false;
2465       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
2466         {
2467           gimple stmt = gsi_stmt (gsi);
2468           bool changed = false;
2469
2470           switch (gimple_code (stmt))
2471             {
2472             case GIMPLE_ASSIGN:
2473               {
2474                 tree rhs1 = gimple_assign_rhs1 (stmt);
2475                 enum tree_code code = gimple_assign_rhs_code (stmt);
2476
2477                 if ((code == BIT_NOT_EXPR
2478                      || code == NEGATE_EXPR)
2479                     && TREE_CODE (rhs1) == SSA_NAME)
2480                   changed = simplify_not_neg_expr (&gsi);
2481                 else if (code == COND_EXPR)
2482                   {
2483                     /* In this case the entire COND_EXPR is in rhs1. */
2484                     int did_something;
2485                     fold_defer_overflow_warnings ();
2486                     did_something = forward_propagate_into_cond (&gsi);
2487                     stmt = gsi_stmt (gsi);
2488                     if (did_something == 2)
2489                       cfg_changed = true;
2490                     fold_undefer_overflow_warnings
2491                       (!TREE_NO_WARNING (rhs1) && did_something, stmt,
2492                        WARN_STRICT_OVERFLOW_CONDITIONAL);
2493                     changed = did_something != 0;
2494                   }
2495                 else if (TREE_CODE_CLASS (code) == tcc_comparison)
2496                   {
2497                     bool no_warning = gimple_no_warning_p (stmt);
2498                     fold_defer_overflow_warnings ();
2499                     changed = forward_propagate_into_comparison (&gsi);
2500                     fold_undefer_overflow_warnings
2501                         (!no_warning && changed,
2502                          stmt, WARN_STRICT_OVERFLOW_CONDITIONAL);
2503                   }
2504                 else if (code == BIT_AND_EXPR
2505                          || code == BIT_IOR_EXPR
2506                          || code == BIT_XOR_EXPR)
2507                   changed = simplify_bitwise_binary (&gsi);
2508                 else if (code == PLUS_EXPR
2509                          || code == MINUS_EXPR)
2510                   changed = associate_plusminus (stmt);
2511                 else if (CONVERT_EXPR_CODE_P (code)
2512                          || code == FLOAT_EXPR
2513                          || code == FIX_TRUNC_EXPR)
2514                   changed = combine_conversions (&gsi);
2515                 break;
2516               }
2517
2518             case GIMPLE_SWITCH:
2519               changed = simplify_gimple_switch (stmt);
2520               break;
2521
2522             case GIMPLE_COND:
2523               {
2524                 int did_something;
2525                 fold_defer_overflow_warnings ();
2526                 did_something = forward_propagate_into_gimple_cond (stmt);
2527                 if (did_something == 2)
2528                   cfg_changed = true;
2529                 fold_undefer_overflow_warnings
2530                   (did_something, stmt, WARN_STRICT_OVERFLOW_CONDITIONAL);
2531                 changed = did_something != 0;
2532                 break;
2533               }
2534
2535             case GIMPLE_CALL:
2536               {
2537                 tree callee = gimple_call_fndecl (stmt);
2538                 if (callee != NULL_TREE
2539                     && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
2540                   changed = simplify_builtin_call (&gsi, callee);
2541                 break;
2542               }
2543
2544             default:;
2545             }
2546
2547           if (changed)
2548             {
2549               /* If the stmt changed then re-visit it and the statements
2550                  inserted before it.  */
2551               if (!prev_initialized)
2552                 gsi = gsi_start_bb (bb);
2553               else
2554                 {
2555                   gsi = prev;
2556                   gsi_next (&gsi);
2557                 }
2558             }
2559           else
2560             {
2561               prev = gsi;
2562               prev_initialized = true;
2563               gsi_next (&gsi);
2564             }
2565         }
2566     }
2567
2568   if (cfg_changed)
2569     todoflags |= TODO_cleanup_cfg;
2570
2571   return todoflags;
2572 }
2573
2574
2575 static bool
2576 gate_forwprop (void)
2577 {
2578   return flag_tree_forwprop;
2579 }
2580
2581 struct gimple_opt_pass pass_forwprop =
2582 {
2583  {
2584   GIMPLE_PASS,
2585   "forwprop",                   /* name */
2586   gate_forwprop,                /* gate */
2587   ssa_forward_propagate_and_combine,    /* execute */
2588   NULL,                         /* sub */
2589   NULL,                         /* next */
2590   0,                            /* static_pass_number */
2591   TV_TREE_FORWPROP,             /* tv_id */
2592   PROP_cfg | PROP_ssa,          /* properties_required */
2593   0,                            /* properties_provided */
2594   0,                            /* properties_destroyed */
2595   0,                            /* todo_flags_start */
2596   TODO_ggc_collect
2597   | TODO_update_ssa
2598   | TODO_verify_ssa             /* todo_flags_finish */
2599  }
2600 };