OSDN Git Service

* g++.dg/torture/type-generic-1.C: Add -mieee for sh.
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-math-opts.c
1 /* Global, SSA-based optimizations using mathematical identities.
2    Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
3    
4 This file is part of GCC.
5    
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3, or (at your option) any
9 later version.
10    
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15    
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19
20 /* Currently, the only mini-pass in this file tries to CSE reciprocal
21    operations.  These are common in sequences such as this one:
22
23         modulus = sqrt(x*x + y*y + z*z);
24         x = x / modulus;
25         y = y / modulus;
26         z = z / modulus;
27
28    that can be optimized to
29
30         modulus = sqrt(x*x + y*y + z*z);
31         rmodulus = 1.0 / modulus;
32         x = x * rmodulus;
33         y = y * rmodulus;
34         z = z * rmodulus;
35
36    We do this for loop invariant divisors, and with this pass whenever
37    we notice that a division has the same divisor multiple times.
38
39    Of course, like in PRE, we don't insert a division if a dominator
40    already has one.  However, this cannot be done as an extension of
41    PRE for several reasons.
42
43    First of all, with some experiments it was found out that the
44    transformation is not always useful if there are only two divisions
45    hy the same divisor.  This is probably because modern processors
46    can pipeline the divisions; on older, in-order processors it should
47    still be effective to optimize two divisions by the same number.
48    We make this a param, and it shall be called N in the remainder of
49    this comment.
50
51    Second, if trapping math is active, we have less freedom on where
52    to insert divisions: we can only do so in basic blocks that already
53    contain one.  (If divisions don't trap, instead, we can insert
54    divisions elsewhere, which will be in blocks that are common dominators
55    of those that have the division).
56
57    We really don't want to compute the reciprocal unless a division will
58    be found.  To do this, we won't insert the division in a basic block
59    that has less than N divisions *post-dominating* it.
60
61    The algorithm constructs a subset of the dominator tree, holding the
62    blocks containing the divisions and the common dominators to them,
63    and walk it twice.  The first walk is in post-order, and it annotates
64    each block with the number of divisions that post-dominate it: this
65    gives information on where divisions can be inserted profitably.
66    The second walk is in pre-order, and it inserts divisions as explained
67    above, and replaces divisions by multiplications.
68
69    In the best case, the cost of the pass is O(n_statements).  In the
70    worst-case, the cost is due to creating the dominator tree subset,
71    with a cost of O(n_basic_blocks ^ 2); however this can only happen
72    for n_statements / n_basic_blocks statements.  So, the amortized cost
73    of creating the dominator tree subset is O(n_basic_blocks) and the
74    worst-case cost of the pass is O(n_statements * n_basic_blocks).
75
76    More practically, the cost will be small because there are few
77    divisions, and they tend to be in the same basic block, so insert_bb
78    is called very few times.
79
80    If we did this using domwalk.c, an efficient implementation would have
81    to work on all the variables in a single pass, because we could not
82    work on just a subset of the dominator tree, as we do now, and the
83    cost would also be something like O(n_statements * n_basic_blocks).
84    The data structures would be more complex in order to work on all the
85    variables in a single pass.  */
86
87 #include "config.h"
88 #include "system.h"
89 #include "coretypes.h"
90 #include "tm.h"
91 #include "flags.h"
92 #include "tree.h"
93 #include "tree-flow.h"
94 #include "real.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
101
102 /* This structure represents one basic block that either computes a
103    division, or is a common dominator for basic block that compute a
104    division.  */
105 struct occurrence {
106   /* The basic block represented by this structure.  */
107   basic_block bb;
108
109   /* If non-NULL, the SSA_NAME holding the definition for a reciprocal
110      inserted in BB.  */
111   tree recip_def;
112
113   /* If non-NULL, the GIMPLE_MODIFY_STMT for a reciprocal computation that
114      was inserted in BB.  */
115   tree recip_def_stmt;
116
117   /* Pointer to a list of "struct occurrence"s for blocks dominated
118      by BB.  */
119   struct occurrence *children;
120
121   /* Pointer to the next "struct occurrence"s in the list of blocks
122      sharing a common dominator.  */
123   struct occurrence *next;
124
125   /* The number of divisions that are in BB before compute_merit.  The
126      number of divisions that are in BB or post-dominate it after
127      compute_merit.  */
128   int num_divisions;
129
130   /* True if the basic block has a division, false if it is a common
131      dominator for basic blocks that do.  If it is false and trapping
132      math is active, BB is not a candidate for inserting a reciprocal.  */
133   bool bb_has_division;
134 };
135
136
137 /* The instance of "struct occurrence" representing the highest
138    interesting block in the dominator tree.  */
139 static struct occurrence *occ_head;
140
141 /* Allocation pool for getting instances of "struct occurrence".  */
142 static alloc_pool occ_pool;
143
144
145
146 /* Allocate and return a new struct occurrence for basic block BB, and
147    whose children list is headed by CHILDREN.  */
148 static struct occurrence *
149 occ_new (basic_block bb, struct occurrence *children)
150 {
151   struct occurrence *occ;
152
153   bb->aux = occ = (struct occurrence *) pool_alloc (occ_pool);
154   memset (occ, 0, sizeof (struct occurrence));
155
156   occ->bb = bb;
157   occ->children = children;
158   return occ;
159 }
160
161
162 /* Insert NEW_OCC into our subset of the dominator tree.  P_HEAD points to a
163    list of "struct occurrence"s, one per basic block, having IDOM as
164    their common dominator.
165
166    We try to insert NEW_OCC as deep as possible in the tree, and we also
167    insert any other block that is a common dominator for BB and one
168    block already in the tree.  */
169
170 static void
171 insert_bb (struct occurrence *new_occ, basic_block idom,
172            struct occurrence **p_head)
173 {
174   struct occurrence *occ, **p_occ;
175
176   for (p_occ = p_head; (occ = *p_occ) != NULL; )
177     {
178       basic_block bb = new_occ->bb, occ_bb = occ->bb;
179       basic_block dom = nearest_common_dominator (CDI_DOMINATORS, occ_bb, bb);
180       if (dom == bb)
181         {
182           /* BB dominates OCC_BB.  OCC becomes NEW_OCC's child: remove OCC
183              from its list.  */
184           *p_occ = occ->next;
185           occ->next = new_occ->children;
186           new_occ->children = occ;
187
188           /* Try the next block (it may as well be dominated by BB).  */
189         }
190
191       else if (dom == occ_bb)
192         {
193           /* OCC_BB dominates BB.  Tail recurse to look deeper.  */
194           insert_bb (new_occ, dom, &occ->children);
195           return;
196         }
197
198       else if (dom != idom)
199         {
200           gcc_assert (!dom->aux);
201
202           /* There is a dominator between IDOM and BB, add it and make
203              two children out of NEW_OCC and OCC.  First, remove OCC from
204              its list.  */
205           *p_occ = occ->next;
206           new_occ->next = occ;
207           occ->next = NULL;
208
209           /* None of the previous blocks has DOM as a dominator: if we tail
210              recursed, we would reexamine them uselessly. Just switch BB with
211              DOM, and go on looking for blocks dominated by DOM.  */
212           new_occ = occ_new (dom, new_occ);
213         }
214
215       else
216         {
217           /* Nothing special, go on with the next element.  */
218           p_occ = &occ->next;
219         }
220     }
221
222   /* No place was found as a child of IDOM.  Make BB a sibling of IDOM.  */
223   new_occ->next = *p_head;
224   *p_head = new_occ;
225 }
226
227 /* Register that we found a division in BB.  */
228
229 static inline void
230 register_division_in (basic_block bb)
231 {
232   struct occurrence *occ;
233
234   occ = (struct occurrence *) bb->aux;
235   if (!occ)
236     {
237       occ = occ_new (bb, NULL);
238       insert_bb (occ, ENTRY_BLOCK_PTR, &occ_head);
239     }
240
241   occ->bb_has_division = true;
242   occ->num_divisions++;
243 }
244
245
246 /* Compute the number of divisions that postdominate each block in OCC and
247    its children.  */
248
249 static void
250 compute_merit (struct occurrence *occ)
251 {
252   struct occurrence *occ_child;
253   basic_block dom = occ->bb;
254
255   for (occ_child = occ->children; occ_child; occ_child = occ_child->next)
256     {
257       basic_block bb;
258       if (occ_child->children)
259         compute_merit (occ_child);
260
261       if (flag_exceptions)
262         bb = single_noncomplex_succ (dom);
263       else
264         bb = dom;
265
266       if (dominated_by_p (CDI_POST_DOMINATORS, bb, occ_child->bb))
267         occ->num_divisions += occ_child->num_divisions;
268     }
269 }
270
271
272 /* Return whether USE_STMT is a floating-point division by DEF.  */
273 static inline bool
274 is_division_by (tree use_stmt, tree def)
275 {
276   return TREE_CODE (use_stmt) == GIMPLE_MODIFY_STMT
277          && TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 1)) == RDIV_EXPR
278          && TREE_OPERAND (GIMPLE_STMT_OPERAND (use_stmt, 1), 1) == def;
279 }
280
281 /* Walk the subset of the dominator tree rooted at OCC, setting the
282    RECIP_DEF field to a definition of 1.0 / DEF that can be used in
283    the given basic block.  The field may be left NULL, of course,
284    if it is not possible or profitable to do the optimization.
285
286    DEF_BSI is an iterator pointing at the statement defining DEF.
287    If RECIP_DEF is set, a dominator already has a computation that can
288    be used.  */
289
290 static void
291 insert_reciprocals (block_stmt_iterator *def_bsi, struct occurrence *occ,
292                     tree def, tree recip_def, int threshold)
293 {
294   tree type, new_stmt;
295   block_stmt_iterator bsi;
296   struct occurrence *occ_child;
297
298   if (!recip_def
299       && (occ->bb_has_division || !flag_trapping_math)
300       && occ->num_divisions >= threshold)
301     {
302       /* Make a variable with the replacement and substitute it.  */
303       type = TREE_TYPE (def);
304       recip_def = make_rename_temp (type, "reciptmp");
305       new_stmt = build_gimple_modify_stmt (recip_def,
306                                            fold_build2 (RDIV_EXPR, type,
307                                                         build_one_cst (type),
308                                                         def));
309   
310   
311       if (occ->bb_has_division)
312         {
313           /* Case 1: insert before an existing division.  */
314           bsi = bsi_after_labels (occ->bb);
315           while (!bsi_end_p (bsi) && !is_division_by (bsi_stmt (bsi), def))
316             bsi_next (&bsi);
317
318           bsi_insert_before (&bsi, new_stmt, BSI_SAME_STMT);
319         }
320       else if (def_bsi && occ->bb == def_bsi->bb)
321         {
322           /* Case 2: insert right after the definition.  Note that this will
323              never happen if the definition statement can throw, because in
324              that case the sole successor of the statement's basic block will
325              dominate all the uses as well.  */
326           bsi_insert_after (def_bsi, new_stmt, BSI_NEW_STMT);
327         }
328       else
329         {
330           /* Case 3: insert in a basic block not containing defs/uses.  */
331           bsi = bsi_after_labels (occ->bb);
332           bsi_insert_before (&bsi, new_stmt, BSI_SAME_STMT);
333         }
334
335       occ->recip_def_stmt = new_stmt;
336     }
337
338   occ->recip_def = recip_def;
339   for (occ_child = occ->children; occ_child; occ_child = occ_child->next)
340     insert_reciprocals (def_bsi, occ_child, def, recip_def, threshold);
341 }
342
343
344 /* Replace the division at USE_P with a multiplication by the reciprocal, if
345    possible.  */
346
347 static inline void
348 replace_reciprocal (use_operand_p use_p)
349 {
350   tree use_stmt = USE_STMT (use_p);
351   basic_block bb = bb_for_stmt (use_stmt);
352   struct occurrence *occ = (struct occurrence *) bb->aux;
353
354   if (occ->recip_def && use_stmt != occ->recip_def_stmt)
355     {
356       TREE_SET_CODE (GIMPLE_STMT_OPERAND (use_stmt, 1), MULT_EXPR);
357       SET_USE (use_p, occ->recip_def);
358       fold_stmt_inplace (use_stmt);
359       update_stmt (use_stmt);
360     }
361 }
362
363
364 /* Free OCC and return one more "struct occurrence" to be freed.  */
365
366 static struct occurrence *
367 free_bb (struct occurrence *occ)
368 {
369   struct occurrence *child, *next;
370
371   /* First get the two pointers hanging off OCC.  */
372   next = occ->next;
373   child = occ->children;
374   occ->bb->aux = NULL;
375   pool_free (occ_pool, occ);
376
377   /* Now ensure that we don't recurse unless it is necessary.  */
378   if (!child)
379     return next;
380   else
381     {
382       while (next)
383         next = free_bb (next);
384
385       return child;
386     }
387 }
388
389
390 /* Look for floating-point divisions among DEF's uses, and try to
391    replace them by multiplications with the reciprocal.  Add
392    as many statements computing the reciprocal as needed.
393
394    DEF must be a GIMPLE register of a floating-point type.  */
395
396 static void
397 execute_cse_reciprocals_1 (block_stmt_iterator *def_bsi, tree def)
398 {
399   use_operand_p use_p;
400   imm_use_iterator use_iter;
401   struct occurrence *occ;
402   int count = 0, threshold;
403
404   gcc_assert (FLOAT_TYPE_P (TREE_TYPE (def)) && is_gimple_reg (def));
405
406   FOR_EACH_IMM_USE_FAST (use_p, use_iter, def)
407     {
408       tree use_stmt = USE_STMT (use_p);
409       if (is_division_by (use_stmt, def))
410         {
411           register_division_in (bb_for_stmt (use_stmt));
412           count++;
413         }
414     }
415   
416   /* Do the expensive part only if we can hope to optimize something.  */
417   threshold = targetm.min_divisions_for_recip_mul (TYPE_MODE (TREE_TYPE (def)));
418   if (count >= threshold)
419     {
420       tree use_stmt;
421       for (occ = occ_head; occ; occ = occ->next)
422         {
423           compute_merit (occ);
424           insert_reciprocals (def_bsi, occ, def, NULL, threshold);
425         }
426
427       FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, def)
428         {
429           if (is_division_by (use_stmt, def))
430             {
431               FOR_EACH_IMM_USE_ON_STMT (use_p, use_iter)
432                 replace_reciprocal (use_p);
433             }
434         }
435     }
436
437   for (occ = occ_head; occ; )
438     occ = free_bb (occ);
439
440   occ_head = NULL;
441 }
442
443 static bool
444 gate_cse_reciprocals (void)
445 {
446   return optimize && !optimize_size && flag_unsafe_math_optimizations;
447 }
448
449 /* Go through all the floating-point SSA_NAMEs, and call
450    execute_cse_reciprocals_1 on each of them.  */
451 static unsigned int
452 execute_cse_reciprocals (void)
453 {
454   basic_block bb;
455   tree arg;
456
457   occ_pool = create_alloc_pool ("dominators for recip",
458                                 sizeof (struct occurrence),
459                                 n_basic_blocks / 3 + 1);
460
461   calculate_dominance_info (CDI_DOMINATORS);
462   calculate_dominance_info (CDI_POST_DOMINATORS);
463
464 #ifdef ENABLE_CHECKING
465   FOR_EACH_BB (bb)
466     gcc_assert (!bb->aux);
467 #endif
468
469   for (arg = DECL_ARGUMENTS (cfun->decl); arg; arg = TREE_CHAIN (arg))
470     if (gimple_default_def (cfun, arg)
471         && FLOAT_TYPE_P (TREE_TYPE (arg))
472         && is_gimple_reg (arg))
473       execute_cse_reciprocals_1 (NULL, gimple_default_def (cfun, arg));
474
475   FOR_EACH_BB (bb)
476     {
477       block_stmt_iterator bsi;
478       tree phi, def;
479
480       for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
481         {
482           def = PHI_RESULT (phi);
483           if (FLOAT_TYPE_P (TREE_TYPE (def))
484               && is_gimple_reg (def))
485             execute_cse_reciprocals_1 (NULL, def);
486         }
487
488       for (bsi = bsi_after_labels (bb); !bsi_end_p (bsi); bsi_next (&bsi))
489         {
490           tree stmt = bsi_stmt (bsi);
491
492           if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
493               && (def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF)) != NULL
494               && FLOAT_TYPE_P (TREE_TYPE (def))
495               && TREE_CODE (def) == SSA_NAME)
496             execute_cse_reciprocals_1 (&bsi, def);
497         }
498
499       /* Scan for a/func(b) and convert it to reciprocal a*rfunc(b).  */
500       for (bsi = bsi_after_labels (bb); !bsi_end_p (bsi); bsi_next (&bsi))
501         {
502           tree stmt = bsi_stmt (bsi);
503           tree fndecl;
504
505           if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
506               && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == RDIV_EXPR)
507             {
508               tree arg1 = TREE_OPERAND (GIMPLE_STMT_OPERAND (stmt, 1), 1);
509               tree stmt1;
510
511               if (TREE_CODE (arg1) != SSA_NAME)
512                 continue;
513
514               stmt1 = SSA_NAME_DEF_STMT (arg1);
515
516               if (TREE_CODE (stmt1) == GIMPLE_MODIFY_STMT
517                   && TREE_CODE (GIMPLE_STMT_OPERAND (stmt1, 1)) == CALL_EXPR
518                   && (fndecl
519                       = get_callee_fndecl (GIMPLE_STMT_OPERAND (stmt1, 1)))
520                   && (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
521                       || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD))
522                 {
523                   enum built_in_function code;
524                   bool md_code;
525                   tree arg10;
526                   tree tmp;
527
528                   code = DECL_FUNCTION_CODE (fndecl);
529                   md_code = DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD;
530
531                   fndecl = targetm.builtin_reciprocal (code, md_code, false);
532                   if (!fndecl)
533                     continue;
534
535                   arg10 = CALL_EXPR_ARG (GIMPLE_STMT_OPERAND (stmt1, 1), 0);
536                   tmp = build_call_expr (fndecl, 1, arg10);
537                   GIMPLE_STMT_OPERAND (stmt1, 1) = tmp;
538                   update_stmt (stmt1);
539
540                   TREE_SET_CODE (GIMPLE_STMT_OPERAND (stmt, 1), MULT_EXPR);
541                   fold_stmt_inplace (stmt);
542                   update_stmt (stmt);
543                 }
544             }
545         }
546     }
547
548   free_dominance_info (CDI_DOMINATORS);
549   free_dominance_info (CDI_POST_DOMINATORS);
550   free_alloc_pool (occ_pool);
551   return 0;
552 }
553
554 struct tree_opt_pass pass_cse_reciprocals =
555 {
556   "recip",                              /* name */
557   gate_cse_reciprocals,                 /* gate */
558   execute_cse_reciprocals,              /* execute */
559   NULL,                                 /* sub */
560   NULL,                                 /* next */
561   0,                                    /* static_pass_number */
562   0,                                    /* tv_id */
563   PROP_ssa,                             /* properties_required */
564   0,                                    /* properties_provided */
565   0,                                    /* properties_destroyed */
566   0,                                    /* todo_flags_start */
567   TODO_dump_func | TODO_update_ssa | TODO_verify_ssa
568     | TODO_verify_stmts,                /* todo_flags_finish */
569   0                                     /* letter */
570 };
571
572 /* Records an occurrence at statement USE_STMT in the vector of trees
573    STMTS if it is dominated by *TOP_BB or dominates it or this basic block
574    is not yet initialized.  Returns true if the occurrence was pushed on
575    the vector.  Adjusts *TOP_BB to be the basic block dominating all
576    statements in the vector.  */
577
578 static bool
579 maybe_record_sincos (VEC(tree, heap) **stmts,
580                      basic_block *top_bb, tree use_stmt)
581 {
582   basic_block use_bb = bb_for_stmt (use_stmt);
583   if (*top_bb
584       && (*top_bb == use_bb
585           || dominated_by_p (CDI_DOMINATORS, use_bb, *top_bb)))
586     VEC_safe_push (tree, heap, *stmts, use_stmt);
587   else if (!*top_bb
588            || dominated_by_p (CDI_DOMINATORS, *top_bb, use_bb))
589     {
590       VEC_safe_push (tree, heap, *stmts, use_stmt);
591       *top_bb = use_bb;
592     }
593   else
594     return false;
595
596   return true;
597 }
598
599 /* Look for sin, cos and cexpi calls with the same argument NAME and
600    create a single call to cexpi CSEing the result in this case.
601    We first walk over all immediate uses of the argument collecting
602    statements that we can CSE in a vector and in a second pass replace
603    the statement rhs with a REALPART or IMAGPART expression on the
604    result of the cexpi call we insert before the use statement that
605    dominates all other candidates.  */
606
607 static void
608 execute_cse_sincos_1 (tree name)
609 {
610   block_stmt_iterator bsi;
611   imm_use_iterator use_iter;
612   tree def_stmt, use_stmt, fndecl, res, call, stmt, type;
613   int seen_cos = 0, seen_sin = 0, seen_cexpi = 0;
614   VEC(tree, heap) *stmts = NULL;
615   basic_block top_bb = NULL;
616   int i;
617
618   type = TREE_TYPE (name);
619   FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, name)
620     {
621       if (TREE_CODE (use_stmt) != GIMPLE_MODIFY_STMT
622           || TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 1)) != CALL_EXPR
623           || !(fndecl = get_callee_fndecl (GIMPLE_STMT_OPERAND (use_stmt, 1)))
624           || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
625         continue;
626
627       switch (DECL_FUNCTION_CODE (fndecl))
628         {
629         CASE_FLT_FN (BUILT_IN_COS):
630           seen_cos |= maybe_record_sincos (&stmts, &top_bb, use_stmt) ? 1 : 0;
631           break;
632
633         CASE_FLT_FN (BUILT_IN_SIN):
634           seen_sin |= maybe_record_sincos (&stmts, &top_bb, use_stmt) ? 1 : 0;
635           break;
636
637         CASE_FLT_FN (BUILT_IN_CEXPI):
638           seen_cexpi |= maybe_record_sincos (&stmts, &top_bb, use_stmt) ? 1 : 0;
639           break;
640
641         default:;
642         }
643     }
644
645   if (seen_cos + seen_sin + seen_cexpi <= 1)
646     {
647       VEC_free(tree, heap, stmts);
648       return;
649     }
650
651   /* Simply insert cexpi at the beginning of top_bb but not earlier than
652      the name def statement.  */
653   fndecl = mathfn_built_in (type, BUILT_IN_CEXPI);
654   if (!fndecl)
655     return;
656   res = make_rename_temp (TREE_TYPE (TREE_TYPE (fndecl)), "sincostmp");
657   call = build_call_expr (fndecl, 1, name);
658   stmt = build_gimple_modify_stmt (res, call);
659   def_stmt = SSA_NAME_DEF_STMT (name);
660   if (bb_for_stmt (def_stmt) == top_bb
661       && TREE_CODE (def_stmt) == GIMPLE_MODIFY_STMT)
662     {
663       bsi = bsi_for_stmt (def_stmt);
664       bsi_insert_after (&bsi, stmt, BSI_SAME_STMT);
665     }
666   else
667     {
668       bsi = bsi_after_labels (top_bb);
669       bsi_insert_before (&bsi, stmt, BSI_SAME_STMT);
670     }
671   update_stmt (stmt);
672
673   /* And adjust the recorded old call sites.  */
674   for (i = 0; VEC_iterate(tree, stmts, i, use_stmt); ++i)
675     {
676       fndecl = get_callee_fndecl (GIMPLE_STMT_OPERAND (use_stmt, 1));
677       switch (DECL_FUNCTION_CODE (fndecl))
678         {
679         CASE_FLT_FN (BUILT_IN_COS):
680           GIMPLE_STMT_OPERAND (use_stmt, 1) = fold_build1 (REALPART_EXPR,
681                                                            type, res);
682           break;
683
684         CASE_FLT_FN (BUILT_IN_SIN):
685           GIMPLE_STMT_OPERAND (use_stmt, 1) = fold_build1 (IMAGPART_EXPR,
686                                                            type, res);
687           break;
688
689         CASE_FLT_FN (BUILT_IN_CEXPI):
690           GIMPLE_STMT_OPERAND (use_stmt, 1) = res;
691           break;
692
693         default:;
694           gcc_unreachable ();
695         }
696
697         update_stmt (use_stmt);
698     }
699
700   VEC_free(tree, heap, stmts);
701 }
702
703 /* Go through all calls to sin, cos and cexpi and call execute_cse_sincos_1
704    on the SSA_NAME argument of each of them.  */
705
706 static unsigned int
707 execute_cse_sincos (void)
708 {
709   basic_block bb;
710
711   calculate_dominance_info (CDI_DOMINATORS);
712
713   FOR_EACH_BB (bb)
714     {
715       block_stmt_iterator bsi;
716
717       for (bsi = bsi_after_labels (bb); !bsi_end_p (bsi); bsi_next (&bsi))
718         {
719           tree stmt = bsi_stmt (bsi);
720           tree fndecl;
721
722           if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
723               && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == CALL_EXPR
724               && (fndecl = get_callee_fndecl (GIMPLE_STMT_OPERAND (stmt, 1)))
725               && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
726             {
727               tree arg;
728
729               switch (DECL_FUNCTION_CODE (fndecl))
730                 {
731                 CASE_FLT_FN (BUILT_IN_COS):
732                 CASE_FLT_FN (BUILT_IN_SIN):
733                 CASE_FLT_FN (BUILT_IN_CEXPI):
734                   arg = GIMPLE_STMT_OPERAND (stmt, 1);
735                   arg = CALL_EXPR_ARG (arg, 0);
736                   if (TREE_CODE (arg) == SSA_NAME)
737                     execute_cse_sincos_1 (arg);
738                   break;
739
740                 default:;
741                 }
742             }
743         }
744     }
745
746   free_dominance_info (CDI_DOMINATORS);
747   return 0;
748 }
749
750 static bool
751 gate_cse_sincos (void)
752 {
753   /* Make sure we have either sincos or cexp.  */
754   return (TARGET_HAS_SINCOS
755           || TARGET_C99_FUNCTIONS)
756          && optimize;
757 }
758
759 struct tree_opt_pass pass_cse_sincos =
760 {
761   "sincos",                             /* name */
762   gate_cse_sincos,                      /* gate */
763   execute_cse_sincos,                   /* execute */
764   NULL,                                 /* sub */
765   NULL,                                 /* next */
766   0,                                    /* static_pass_number */
767   0,                                    /* tv_id */
768   PROP_ssa,                             /* properties_required */
769   0,                                    /* properties_provided */
770   0,                                    /* properties_destroyed */
771   0,                                    /* todo_flags_start */
772   TODO_dump_func | TODO_update_ssa | TODO_verify_ssa
773     | TODO_verify_stmts,                /* todo_flags_finish */
774   0                                     /* letter */
775 };
776
777 /* Find all expressions in the form of sqrt(a/b) and
778    convert them to rsqrt(b/a).  */
779
780 static unsigned int
781 execute_convert_to_rsqrt (void)
782 {
783   basic_block bb;
784
785   FOR_EACH_BB (bb)
786     {
787       block_stmt_iterator bsi;
788
789       for (bsi = bsi_after_labels (bb); !bsi_end_p (bsi); bsi_next (&bsi))
790         {
791           tree stmt = bsi_stmt (bsi);
792           tree fndecl;
793
794           if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
795               && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == CALL_EXPR
796               && (fndecl = get_callee_fndecl (GIMPLE_STMT_OPERAND (stmt, 1)))
797               && (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
798                   || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD))
799             {
800               enum built_in_function code;
801               bool md_code;
802               tree arg1;
803               tree stmt1;
804
805               code = DECL_FUNCTION_CODE (fndecl);
806               md_code = DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD;
807
808               fndecl = targetm.builtin_reciprocal (code, md_code, true);
809               if (!fndecl)
810                 continue;
811
812               arg1 = CALL_EXPR_ARG (GIMPLE_STMT_OPERAND (stmt, 1), 0);
813
814               if (TREE_CODE (arg1) != SSA_NAME)
815                 continue;
816
817               stmt1 = SSA_NAME_DEF_STMT (arg1);
818
819               if (TREE_CODE (stmt1) == GIMPLE_MODIFY_STMT
820                   && TREE_CODE (GIMPLE_STMT_OPERAND (stmt1, 1)) == RDIV_EXPR)
821                 {
822                   tree arg10, arg11;
823                   tree tmp;
824
825                   arg10 = TREE_OPERAND (GIMPLE_STMT_OPERAND (stmt1, 1), 0);
826                   arg11 = TREE_OPERAND (GIMPLE_STMT_OPERAND (stmt1, 1), 1);
827
828                   /* Swap operands of RDIV_EXPR.  */
829                   TREE_OPERAND (GIMPLE_STMT_OPERAND (stmt1, 1), 0) = arg11;
830                   TREE_OPERAND (GIMPLE_STMT_OPERAND (stmt1, 1), 1) = arg10;
831                   fold_stmt_inplace (stmt1);
832                   update_stmt (stmt1);
833
834                   tmp = build_call_expr (fndecl, 1, arg1);
835                   GIMPLE_STMT_OPERAND (stmt, 1) = tmp;
836                   update_stmt (stmt);
837                 }
838             }
839         }
840     }
841
842   return 0;
843 }
844
845 static bool
846 gate_convert_to_rsqrt (void)
847 {
848   return flag_unsafe_math_optimizations && optimize;
849 }
850
851 struct tree_opt_pass pass_convert_to_rsqrt =
852 {
853   "rsqrt",                              /* name */
854   gate_convert_to_rsqrt,                /* gate */
855   execute_convert_to_rsqrt,             /* execute */
856   NULL,                                 /* sub */
857   NULL,                                 /* next */
858   0,                                    /* static_pass_number */
859   0,                                    /* tv_id */
860   PROP_ssa,                             /* properties_required */
861   0,                                    /* properties_provided */
862   0,                                    /* properties_destroyed */
863   0,                                    /* todo_flags_start */
864   TODO_dump_func | TODO_update_ssa | TODO_verify_ssa
865     | TODO_verify_stmts,                /* todo_flags_finish */
866   0                                     /* letter */
867 };