OSDN Git Service

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