OSDN Git Service

gcc/
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-math-opts.c
1 /* Global, SSA-based optimizations using mathematical identities.
2    Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
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 it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3, or (at your option) any
10 later version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 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 /* Currently, the only mini-pass in this file tries to CSE reciprocal
22    operations.  These are common in sequences such as this one:
23
24         modulus = sqrt(x*x + y*y + z*z);
25         x = x / modulus;
26         y = y / modulus;
27         z = z / modulus;
28
29    that can be optimized to
30
31         modulus = sqrt(x*x + y*y + z*z);
32         rmodulus = 1.0 / modulus;
33         x = x * rmodulus;
34         y = y * rmodulus;
35         z = z * rmodulus;
36
37    We do this for loop invariant divisors, and with this pass whenever
38    we notice that a division has the same divisor multiple times.
39
40    Of course, like in PRE, we don't insert a division if a dominator
41    already has one.  However, this cannot be done as an extension of
42    PRE for several reasons.
43
44    First of all, with some experiments it was found out that the
45    transformation is not always useful if there are only two divisions
46    hy the same divisor.  This is probably because modern processors
47    can pipeline the divisions; on older, in-order processors it should
48    still be effective to optimize two divisions by the same number.
49    We make this a param, and it shall be called N in the remainder of
50    this comment.
51
52    Second, if trapping math is active, we have less freedom on where
53    to insert divisions: we can only do so in basic blocks that already
54    contain one.  (If divisions don't trap, instead, we can insert
55    divisions elsewhere, which will be in blocks that are common dominators
56    of those that have the division).
57
58    We really don't want to compute the reciprocal unless a division will
59    be found.  To do this, we won't insert the division in a basic block
60    that has less than N divisions *post-dominating* it.
61
62    The algorithm constructs a subset of the dominator tree, holding the
63    blocks containing the divisions and the common dominators to them,
64    and walk it twice.  The first walk is in post-order, and it annotates
65    each block with the number of divisions that post-dominate it: this
66    gives information on where divisions can be inserted profitably.
67    The second walk is in pre-order, and it inserts divisions as explained
68    above, and replaces divisions by multiplications.
69
70    In the best case, the cost of the pass is O(n_statements).  In the
71    worst-case, the cost is due to creating the dominator tree subset,
72    with a cost of O(n_basic_blocks ^ 2); however this can only happen
73    for n_statements / n_basic_blocks statements.  So, the amortized cost
74    of creating the dominator tree subset is O(n_basic_blocks) and the
75    worst-case cost of the pass is O(n_statements * n_basic_blocks).
76
77    More practically, the cost will be small because there are few
78    divisions, and they tend to be in the same basic block, so insert_bb
79    is called very few times.
80
81    If we did this using domwalk.c, an efficient implementation would have
82    to work on all the variables in a single pass, because we could not
83    work on just a subset of the dominator tree, as we do now, and the
84    cost would also be something like O(n_statements * n_basic_blocks).
85    The data structures would be more complex in order to work on all the
86    variables in a single pass.  */
87
88 #include "config.h"
89 #include "system.h"
90 #include "coretypes.h"
91 #include "tm.h"
92 #include "flags.h"
93 #include "tree.h"
94 #include "tree-flow.h"
95 #include "timevar.h"
96 #include "tree-pass.h"
97 #include "alloc-pool.h"
98 #include "basic-block.h"
99 #include "target.h"
100 #include "gimple-pretty-print.h"
101
102 /* FIXME: RTL headers have to be included here for optabs.  */
103 #include "rtl.h"                /* Because optabs.h wants enum rtx_code.  */
104 #include "expr.h"               /* Because optabs.h wants sepops.  */
105 #include "optabs.h"
106
107 /* This structure represents one basic block that either computes a
108    division, or is a common dominator for basic block that compute a
109    division.  */
110 struct occurrence {
111   /* The basic block represented by this structure.  */
112   basic_block bb;
113
114   /* If non-NULL, the SSA_NAME holding the definition for a reciprocal
115      inserted in BB.  */
116   tree recip_def;
117
118   /* If non-NULL, the GIMPLE_ASSIGN for a reciprocal computation that
119      was inserted in BB.  */
120   gimple recip_def_stmt;
121
122   /* Pointer to a list of "struct occurrence"s for blocks dominated
123      by BB.  */
124   struct occurrence *children;
125
126   /* Pointer to the next "struct occurrence"s in the list of blocks
127      sharing a common dominator.  */
128   struct occurrence *next;
129
130   /* The number of divisions that are in BB before compute_merit.  The
131      number of divisions that are in BB or post-dominate it after
132      compute_merit.  */
133   int num_divisions;
134
135   /* True if the basic block has a division, false if it is a common
136      dominator for basic blocks that do.  If it is false and trapping
137      math is active, BB is not a candidate for inserting a reciprocal.  */
138   bool bb_has_division;
139 };
140
141
142 /* The instance of "struct occurrence" representing the highest
143    interesting block in the dominator tree.  */
144 static struct occurrence *occ_head;
145
146 /* Allocation pool for getting instances of "struct occurrence".  */
147 static alloc_pool occ_pool;
148
149
150
151 /* Allocate and return a new struct occurrence for basic block BB, and
152    whose children list is headed by CHILDREN.  */
153 static struct occurrence *
154 occ_new (basic_block bb, struct occurrence *children)
155 {
156   struct occurrence *occ;
157
158   bb->aux = occ = (struct occurrence *) pool_alloc (occ_pool);
159   memset (occ, 0, sizeof (struct occurrence));
160
161   occ->bb = bb;
162   occ->children = children;
163   return occ;
164 }
165
166
167 /* Insert NEW_OCC into our subset of the dominator tree.  P_HEAD points to a
168    list of "struct occurrence"s, one per basic block, having IDOM as
169    their common dominator.
170
171    We try to insert NEW_OCC as deep as possible in the tree, and we also
172    insert any other block that is a common dominator for BB and one
173    block already in the tree.  */
174
175 static void
176 insert_bb (struct occurrence *new_occ, basic_block idom,
177            struct occurrence **p_head)
178 {
179   struct occurrence *occ, **p_occ;
180
181   for (p_occ = p_head; (occ = *p_occ) != NULL; )
182     {
183       basic_block bb = new_occ->bb, occ_bb = occ->bb;
184       basic_block dom = nearest_common_dominator (CDI_DOMINATORS, occ_bb, bb);
185       if (dom == bb)
186         {
187           /* BB dominates OCC_BB.  OCC becomes NEW_OCC's child: remove OCC
188              from its list.  */
189           *p_occ = occ->next;
190           occ->next = new_occ->children;
191           new_occ->children = occ;
192
193           /* Try the next block (it may as well be dominated by BB).  */
194         }
195
196       else if (dom == occ_bb)
197         {
198           /* OCC_BB dominates BB.  Tail recurse to look deeper.  */
199           insert_bb (new_occ, dom, &occ->children);
200           return;
201         }
202
203       else if (dom != idom)
204         {
205           gcc_assert (!dom->aux);
206
207           /* There is a dominator between IDOM and BB, add it and make
208              two children out of NEW_OCC and OCC.  First, remove OCC from
209              its list.  */
210           *p_occ = occ->next;
211           new_occ->next = occ;
212           occ->next = NULL;
213
214           /* None of the previous blocks has DOM as a dominator: if we tail
215              recursed, we would reexamine them uselessly. Just switch BB with
216              DOM, and go on looking for blocks dominated by DOM.  */
217           new_occ = occ_new (dom, new_occ);
218         }
219
220       else
221         {
222           /* Nothing special, go on with the next element.  */
223           p_occ = &occ->next;
224         }
225     }
226
227   /* No place was found as a child of IDOM.  Make BB a sibling of IDOM.  */
228   new_occ->next = *p_head;
229   *p_head = new_occ;
230 }
231
232 /* Register that we found a division in BB.  */
233
234 static inline void
235 register_division_in (basic_block bb)
236 {
237   struct occurrence *occ;
238
239   occ = (struct occurrence *) bb->aux;
240   if (!occ)
241     {
242       occ = occ_new (bb, NULL);
243       insert_bb (occ, ENTRY_BLOCK_PTR, &occ_head);
244     }
245
246   occ->bb_has_division = true;
247   occ->num_divisions++;
248 }
249
250
251 /* Compute the number of divisions that postdominate each block in OCC and
252    its children.  */
253
254 static void
255 compute_merit (struct occurrence *occ)
256 {
257   struct occurrence *occ_child;
258   basic_block dom = occ->bb;
259
260   for (occ_child = occ->children; occ_child; occ_child = occ_child->next)
261     {
262       basic_block bb;
263       if (occ_child->children)
264         compute_merit (occ_child);
265
266       if (flag_exceptions)
267         bb = single_noncomplex_succ (dom);
268       else
269         bb = dom;
270
271       if (dominated_by_p (CDI_POST_DOMINATORS, bb, occ_child->bb))
272         occ->num_divisions += occ_child->num_divisions;
273     }
274 }
275
276
277 /* Return whether USE_STMT is a floating-point division by DEF.  */
278 static inline bool
279 is_division_by (gimple use_stmt, tree def)
280 {
281   return is_gimple_assign (use_stmt)
282          && gimple_assign_rhs_code (use_stmt) == RDIV_EXPR
283          && gimple_assign_rhs2 (use_stmt) == def
284          /* Do not recognize x / x as valid division, as we are getting
285             confused later by replacing all immediate uses x in such
286             a stmt.  */
287          && gimple_assign_rhs1 (use_stmt) != def;
288 }
289
290 /* Walk the subset of the dominator tree rooted at OCC, setting the
291    RECIP_DEF field to a definition of 1.0 / DEF that can be used in
292    the given basic block.  The field may be left NULL, of course,
293    if it is not possible or profitable to do the optimization.
294
295    DEF_BSI is an iterator pointing at the statement defining DEF.
296    If RECIP_DEF is set, a dominator already has a computation that can
297    be used.  */
298
299 static void
300 insert_reciprocals (gimple_stmt_iterator *def_gsi, struct occurrence *occ,
301                     tree def, tree recip_def, int threshold)
302 {
303   tree type;
304   gimple new_stmt;
305   gimple_stmt_iterator gsi;
306   struct occurrence *occ_child;
307
308   if (!recip_def
309       && (occ->bb_has_division || !flag_trapping_math)
310       && occ->num_divisions >= threshold)
311     {
312       /* Make a variable with the replacement and substitute it.  */
313       type = TREE_TYPE (def);
314       recip_def = make_rename_temp (type, "reciptmp");
315       new_stmt = gimple_build_assign_with_ops (RDIV_EXPR, recip_def,
316                                                build_one_cst (type), def);
317
318       if (occ->bb_has_division)
319         {
320           /* Case 1: insert before an existing division.  */
321           gsi = gsi_after_labels (occ->bb);
322           while (!gsi_end_p (gsi) && !is_division_by (gsi_stmt (gsi), def))
323             gsi_next (&gsi);
324
325           gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
326         }
327       else if (def_gsi && occ->bb == def_gsi->bb)
328         {
329           /* Case 2: insert right after the definition.  Note that this will
330              never happen if the definition statement can throw, because in
331              that case the sole successor of the statement's basic block will
332              dominate all the uses as well.  */
333           gsi_insert_after (def_gsi, new_stmt, GSI_NEW_STMT);
334         }
335       else
336         {
337           /* Case 3: insert in a basic block not containing defs/uses.  */
338           gsi = gsi_after_labels (occ->bb);
339           gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
340         }
341
342       occ->recip_def_stmt = new_stmt;
343     }
344
345   occ->recip_def = recip_def;
346   for (occ_child = occ->children; occ_child; occ_child = occ_child->next)
347     insert_reciprocals (def_gsi, occ_child, def, recip_def, threshold);
348 }
349
350
351 /* Replace the division at USE_P with a multiplication by the reciprocal, if
352    possible.  */
353
354 static inline void
355 replace_reciprocal (use_operand_p use_p)
356 {
357   gimple use_stmt = USE_STMT (use_p);
358   basic_block bb = gimple_bb (use_stmt);
359   struct occurrence *occ = (struct occurrence *) bb->aux;
360
361   if (optimize_bb_for_speed_p (bb)
362       && occ->recip_def && use_stmt != occ->recip_def_stmt)
363     {
364       gimple_assign_set_rhs_code (use_stmt, MULT_EXPR);
365       SET_USE (use_p, occ->recip_def);
366       fold_stmt_inplace (use_stmt);
367       update_stmt (use_stmt);
368     }
369 }
370
371
372 /* Free OCC and return one more "struct occurrence" to be freed.  */
373
374 static struct occurrence *
375 free_bb (struct occurrence *occ)
376 {
377   struct occurrence *child, *next;
378
379   /* First get the two pointers hanging off OCC.  */
380   next = occ->next;
381   child = occ->children;
382   occ->bb->aux = NULL;
383   pool_free (occ_pool, occ);
384
385   /* Now ensure that we don't recurse unless it is necessary.  */
386   if (!child)
387     return next;
388   else
389     {
390       while (next)
391         next = free_bb (next);
392
393       return child;
394     }
395 }
396
397
398 /* Look for floating-point divisions among DEF's uses, and try to
399    replace them by multiplications with the reciprocal.  Add
400    as many statements computing the reciprocal as needed.
401
402    DEF must be a GIMPLE register of a floating-point type.  */
403
404 static void
405 execute_cse_reciprocals_1 (gimple_stmt_iterator *def_gsi, tree def)
406 {
407   use_operand_p use_p;
408   imm_use_iterator use_iter;
409   struct occurrence *occ;
410   int count = 0, threshold;
411
412   gcc_assert (FLOAT_TYPE_P (TREE_TYPE (def)) && is_gimple_reg (def));
413
414   FOR_EACH_IMM_USE_FAST (use_p, use_iter, def)
415     {
416       gimple use_stmt = USE_STMT (use_p);
417       if (is_division_by (use_stmt, def))
418         {
419           register_division_in (gimple_bb (use_stmt));
420           count++;
421         }
422     }
423
424   /* Do the expensive part only if we can hope to optimize something.  */
425   threshold = targetm.min_divisions_for_recip_mul (TYPE_MODE (TREE_TYPE (def)));
426   if (count >= threshold)
427     {
428       gimple use_stmt;
429       for (occ = occ_head; occ; occ = occ->next)
430         {
431           compute_merit (occ);
432           insert_reciprocals (def_gsi, occ, def, NULL, threshold);
433         }
434
435       FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, def)
436         {
437           if (is_division_by (use_stmt, def))
438             {
439               FOR_EACH_IMM_USE_ON_STMT (use_p, use_iter)
440                 replace_reciprocal (use_p);
441             }
442         }
443     }
444
445   for (occ = occ_head; occ; )
446     occ = free_bb (occ);
447
448   occ_head = NULL;
449 }
450
451 static bool
452 gate_cse_reciprocals (void)
453 {
454   return optimize && flag_reciprocal_math;
455 }
456
457 /* Go through all the floating-point SSA_NAMEs, and call
458    execute_cse_reciprocals_1 on each of them.  */
459 static unsigned int
460 execute_cse_reciprocals (void)
461 {
462   basic_block bb;
463   tree arg;
464
465   occ_pool = create_alloc_pool ("dominators for recip",
466                                 sizeof (struct occurrence),
467                                 n_basic_blocks / 3 + 1);
468
469   calculate_dominance_info (CDI_DOMINATORS);
470   calculate_dominance_info (CDI_POST_DOMINATORS);
471
472 #ifdef ENABLE_CHECKING
473   FOR_EACH_BB (bb)
474     gcc_assert (!bb->aux);
475 #endif
476
477   for (arg = DECL_ARGUMENTS (cfun->decl); arg; arg = DECL_CHAIN (arg))
478     if (gimple_default_def (cfun, arg)
479         && FLOAT_TYPE_P (TREE_TYPE (arg))
480         && is_gimple_reg (arg))
481       execute_cse_reciprocals_1 (NULL, gimple_default_def (cfun, arg));
482
483   FOR_EACH_BB (bb)
484     {
485       gimple_stmt_iterator gsi;
486       gimple phi;
487       tree def;
488
489       for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
490         {
491           phi = gsi_stmt (gsi);
492           def = PHI_RESULT (phi);
493           if (FLOAT_TYPE_P (TREE_TYPE (def))
494               && is_gimple_reg (def))
495             execute_cse_reciprocals_1 (NULL, def);
496         }
497
498       for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
499         {
500           gimple stmt = gsi_stmt (gsi);
501
502           if (gimple_has_lhs (stmt)
503               && (def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF)) != NULL
504               && FLOAT_TYPE_P (TREE_TYPE (def))
505               && TREE_CODE (def) == SSA_NAME)
506             execute_cse_reciprocals_1 (&gsi, def);
507         }
508
509       if (optimize_bb_for_size_p (bb))
510         continue;
511
512       /* Scan for a/func(b) and convert it to reciprocal a*rfunc(b).  */
513       for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
514         {
515           gimple stmt = gsi_stmt (gsi);
516           tree fndecl;
517
518           if (is_gimple_assign (stmt)
519               && gimple_assign_rhs_code (stmt) == RDIV_EXPR)
520             {
521               tree arg1 = gimple_assign_rhs2 (stmt);
522               gimple stmt1;
523
524               if (TREE_CODE (arg1) != SSA_NAME)
525                 continue;
526
527               stmt1 = SSA_NAME_DEF_STMT (arg1);
528
529               if (is_gimple_call (stmt1)
530                   && gimple_call_lhs (stmt1)
531                   && (fndecl = gimple_call_fndecl (stmt1))
532                   && (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
533                       || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD))
534                 {
535                   enum built_in_function code;
536                   bool md_code, fail;
537                   imm_use_iterator ui;
538                   use_operand_p use_p;
539
540                   code = DECL_FUNCTION_CODE (fndecl);
541                   md_code = DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD;
542
543                   fndecl = targetm.builtin_reciprocal (code, md_code, false);
544                   if (!fndecl)
545                     continue;
546
547                   /* Check that all uses of the SSA name are divisions,
548                      otherwise replacing the defining statement will do
549                      the wrong thing.  */
550                   fail = false;
551                   FOR_EACH_IMM_USE_FAST (use_p, ui, arg1)
552                     {
553                       gimple stmt2 = USE_STMT (use_p);
554                       if (is_gimple_debug (stmt2))
555                         continue;
556                       if (!is_gimple_assign (stmt2)
557                           || gimple_assign_rhs_code (stmt2) != RDIV_EXPR
558                           || gimple_assign_rhs1 (stmt2) == arg1
559                           || gimple_assign_rhs2 (stmt2) != arg1)
560                         {
561                           fail = true;
562                           break;
563                         }
564                     }
565                   if (fail)
566                     continue;
567
568                   gimple_replace_lhs (stmt1, arg1);
569                   gimple_call_set_fndecl (stmt1, fndecl);
570                   update_stmt (stmt1);
571
572                   FOR_EACH_IMM_USE_STMT (stmt, ui, arg1)
573                     {
574                       gimple_assign_set_rhs_code (stmt, MULT_EXPR);
575                       fold_stmt_inplace (stmt);
576                       update_stmt (stmt);
577                     }
578                 }
579             }
580         }
581     }
582
583   free_dominance_info (CDI_DOMINATORS);
584   free_dominance_info (CDI_POST_DOMINATORS);
585   free_alloc_pool (occ_pool);
586   return 0;
587 }
588
589 struct gimple_opt_pass pass_cse_reciprocals =
590 {
591  {
592   GIMPLE_PASS,
593   "recip",                              /* name */
594   gate_cse_reciprocals,                 /* gate */
595   execute_cse_reciprocals,              /* execute */
596   NULL,                                 /* sub */
597   NULL,                                 /* next */
598   0,                                    /* static_pass_number */
599   TV_NONE,                              /* tv_id */
600   PROP_ssa,                             /* properties_required */
601   0,                                    /* properties_provided */
602   0,                                    /* properties_destroyed */
603   0,                                    /* todo_flags_start */
604   TODO_dump_func | TODO_update_ssa | TODO_verify_ssa
605     | TODO_verify_stmts                /* todo_flags_finish */
606  }
607 };
608
609 /* Records an occurrence at statement USE_STMT in the vector of trees
610    STMTS if it is dominated by *TOP_BB or dominates it or this basic block
611    is not yet initialized.  Returns true if the occurrence was pushed on
612    the vector.  Adjusts *TOP_BB to be the basic block dominating all
613    statements in the vector.  */
614
615 static bool
616 maybe_record_sincos (VEC(gimple, heap) **stmts,
617                      basic_block *top_bb, gimple use_stmt)
618 {
619   basic_block use_bb = gimple_bb (use_stmt);
620   if (*top_bb
621       && (*top_bb == use_bb
622           || dominated_by_p (CDI_DOMINATORS, use_bb, *top_bb)))
623     VEC_safe_push (gimple, heap, *stmts, use_stmt);
624   else if (!*top_bb
625            || dominated_by_p (CDI_DOMINATORS, *top_bb, use_bb))
626     {
627       VEC_safe_push (gimple, heap, *stmts, use_stmt);
628       *top_bb = use_bb;
629     }
630   else
631     return false;
632
633   return true;
634 }
635
636 /* Look for sin, cos and cexpi calls with the same argument NAME and
637    create a single call to cexpi CSEing the result in this case.
638    We first walk over all immediate uses of the argument collecting
639    statements that we can CSE in a vector and in a second pass replace
640    the statement rhs with a REALPART or IMAGPART expression on the
641    result of the cexpi call we insert before the use statement that
642    dominates all other candidates.  */
643
644 static void
645 execute_cse_sincos_1 (tree name)
646 {
647   gimple_stmt_iterator gsi;
648   imm_use_iterator use_iter;
649   tree fndecl, res, type;
650   gimple def_stmt, use_stmt, stmt;
651   int seen_cos = 0, seen_sin = 0, seen_cexpi = 0;
652   VEC(gimple, heap) *stmts = NULL;
653   basic_block top_bb = NULL;
654   int i;
655
656   type = TREE_TYPE (name);
657   FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, name)
658     {
659       if (gimple_code (use_stmt) != GIMPLE_CALL
660           || !gimple_call_lhs (use_stmt)
661           || !(fndecl = gimple_call_fndecl (use_stmt))
662           || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
663         continue;
664
665       switch (DECL_FUNCTION_CODE (fndecl))
666         {
667         CASE_FLT_FN (BUILT_IN_COS):
668           seen_cos |= maybe_record_sincos (&stmts, &top_bb, use_stmt) ? 1 : 0;
669           break;
670
671         CASE_FLT_FN (BUILT_IN_SIN):
672           seen_sin |= maybe_record_sincos (&stmts, &top_bb, use_stmt) ? 1 : 0;
673           break;
674
675         CASE_FLT_FN (BUILT_IN_CEXPI):
676           seen_cexpi |= maybe_record_sincos (&stmts, &top_bb, use_stmt) ? 1 : 0;
677           break;
678
679         default:;
680         }
681     }
682
683   if (seen_cos + seen_sin + seen_cexpi <= 1)
684     {
685       VEC_free(gimple, heap, stmts);
686       return;
687     }
688
689   /* Simply insert cexpi at the beginning of top_bb but not earlier than
690      the name def statement.  */
691   fndecl = mathfn_built_in (type, BUILT_IN_CEXPI);
692   if (!fndecl)
693     return;
694   res = make_rename_temp (TREE_TYPE (TREE_TYPE (fndecl)), "sincostmp");
695   stmt = gimple_build_call (fndecl, 1, name);
696   gimple_call_set_lhs (stmt, res);
697
698   def_stmt = SSA_NAME_DEF_STMT (name);
699   if (!SSA_NAME_IS_DEFAULT_DEF (name)
700       && gimple_code (def_stmt) != GIMPLE_PHI
701       && gimple_bb (def_stmt) == top_bb)
702     {
703       gsi = gsi_for_stmt (def_stmt);
704       gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
705     }
706   else
707     {
708       gsi = gsi_after_labels (top_bb);
709       gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
710     }
711   update_stmt (stmt);
712
713   /* And adjust the recorded old call sites.  */
714   for (i = 0; VEC_iterate(gimple, stmts, i, use_stmt); ++i)
715     {
716       tree rhs = NULL;
717       fndecl = gimple_call_fndecl (use_stmt);
718
719       switch (DECL_FUNCTION_CODE (fndecl))
720         {
721         CASE_FLT_FN (BUILT_IN_COS):
722           rhs = fold_build1 (REALPART_EXPR, type, res);
723           break;
724
725         CASE_FLT_FN (BUILT_IN_SIN):
726           rhs = fold_build1 (IMAGPART_EXPR, type, res);
727           break;
728
729         CASE_FLT_FN (BUILT_IN_CEXPI):
730           rhs = res;
731           break;
732
733         default:;
734           gcc_unreachable ();
735         }
736
737         /* Replace call with a copy.  */
738         stmt = gimple_build_assign (gimple_call_lhs (use_stmt), rhs);
739
740         gsi = gsi_for_stmt (use_stmt);
741         gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
742         gsi_remove (&gsi, true);
743     }
744
745   VEC_free(gimple, heap, stmts);
746 }
747
748 /* Go through all calls to sin, cos and cexpi and call execute_cse_sincos_1
749    on the SSA_NAME argument of each of them.  */
750
751 static unsigned int
752 execute_cse_sincos (void)
753 {
754   basic_block bb;
755
756   calculate_dominance_info (CDI_DOMINATORS);
757
758   FOR_EACH_BB (bb)
759     {
760       gimple_stmt_iterator gsi;
761
762       for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
763         {
764           gimple stmt = gsi_stmt (gsi);
765           tree fndecl;
766
767           if (is_gimple_call (stmt)
768               && gimple_call_lhs (stmt)
769               && (fndecl = gimple_call_fndecl (stmt))
770               && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
771             {
772               tree arg;
773
774               switch (DECL_FUNCTION_CODE (fndecl))
775                 {
776                 CASE_FLT_FN (BUILT_IN_COS):
777                 CASE_FLT_FN (BUILT_IN_SIN):
778                 CASE_FLT_FN (BUILT_IN_CEXPI):
779                   arg = gimple_call_arg (stmt, 0);
780                   if (TREE_CODE (arg) == SSA_NAME)
781                     execute_cse_sincos_1 (arg);
782                   break;
783
784                 default:;
785                 }
786             }
787         }
788     }
789
790   free_dominance_info (CDI_DOMINATORS);
791   return 0;
792 }
793
794 static bool
795 gate_cse_sincos (void)
796 {
797   /* Make sure we have either sincos or cexp.  */
798   return (TARGET_HAS_SINCOS
799           || TARGET_C99_FUNCTIONS)
800          && optimize;
801 }
802
803 struct gimple_opt_pass pass_cse_sincos =
804 {
805  {
806   GIMPLE_PASS,
807   "sincos",                             /* name */
808   gate_cse_sincos,                      /* gate */
809   execute_cse_sincos,                   /* execute */
810   NULL,                                 /* sub */
811   NULL,                                 /* next */
812   0,                                    /* static_pass_number */
813   TV_NONE,                              /* tv_id */
814   PROP_ssa,                             /* properties_required */
815   0,                                    /* properties_provided */
816   0,                                    /* properties_destroyed */
817   0,                                    /* todo_flags_start */
818   TODO_dump_func | TODO_update_ssa | TODO_verify_ssa
819     | TODO_verify_stmts                 /* todo_flags_finish */
820  }
821 };
822
823 /* A symbolic number is used to detect byte permutation and selection
824    patterns.  Therefore the field N contains an artificial number
825    consisting of byte size markers:
826
827    0    - byte has the value 0
828    1..size - byte contains the content of the byte
829    number indexed with that value minus one  */
830
831 struct symbolic_number {
832   unsigned HOST_WIDEST_INT n;
833   int size;
834 };
835
836 /* Perform a SHIFT or ROTATE operation by COUNT bits on symbolic
837    number N.  Return false if the requested operation is not permitted
838    on a symbolic number.  */
839
840 static inline bool
841 do_shift_rotate (enum tree_code code,
842                  struct symbolic_number *n,
843                  int count)
844 {
845   if (count % 8 != 0)
846     return false;
847
848   /* Zero out the extra bits of N in order to avoid them being shifted
849      into the significant bits.  */
850   if (n->size < (int)sizeof (HOST_WIDEST_INT))
851     n->n &= ((unsigned HOST_WIDEST_INT)1 << (n->size * BITS_PER_UNIT)) - 1;
852
853   switch (code)
854     {
855     case LSHIFT_EXPR:
856       n->n <<= count;
857       break;
858     case RSHIFT_EXPR:
859       n->n >>= count;
860       break;
861     case LROTATE_EXPR:
862       n->n = (n->n << count) | (n->n >> ((n->size * BITS_PER_UNIT) - count));
863       break;
864     case RROTATE_EXPR:
865       n->n = (n->n >> count) | (n->n << ((n->size * BITS_PER_UNIT) - count));
866       break;
867     default:
868       return false;
869     }
870   return true;
871 }
872
873 /* Perform sanity checking for the symbolic number N and the gimple
874    statement STMT.  */
875
876 static inline bool
877 verify_symbolic_number_p (struct symbolic_number *n, gimple stmt)
878 {
879   tree lhs_type;
880
881   lhs_type = gimple_expr_type (stmt);
882
883   if (TREE_CODE (lhs_type) != INTEGER_TYPE)
884     return false;
885
886   if (TYPE_PRECISION (lhs_type) != n->size * BITS_PER_UNIT)
887     return false;
888
889   return true;
890 }
891
892 /* find_bswap_1 invokes itself recursively with N and tries to perform
893    the operation given by the rhs of STMT on the result.  If the
894    operation could successfully be executed the function returns the
895    tree expression of the source operand and NULL otherwise.  */
896
897 static tree
898 find_bswap_1 (gimple stmt, struct symbolic_number *n, int limit)
899 {
900   enum tree_code code;
901   tree rhs1, rhs2 = NULL;
902   gimple rhs1_stmt, rhs2_stmt;
903   tree source_expr1;
904   enum gimple_rhs_class rhs_class;
905
906   if (!limit || !is_gimple_assign (stmt))
907     return NULL_TREE;
908
909   rhs1 = gimple_assign_rhs1 (stmt);
910
911   if (TREE_CODE (rhs1) != SSA_NAME)
912     return NULL_TREE;
913
914   code = gimple_assign_rhs_code (stmt);
915   rhs_class = gimple_assign_rhs_class (stmt);
916   rhs1_stmt = SSA_NAME_DEF_STMT (rhs1);
917
918   if (rhs_class == GIMPLE_BINARY_RHS)
919     rhs2 = gimple_assign_rhs2 (stmt);
920
921   /* Handle unary rhs and binary rhs with integer constants as second
922      operand.  */
923
924   if (rhs_class == GIMPLE_UNARY_RHS
925       || (rhs_class == GIMPLE_BINARY_RHS
926           && TREE_CODE (rhs2) == INTEGER_CST))
927     {
928       if (code != BIT_AND_EXPR
929           && code != LSHIFT_EXPR
930           && code != RSHIFT_EXPR
931           && code != LROTATE_EXPR
932           && code != RROTATE_EXPR
933           && code != NOP_EXPR
934           && code != CONVERT_EXPR)
935         return NULL_TREE;
936
937       source_expr1 = find_bswap_1 (rhs1_stmt, n, limit - 1);
938
939       /* If find_bswap_1 returned NULL STMT is a leaf node and we have
940          to initialize the symbolic number.  */
941       if (!source_expr1)
942         {
943           /* Set up the symbolic number N by setting each byte to a
944              value between 1 and the byte size of rhs1.  The highest
945              order byte is set to n->size and the lowest order
946              byte to 1.  */
947           n->size = TYPE_PRECISION (TREE_TYPE (rhs1));
948           if (n->size % BITS_PER_UNIT != 0)
949             return NULL_TREE;
950           n->size /= BITS_PER_UNIT;
951           n->n = (sizeof (HOST_WIDEST_INT) < 8 ? 0 :
952                   (unsigned HOST_WIDEST_INT)0x08070605 << 32 | 0x04030201);
953
954           if (n->size < (int)sizeof (HOST_WIDEST_INT))
955             n->n &= ((unsigned HOST_WIDEST_INT)1 <<
956                      (n->size * BITS_PER_UNIT)) - 1;
957
958           source_expr1 = rhs1;
959         }
960
961       switch (code)
962         {
963         case BIT_AND_EXPR:
964           {
965             int i;
966             unsigned HOST_WIDEST_INT val = widest_int_cst_value (rhs2);
967             unsigned HOST_WIDEST_INT tmp = val;
968
969             /* Only constants masking full bytes are allowed.  */
970             for (i = 0; i < n->size; i++, tmp >>= BITS_PER_UNIT)
971               if ((tmp & 0xff) != 0 && (tmp & 0xff) != 0xff)
972                 return NULL_TREE;
973
974             n->n &= val;
975           }
976           break;
977         case LSHIFT_EXPR:
978         case RSHIFT_EXPR:
979         case LROTATE_EXPR:
980         case RROTATE_EXPR:
981           if (!do_shift_rotate (code, n, (int)TREE_INT_CST_LOW (rhs2)))
982             return NULL_TREE;
983           break;
984         CASE_CONVERT:
985           {
986             int type_size;
987
988             type_size = TYPE_PRECISION (gimple_expr_type (stmt));
989             if (type_size % BITS_PER_UNIT != 0)
990               return NULL_TREE;
991
992             if (type_size / BITS_PER_UNIT < (int)(sizeof (HOST_WIDEST_INT)))
993               {
994                 /* If STMT casts to a smaller type mask out the bits not
995                    belonging to the target type.  */
996                 n->n &= ((unsigned HOST_WIDEST_INT)1 << type_size) - 1;
997               }
998             n->size = type_size / BITS_PER_UNIT;
999           }
1000           break;
1001         default:
1002           return NULL_TREE;
1003         };
1004       return verify_symbolic_number_p (n, stmt) ? source_expr1 : NULL;
1005     }
1006
1007   /* Handle binary rhs.  */
1008
1009   if (rhs_class == GIMPLE_BINARY_RHS)
1010     {
1011       struct symbolic_number n1, n2;
1012       tree source_expr2;
1013
1014       if (code != BIT_IOR_EXPR)
1015         return NULL_TREE;
1016
1017       if (TREE_CODE (rhs2) != SSA_NAME)
1018         return NULL_TREE;
1019
1020       rhs2_stmt = SSA_NAME_DEF_STMT (rhs2);
1021
1022       switch (code)
1023         {
1024         case BIT_IOR_EXPR:
1025           source_expr1 = find_bswap_1 (rhs1_stmt, &n1, limit - 1);
1026
1027           if (!source_expr1)
1028             return NULL_TREE;
1029
1030           source_expr2 = find_bswap_1 (rhs2_stmt, &n2, limit - 1);
1031
1032           if (source_expr1 != source_expr2
1033               || n1.size != n2.size)
1034             return NULL_TREE;
1035
1036           n->size = n1.size;
1037           n->n = n1.n | n2.n;
1038
1039           if (!verify_symbolic_number_p (n, stmt))
1040             return NULL_TREE;
1041
1042           break;
1043         default:
1044           return NULL_TREE;
1045         }
1046       return source_expr1;
1047     }
1048   return NULL_TREE;
1049 }
1050
1051 /* Check if STMT completes a bswap implementation consisting of ORs,
1052    SHIFTs and ANDs.  Return the source tree expression on which the
1053    byte swap is performed and NULL if no bswap was found.  */
1054
1055 static tree
1056 find_bswap (gimple stmt)
1057 {
1058 /* The number which the find_bswap result should match in order to
1059    have a full byte swap.  The number is shifted to the left according
1060    to the size of the symbolic number before using it.  */
1061   unsigned HOST_WIDEST_INT cmp =
1062     sizeof (HOST_WIDEST_INT) < 8 ? 0 :
1063     (unsigned HOST_WIDEST_INT)0x01020304 << 32 | 0x05060708;
1064
1065   struct symbolic_number n;
1066   tree source_expr;
1067
1068   /* The last parameter determines the depth search limit.  It usually
1069      correlates directly to the number of bytes to be touched.  We
1070      increase that number by one here in order to also cover signed ->
1071      unsigned conversions of the src operand as can be seen in
1072      libgcc.  */
1073   source_expr =  find_bswap_1 (stmt, &n,
1074                                TREE_INT_CST_LOW (
1075                                  TYPE_SIZE_UNIT (gimple_expr_type (stmt))) + 1);
1076
1077   if (!source_expr)
1078     return NULL_TREE;
1079
1080   /* Zero out the extra bits of N and CMP.  */
1081   if (n.size < (int)sizeof (HOST_WIDEST_INT))
1082     {
1083       unsigned HOST_WIDEST_INT mask =
1084         ((unsigned HOST_WIDEST_INT)1 << (n.size * BITS_PER_UNIT)) - 1;
1085
1086       n.n &= mask;
1087       cmp >>= (sizeof (HOST_WIDEST_INT) - n.size) * BITS_PER_UNIT;
1088     }
1089
1090   /* A complete byte swap should make the symbolic number to start
1091      with the largest digit in the highest order byte.  */
1092   if (cmp != n.n)
1093     return NULL_TREE;
1094
1095   return source_expr;
1096 }
1097
1098 /* Find manual byte swap implementations and turn them into a bswap
1099    builtin invokation.  */
1100
1101 static unsigned int
1102 execute_optimize_bswap (void)
1103 {
1104   basic_block bb;
1105   bool bswap32_p, bswap64_p;
1106   bool changed = false;
1107   tree bswap32_type = NULL_TREE, bswap64_type = NULL_TREE;
1108
1109   if (BITS_PER_UNIT != 8)
1110     return 0;
1111
1112   if (sizeof (HOST_WIDEST_INT) < 8)
1113     return 0;
1114
1115   bswap32_p = (built_in_decls[BUILT_IN_BSWAP32]
1116                && optab_handler (bswap_optab, SImode) != CODE_FOR_nothing);
1117   bswap64_p = (built_in_decls[BUILT_IN_BSWAP64]
1118                && (optab_handler (bswap_optab, DImode) != CODE_FOR_nothing
1119                    || (bswap32_p && word_mode == SImode)));
1120
1121   if (!bswap32_p && !bswap64_p)
1122     return 0;
1123
1124   /* Determine the argument type of the builtins.  The code later on
1125      assumes that the return and argument type are the same.  */
1126   if (bswap32_p)
1127     {
1128       tree fndecl = built_in_decls[BUILT_IN_BSWAP32];
1129       bswap32_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
1130     }
1131
1132   if (bswap64_p)
1133     {
1134       tree fndecl = built_in_decls[BUILT_IN_BSWAP64];
1135       bswap64_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
1136     }
1137
1138   FOR_EACH_BB (bb)
1139     {
1140       gimple_stmt_iterator gsi;
1141
1142       for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1143         {
1144           gimple stmt = gsi_stmt (gsi);
1145           tree bswap_src, bswap_type;
1146           tree bswap_tmp;
1147           tree fndecl = NULL_TREE;
1148           int type_size;
1149           gimple call;
1150
1151           if (!is_gimple_assign (stmt)
1152               || gimple_assign_rhs_code (stmt) != BIT_IOR_EXPR)
1153             continue;
1154
1155           type_size = TYPE_PRECISION (gimple_expr_type (stmt));
1156
1157           switch (type_size)
1158             {
1159             case 32:
1160               if (bswap32_p)
1161                 {
1162                   fndecl = built_in_decls[BUILT_IN_BSWAP32];
1163                   bswap_type = bswap32_type;
1164                 }
1165               break;
1166             case 64:
1167               if (bswap64_p)
1168                 {
1169                   fndecl = built_in_decls[BUILT_IN_BSWAP64];
1170                   bswap_type = bswap64_type;
1171                 }
1172               break;
1173             default:
1174               continue;
1175             }
1176
1177           if (!fndecl)
1178             continue;
1179
1180           bswap_src = find_bswap (stmt);
1181
1182           if (!bswap_src)
1183             continue;
1184
1185           changed = true;
1186
1187           bswap_tmp = bswap_src;
1188
1189           /* Convert the src expression if necessary.  */
1190           if (!useless_type_conversion_p (TREE_TYPE (bswap_tmp), bswap_type))
1191             {
1192               gimple convert_stmt;
1193
1194               bswap_tmp = create_tmp_var (bswap_type, "bswapsrc");
1195               add_referenced_var (bswap_tmp);
1196               bswap_tmp = make_ssa_name (bswap_tmp, NULL);
1197
1198               convert_stmt = gimple_build_assign_with_ops (
1199                                CONVERT_EXPR, bswap_tmp, bswap_src, NULL);
1200               gsi_insert_before (&gsi, convert_stmt, GSI_SAME_STMT);
1201             }
1202
1203           call = gimple_build_call (fndecl, 1, bswap_tmp);
1204
1205           bswap_tmp = gimple_assign_lhs (stmt);
1206
1207           /* Convert the result if necessary.  */
1208           if (!useless_type_conversion_p (TREE_TYPE (bswap_tmp), bswap_type))
1209             {
1210               gimple convert_stmt;
1211
1212               bswap_tmp = create_tmp_var (bswap_type, "bswapdst");
1213               add_referenced_var (bswap_tmp);
1214               bswap_tmp = make_ssa_name (bswap_tmp, NULL);
1215               convert_stmt = gimple_build_assign_with_ops (
1216                                CONVERT_EXPR, gimple_assign_lhs (stmt), bswap_tmp, NULL);
1217               gsi_insert_after (&gsi, convert_stmt, GSI_SAME_STMT);
1218             }
1219
1220           gimple_call_set_lhs (call, bswap_tmp);
1221
1222           if (dump_file)
1223             {
1224               fprintf (dump_file, "%d bit bswap implementation found at: ",
1225                        (int)type_size);
1226               print_gimple_stmt (dump_file, stmt, 0, 0);
1227             }
1228
1229           gsi_insert_after (&gsi, call, GSI_SAME_STMT);
1230           gsi_remove (&gsi, true);
1231         }
1232     }
1233
1234   return (changed ? TODO_dump_func | TODO_update_ssa | TODO_verify_ssa
1235           | TODO_verify_stmts : 0);
1236 }
1237
1238 static bool
1239 gate_optimize_bswap (void)
1240 {
1241   return flag_expensive_optimizations && optimize;
1242 }
1243
1244 struct gimple_opt_pass pass_optimize_bswap =
1245 {
1246  {
1247   GIMPLE_PASS,
1248   "bswap",                              /* name */
1249   gate_optimize_bswap,                  /* gate */
1250   execute_optimize_bswap,               /* execute */
1251   NULL,                                 /* sub */
1252   NULL,                                 /* next */
1253   0,                                    /* static_pass_number */
1254   TV_NONE,                              /* tv_id */
1255   PROP_ssa,                             /* properties_required */
1256   0,                                    /* properties_provided */
1257   0,                                    /* properties_destroyed */
1258   0,                                    /* todo_flags_start */
1259   0                                     /* todo_flags_finish */
1260  }
1261 };
1262
1263 /* Process a single gimple statement STMT, which has a MULT_EXPR as
1264    its rhs, and try to convert it into a WIDEN_MULT_EXPR.  The return
1265    value is true iff we converted the statement.  */
1266
1267 static bool
1268 convert_mult_to_widen (gimple stmt)
1269 {
1270   gimple rhs1_stmt = NULL, rhs2_stmt = NULL;
1271   tree type1 = NULL, type2 = NULL;
1272   tree rhs1, rhs2, rhs1_convop = NULL, rhs2_convop = NULL;
1273   enum tree_code rhs1_code, rhs2_code;
1274   tree type;
1275
1276   type = TREE_TYPE (gimple_assign_lhs (stmt));
1277
1278   if (TREE_CODE (type) != INTEGER_TYPE)
1279     return false;
1280
1281   rhs1 = gimple_assign_rhs1 (stmt);
1282   rhs2 = gimple_assign_rhs2 (stmt);
1283
1284   if (TREE_CODE (rhs1) == SSA_NAME)
1285     {
1286       rhs1_stmt = SSA_NAME_DEF_STMT (rhs1);
1287       if (!is_gimple_assign (rhs1_stmt))
1288         return false;
1289       rhs1_code = gimple_assign_rhs_code (rhs1_stmt);
1290       if (!CONVERT_EXPR_CODE_P (rhs1_code))
1291         return false;
1292       rhs1_convop = gimple_assign_rhs1 (rhs1_stmt);
1293       type1 = TREE_TYPE (rhs1_convop);
1294       if (TYPE_PRECISION (type1) * 2 != TYPE_PRECISION (type))
1295         return false;
1296     }
1297   else if (TREE_CODE (rhs1) != INTEGER_CST)
1298     return false;
1299
1300   if (TREE_CODE (rhs2) == SSA_NAME)
1301     {
1302       rhs2_stmt = SSA_NAME_DEF_STMT (rhs2);
1303       if (!is_gimple_assign (rhs2_stmt))
1304         return false;
1305       rhs2_code = gimple_assign_rhs_code (rhs2_stmt);
1306       if (!CONVERT_EXPR_CODE_P (rhs2_code))
1307         return false;
1308       rhs2_convop = gimple_assign_rhs1 (rhs2_stmt);
1309       type2 = TREE_TYPE (rhs2_convop);
1310       if (TYPE_PRECISION (type2) * 2 != TYPE_PRECISION (type))
1311         return false;
1312     }
1313   else if (TREE_CODE (rhs2) != INTEGER_CST)
1314     return false;
1315
1316   if (rhs1_stmt == NULL && rhs2_stmt == NULL)
1317     return false;
1318
1319   /* Verify that the machine can perform a widening multiply in this
1320      mode/signedness combination, otherwise this transformation is
1321      likely to pessimize code.  */
1322   if ((rhs1_stmt == NULL || TYPE_UNSIGNED (type1))
1323       && (rhs2_stmt == NULL || TYPE_UNSIGNED (type2))
1324       && (optab_handler (umul_widen_optab, TYPE_MODE (type))
1325           == CODE_FOR_nothing))
1326     return false;
1327   else if ((rhs1_stmt == NULL || !TYPE_UNSIGNED (type1))
1328            && (rhs2_stmt == NULL || !TYPE_UNSIGNED (type2))
1329            && (optab_handler (smul_widen_optab, TYPE_MODE (type))
1330                == CODE_FOR_nothing))
1331     return false;
1332   else if (rhs1_stmt != NULL && rhs2_stmt != NULL
1333            && (TYPE_UNSIGNED (type1) != TYPE_UNSIGNED (type2))
1334            && (optab_handler (usmul_widen_optab, TYPE_MODE (type))
1335                == CODE_FOR_nothing))
1336     return false;
1337
1338   if ((rhs1_stmt == NULL && !int_fits_type_p (rhs1, type2))
1339       || (rhs2_stmt == NULL && !int_fits_type_p (rhs2, type1)))
1340     return false;
1341
1342   if (rhs1_stmt == NULL)
1343     gimple_assign_set_rhs1 (stmt, fold_convert (type2, rhs1));
1344   else
1345     gimple_assign_set_rhs1 (stmt, rhs1_convop);
1346   if (rhs2_stmt == NULL)
1347     gimple_assign_set_rhs2 (stmt, fold_convert (type1, rhs2));
1348   else
1349     gimple_assign_set_rhs2 (stmt, rhs2_convop);
1350   gimple_assign_set_rhs_code (stmt, WIDEN_MULT_EXPR);
1351   update_stmt (stmt);
1352   return true;
1353 }
1354
1355 /* Process a single gimple statement STMT, which is found at the
1356    iterator GSI and has a either a PLUS_EXPR or a MINUS_EXPR as its
1357    rhs (given by CODE), and try to convert it into a
1358    WIDEN_MULT_PLUS_EXPR or a WIDEN_MULT_MINUS_EXPR.  The return value
1359    is true iff we converted the statement.  */
1360
1361 static bool
1362 convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple stmt,
1363                             enum tree_code code)
1364 {
1365   gimple rhs1_stmt = NULL, rhs2_stmt = NULL;
1366   tree type;
1367   tree lhs, rhs1, rhs2, mult_rhs1, mult_rhs2, add_rhs;
1368   enum tree_code rhs1_code = ERROR_MARK, rhs2_code = ERROR_MARK;
1369   optab this_optab;
1370   enum tree_code wmult_code;
1371
1372   lhs = gimple_assign_lhs (stmt);
1373   type = TREE_TYPE (lhs);
1374   if (TREE_CODE (type) != INTEGER_TYPE)
1375     return false;
1376
1377   if (code == MINUS_EXPR)
1378     wmult_code = WIDEN_MULT_MINUS_EXPR;
1379   else
1380     wmult_code = WIDEN_MULT_PLUS_EXPR;
1381
1382   /* Verify that the machine can perform a widening multiply
1383      accumulate in this mode/signedness combination, otherwise
1384      this transformation is likely to pessimize code.  */
1385   this_optab = optab_for_tree_code (wmult_code, type, optab_default);
1386   if (optab_handler (this_optab, TYPE_MODE (type)) == CODE_FOR_nothing)
1387     return false;
1388
1389   rhs1 = gimple_assign_rhs1 (stmt);
1390   rhs2 = gimple_assign_rhs2 (stmt);
1391
1392   if (TREE_CODE (rhs1) == SSA_NAME)
1393     {
1394       rhs1_stmt = SSA_NAME_DEF_STMT (rhs1);
1395       if (is_gimple_assign (rhs1_stmt))
1396         rhs1_code = gimple_assign_rhs_code (rhs1_stmt);
1397     }
1398   else
1399     return false;
1400
1401   if (TREE_CODE (rhs2) == SSA_NAME)
1402     {
1403       rhs2_stmt = SSA_NAME_DEF_STMT (rhs2);
1404       if (is_gimple_assign (rhs2_stmt))
1405         rhs2_code = gimple_assign_rhs_code (rhs2_stmt);
1406     }
1407   else
1408     return false;
1409
1410   if (rhs1_code == MULT_EXPR)
1411     {
1412       if (!convert_mult_to_widen (rhs1_stmt))
1413         return false;
1414       rhs1_code = gimple_assign_rhs_code (rhs1_stmt);
1415     }
1416   if (rhs2_code == MULT_EXPR)
1417     {
1418       if (!convert_mult_to_widen (rhs2_stmt))
1419         return false;
1420       rhs2_code = gimple_assign_rhs_code (rhs2_stmt);
1421     }
1422   
1423   if (code == PLUS_EXPR && rhs1_code == WIDEN_MULT_EXPR)
1424     {
1425       mult_rhs1 = gimple_assign_rhs1 (rhs1_stmt);
1426       mult_rhs2 = gimple_assign_rhs2 (rhs1_stmt);
1427       add_rhs = rhs2;
1428     }
1429   else if (rhs2_code == WIDEN_MULT_EXPR)
1430     {
1431       mult_rhs1 = gimple_assign_rhs1 (rhs2_stmt);
1432       mult_rhs2 = gimple_assign_rhs2 (rhs2_stmt);
1433       add_rhs = rhs1;
1434     }
1435   else
1436     return false;
1437
1438   /* ??? May need some type verification here?  */
1439
1440   gimple_assign_set_rhs_with_ops_1 (gsi, wmult_code, mult_rhs1, mult_rhs2,
1441                                     add_rhs);
1442   update_stmt (gsi_stmt (*gsi));
1443   return true;
1444 }
1445
1446 /* Find integer multiplications where the operands are extended from
1447    smaller types, and replace the MULT_EXPR with a WIDEN_MULT_EXPR
1448    where appropriate.  */
1449
1450 static unsigned int
1451 execute_optimize_widening_mul (void)
1452 {
1453   bool changed = false;
1454   basic_block bb;
1455
1456   FOR_EACH_BB (bb)
1457     {
1458       gimple_stmt_iterator gsi;
1459
1460       for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1461         {
1462           gimple stmt = gsi_stmt (gsi);
1463           enum tree_code code;
1464
1465           if (!is_gimple_assign (stmt))
1466             continue;
1467
1468           code = gimple_assign_rhs_code (stmt);
1469           if (code == MULT_EXPR)
1470             changed |= convert_mult_to_widen (stmt);
1471           else if (code == PLUS_EXPR || code == MINUS_EXPR)
1472             changed |= convert_plusminus_to_widen (&gsi, stmt, code);
1473         }
1474     }
1475
1476   return (changed ? TODO_dump_func | TODO_update_ssa | TODO_verify_ssa
1477           | TODO_verify_stmts : 0);
1478 }
1479
1480 static bool
1481 gate_optimize_widening_mul (void)
1482 {
1483   return flag_expensive_optimizations && optimize;
1484 }
1485
1486 struct gimple_opt_pass pass_optimize_widening_mul =
1487 {
1488  {
1489   GIMPLE_PASS,
1490   "widening_mul",                       /* name */
1491   gate_optimize_widening_mul,           /* gate */
1492   execute_optimize_widening_mul,        /* execute */
1493   NULL,                                 /* sub */
1494   NULL,                                 /* next */
1495   0,                                    /* static_pass_number */
1496   TV_NONE,                              /* tv_id */
1497   PROP_ssa,                             /* properties_required */
1498   0,                                    /* properties_provided */
1499   0,                                    /* properties_destroyed */
1500   0,                                    /* todo_flags_start */
1501   0                                     /* todo_flags_finish */
1502  }
1503 };