OSDN Git Service

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