OSDN Git Service

2005-07-18 Daniel Berlin <dberlin@dberlin.org>
[pf3gnuchains/gcc-fork.git] / gcc / tree-complex.c
1 /* Lower complex number operations to scalar operations.
2    Copyright (C) 2004, 2005 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 2, 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 COPYING.  If not, write to the Free
18 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301, USA.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "tree.h"
26 #include "rtl.h"
27 #include "real.h"
28 #include "flags.h"
29 #include "tree-flow.h"
30 #include "tree-gimple.h"
31 #include "tree-iterator.h"
32 #include "tree-pass.h"
33 #include "tree-ssa-propagate.h"
34
35
36 /* For each complex ssa name, a lattice value.  We're interested in finding
37    out whether a complex number is degenerate in some way, having only real
38    or only complex parts.  */
39
40 typedef enum
41 {
42   UNINITIALIZED = 0,
43   ONLY_REAL = 1,
44   ONLY_IMAG = 2,
45   VARYING = 3
46 } complex_lattice_t;
47
48 #define PAIR(a, b)  ((a) << 2 | (b))
49
50 DEF_VEC_I(complex_lattice_t);
51 DEF_VEC_ALLOC_I(complex_lattice_t, heap);
52
53 static VEC(complex_lattice_t, heap) *complex_lattice_values;
54
55 /* For each complex variable, a pair of variables for the components exists in
56    the hashtable.  */
57 static htab_t complex_variable_components;
58
59 /* Lookup UID in the complex_variable_components hashtable and return the
60    associated tree.  */
61 static tree 
62 cvc_lookup (unsigned int uid)
63 {
64   struct int_tree_map *h, in;
65   in.uid = uid;
66   h = htab_find_with_hash (complex_variable_components, &in, uid);
67   gcc_assert (h);
68   return h->to;
69 }
70  
71 /* Insert the pair UID, TO into the complex_variable_components hashtable.  */
72
73 static void 
74 cvc_insert (unsigned int uid, tree to)
75
76   struct int_tree_map *h;
77   void **loc;
78
79   h = xmalloc (sizeof (struct int_tree_map));
80   h->uid = uid;
81   h->to = to;
82   loc = htab_find_slot_with_hash (complex_variable_components, h,
83                                   uid, INSERT);
84   *(struct int_tree_map **)  loc = h;
85 }
86
87
88 /* Return true if T is not a zero constant.  In the case of real values,
89    we're only interested in +0.0.  */
90
91 static int
92 some_nonzerop (tree t)
93 {
94   int zerop = false;
95
96   if (TREE_CODE (t) == REAL_CST)
97     zerop = REAL_VALUES_IDENTICAL (TREE_REAL_CST (t), dconst0);
98   else if (TREE_CODE (t) == INTEGER_CST)
99     zerop = integer_zerop (t);
100
101   return !zerop;
102 }
103
104 /* Compute a lattice value from T.  It may be a gimple_val, or, as a 
105    special exception, a COMPLEX_EXPR.  */
106
107 static complex_lattice_t
108 find_lattice_value (tree t)
109 {
110   tree real, imag;
111   int r, i;
112   complex_lattice_t ret;
113
114   switch (TREE_CODE (t))
115     {
116     case SSA_NAME:
117       return VEC_index (complex_lattice_t, complex_lattice_values,
118                         SSA_NAME_VERSION (t));
119
120     case COMPLEX_CST:
121       real = TREE_REALPART (t);
122       imag = TREE_IMAGPART (t);
123       break;
124
125     case COMPLEX_EXPR:
126       real = TREE_OPERAND (t, 0);
127       imag = TREE_OPERAND (t, 1);
128       break;
129
130     default:
131       gcc_unreachable ();
132     }
133
134   r = some_nonzerop (real);
135   i = some_nonzerop (imag);
136   ret = r*ONLY_REAL + i*ONLY_IMAG;
137
138   /* ??? On occasion we could do better than mapping 0+0i to real, but we
139      certainly don't want to leave it UNINITIALIZED, which eventually gets
140      mapped to VARYING.  */
141   if (ret == UNINITIALIZED)
142     ret = ONLY_REAL;
143
144   return ret;
145 }
146
147 /* Determine if LHS is something for which we're interested in seeing
148    simulation results.  */
149
150 static bool
151 is_complex_reg (tree lhs)
152 {
153   return TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE && is_gimple_reg (lhs);
154 }
155
156 /* Mark the incoming parameters to the function as VARYING.  */
157
158 static void
159 init_parameter_lattice_values (void)
160 {
161   tree parm;
162
163   for (parm = DECL_ARGUMENTS (cfun->decl); parm ; parm = TREE_CHAIN (parm))
164     if (is_complex_reg (parm) && var_ann (parm) != NULL)
165       {
166         tree ssa_name = default_def (parm);
167         VEC_replace (complex_lattice_t, complex_lattice_values,
168                      SSA_NAME_VERSION (ssa_name), VARYING);
169       }
170 }
171
172 /* Initialize DONT_SIMULATE_AGAIN for each stmt and phi.  Return false if
173    we found no statements we want to simulate, and thus there's nothing for
174    the entire pass to do.  */
175
176 static bool
177 init_dont_simulate_again (void)
178 {
179   basic_block bb;
180   block_stmt_iterator bsi;
181   tree phi;
182   bool saw_a_complex_op = false;
183
184   FOR_EACH_BB (bb)
185     {
186       for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
187         DONT_SIMULATE_AGAIN (phi) = !is_complex_reg (PHI_RESULT (phi));
188
189       for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
190         {
191           tree orig_stmt, stmt, rhs = NULL;
192           bool dsa;
193
194           orig_stmt = stmt = bsi_stmt (bsi);
195
196           /* Most control-altering statements must be initially 
197              simulated, else we won't cover the entire cfg.  */
198           dsa = !stmt_ends_bb_p (stmt);
199
200           switch (TREE_CODE (stmt))
201             {
202             case RETURN_EXPR:
203               /* We don't care what the lattice value of <retval> is,
204                  since it's never used as an input to another computation.  */
205               dsa = true;
206               stmt = TREE_OPERAND (stmt, 0);
207               if (!stmt || TREE_CODE (stmt) != MODIFY_EXPR)
208                 break;
209               /* FALLTHRU */
210
211             case MODIFY_EXPR:
212               dsa = !is_complex_reg (TREE_OPERAND (stmt, 0));
213               rhs = TREE_OPERAND (stmt, 1);
214               break;
215
216             case COND_EXPR:
217               rhs = TREE_OPERAND (stmt, 0);
218               break;
219
220             default:
221               break;
222             }
223
224           if (rhs)
225             switch (TREE_CODE (rhs))
226               {
227               case EQ_EXPR:
228               case NE_EXPR:
229                 rhs = TREE_OPERAND (rhs, 0);
230                 /* FALLTHRU */
231
232               case PLUS_EXPR:
233               case MINUS_EXPR:
234               case MULT_EXPR:
235               case TRUNC_DIV_EXPR:
236               case CEIL_DIV_EXPR:
237               case FLOOR_DIV_EXPR:
238               case ROUND_DIV_EXPR:
239               case RDIV_EXPR:
240               case NEGATE_EXPR:
241               case CONJ_EXPR:
242                 if (TREE_CODE (TREE_TYPE (rhs)) == COMPLEX_TYPE)
243                   saw_a_complex_op = true;
244                 break;
245
246               default:
247                 break;
248               }
249
250           DONT_SIMULATE_AGAIN (orig_stmt) = dsa;
251         }
252     }
253
254   return saw_a_complex_op;
255 }
256
257
258 /* Evaluate statement STMT against the complex lattice defined above.  */
259
260 static enum ssa_prop_result
261 complex_visit_stmt (tree stmt, edge *taken_edge_p ATTRIBUTE_UNUSED,
262                     tree *result_p)
263 {
264   complex_lattice_t new_l, old_l, op1_l, op2_l;
265   unsigned int ver;
266   tree lhs, rhs;
267
268   if (TREE_CODE (stmt) != MODIFY_EXPR)
269     return SSA_PROP_VARYING;
270
271   lhs = TREE_OPERAND (stmt, 0);
272   rhs = TREE_OPERAND (stmt, 1);
273
274   /* These conditions should be satisfied due to the initial filter
275      set up in init_dont_simulate_again.  */
276   gcc_assert (TREE_CODE (lhs) == SSA_NAME);
277   gcc_assert (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE);
278
279   *result_p = lhs;
280   ver = SSA_NAME_VERSION (lhs);
281   old_l = VEC_index (complex_lattice_t, complex_lattice_values, ver);
282
283   switch (TREE_CODE (rhs))
284     {
285     case SSA_NAME:
286     case COMPLEX_EXPR:
287     case COMPLEX_CST:
288       new_l = find_lattice_value (rhs);
289       break;
290
291     case PLUS_EXPR:
292     case MINUS_EXPR:
293       op1_l = find_lattice_value (TREE_OPERAND (rhs, 0));
294       op2_l = find_lattice_value (TREE_OPERAND (rhs, 1));
295
296       /* We've set up the lattice values such that IOR neatly
297          models addition.  */
298       new_l = op1_l | op2_l;
299       break;
300
301     case MULT_EXPR:
302     case RDIV_EXPR:
303     case TRUNC_DIV_EXPR:
304     case CEIL_DIV_EXPR:
305     case FLOOR_DIV_EXPR:
306     case ROUND_DIV_EXPR:
307       op1_l = find_lattice_value (TREE_OPERAND (rhs, 0));
308       op2_l = find_lattice_value (TREE_OPERAND (rhs, 1));
309
310       /* Obviously, if either varies, so does the result.  */
311       if (op1_l == VARYING || op2_l == VARYING)
312         new_l = VARYING;
313       /* Don't prematurely promote variables if we've not yet seen
314          their inputs.  */
315       else if (op1_l == UNINITIALIZED)
316         new_l = op2_l;
317       else if (op2_l == UNINITIALIZED)
318         new_l = op1_l;
319       else
320         {
321           /* At this point both numbers have only one component. If the
322              numbers are of opposite kind, the result is imaginary,
323              otherwise the result is real. The add/subtract translates
324              the real/imag from/to 0/1; the ^ performs the comparison.  */
325           new_l = ((op1_l - ONLY_REAL) ^ (op2_l - ONLY_REAL)) + ONLY_REAL;
326
327           /* Don't allow the lattice value to flip-flop indefinitely.  */
328           new_l |= old_l;
329         }
330       break;
331
332     case NEGATE_EXPR:
333     case CONJ_EXPR:
334       new_l = find_lattice_value (TREE_OPERAND (rhs, 0));
335       break;
336
337     default:
338       new_l = VARYING;
339       break;
340     }
341
342   /* If nothing changed this round, let the propagator know.  */
343   if (new_l == old_l)
344     return SSA_PROP_NOT_INTERESTING;
345
346   VEC_replace (complex_lattice_t, complex_lattice_values, ver, new_l);
347   return new_l == VARYING ? SSA_PROP_VARYING : SSA_PROP_INTERESTING;
348 }
349
350 /* Evaluate a PHI node against the complex lattice defined above.  */
351
352 static enum ssa_prop_result
353 complex_visit_phi (tree phi)
354 {
355   complex_lattice_t new_l, old_l;
356   unsigned int ver;
357   tree lhs;
358   int i;
359
360   lhs = PHI_RESULT (phi);
361
362   /* This condition should be satisfied due to the initial filter
363      set up in init_dont_simulate_again.  */
364   gcc_assert (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE);
365
366   /* We've set up the lattice values such that IOR neatly models PHI meet.  */
367   new_l = UNINITIALIZED;
368   for (i = PHI_NUM_ARGS (phi) - 1; i >= 0; --i)
369     new_l |= find_lattice_value (PHI_ARG_DEF (phi, i));
370
371   ver = SSA_NAME_VERSION (lhs);
372   old_l = VEC_index (complex_lattice_t, complex_lattice_values, ver);
373
374   if (new_l == old_l)
375     return SSA_PROP_NOT_INTERESTING;
376
377   VEC_replace (complex_lattice_t, complex_lattice_values, ver, new_l);
378   return new_l == VARYING ? SSA_PROP_VARYING : SSA_PROP_INTERESTING;
379 }
380
381 /* For each referenced complex gimple register, set up a pair of registers
382    to hold the components of the complex value.  */
383
384 static void
385 create_components (void)
386 {
387   size_t n;
388   tree var;
389   safe_referenced_var_iterator rvi;
390   VEC (tree, heap) *refvars;
391
392   n = num_referenced_vars;
393   if (n == 0)
394     return;
395
396   complex_variable_components = htab_create (10,  int_tree_map_hash,
397                                              int_tree_map_eq, free);
398
399   FOR_EACH_REFERENCED_VAR_SAFE (var, refvars, rvi)
400     {
401       tree r = NULL, i = NULL;
402
403       if (var != NULL
404           && TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
405           && is_gimple_reg (var))
406         {
407           tree inner_type = TREE_TYPE (TREE_TYPE (var));
408
409           r = make_rename_temp (inner_type, "CR");
410           i = make_rename_temp (inner_type, "CI");
411           DECL_SOURCE_LOCATION (r) = DECL_SOURCE_LOCATION (var);
412           DECL_SOURCE_LOCATION (i) = DECL_SOURCE_LOCATION (var);
413           DECL_ARTIFICIAL (r) = 1;
414           DECL_ARTIFICIAL (i) = 1;
415
416           if (DECL_NAME (var) && !DECL_IGNORED_P (var))
417             {
418               const char *name = IDENTIFIER_POINTER (DECL_NAME (var));
419
420               DECL_NAME (r) = get_identifier (ACONCAT ((name, "$real", NULL)));
421               DECL_NAME (i) = get_identifier (ACONCAT ((name, "$imag", NULL)));
422
423               SET_DECL_DEBUG_EXPR (r, build1 (REALPART_EXPR, inner_type, var));
424               SET_DECL_DEBUG_EXPR (i, build1 (IMAGPART_EXPR, inner_type, var));
425               DECL_DEBUG_EXPR_IS_FROM (r) = 1;
426               DECL_DEBUG_EXPR_IS_FROM (i) = 1;
427
428               DECL_IGNORED_P (r) = 0;
429               DECL_IGNORED_P (i) = 0;
430
431               TREE_NO_WARNING (r) = TREE_NO_WARNING (var);
432               TREE_NO_WARNING (i) = TREE_NO_WARNING (var);
433             }
434           else
435             {
436               DECL_IGNORED_P (r) = 1;
437               DECL_IGNORED_P (i) = 1;
438               TREE_NO_WARNING (r) = 1;
439               TREE_NO_WARNING (i) = 1;
440             }
441         }
442
443       cvc_insert (2 * DECL_UID (var), r);
444       cvc_insert (2 * DECL_UID (var) + 1, i);
445     }
446   VEC_free (tree, heap, refvars);
447 }
448
449 /* Extract the real or imaginary part of a complex variable or constant.
450    Make sure that it's a proper gimple_val and gimplify it if not.
451    Emit any new code before BSI.  */
452
453 static tree
454 extract_component (block_stmt_iterator *bsi, tree t, bool imagpart_p,
455                    bool gimple_p)
456 {
457   switch (TREE_CODE (t))
458     {
459     case COMPLEX_CST:
460       return imagpart_p ? TREE_IMAGPART (t) : TREE_REALPART (t);
461
462     case COMPLEX_EXPR:
463       return TREE_OPERAND (t, imagpart_p);
464
465     case VAR_DECL:
466     case PARM_DECL:
467     case INDIRECT_REF:
468     case COMPONENT_REF:
469     case ARRAY_REF:
470       {
471         tree inner_type = TREE_TYPE (TREE_TYPE (t));
472
473         t = build1 ((imagpart_p ? IMAGPART_EXPR : REALPART_EXPR),
474                     inner_type, unshare_expr (t));
475
476         if (gimple_p)
477           t = gimplify_val (bsi, inner_type, t);
478
479         return t;
480       }
481
482     case SSA_NAME:
483       {
484         tree def = SSA_NAME_DEF_STMT (t);
485
486         if (TREE_CODE (def) == MODIFY_EXPR)
487           {
488             def = TREE_OPERAND (def, 1);
489             if (TREE_CODE (def) == COMPLEX_CST)
490               return imagpart_p ? TREE_IMAGPART (def) : TREE_REALPART (def);
491             if (TREE_CODE (def) == COMPLEX_EXPR)
492               {
493                 def = TREE_OPERAND (def, imagpart_p);
494                 if (TREE_CONSTANT (def))
495                   return def;
496               }
497           }
498
499         return cvc_lookup (DECL_UID (SSA_NAME_VAR (t)) * 2 + imagpart_p);
500       }
501
502     default:
503       gcc_unreachable ();
504     }
505 }
506
507 /* Update the complex components of the ssa name on the lhs of STMT.  */
508
509 static void
510 update_complex_components (block_stmt_iterator *bsi, tree stmt, tree r, tree i)
511 {
512   unsigned int uid = DECL_UID (SSA_NAME_VAR (TREE_OPERAND (stmt, 0)));
513   tree v, x;
514
515   v = cvc_lookup (2*uid);
516   x = build2 (MODIFY_EXPR, TREE_TYPE (v), v, r);
517   SET_EXPR_LOCUS (x, EXPR_LOCUS (stmt));
518   TREE_BLOCK (x) = TREE_BLOCK (stmt);
519   bsi_insert_after (bsi, x, BSI_NEW_STMT);
520
521   v = cvc_lookup (2*uid + 1);
522   x = build2 (MODIFY_EXPR, TREE_TYPE (v), v, i);
523   SET_EXPR_LOCUS (x, EXPR_LOCUS (stmt));
524   TREE_BLOCK (x) = TREE_BLOCK (stmt);
525   bsi_insert_after (bsi, x, BSI_NEW_STMT);
526 }
527
528 static void
529 update_complex_components_on_edge (edge e, tree stmt, tree lhs, tree r, tree i)
530 {
531   unsigned int uid = DECL_UID (SSA_NAME_VAR (lhs));
532   tree v, x;
533
534   v = cvc_lookup (2*uid);
535   x = build2 (MODIFY_EXPR, TREE_TYPE (v), v, r);
536   if (stmt)
537     {
538       SET_EXPR_LOCUS (x, EXPR_LOCUS (stmt));
539       TREE_BLOCK (x) = TREE_BLOCK (stmt);
540     }
541   bsi_insert_on_edge (e, x);
542
543   v = cvc_lookup (2*uid + 1);
544   x = build2 (MODIFY_EXPR, TREE_TYPE (v), v, i);
545   if (stmt)
546     {
547       SET_EXPR_LOCUS (x, EXPR_LOCUS (stmt));
548       TREE_BLOCK (x) = TREE_BLOCK (stmt);
549     }
550   bsi_insert_on_edge (e, x);
551 }
552
553 /* Update an assignment to a complex variable in place.  */
554
555 static void
556 update_complex_assignment (block_stmt_iterator *bsi, tree r, tree i)
557 {
558   tree stmt, mod;
559   tree type;
560
561   mod = stmt = bsi_stmt (*bsi);
562   if (TREE_CODE (stmt) == RETURN_EXPR)
563     mod = TREE_OPERAND (mod, 0);
564   else if (in_ssa_p)
565     update_complex_components (bsi, stmt, r, i);
566   
567   type = TREE_TYPE (TREE_OPERAND (mod, 1));
568   TREE_OPERAND (mod, 1) = build (COMPLEX_EXPR, type, r, i);
569   update_stmt (stmt);
570 }
571
572 /* Generate code at the entry point of the function to initialize the
573    component variables for a complex parameter.  */
574
575 static void
576 update_parameter_components (void)
577 {
578   edge entry_edge = single_succ_edge (ENTRY_BLOCK_PTR);
579   tree parm;
580
581   for (parm = DECL_ARGUMENTS (cfun->decl); parm ; parm = TREE_CHAIN (parm))
582     {
583       tree type = TREE_TYPE (parm);
584       tree ssa_name, r, i;
585
586       if (TREE_CODE (type) != COMPLEX_TYPE || !is_gimple_reg (parm))
587         continue;
588
589       type = TREE_TYPE (type);
590       ssa_name = default_def (parm);
591
592       r = build1 (REALPART_EXPR, type, ssa_name);
593       i = build1 (IMAGPART_EXPR, type, ssa_name);
594       update_complex_components_on_edge (entry_edge, NULL, ssa_name, r, i);
595     }
596 }
597
598 /* Generate code to set the component variables of a complex variable
599    to match the PHI statements in block BB.  */
600
601 static void
602 update_phi_components (basic_block bb)
603 {
604   tree phi;
605
606   for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
607     if (is_complex_reg (PHI_RESULT (phi)))
608       {
609         unsigned int i, n;
610         tree lhs = PHI_RESULT (phi);
611
612         for (i = 0, n = PHI_NUM_ARGS (phi); i < n; ++i)
613           {
614             edge e = PHI_ARG_EDGE (phi, i);
615             tree arg = PHI_ARG_DEF (phi, i);
616             tree r, i;
617
618             /* Avoid no-op assignments.  This also prevents insertting stmts
619                onto abnormal edges, assuming the PHI isn't already broken.  */
620             if (TREE_CODE (arg) == SSA_NAME
621                 && SSA_NAME_VAR (arg) == SSA_NAME_VAR (lhs))
622               continue;
623
624             r = extract_component (NULL, arg, 0, false);
625             i = extract_component (NULL, arg, 1, false);
626             update_complex_components_on_edge (e, NULL, lhs, r, i);
627           }
628       }
629 }
630
631 /* Mark each virtual op in STMT for ssa update.  */
632
633 static void
634 update_all_vops (tree stmt)
635 {
636   ssa_op_iter iter;
637   tree sym;
638
639   FOR_EACH_SSA_TREE_OPERAND (sym, stmt, iter, SSA_OP_ALL_VIRTUALS)
640     {
641       if (TREE_CODE (sym) == SSA_NAME)
642         sym = SSA_NAME_VAR (sym);
643       mark_sym_for_renaming (sym);
644     }
645 }
646
647 /* Expand a complex move to scalars.  */
648
649 static void
650 expand_complex_move (block_stmt_iterator *bsi, tree stmt, tree type,
651                      tree lhs, tree rhs)
652 {
653   tree inner_type = TREE_TYPE (type);
654   tree r, i;
655
656   if (TREE_CODE (lhs) == SSA_NAME)
657     {
658       if (is_ctrl_altering_stmt (bsi_stmt (*bsi)))
659         {
660           edge_iterator ei;
661           edge e;
662
663           /* The value is not assigned on the exception edges, so we need not
664              concern ourselves there.  We do need to update on the fallthru
665              edge.  Find it.  */
666           FOR_EACH_EDGE (e, ei, bsi->bb->succs)
667             if (e->flags & EDGE_FALLTHRU)
668               goto found_fallthru;
669           gcc_unreachable ();
670         found_fallthru:
671
672           r = build1 (REALPART_EXPR, inner_type, lhs);
673           i = build1 (IMAGPART_EXPR, inner_type, lhs);
674           update_complex_components_on_edge (e, stmt, lhs, r, i);
675         }
676       else if (TREE_CODE (rhs) == CALL_EXPR || TREE_SIDE_EFFECTS (rhs))
677         {
678           r = build1 (REALPART_EXPR, inner_type, lhs);
679           i = build1 (IMAGPART_EXPR, inner_type, lhs);
680           update_complex_components (bsi, stmt, r, i);
681         }
682       else
683         {
684           update_all_vops (bsi_stmt (*bsi));
685           r = extract_component (bsi, rhs, 0, true);
686           i = extract_component (bsi, rhs, 1, true);
687           update_complex_assignment (bsi, r, i);
688         }
689     }
690   else if (TREE_CODE (rhs) == SSA_NAME && !TREE_SIDE_EFFECTS (lhs))
691     {
692       tree x;
693
694       r = extract_component (bsi, rhs, 0, false);
695       i = extract_component (bsi, rhs, 1, false);
696
697       x = build1 (REALPART_EXPR, inner_type, unshare_expr (lhs));
698       x = build2 (MODIFY_EXPR, inner_type, x, r);
699       bsi_insert_before (bsi, x, BSI_SAME_STMT);
700
701       if (stmt == bsi_stmt (*bsi))
702         {
703           x = build1 (IMAGPART_EXPR, inner_type, unshare_expr (lhs));
704           TREE_OPERAND (stmt, 0) = x;
705           TREE_OPERAND (stmt, 1) = i;
706           TREE_TYPE (stmt) = inner_type;
707         }
708       else
709         {
710           x = build1 (IMAGPART_EXPR, inner_type, unshare_expr (lhs));
711           x = build2 (MODIFY_EXPR, inner_type, x, i);
712           bsi_insert_before (bsi, x, BSI_SAME_STMT);
713
714           stmt = bsi_stmt (*bsi);
715           gcc_assert (TREE_CODE (stmt) == RETURN_EXPR);
716           TREE_OPERAND (stmt, 0) = lhs;
717         }
718
719       update_all_vops (stmt);
720       update_stmt (stmt);
721     }
722 }
723
724 /* Expand complex addition to scalars:
725         a + b = (ar + br) + i(ai + bi)
726         a - b = (ar - br) + i(ai + bi)
727 */
728
729 static void
730 expand_complex_addition (block_stmt_iterator *bsi, tree inner_type,
731                          tree ar, tree ai, tree br, tree bi,
732                          enum tree_code code,
733                          complex_lattice_t al, complex_lattice_t bl)
734 {
735   tree rr, ri;
736
737   switch (PAIR (al, bl))
738     {
739     case PAIR (ONLY_REAL, ONLY_REAL):
740       rr = gimplify_build2 (bsi, code, inner_type, ar, br);
741       ri = ai;
742       break;
743
744     case PAIR (ONLY_REAL, ONLY_IMAG):
745       rr = ar;
746       if (code == MINUS_EXPR)
747         ri = gimplify_build2 (bsi, MINUS_EXPR, inner_type, ai, bi);
748       else
749         ri = bi;
750       break;
751
752     case PAIR (ONLY_IMAG, ONLY_REAL):
753       if (code == MINUS_EXPR)
754         rr = gimplify_build2 (bsi, MINUS_EXPR, inner_type, ar, br);
755       else
756         rr = br;
757       ri = ai;
758       break;
759
760     case PAIR (ONLY_IMAG, ONLY_IMAG):
761       rr = ar;
762       ri = gimplify_build2 (bsi, code, inner_type, ai, bi);
763       break;
764
765     case PAIR (VARYING, ONLY_REAL):
766       rr = gimplify_build2 (bsi, code, inner_type, ar, br);
767       ri = ai;
768       break;
769
770     case PAIR (VARYING, ONLY_IMAG):
771       rr = ar;
772       ri = gimplify_build2 (bsi, MINUS_EXPR, inner_type, ai, bi);
773       break;
774
775     case PAIR (ONLY_REAL, VARYING):
776       if (code == MINUS_EXPR)
777         goto general;
778       rr = gimplify_build2 (bsi, code, inner_type, ar, br);
779       ri = bi;
780       break;
781
782     case PAIR (ONLY_IMAG, VARYING):
783       if (code == MINUS_EXPR)
784         goto general;
785       rr = br;
786       ri = gimplify_build2 (bsi, MINUS_EXPR, inner_type, ai, bi);
787       break;
788
789     case PAIR (VARYING, VARYING):
790     general:
791       rr = gimplify_build2 (bsi, code, inner_type, ar, br);
792       ri = gimplify_build2 (bsi, code, inner_type, ai, bi);
793       break;
794
795     default:
796       gcc_unreachable ();
797     }
798
799   update_complex_assignment (bsi, rr, ri);
800 }
801
802 /* Expand a complex multiplication or division to a libcall to the c99
803    compliant routines.  */
804
805 static void
806 expand_complex_libcall (block_stmt_iterator *bsi, tree ar, tree ai,
807                         tree br, tree bi, enum tree_code code)
808 {
809   enum machine_mode mode;
810   enum built_in_function bcode;
811   tree args, fn, stmt, type;
812
813   args = tree_cons (NULL, bi, NULL);
814   args = tree_cons (NULL, br, args);
815   args = tree_cons (NULL, ai, args);
816   args = tree_cons (NULL, ar, args);
817
818   stmt = bsi_stmt (*bsi);
819   type = TREE_TYPE (TREE_OPERAND (stmt, 1));
820
821   mode = TYPE_MODE (type);
822   gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
823   if (code == MULT_EXPR)
824     bcode = BUILT_IN_COMPLEX_MUL_MIN + mode - MIN_MODE_COMPLEX_FLOAT;
825   else if (code == RDIV_EXPR)
826     bcode = BUILT_IN_COMPLEX_DIV_MIN + mode - MIN_MODE_COMPLEX_FLOAT;
827   else
828     gcc_unreachable ();
829   fn = built_in_decls[bcode];
830
831   TREE_OPERAND (stmt, 1)
832     = build3 (CALL_EXPR, type, build_fold_addr_expr (fn), args, NULL);
833   update_stmt (stmt);
834
835   if (in_ssa_p)
836     {
837       tree lhs = TREE_OPERAND (stmt, 0);
838       type = TREE_TYPE (type);
839       update_complex_components (bsi, stmt,
840                                  build1 (REALPART_EXPR, type, lhs),
841                                  build1 (IMAGPART_EXPR, type, lhs));
842     }
843 }
844
845 /* Expand complex multiplication to scalars:
846         a * b = (ar*br - ai*bi) + i(ar*bi + br*ai)
847 */
848
849 static void
850 expand_complex_multiplication (block_stmt_iterator *bsi, tree inner_type,
851                                tree ar, tree ai, tree br, tree bi,
852                                complex_lattice_t al, complex_lattice_t bl)
853 {
854   tree rr, ri;
855
856   if (al < bl)
857     {
858       complex_lattice_t tl;
859       rr = ar, ar = br, br = rr;
860       ri = ai, ai = bi, bi = ri;
861       tl = al, al = bl, bl = tl;
862     }
863
864   switch (PAIR (al, bl))
865     {
866     case PAIR (ONLY_REAL, ONLY_REAL):
867       rr = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, br);
868       ri = ai;
869       break;
870
871     case PAIR (ONLY_IMAG, ONLY_REAL):
872       rr = ar;
873       if (TREE_CODE (ai) == REAL_CST
874           && REAL_VALUES_IDENTICAL (TREE_REAL_CST (ai), dconst1))
875         ri = br;
876       else
877         ri = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, br);
878       break;
879
880     case PAIR (ONLY_IMAG, ONLY_IMAG):
881       rr = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, bi);
882       rr = gimplify_build1 (bsi, NEGATE_EXPR, inner_type, rr);
883       ri = ar;
884       break;
885
886     case PAIR (VARYING, ONLY_REAL):
887       rr = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, br);
888       ri = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, br);
889       break;
890
891     case PAIR (VARYING, ONLY_IMAG):
892       rr = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, bi);
893       rr = gimplify_build1 (bsi, NEGATE_EXPR, inner_type, rr);
894       ri = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, bi);
895       break;
896
897     case PAIR (VARYING, VARYING):
898       if (flag_complex_method == 2 && SCALAR_FLOAT_TYPE_P (inner_type))
899         {
900           expand_complex_libcall (bsi, ar, ai, br, bi, MULT_EXPR);
901           return;
902         }
903       else
904         {
905           tree t1, t2, t3, t4;
906
907           t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, br);
908           t2 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, bi);
909           t3 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, bi);
910
911           /* Avoid expanding redundant multiplication for the common
912              case of squaring a complex number.  */
913           if (ar == br && ai == bi)
914             t4 = t3;
915           else
916             t4 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, br);
917
918           rr = gimplify_build2 (bsi, MINUS_EXPR, inner_type, t1, t2);
919           ri = gimplify_build2 (bsi, PLUS_EXPR, inner_type, t3, t4);
920         }
921       break;
922
923     default:
924       gcc_unreachable ();
925     }
926
927   update_complex_assignment (bsi, rr, ri);
928 }
929
930 /* Expand complex division to scalars, straightforward algorithm.
931         a / b = ((ar*br + ai*bi)/t) + i((ai*br - ar*bi)/t)
932             t = br*br + bi*bi
933 */
934
935 static void
936 expand_complex_div_straight (block_stmt_iterator *bsi, tree inner_type,
937                              tree ar, tree ai, tree br, tree bi,
938                              enum tree_code code)
939 {
940   tree rr, ri, div, t1, t2, t3;
941
942   t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, br, br);
943   t2 = gimplify_build2 (bsi, MULT_EXPR, inner_type, bi, bi);
944   div = gimplify_build2 (bsi, PLUS_EXPR, inner_type, t1, t2);
945
946   t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, br);
947   t2 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, bi);
948   t3 = gimplify_build2 (bsi, PLUS_EXPR, inner_type, t1, t2);
949   rr = gimplify_build2 (bsi, code, inner_type, t3, div);
950
951   t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, br);
952   t2 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, bi);
953   t3 = gimplify_build2 (bsi, MINUS_EXPR, inner_type, t1, t2);
954   ri = gimplify_build2 (bsi, code, inner_type, t3, div);
955
956   update_complex_assignment (bsi, rr, ri);
957 }
958
959 /* Expand complex division to scalars, modified algorithm to minimize
960    overflow with wide input ranges.  */
961
962 static void
963 expand_complex_div_wide (block_stmt_iterator *bsi, tree inner_type,
964                          tree ar, tree ai, tree br, tree bi,
965                          enum tree_code code)
966 {
967   tree rr, ri, ratio, div, t1, t2, tr, ti, cond;
968   basic_block bb_cond, bb_true, bb_false, bb_join;
969
970   /* Examine |br| < |bi|, and branch.  */
971   t1 = gimplify_build1 (bsi, ABS_EXPR, inner_type, br);
972   t2 = gimplify_build1 (bsi, ABS_EXPR, inner_type, bi);
973   cond = fold_build2 (LT_EXPR, boolean_type_node, t1, t2);
974   STRIP_NOPS (cond);
975
976   bb_cond = bb_true = bb_false = bb_join = NULL;
977   rr = ri = tr = ti = NULL;
978   if (!TREE_CONSTANT (cond))
979     {
980       edge e;
981
982       cond = build (COND_EXPR, void_type_node, cond, NULL, NULL);
983       bsi_insert_before (bsi, cond, BSI_SAME_STMT);
984
985       /* Split the original block, and create the TRUE and FALSE blocks.  */
986       e = split_block (bsi->bb, cond);
987       bb_cond = e->src;
988       bb_join = e->dest;
989       bb_true = create_empty_bb (bb_cond);
990       bb_false = create_empty_bb (bb_true);
991
992       t1 = build (GOTO_EXPR, void_type_node, tree_block_label (bb_true));
993       t2 = build (GOTO_EXPR, void_type_node, tree_block_label (bb_false));
994       COND_EXPR_THEN (cond) = t1;
995       COND_EXPR_ELSE (cond) = t2;
996
997       /* Wire the blocks together.  */
998       e->flags = EDGE_TRUE_VALUE;
999       redirect_edge_succ (e, bb_true);
1000       make_edge (bb_cond, bb_false, EDGE_FALSE_VALUE);
1001       make_edge (bb_true, bb_join, EDGE_FALLTHRU);
1002       make_edge (bb_false, bb_join, EDGE_FALLTHRU);
1003
1004       /* Update dominance info.  Note that bb_join's data was
1005          updated by split_block.  */
1006       if (dom_info_available_p (CDI_DOMINATORS))
1007         {
1008           set_immediate_dominator (CDI_DOMINATORS, bb_true, bb_cond);
1009           set_immediate_dominator (CDI_DOMINATORS, bb_false, bb_cond);
1010         }
1011
1012       rr = make_rename_temp (inner_type, NULL);
1013       ri = make_rename_temp (inner_type, NULL);
1014     }
1015
1016   /* In the TRUE branch, we compute
1017       ratio = br/bi;
1018       div = (br * ratio) + bi;
1019       tr = (ar * ratio) + ai;
1020       ti = (ai * ratio) - ar;
1021       tr = tr / div;
1022       ti = ti / div;  */
1023   if (bb_true || integer_nonzerop (cond))
1024     {
1025       if (bb_true)
1026         {
1027           *bsi = bsi_last (bb_true);
1028           bsi_insert_after (bsi, build_empty_stmt (), BSI_NEW_STMT);
1029         }
1030
1031       ratio = gimplify_build2 (bsi, code, inner_type, br, bi);
1032
1033       t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, br, ratio);
1034       div = gimplify_build2 (bsi, PLUS_EXPR, inner_type, t1, bi);
1035
1036       t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, ratio);
1037       tr = gimplify_build2 (bsi, PLUS_EXPR, inner_type, t1, ai);
1038
1039       t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, ratio);
1040       ti = gimplify_build2 (bsi, MINUS_EXPR, inner_type, t1, ar);
1041
1042       tr = gimplify_build2 (bsi, code, inner_type, tr, div);
1043       ti = gimplify_build2 (bsi, code, inner_type, ti, div);
1044
1045      if (bb_true)
1046        {
1047          t1 = build (MODIFY_EXPR, inner_type, rr, tr);
1048          bsi_insert_before (bsi, t1, BSI_SAME_STMT);
1049          t1 = build (MODIFY_EXPR, inner_type, ri, ti);
1050          bsi_insert_before (bsi, t1, BSI_SAME_STMT);
1051          bsi_remove (bsi);
1052        }
1053     }
1054
1055   /* In the FALSE branch, we compute
1056       ratio = d/c;
1057       divisor = (d * ratio) + c;
1058       tr = (b * ratio) + a;
1059       ti = b - (a * ratio);
1060       tr = tr / div;
1061       ti = ti / div;  */
1062   if (bb_false || integer_zerop (cond))
1063     {
1064       if (bb_false)
1065         {
1066           *bsi = bsi_last (bb_false);
1067           bsi_insert_after (bsi, build_empty_stmt (), BSI_NEW_STMT);
1068         }
1069
1070       ratio = gimplify_build2 (bsi, code, inner_type, bi, br);
1071
1072       t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, bi, ratio);
1073       div = gimplify_build2 (bsi, PLUS_EXPR, inner_type, t1, br);
1074
1075       t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, ratio);
1076       tr = gimplify_build2 (bsi, PLUS_EXPR, inner_type, t1, ar);
1077
1078       t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, ratio);
1079       ti = gimplify_build2 (bsi, MINUS_EXPR, inner_type, ai, t1);
1080
1081       tr = gimplify_build2 (bsi, code, inner_type, tr, div);
1082       ti = gimplify_build2 (bsi, code, inner_type, ti, div);
1083
1084      if (bb_false)
1085        {
1086          t1 = build (MODIFY_EXPR, inner_type, rr, tr);
1087          bsi_insert_before (bsi, t1, BSI_SAME_STMT);
1088          t1 = build (MODIFY_EXPR, inner_type, ri, ti);
1089          bsi_insert_before (bsi, t1, BSI_SAME_STMT);
1090          bsi_remove (bsi);
1091        }
1092     }
1093
1094   if (bb_join)
1095     *bsi = bsi_start (bb_join);
1096   else
1097     rr = tr, ri = ti;
1098
1099   update_complex_assignment (bsi, rr, ri);
1100 }
1101
1102 /* Expand complex division to scalars.  */
1103
1104 static void
1105 expand_complex_division (block_stmt_iterator *bsi, tree inner_type,
1106                          tree ar, tree ai, tree br, tree bi,
1107                          enum tree_code code,
1108                          complex_lattice_t al, complex_lattice_t bl)
1109 {
1110   tree rr, ri;
1111
1112   switch (PAIR (al, bl))
1113     {
1114     case PAIR (ONLY_REAL, ONLY_REAL):
1115       rr = gimplify_build2 (bsi, code, inner_type, ar, br);
1116       ri = ai;
1117       break;
1118
1119     case PAIR (ONLY_REAL, ONLY_IMAG):
1120       rr = ai;
1121       ri = gimplify_build2 (bsi, code, inner_type, ar, bi);
1122       ri = gimplify_build1 (bsi, NEGATE_EXPR, inner_type, ri);
1123       break;
1124
1125     case PAIR (ONLY_IMAG, ONLY_REAL):
1126       rr = ar;
1127       ri = gimplify_build2 (bsi, code, inner_type, ai, br);
1128       break;
1129
1130     case PAIR (ONLY_IMAG, ONLY_IMAG):
1131       rr = gimplify_build2 (bsi, code, inner_type, ai, bi);
1132       ri = ar;
1133       break;
1134
1135     case PAIR (VARYING, ONLY_REAL):
1136       rr = gimplify_build2 (bsi, code, inner_type, ar, br);
1137       ri = gimplify_build2 (bsi, code, inner_type, ai, br);
1138       break;
1139
1140     case PAIR (VARYING, ONLY_IMAG):
1141       rr = gimplify_build2 (bsi, code, inner_type, ai, bi);
1142       ri = gimplify_build2 (bsi, code, inner_type, ar, bi);
1143       ri = gimplify_build1 (bsi, NEGATE_EXPR, inner_type, ri);
1144
1145     case PAIR (ONLY_REAL, VARYING):
1146     case PAIR (ONLY_IMAG, VARYING):
1147     case PAIR (VARYING, VARYING):
1148       switch (flag_complex_method)
1149         {
1150         case 0:
1151           /* straightforward implementation of complex divide acceptable.  */
1152           expand_complex_div_straight (bsi, inner_type, ar, ai, br, bi, code);
1153           break;
1154
1155         case 2:
1156           if (SCALAR_FLOAT_TYPE_P (inner_type))
1157             {
1158               expand_complex_libcall (bsi, ar, ai, br, bi, code);
1159               break;
1160             }
1161           /* FALLTHRU */
1162
1163         case 1:
1164           /* wide ranges of inputs must work for complex divide.  */
1165           expand_complex_div_wide (bsi, inner_type, ar, ai, br, bi, code);
1166           break;
1167
1168         default:
1169           gcc_unreachable ();
1170         }
1171       return;
1172
1173     default:
1174       gcc_unreachable ();
1175     }
1176
1177   update_complex_assignment (bsi, rr, ri);
1178 }
1179
1180 /* Expand complex negation to scalars:
1181         -a = (-ar) + i(-ai)
1182 */
1183
1184 static void
1185 expand_complex_negation (block_stmt_iterator *bsi, tree inner_type,
1186                          tree ar, tree ai)
1187 {
1188   tree rr, ri;
1189
1190   rr = gimplify_build1 (bsi, NEGATE_EXPR, inner_type, ar);
1191   ri = gimplify_build1 (bsi, NEGATE_EXPR, inner_type, ai);
1192
1193   update_complex_assignment (bsi, rr, ri);
1194 }
1195
1196 /* Expand complex conjugate to scalars:
1197         ~a = (ar) + i(-ai)
1198 */
1199
1200 static void
1201 expand_complex_conjugate (block_stmt_iterator *bsi, tree inner_type,
1202                           tree ar, tree ai)
1203 {
1204   tree ri;
1205
1206   ri = gimplify_build1 (bsi, NEGATE_EXPR, inner_type, ai);
1207
1208   update_complex_assignment (bsi, ar, ri);
1209 }
1210
1211 /* Expand complex comparison (EQ or NE only).  */
1212
1213 static void
1214 expand_complex_comparison (block_stmt_iterator *bsi, tree ar, tree ai,
1215                            tree br, tree bi, enum tree_code code)
1216 {
1217   tree cr, ci, cc, stmt, expr, type;
1218
1219   cr = gimplify_build2 (bsi, code, boolean_type_node, ar, br);
1220   ci = gimplify_build2 (bsi, code, boolean_type_node, ai, bi);
1221   cc = gimplify_build2 (bsi,
1222                         (code == EQ_EXPR ? TRUTH_AND_EXPR : TRUTH_OR_EXPR),
1223                         boolean_type_node, cr, ci);
1224
1225   stmt = expr = bsi_stmt (*bsi);
1226
1227   switch (TREE_CODE (stmt))
1228     {
1229     case RETURN_EXPR:
1230       expr = TREE_OPERAND (stmt, 0);
1231       /* FALLTHRU */
1232     case MODIFY_EXPR:
1233       type = TREE_TYPE (TREE_OPERAND (expr, 1));
1234       TREE_OPERAND (expr, 1) = fold_convert (type, cc);
1235       break;
1236     case COND_EXPR:
1237       TREE_OPERAND (stmt, 0) = cc;
1238       break;
1239     default:
1240       gcc_unreachable ();
1241     }
1242
1243   update_stmt (stmt);
1244 }
1245
1246 /* Process one statement.  If we identify a complex operation, expand it.  */
1247
1248 static void
1249 expand_complex_operations_1 (block_stmt_iterator *bsi)
1250 {
1251   tree stmt = bsi_stmt (*bsi);
1252   tree rhs, type, inner_type;
1253   tree ac, ar, ai, bc, br, bi;
1254   complex_lattice_t al, bl;
1255   enum tree_code code;
1256
1257   switch (TREE_CODE (stmt))
1258     {
1259     case RETURN_EXPR:
1260       stmt = TREE_OPERAND (stmt, 0);
1261       if (!stmt)
1262         return;
1263       if (TREE_CODE (stmt) != MODIFY_EXPR)
1264         return;
1265       /* FALLTHRU */
1266
1267     case MODIFY_EXPR:
1268       rhs = TREE_OPERAND (stmt, 1);
1269       break;
1270
1271     case COND_EXPR:
1272       rhs = TREE_OPERAND (stmt, 0);
1273       break;
1274
1275     default:
1276       return;
1277     }
1278
1279   type = TREE_TYPE (rhs);
1280   code = TREE_CODE (rhs);
1281
1282   /* Initial filter for operations we handle.  */
1283   switch (code)
1284     {
1285     case PLUS_EXPR:
1286     case MINUS_EXPR:
1287     case MULT_EXPR:
1288     case TRUNC_DIV_EXPR:
1289     case CEIL_DIV_EXPR:
1290     case FLOOR_DIV_EXPR:
1291     case ROUND_DIV_EXPR:
1292     case RDIV_EXPR:
1293     case NEGATE_EXPR:
1294     case CONJ_EXPR:
1295       if (TREE_CODE (type) != COMPLEX_TYPE)
1296         return;
1297       inner_type = TREE_TYPE (type);
1298       break;
1299
1300     case EQ_EXPR:
1301     case NE_EXPR:
1302       inner_type = TREE_TYPE (TREE_OPERAND (rhs, 1));
1303       if (TREE_CODE (inner_type) != COMPLEX_TYPE)
1304         return;
1305       break;
1306
1307     default:
1308       {
1309         tree lhs = TREE_OPERAND (stmt, 0);
1310         tree rhs = TREE_OPERAND (stmt, 1);
1311
1312         if (TREE_CODE (type) == COMPLEX_TYPE)
1313           expand_complex_move (bsi, stmt, type, lhs, rhs);
1314         else if ((TREE_CODE (rhs) == REALPART_EXPR
1315                   || TREE_CODE (rhs) == IMAGPART_EXPR)
1316                  && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
1317           {
1318             TREE_OPERAND (stmt, 1)
1319               = extract_component (bsi, TREE_OPERAND (rhs, 0),
1320                                    TREE_CODE (rhs) == IMAGPART_EXPR, false);
1321             update_stmt (stmt);
1322           }
1323       }
1324       return;
1325     }
1326
1327   /* Extract the components of the two complex values.  Make sure and
1328      handle the common case of the same value used twice specially.  */
1329   ac = TREE_OPERAND (rhs, 0);
1330   ar = extract_component (bsi, ac, 0, true);
1331   ai = extract_component (bsi, ac, 1, true);
1332
1333   if (TREE_CODE_CLASS (code) == tcc_unary)
1334     bc = br = bi = NULL;
1335   else
1336     {
1337       bc = TREE_OPERAND (rhs, 1);
1338       if (ac == bc)
1339         br = ar, bi = ai;
1340       else
1341         {
1342           br = extract_component (bsi, bc, 0, true);
1343           bi = extract_component (bsi, bc, 1, true);
1344         }
1345     }
1346
1347   if (in_ssa_p)
1348     {
1349       al = find_lattice_value (ac);
1350       if (al == UNINITIALIZED)
1351         al = VARYING;
1352
1353       if (TREE_CODE_CLASS (code) == tcc_unary)
1354         bl = UNINITIALIZED;
1355       else if (ac == bc)
1356         bl = al;
1357       else
1358         {
1359           bl = find_lattice_value (bc);
1360           if (bl == UNINITIALIZED)
1361             bl = VARYING;
1362         }
1363     }
1364   else
1365     al = bl = VARYING;
1366
1367   switch (code)
1368     {
1369     case PLUS_EXPR:
1370     case MINUS_EXPR:
1371       expand_complex_addition (bsi, inner_type, ar, ai, br, bi, code, al, bl);
1372       break;
1373
1374     case MULT_EXPR:
1375       expand_complex_multiplication (bsi, inner_type, ar, ai, br, bi, al, bl);
1376       break;
1377
1378     case TRUNC_DIV_EXPR:
1379     case CEIL_DIV_EXPR:
1380     case FLOOR_DIV_EXPR:
1381     case ROUND_DIV_EXPR:
1382     case RDIV_EXPR:
1383       expand_complex_division (bsi, inner_type, ar, ai, br, bi, code, al, bl);
1384       break;
1385       
1386     case NEGATE_EXPR:
1387       expand_complex_negation (bsi, inner_type, ar, ai);
1388       break;
1389
1390     case CONJ_EXPR:
1391       expand_complex_conjugate (bsi, inner_type, ar, ai);
1392       break;
1393
1394     case EQ_EXPR:
1395     case NE_EXPR:
1396       expand_complex_comparison (bsi, ar, ai, br, bi, code);
1397       break;
1398
1399     default:
1400       gcc_unreachable ();
1401     }
1402 }
1403
1404 \f
1405 /* Entry point for complex operation lowering during optimization.  */
1406
1407 static void
1408 tree_lower_complex (void)
1409 {
1410   int old_last_basic_block;
1411   block_stmt_iterator bsi;
1412   basic_block bb;
1413
1414   if (!init_dont_simulate_again ())
1415     return;
1416
1417   complex_lattice_values = VEC_alloc (complex_lattice_t, heap, num_ssa_names);
1418   VEC_safe_grow (complex_lattice_t, heap,
1419                  complex_lattice_values, num_ssa_names);
1420   memset (VEC_address (complex_lattice_t, complex_lattice_values), 0,
1421           num_ssa_names * sizeof(complex_lattice_t));
1422   init_parameter_lattice_values ();
1423
1424   ssa_propagate (complex_visit_stmt, complex_visit_phi);
1425
1426   create_components ();
1427   update_parameter_components ();
1428
1429   old_last_basic_block = last_basic_block;
1430   FOR_EACH_BB (bb)
1431     {
1432       if (bb->index >= old_last_basic_block)
1433         continue;
1434       update_phi_components (bb);
1435       for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
1436         expand_complex_operations_1 (&bsi);
1437     }
1438
1439   bsi_commit_edge_inserts ();
1440
1441   if (complex_variable_components)
1442     htab_delete (complex_variable_components);
1443
1444   VEC_free (complex_lattice_t, heap, complex_lattice_values);
1445 }
1446
1447 struct tree_opt_pass pass_lower_complex = 
1448 {
1449   "cplxlower",                          /* name */
1450   0,                                    /* gate */
1451   tree_lower_complex,                   /* execute */
1452   NULL,                                 /* sub */
1453   NULL,                                 /* next */
1454   0,                                    /* static_pass_number */
1455   0,                                    /* tv_id */
1456   PROP_ssa,                             /* properties_required */
1457   0,                                    /* properties_provided */
1458   0,                                    /* properties_destroyed */
1459   0,                                    /* todo_flags_start */
1460   TODO_dump_func | TODO_ggc_collect
1461     | TODO_update_ssa
1462     | TODO_verify_stmts,                /* todo_flags_finish */
1463   0                                     /* letter */
1464 };
1465
1466 \f
1467 /* Entry point for complex operation lowering without optimization.  */
1468
1469 static void
1470 tree_lower_complex_O0 (void)
1471 {
1472   int old_last_basic_block = last_basic_block;
1473   block_stmt_iterator bsi;
1474   basic_block bb;
1475
1476   FOR_EACH_BB (bb)
1477     {
1478       if (bb->index >= old_last_basic_block)
1479         continue;
1480       for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
1481         expand_complex_operations_1 (&bsi);
1482     }
1483 }
1484
1485 static bool
1486 gate_no_optimization (void)
1487 {
1488   return optimize == 0;
1489 }
1490
1491 struct tree_opt_pass pass_lower_complex_O0 = 
1492 {
1493   "cplxlower0",                         /* name */
1494   gate_no_optimization,                 /* gate */
1495   tree_lower_complex_O0,                /* execute */
1496   NULL,                                 /* sub */
1497   NULL,                                 /* next */
1498   0,                                    /* static_pass_number */
1499   0,                                    /* tv_id */
1500   PROP_cfg,                             /* properties_required */
1501   0,                                    /* properties_provided */
1502   0,                                    /* properties_destroyed */
1503   0,                                    /* todo_flags_start */
1504   TODO_dump_func | TODO_ggc_collect
1505     | TODO_verify_stmts,                /* todo_flags_finish */
1506   0                                     /* letter */
1507 };