xref: /netbsd-src/external/gpl3/gcc/dist/gcc/tree-complex.cc (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1 /* Lower complex number operations to scalar operations.
2    Copyright (C) 2004-2022 Free Software Foundation, Inc.
3 
4 This file is part of GCC.
5 
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3, or (at your option) any
9 later version.
10 
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19 
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "backend.h"
24 #include "rtl.h"
25 #include "tree.h"
26 #include "gimple.h"
27 #include "cfghooks.h"
28 #include "tree-pass.h"
29 #include "ssa.h"
30 #include "fold-const.h"
31 #include "stor-layout.h"
32 #include "tree-eh.h"
33 #include "gimplify.h"
34 #include "gimple-iterator.h"
35 #include "gimplify-me.h"
36 #include "tree-cfg.h"
37 #include "tree-dfa.h"
38 #include "tree-ssa.h"
39 #include "tree-ssa-propagate.h"
40 #include "tree-hasher.h"
41 #include "cfgloop.h"
42 #include "cfganal.h"
43 #include "gimple-fold.h"
44 #include "diagnostic-core.h"
45 
46 
47 /* For each complex ssa name, a lattice value.  We're interested in finding
48    out whether a complex number is degenerate in some way, having only real
49    or only complex parts.  */
50 
51 enum
52 {
53   UNINITIALIZED = 0,
54   ONLY_REAL = 1,
55   ONLY_IMAG = 2,
56   VARYING = 3
57 };
58 
59 /* The type complex_lattice_t holds combinations of the above
60    constants.  */
61 typedef int complex_lattice_t;
62 
63 #define PAIR(a, b)  ((a) << 2 | (b))
64 
65 class complex_propagate : public ssa_propagation_engine
66 {
67   enum ssa_prop_result visit_stmt (gimple *, edge *, tree *) FINAL OVERRIDE;
68   enum ssa_prop_result visit_phi (gphi *) FINAL OVERRIDE;
69 };
70 
71 static vec<complex_lattice_t> complex_lattice_values;
72 
73 /* For each complex variable, a pair of variables for the components exists in
74    the hashtable.  */
75 static int_tree_htab_type *complex_variable_components;
76 
77 /* For each complex SSA_NAME, a pair of ssa names for the components.  */
78 static vec<tree> complex_ssa_name_components;
79 
80 /* Vector of PHI triplets (original complex PHI and corresponding real and
81    imag PHIs if real and/or imag PHIs contain temporarily
82    non-SSA_NAME/non-invariant args that need to be replaced by SSA_NAMEs.  */
83 static vec<gphi *> phis_to_revisit;
84 
85 /* BBs that need EH cleanup.  */
86 static bitmap need_eh_cleanup;
87 
88 /* Lookup UID in the complex_variable_components hashtable and return the
89    associated tree.  */
90 static tree
cvc_lookup(unsigned int uid)91 cvc_lookup (unsigned int uid)
92 {
93   struct int_tree_map in;
94   in.uid = uid;
95   return complex_variable_components->find_with_hash (in, uid).to;
96 }
97 
98 /* Insert the pair UID, TO into the complex_variable_components hashtable.  */
99 
100 static void
cvc_insert(unsigned int uid,tree to)101 cvc_insert (unsigned int uid, tree to)
102 {
103   int_tree_map h;
104   int_tree_map *loc;
105 
106   h.uid = uid;
107   loc = complex_variable_components->find_slot_with_hash (h, uid, INSERT);
108   loc->uid = uid;
109   loc->to = to;
110 }
111 
112 /* Return true if T is not a zero constant.  In the case of real values,
113    we're only interested in +0.0.  */
114 
115 static int
some_nonzerop(tree t)116 some_nonzerop (tree t)
117 {
118   int zerop = false;
119 
120   /* Operations with real or imaginary part of a complex number zero
121      cannot be treated the same as operations with a real or imaginary
122      operand if we care about the signs of zeros in the result.  */
123   if (TREE_CODE (t) == REAL_CST && !flag_signed_zeros)
124     zerop = real_identical (&TREE_REAL_CST (t), &dconst0);
125   else if (TREE_CODE (t) == FIXED_CST)
126     zerop = fixed_zerop (t);
127   else if (TREE_CODE (t) == INTEGER_CST)
128     zerop = integer_zerop (t);
129 
130   return !zerop;
131 }
132 
133 
134 /* Compute a lattice value from the components of a complex type REAL
135    and IMAG.  */
136 
137 static complex_lattice_t
find_lattice_value_parts(tree real,tree imag)138 find_lattice_value_parts (tree real, tree imag)
139 {
140   int r, i;
141   complex_lattice_t ret;
142 
143   r = some_nonzerop (real);
144   i = some_nonzerop (imag);
145   ret = r * ONLY_REAL + i * ONLY_IMAG;
146 
147   /* ??? On occasion we could do better than mapping 0+0i to real, but we
148      certainly don't want to leave it UNINITIALIZED, which eventually gets
149      mapped to VARYING.  */
150   if (ret == UNINITIALIZED)
151     ret = ONLY_REAL;
152 
153   return ret;
154 }
155 
156 
157 /* Compute a lattice value from gimple_val T.  */
158 
159 static complex_lattice_t
find_lattice_value(tree t)160 find_lattice_value (tree t)
161 {
162   tree real, imag;
163 
164   switch (TREE_CODE (t))
165     {
166     case SSA_NAME:
167       return complex_lattice_values[SSA_NAME_VERSION (t)];
168 
169     case COMPLEX_CST:
170       real = TREE_REALPART (t);
171       imag = TREE_IMAGPART (t);
172       break;
173 
174     default:
175       gcc_unreachable ();
176     }
177 
178   return find_lattice_value_parts (real, imag);
179 }
180 
181 /* Determine if LHS is something for which we're interested in seeing
182    simulation results.  */
183 
184 static bool
is_complex_reg(tree lhs)185 is_complex_reg (tree lhs)
186 {
187   return TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE && is_gimple_reg (lhs);
188 }
189 
190 /* Mark the incoming parameters to the function as VARYING.  */
191 
192 static void
init_parameter_lattice_values(void)193 init_parameter_lattice_values (void)
194 {
195   tree parm, ssa_name;
196 
197   for (parm = DECL_ARGUMENTS (cfun->decl); parm ; parm = DECL_CHAIN (parm))
198     if (is_complex_reg (parm)
199 	&& (ssa_name = ssa_default_def (cfun, parm)) != NULL_TREE)
200       complex_lattice_values[SSA_NAME_VERSION (ssa_name)] = VARYING;
201 }
202 
203 /* Initialize simulation state for each statement.  Return false if we
204    found no statements we want to simulate, and thus there's nothing
205    for the entire pass to do.  */
206 
207 static bool
init_dont_simulate_again(void)208 init_dont_simulate_again (void)
209 {
210   basic_block bb;
211   bool saw_a_complex_op = false;
212 
213   FOR_EACH_BB_FN (bb, cfun)
214     {
215       for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
216 	   gsi_next (&gsi))
217 	{
218 	  gphi *phi = gsi.phi ();
219 	  prop_set_simulate_again (phi,
220 				   is_complex_reg (gimple_phi_result (phi)));
221 	}
222 
223       for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
224 	   gsi_next (&gsi))
225 	{
226 	  gimple *stmt;
227 	  tree op0, op1;
228 	  bool sim_again_p;
229 
230 	  stmt = gsi_stmt (gsi);
231 	  op0 = op1 = NULL_TREE;
232 
233 	  /* Most control-altering statements must be initially
234 	     simulated, else we won't cover the entire cfg.  */
235 	  sim_again_p = stmt_ends_bb_p (stmt);
236 
237 	  switch (gimple_code (stmt))
238 	    {
239 	    case GIMPLE_CALL:
240 	      if (gimple_call_lhs (stmt))
241 	        sim_again_p = is_complex_reg (gimple_call_lhs (stmt));
242 	      break;
243 
244 	    case GIMPLE_ASSIGN:
245 	      sim_again_p = is_complex_reg (gimple_assign_lhs (stmt));
246 	      if (gimple_assign_rhs_code (stmt) == REALPART_EXPR
247 		  || gimple_assign_rhs_code (stmt) == IMAGPART_EXPR)
248 		op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
249 	      else
250 		op0 = gimple_assign_rhs1 (stmt);
251 	      if (gimple_num_ops (stmt) > 2)
252 		op1 = gimple_assign_rhs2 (stmt);
253 	      break;
254 
255 	    case GIMPLE_COND:
256 	      op0 = gimple_cond_lhs (stmt);
257 	      op1 = gimple_cond_rhs (stmt);
258 	      break;
259 
260 	    default:
261 	      break;
262 	    }
263 
264 	  if (op0 || op1)
265 	    switch (gimple_expr_code (stmt))
266 	      {
267 	      case EQ_EXPR:
268 	      case NE_EXPR:
269 	      case PLUS_EXPR:
270 	      case MINUS_EXPR:
271 	      case MULT_EXPR:
272 	      case TRUNC_DIV_EXPR:
273 	      case CEIL_DIV_EXPR:
274 	      case FLOOR_DIV_EXPR:
275 	      case ROUND_DIV_EXPR:
276 	      case RDIV_EXPR:
277 		if (TREE_CODE (TREE_TYPE (op0)) == COMPLEX_TYPE
278 		    || TREE_CODE (TREE_TYPE (op1)) == COMPLEX_TYPE)
279 		  saw_a_complex_op = true;
280 		break;
281 
282 	      case NEGATE_EXPR:
283 	      case CONJ_EXPR:
284 		if (TREE_CODE (TREE_TYPE (op0)) == COMPLEX_TYPE)
285 		  saw_a_complex_op = true;
286 		break;
287 
288 	      case REALPART_EXPR:
289 	      case IMAGPART_EXPR:
290 		/* The total store transformation performed during
291 		  gimplification creates such uninitialized loads
292 		  and we need to lower the statement to be able
293 		  to fix things up.  */
294 		if (TREE_CODE (op0) == SSA_NAME
295 		    && ssa_undefined_value_p (op0))
296 		  saw_a_complex_op = true;
297 		break;
298 
299 	      default:
300 		break;
301 	      }
302 
303 	  prop_set_simulate_again (stmt, sim_again_p);
304 	}
305     }
306 
307   return saw_a_complex_op;
308 }
309 
310 
311 /* Evaluate statement STMT against the complex lattice defined above.  */
312 
313 enum ssa_prop_result
visit_stmt(gimple * stmt,edge * taken_edge_p ATTRIBUTE_UNUSED,tree * result_p)314 complex_propagate::visit_stmt (gimple *stmt, edge *taken_edge_p ATTRIBUTE_UNUSED,
315 			       tree *result_p)
316 {
317   complex_lattice_t new_l, old_l, op1_l, op2_l;
318   unsigned int ver;
319   tree lhs;
320 
321   lhs = gimple_get_lhs (stmt);
322   /* Skip anything but GIMPLE_ASSIGN and GIMPLE_CALL with a lhs.  */
323   if (!lhs || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
324     return SSA_PROP_VARYING;
325 
326   /* These conditions should be satisfied due to the initial filter
327      set up in init_dont_simulate_again.  */
328   gcc_assert (TREE_CODE (lhs) == SSA_NAME);
329   gcc_assert (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE);
330 
331   *result_p = lhs;
332   ver = SSA_NAME_VERSION (lhs);
333   old_l = complex_lattice_values[ver];
334 
335   switch (gimple_expr_code (stmt))
336     {
337     case SSA_NAME:
338     case COMPLEX_CST:
339       new_l = find_lattice_value (gimple_assign_rhs1 (stmt));
340       break;
341 
342     case COMPLEX_EXPR:
343       new_l = find_lattice_value_parts (gimple_assign_rhs1 (stmt),
344 				        gimple_assign_rhs2 (stmt));
345       break;
346 
347     case PLUS_EXPR:
348     case MINUS_EXPR:
349       op1_l = find_lattice_value (gimple_assign_rhs1 (stmt));
350       op2_l = find_lattice_value (gimple_assign_rhs2 (stmt));
351 
352       /* We've set up the lattice values such that IOR neatly
353 	 models addition.  */
354       new_l = op1_l | op2_l;
355       break;
356 
357     case MULT_EXPR:
358     case RDIV_EXPR:
359     case TRUNC_DIV_EXPR:
360     case CEIL_DIV_EXPR:
361     case FLOOR_DIV_EXPR:
362     case ROUND_DIV_EXPR:
363       op1_l = find_lattice_value (gimple_assign_rhs1 (stmt));
364       op2_l = find_lattice_value (gimple_assign_rhs2 (stmt));
365 
366       /* Obviously, if either varies, so does the result.  */
367       if (op1_l == VARYING || op2_l == VARYING)
368 	new_l = VARYING;
369       /* Don't prematurely promote variables if we've not yet seen
370 	 their inputs.  */
371       else if (op1_l == UNINITIALIZED)
372 	new_l = op2_l;
373       else if (op2_l == UNINITIALIZED)
374 	new_l = op1_l;
375       else
376 	{
377 	  /* At this point both numbers have only one component. If the
378 	     numbers are of opposite kind, the result is imaginary,
379 	     otherwise the result is real. The add/subtract translates
380 	     the real/imag from/to 0/1; the ^ performs the comparison.  */
381 	  new_l = ((op1_l - ONLY_REAL) ^ (op2_l - ONLY_REAL)) + ONLY_REAL;
382 
383 	  /* Don't allow the lattice value to flip-flop indefinitely.  */
384 	  new_l |= old_l;
385 	}
386       break;
387 
388     case NEGATE_EXPR:
389     case CONJ_EXPR:
390       new_l = find_lattice_value (gimple_assign_rhs1 (stmt));
391       break;
392 
393     default:
394       new_l = VARYING;
395       break;
396     }
397 
398   /* If nothing changed this round, let the propagator know.  */
399   if (new_l == old_l)
400     return SSA_PROP_NOT_INTERESTING;
401 
402   complex_lattice_values[ver] = new_l;
403   return new_l == VARYING ? SSA_PROP_VARYING : SSA_PROP_INTERESTING;
404 }
405 
406 /* Evaluate a PHI node against the complex lattice defined above.  */
407 
408 enum ssa_prop_result
visit_phi(gphi * phi)409 complex_propagate::visit_phi (gphi *phi)
410 {
411   complex_lattice_t new_l, old_l;
412   unsigned int ver;
413   tree lhs;
414   int i;
415 
416   lhs = gimple_phi_result (phi);
417 
418   /* This condition should be satisfied due to the initial filter
419      set up in init_dont_simulate_again.  */
420   gcc_assert (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE);
421 
422   if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
423     return SSA_PROP_VARYING;
424 
425   /* We've set up the lattice values such that IOR neatly models PHI meet.  */
426   new_l = UNINITIALIZED;
427   for (i = gimple_phi_num_args (phi) - 1; i >= 0; --i)
428     new_l |= find_lattice_value (gimple_phi_arg_def (phi, i));
429 
430   ver = SSA_NAME_VERSION (lhs);
431   old_l = complex_lattice_values[ver];
432 
433   if (new_l == old_l)
434     return SSA_PROP_NOT_INTERESTING;
435 
436   complex_lattice_values[ver] = new_l;
437   return new_l == VARYING ? SSA_PROP_VARYING : SSA_PROP_INTERESTING;
438 }
439 
440 /* Create one backing variable for a complex component of ORIG.  */
441 
442 static tree
create_one_component_var(tree type,tree orig,const char * prefix,const char * suffix,enum tree_code code)443 create_one_component_var (tree type, tree orig, const char *prefix,
444 			  const char *suffix, enum tree_code code)
445 {
446   tree r = create_tmp_var (type, prefix);
447 
448   DECL_SOURCE_LOCATION (r) = DECL_SOURCE_LOCATION (orig);
449   DECL_ARTIFICIAL (r) = 1;
450 
451   if (DECL_NAME (orig) && !DECL_IGNORED_P (orig))
452     {
453       const char *name = IDENTIFIER_POINTER (DECL_NAME (orig));
454       name = ACONCAT ((name, suffix, NULL));
455       DECL_NAME (r) = get_identifier (name);
456 
457       SET_DECL_DEBUG_EXPR (r, build1 (code, type, orig));
458       DECL_HAS_DEBUG_EXPR_P (r) = 1;
459       DECL_IGNORED_P (r) = 0;
460       copy_warning (r, orig);
461     }
462   else
463     {
464       DECL_IGNORED_P (r) = 1;
465       suppress_warning (r);
466     }
467 
468   return r;
469 }
470 
471 /* Retrieve a value for a complex component of VAR.  */
472 
473 static tree
get_component_var(tree var,bool imag_p)474 get_component_var (tree var, bool imag_p)
475 {
476   size_t decl_index = DECL_UID (var) * 2 + imag_p;
477   tree ret = cvc_lookup (decl_index);
478 
479   if (ret == NULL)
480     {
481       ret = create_one_component_var (TREE_TYPE (TREE_TYPE (var)), var,
482 				      imag_p ? "CI" : "CR",
483 				      imag_p ? "$imag" : "$real",
484 				      imag_p ? IMAGPART_EXPR : REALPART_EXPR);
485       cvc_insert (decl_index, ret);
486     }
487 
488   return ret;
489 }
490 
491 /* Retrieve a value for a complex component of SSA_NAME.  */
492 
493 static tree
get_component_ssa_name(tree ssa_name,bool imag_p)494 get_component_ssa_name (tree ssa_name, bool imag_p)
495 {
496   complex_lattice_t lattice = find_lattice_value (ssa_name);
497   size_t ssa_name_index;
498   tree ret;
499 
500   if (lattice == (imag_p ? ONLY_REAL : ONLY_IMAG))
501     {
502       tree inner_type = TREE_TYPE (TREE_TYPE (ssa_name));
503       if (SCALAR_FLOAT_TYPE_P (inner_type))
504 	return build_real (inner_type, dconst0);
505       else
506 	return build_int_cst (inner_type, 0);
507     }
508 
509   ssa_name_index = SSA_NAME_VERSION (ssa_name) * 2 + imag_p;
510   ret = complex_ssa_name_components[ssa_name_index];
511   if (ret == NULL)
512     {
513       if (SSA_NAME_VAR (ssa_name))
514 	ret = get_component_var (SSA_NAME_VAR (ssa_name), imag_p);
515       else
516 	ret = TREE_TYPE (TREE_TYPE (ssa_name));
517       ret = make_ssa_name (ret);
518 
519       /* Copy some properties from the original.  In particular, whether it
520 	 is used in an abnormal phi, and whether it's uninitialized.  */
521       SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ret)
522 	= SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssa_name);
523       if (SSA_NAME_IS_DEFAULT_DEF (ssa_name)
524 	  && TREE_CODE (SSA_NAME_VAR (ssa_name)) == VAR_DECL)
525 	{
526 	  SSA_NAME_DEF_STMT (ret) = SSA_NAME_DEF_STMT (ssa_name);
527 	  set_ssa_default_def (cfun, SSA_NAME_VAR (ret), ret);
528 	}
529 
530       complex_ssa_name_components[ssa_name_index] = ret;
531     }
532 
533   return ret;
534 }
535 
536 /* Set a value for a complex component of SSA_NAME, return a
537    gimple_seq of stuff that needs doing.  */
538 
539 static gimple_seq
set_component_ssa_name(tree ssa_name,bool imag_p,tree value)540 set_component_ssa_name (tree ssa_name, bool imag_p, tree value)
541 {
542   complex_lattice_t lattice = find_lattice_value (ssa_name);
543   size_t ssa_name_index;
544   tree comp;
545   gimple *last;
546   gimple_seq list;
547 
548   /* We know the value must be zero, else there's a bug in our lattice
549      analysis.  But the value may well be a variable known to contain
550      zero.  We should be safe ignoring it.  */
551   if (lattice == (imag_p ? ONLY_REAL : ONLY_IMAG))
552     return NULL;
553 
554   /* If we've already assigned an SSA_NAME to this component, then this
555      means that our walk of the basic blocks found a use before the set.
556      This is fine.  Now we should create an initialization for the value
557      we created earlier.  */
558   ssa_name_index = SSA_NAME_VERSION (ssa_name) * 2 + imag_p;
559   comp = complex_ssa_name_components[ssa_name_index];
560   if (comp)
561     ;
562 
563   /* If we've nothing assigned, and the value we're given is already stable,
564      then install that as the value for this SSA_NAME.  This preemptively
565      copy-propagates the value, which avoids unnecessary memory allocation.  */
566   else if (is_gimple_min_invariant (value)
567 	   && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssa_name))
568     {
569       complex_ssa_name_components[ssa_name_index] = value;
570       return NULL;
571     }
572   else if (TREE_CODE (value) == SSA_NAME
573 	   && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssa_name))
574     {
575       /* Replace an anonymous base value with the variable from cvc_lookup.
576 	 This should result in better debug info.  */
577       if (!SSA_NAME_IS_DEFAULT_DEF (value)
578 	  && SSA_NAME_VAR (ssa_name)
579 	  && (!SSA_NAME_VAR (value) || DECL_IGNORED_P (SSA_NAME_VAR (value)))
580 	  && !DECL_IGNORED_P (SSA_NAME_VAR (ssa_name)))
581 	{
582 	  comp = get_component_var (SSA_NAME_VAR (ssa_name), imag_p);
583 	  replace_ssa_name_symbol (value, comp);
584 	}
585 
586       complex_ssa_name_components[ssa_name_index] = value;
587       return NULL;
588     }
589 
590   /* Finally, we need to stabilize the result by installing the value into
591      a new ssa name.  */
592   else
593     comp = get_component_ssa_name (ssa_name, imag_p);
594 
595   /* Do all the work to assign VALUE to COMP.  */
596   list = NULL;
597   value = force_gimple_operand (value, &list, false, NULL);
598   last =  gimple_build_assign (comp, value);
599   gimple_seq_add_stmt (&list, last);
600   gcc_assert (SSA_NAME_DEF_STMT (comp) == last);
601 
602   return list;
603 }
604 
605 /* Extract the real or imaginary part of a complex variable or constant.
606    Make sure that it's a proper gimple_val and gimplify it if not.
607    Emit any new code before gsi.  */
608 
609 static tree
extract_component(gimple_stmt_iterator * gsi,tree t,bool imagpart_p,bool gimple_p,bool phiarg_p=false)610 extract_component (gimple_stmt_iterator *gsi, tree t, bool imagpart_p,
611 		   bool gimple_p, bool phiarg_p = false)
612 {
613   switch (TREE_CODE (t))
614     {
615     case COMPLEX_CST:
616       return imagpart_p ? TREE_IMAGPART (t) : TREE_REALPART (t);
617 
618     case COMPLEX_EXPR:
619       gcc_unreachable ();
620 
621     case BIT_FIELD_REF:
622       {
623 	tree inner_type = TREE_TYPE (TREE_TYPE (t));
624 	t = unshare_expr (t);
625 	TREE_TYPE (t) = inner_type;
626 	TREE_OPERAND (t, 1) = TYPE_SIZE (inner_type);
627 	if (imagpart_p)
628 	  TREE_OPERAND (t, 2) = size_binop (PLUS_EXPR, TREE_OPERAND (t, 2),
629 					    TYPE_SIZE (inner_type));
630 	if (gimple_p)
631 	  t = force_gimple_operand_gsi (gsi, t, true, NULL, true,
632 					GSI_SAME_STMT);
633 	return t;
634       }
635 
636     case VAR_DECL:
637     case RESULT_DECL:
638     case PARM_DECL:
639     case COMPONENT_REF:
640     case ARRAY_REF:
641     case VIEW_CONVERT_EXPR:
642     case MEM_REF:
643       {
644 	tree inner_type = TREE_TYPE (TREE_TYPE (t));
645 
646 	t = build1 ((imagpart_p ? IMAGPART_EXPR : REALPART_EXPR),
647 		    inner_type, unshare_expr (t));
648 
649 	if (gimple_p)
650 	  t = force_gimple_operand_gsi (gsi, t, true, NULL, true,
651                                         GSI_SAME_STMT);
652 
653 	return t;
654       }
655 
656     case SSA_NAME:
657       t = get_component_ssa_name (t, imagpart_p);
658       if (TREE_CODE (t) == SSA_NAME && SSA_NAME_DEF_STMT (t) == NULL)
659 	gcc_assert (phiarg_p);
660       return t;
661 
662     default:
663       gcc_unreachable ();
664     }
665 }
666 
667 /* Update the complex components of the ssa name on the lhs of STMT.  */
668 
669 static void
update_complex_components(gimple_stmt_iterator * gsi,gimple * stmt,tree r,tree i)670 update_complex_components (gimple_stmt_iterator *gsi, gimple *stmt, tree r,
671 			   tree i)
672 {
673   tree lhs;
674   gimple_seq list;
675 
676   lhs = gimple_get_lhs (stmt);
677 
678   list = set_component_ssa_name (lhs, false, r);
679   if (list)
680     gsi_insert_seq_after (gsi, list, GSI_CONTINUE_LINKING);
681 
682   list = set_component_ssa_name (lhs, true, i);
683   if (list)
684     gsi_insert_seq_after (gsi, list, GSI_CONTINUE_LINKING);
685 }
686 
687 static void
update_complex_components_on_edge(edge e,tree lhs,tree r,tree i)688 update_complex_components_on_edge (edge e, tree lhs, tree r, tree i)
689 {
690   gimple_seq list;
691 
692   list = set_component_ssa_name (lhs, false, r);
693   if (list)
694     gsi_insert_seq_on_edge (e, list);
695 
696   list = set_component_ssa_name (lhs, true, i);
697   if (list)
698     gsi_insert_seq_on_edge (e, list);
699 }
700 
701 
702 /* Update an assignment to a complex variable in place.  */
703 
704 static void
update_complex_assignment(gimple_stmt_iterator * gsi,tree r,tree i)705 update_complex_assignment (gimple_stmt_iterator *gsi, tree r, tree i)
706 {
707   gimple *old_stmt = gsi_stmt (*gsi);
708   gimple_assign_set_rhs_with_ops (gsi, COMPLEX_EXPR, r, i);
709   gimple *stmt = gsi_stmt (*gsi);
710   update_stmt (stmt);
711   if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
712     bitmap_set_bit (need_eh_cleanup, gimple_bb (stmt)->index);
713 
714   update_complex_components (gsi, gsi_stmt (*gsi), r, i);
715 }
716 
717 
718 /* Generate code at the entry point of the function to initialize the
719    component variables for a complex parameter.  */
720 
721 static void
update_parameter_components(void)722 update_parameter_components (void)
723 {
724   edge entry_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
725   tree parm;
726 
727   for (parm = DECL_ARGUMENTS (cfun->decl); parm ; parm = DECL_CHAIN (parm))
728     {
729       tree type = TREE_TYPE (parm);
730       tree ssa_name, r, i;
731 
732       if (TREE_CODE (type) != COMPLEX_TYPE || !is_gimple_reg (parm))
733 	continue;
734 
735       type = TREE_TYPE (type);
736       ssa_name = ssa_default_def (cfun, parm);
737       if (!ssa_name)
738 	continue;
739 
740       r = build1 (REALPART_EXPR, type, ssa_name);
741       i = build1 (IMAGPART_EXPR, type, ssa_name);
742       update_complex_components_on_edge (entry_edge, ssa_name, r, i);
743     }
744 }
745 
746 /* Generate code to set the component variables of a complex variable
747    to match the PHI statements in block BB.  */
748 
749 static void
update_phi_components(basic_block bb)750 update_phi_components (basic_block bb)
751 {
752   gphi_iterator gsi;
753 
754   for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
755     {
756       gphi *phi = gsi.phi ();
757 
758       if (is_complex_reg (gimple_phi_result (phi)))
759 	{
760 	  gphi *p[2] = { NULL, NULL };
761 	  unsigned int i, j, n;
762 	  bool revisit_phi = false;
763 
764 	  for (j = 0; j < 2; j++)
765 	    {
766 	      tree l = get_component_ssa_name (gimple_phi_result (phi), j > 0);
767 	      if (TREE_CODE (l) == SSA_NAME)
768 		p[j] = create_phi_node (l, bb);
769 	    }
770 
771 	  for (i = 0, n = gimple_phi_num_args (phi); i < n; ++i)
772 	    {
773 	      tree comp, arg = gimple_phi_arg_def (phi, i);
774 	      for (j = 0; j < 2; j++)
775 		if (p[j])
776 		  {
777 		    comp = extract_component (NULL, arg, j > 0, false, true);
778 		    if (TREE_CODE (comp) == SSA_NAME
779 			&& SSA_NAME_DEF_STMT (comp) == NULL)
780 		      {
781 			/* For the benefit of any gimple simplification during
782 			   this pass that might walk SSA_NAME def stmts,
783 			   don't add SSA_NAMEs without definitions into the
784 			   PHI arguments, but put a decl in there instead
785 			   temporarily, and revisit this PHI later on.  */
786 			if (SSA_NAME_VAR (comp))
787 			  comp = SSA_NAME_VAR (comp);
788 			else
789 			  comp = create_tmp_reg (TREE_TYPE (comp),
790 						 get_name (comp));
791 			revisit_phi = true;
792 		      }
793 		    SET_PHI_ARG_DEF (p[j], i, comp);
794 		  }
795 	    }
796 
797 	  if (revisit_phi)
798 	    {
799 	      phis_to_revisit.safe_push (phi);
800 	      phis_to_revisit.safe_push (p[0]);
801 	      phis_to_revisit.safe_push (p[1]);
802 	    }
803 	}
804     }
805 }
806 
807 /* Expand a complex move to scalars.  */
808 
809 static void
expand_complex_move(gimple_stmt_iterator * gsi,tree type)810 expand_complex_move (gimple_stmt_iterator *gsi, tree type)
811 {
812   tree inner_type = TREE_TYPE (type);
813   tree r, i, lhs, rhs;
814   gimple *stmt = gsi_stmt (*gsi);
815 
816   if (is_gimple_assign (stmt))
817     {
818       lhs = gimple_assign_lhs (stmt);
819       if (gimple_num_ops (stmt) == 2)
820 	rhs = gimple_assign_rhs1 (stmt);
821       else
822 	rhs = NULL_TREE;
823     }
824   else if (is_gimple_call (stmt))
825     {
826       lhs = gimple_call_lhs (stmt);
827       rhs = NULL_TREE;
828     }
829   else
830     gcc_unreachable ();
831 
832   if (TREE_CODE (lhs) == SSA_NAME)
833     {
834       if (is_ctrl_altering_stmt (stmt))
835 	{
836 	  edge e;
837 
838 	  /* The value is not assigned on the exception edges, so we need not
839 	     concern ourselves there.  We do need to update on the fallthru
840 	     edge.  Find it.  */
841 	  e = find_fallthru_edge (gsi_bb (*gsi)->succs);
842 	  if (!e)
843 	    gcc_unreachable ();
844 
845 	  r = build1 (REALPART_EXPR, inner_type, lhs);
846 	  i = build1 (IMAGPART_EXPR, inner_type, lhs);
847 	  update_complex_components_on_edge (e, lhs, r, i);
848 	}
849       else if (is_gimple_call (stmt)
850 	       || gimple_has_side_effects (stmt)
851 	       || gimple_assign_rhs_code (stmt) == PAREN_EXPR)
852 	{
853 	  r = build1 (REALPART_EXPR, inner_type, lhs);
854 	  i = build1 (IMAGPART_EXPR, inner_type, lhs);
855 	  update_complex_components (gsi, stmt, r, i);
856 	}
857       else
858 	{
859 	  if (gimple_assign_rhs_code (stmt) != COMPLEX_EXPR)
860 	    {
861 	      r = extract_component (gsi, rhs, 0, true);
862 	      i = extract_component (gsi, rhs, 1, true);
863 	    }
864 	  else
865 	    {
866 	      r = gimple_assign_rhs1 (stmt);
867 	      i = gimple_assign_rhs2 (stmt);
868 	    }
869 	  update_complex_assignment (gsi, r, i);
870 	}
871     }
872   else if (rhs && TREE_CODE (rhs) == SSA_NAME && !TREE_SIDE_EFFECTS (lhs))
873     {
874       tree x;
875       gimple *t;
876       location_t loc;
877 
878       loc = gimple_location (stmt);
879       r = extract_component (gsi, rhs, 0, false);
880       i = extract_component (gsi, rhs, 1, false);
881 
882       x = build1 (REALPART_EXPR, inner_type, unshare_expr (lhs));
883       t = gimple_build_assign (x, r);
884       gimple_set_location (t, loc);
885       gsi_insert_before (gsi, t, GSI_SAME_STMT);
886 
887       if (stmt == gsi_stmt (*gsi))
888 	{
889 	  x = build1 (IMAGPART_EXPR, inner_type, unshare_expr (lhs));
890 	  gimple_assign_set_lhs (stmt, x);
891 	  gimple_assign_set_rhs1 (stmt, i);
892 	}
893       else
894 	{
895 	  x = build1 (IMAGPART_EXPR, inner_type, unshare_expr (lhs));
896 	  t = gimple_build_assign (x, i);
897 	  gimple_set_location (t, loc);
898 	  gsi_insert_before (gsi, t, GSI_SAME_STMT);
899 
900 	  stmt = gsi_stmt (*gsi);
901 	  gcc_assert (gimple_code (stmt) == GIMPLE_RETURN);
902 	  gimple_return_set_retval (as_a <greturn *> (stmt), lhs);
903 	}
904 
905       update_stmt (stmt);
906     }
907 }
908 
909 /* Expand complex addition to scalars:
910 	a + b = (ar + br) + i(ai + bi)
911 	a - b = (ar - br) + i(ai + bi)
912 */
913 
914 static void
expand_complex_addition(gimple_stmt_iterator * gsi,tree inner_type,tree ar,tree ai,tree br,tree bi,enum tree_code code,complex_lattice_t al,complex_lattice_t bl)915 expand_complex_addition (gimple_stmt_iterator *gsi, tree inner_type,
916 			 tree ar, tree ai, tree br, tree bi,
917 			 enum tree_code code,
918 			 complex_lattice_t al, complex_lattice_t bl)
919 {
920   tree rr, ri;
921   gimple_seq stmts = NULL;
922   location_t loc = gimple_location (gsi_stmt (*gsi));
923 
924   switch (PAIR (al, bl))
925     {
926     case PAIR (ONLY_REAL, ONLY_REAL):
927       rr = gimple_build (&stmts, loc, code, inner_type, ar, br);
928       ri = ai;
929       break;
930 
931     case PAIR (ONLY_REAL, ONLY_IMAG):
932       rr = ar;
933       if (code == MINUS_EXPR)
934 	ri = gimple_build (&stmts, loc, MINUS_EXPR, inner_type, ai, bi);
935       else
936 	ri = bi;
937       break;
938 
939     case PAIR (ONLY_IMAG, ONLY_REAL):
940       if (code == MINUS_EXPR)
941 	rr = gimple_build (&stmts, loc, MINUS_EXPR, inner_type, ar, br);
942       else
943 	rr = br;
944       ri = ai;
945       break;
946 
947     case PAIR (ONLY_IMAG, ONLY_IMAG):
948       rr = ar;
949       ri = gimple_build (&stmts, loc, code, inner_type, ai, bi);
950       break;
951 
952     case PAIR (VARYING, ONLY_REAL):
953       rr = gimple_build (&stmts, loc, code, inner_type, ar, br);
954       ri = ai;
955       break;
956 
957     case PAIR (VARYING, ONLY_IMAG):
958       rr = ar;
959       ri = gimple_build (&stmts, loc, code, inner_type, ai, bi);
960       break;
961 
962     case PAIR (ONLY_REAL, VARYING):
963       if (code == MINUS_EXPR)
964 	goto general;
965       rr = gimple_build (&stmts, loc, code, inner_type, ar, br);
966       ri = bi;
967       break;
968 
969     case PAIR (ONLY_IMAG, VARYING):
970       if (code == MINUS_EXPR)
971 	goto general;
972       rr = br;
973       ri = gimple_build (&stmts, loc, code, inner_type, ai, bi);
974       break;
975 
976     case PAIR (VARYING, VARYING):
977     general:
978       rr = gimple_build (&stmts, loc, code, inner_type, ar, br);
979       ri = gimple_build (&stmts, loc, code, inner_type, ai, bi);
980       break;
981 
982     default:
983       gcc_unreachable ();
984     }
985 
986   gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
987   update_complex_assignment (gsi, rr, ri);
988 }
989 
990 /* Expand a complex multiplication or division to a libcall to the c99
991    compliant routines.  TYPE is the complex type of the operation.
992    If INPLACE_P replace the statement at GSI with
993    the libcall and return NULL_TREE.  Else insert the call, assign its
994    result to an output variable and return that variable.  If INPLACE_P
995    is true then the statement being replaced should be an assignment
996    statement.  */
997 
998 static tree
expand_complex_libcall(gimple_stmt_iterator * gsi,tree type,tree ar,tree ai,tree br,tree bi,enum tree_code code,bool inplace_p)999 expand_complex_libcall (gimple_stmt_iterator *gsi, tree type, tree ar, tree ai,
1000 			tree br, tree bi, enum tree_code code, bool inplace_p)
1001 {
1002   machine_mode mode;
1003   enum built_in_function bcode;
1004   tree fn, lhs;
1005   gcall *stmt;
1006 
1007   mode = TYPE_MODE (type);
1008   gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
1009 
1010   if (code == MULT_EXPR)
1011     bcode = ((enum built_in_function)
1012 	     (BUILT_IN_COMPLEX_MUL_MIN + mode - MIN_MODE_COMPLEX_FLOAT));
1013   else if (code == RDIV_EXPR)
1014     bcode = ((enum built_in_function)
1015 	     (BUILT_IN_COMPLEX_DIV_MIN + mode - MIN_MODE_COMPLEX_FLOAT));
1016   else
1017     gcc_unreachable ();
1018   fn = builtin_decl_explicit (bcode);
1019   stmt = gimple_build_call (fn, 4, ar, ai, br, bi);
1020 
1021   if (inplace_p)
1022     {
1023       gimple *old_stmt = gsi_stmt (*gsi);
1024       gimple_call_set_nothrow (stmt, !stmt_could_throw_p (cfun, old_stmt));
1025       lhs = gimple_assign_lhs (old_stmt);
1026       gimple_call_set_lhs (stmt, lhs);
1027       gsi_replace (gsi, stmt, true);
1028 
1029       type = TREE_TYPE (type);
1030       if (stmt_can_throw_internal (cfun, stmt))
1031 	{
1032 	  edge_iterator ei;
1033 	  edge e;
1034 	  FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs)
1035 	      if (!(e->flags & EDGE_EH))
1036 		break;
1037 	  basic_block bb = split_edge (e);
1038 	  gimple_stmt_iterator gsi2 = gsi_start_bb (bb);
1039 	  update_complex_components (&gsi2, stmt,
1040 				     build1 (REALPART_EXPR, type, lhs),
1041 				     build1 (IMAGPART_EXPR, type, lhs));
1042 	  return NULL_TREE;
1043 	}
1044       else
1045 	update_complex_components (gsi, stmt,
1046 				   build1 (REALPART_EXPR, type, lhs),
1047 				   build1 (IMAGPART_EXPR, type, lhs));
1048       SSA_NAME_DEF_STMT (lhs) = stmt;
1049       return NULL_TREE;
1050     }
1051 
1052   gimple_call_set_nothrow (stmt, true);
1053   lhs = make_ssa_name (type);
1054   gimple_call_set_lhs (stmt, lhs);
1055   gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1056 
1057   return lhs;
1058 }
1059 
1060 /* Perform a complex multiplication on two complex constants A, B represented
1061    by AR, AI, BR, BI of type TYPE.
1062    The operation we want is: a * b = (ar*br - ai*bi) + i(ar*bi + br*ai).
1063    Insert the GIMPLE statements into GSI.  Store the real and imaginary
1064    components of the result into RR and RI.  */
1065 
1066 static void
expand_complex_multiplication_components(gimple_seq * stmts,location_t loc,tree type,tree ar,tree ai,tree br,tree bi,tree * rr,tree * ri)1067 expand_complex_multiplication_components (gimple_seq *stmts, location_t loc,
1068 					  tree type, tree ar, tree ai,
1069 					  tree br, tree bi,
1070 					  tree *rr, tree *ri)
1071 {
1072   tree t1, t2, t3, t4;
1073 
1074   t1 = gimple_build (stmts, loc, MULT_EXPR, type, ar, br);
1075   t2 = gimple_build (stmts, loc, MULT_EXPR, type, ai, bi);
1076   t3 = gimple_build (stmts, loc, MULT_EXPR, type, ar, bi);
1077 
1078   /* Avoid expanding redundant multiplication for the common
1079      case of squaring a complex number.  */
1080   if (ar == br && ai == bi)
1081     t4 = t3;
1082   else
1083     t4 = gimple_build (stmts, loc, MULT_EXPR, type, ai, br);
1084 
1085   *rr = gimple_build (stmts, loc, MINUS_EXPR, type, t1, t2);
1086   *ri = gimple_build (stmts, loc, PLUS_EXPR, type, t3, t4);
1087 }
1088 
1089 /* Expand complex multiplication to scalars:
1090 	a * b = (ar*br - ai*bi) + i(ar*bi + br*ai)
1091 */
1092 
1093 static void
expand_complex_multiplication(gimple_stmt_iterator * gsi,tree type,tree ar,tree ai,tree br,tree bi,complex_lattice_t al,complex_lattice_t bl)1094 expand_complex_multiplication (gimple_stmt_iterator *gsi, tree type,
1095 			       tree ar, tree ai, tree br, tree bi,
1096 			       complex_lattice_t al, complex_lattice_t bl)
1097 {
1098   tree rr, ri;
1099   tree inner_type = TREE_TYPE (type);
1100   location_t loc = gimple_location (gsi_stmt (*gsi));
1101   gimple_seq stmts = NULL;
1102 
1103   if (al < bl)
1104     {
1105       complex_lattice_t tl;
1106       rr = ar, ar = br, br = rr;
1107       ri = ai, ai = bi, bi = ri;
1108       tl = al, al = bl, bl = tl;
1109     }
1110 
1111   switch (PAIR (al, bl))
1112     {
1113     case PAIR (ONLY_REAL, ONLY_REAL):
1114       rr = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ar, br);
1115       ri = ai;
1116       break;
1117 
1118     case PAIR (ONLY_IMAG, ONLY_REAL):
1119       rr = ar;
1120       if (TREE_CODE (ai) == REAL_CST
1121 	  && real_identical (&TREE_REAL_CST (ai), &dconst1))
1122 	ri = br;
1123       else
1124 	ri = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ai, br);
1125       break;
1126 
1127     case PAIR (ONLY_IMAG, ONLY_IMAG):
1128       rr = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ai, bi);
1129       rr = gimple_build (&stmts, loc, NEGATE_EXPR, inner_type, rr);
1130       ri = ar;
1131       break;
1132 
1133     case PAIR (VARYING, ONLY_REAL):
1134       rr = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ar, br);
1135       ri = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ai, br);
1136       break;
1137 
1138     case PAIR (VARYING, ONLY_IMAG):
1139       rr = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ai, bi);
1140       rr = gimple_build (&stmts, loc, NEGATE_EXPR, inner_type, rr);
1141       ri = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ar, bi);
1142       break;
1143 
1144     case PAIR (VARYING, VARYING):
1145       if (flag_complex_method == 2 && SCALAR_FLOAT_TYPE_P (inner_type))
1146 	{
1147 	  /* If optimizing for size or not at all just do a libcall.
1148 	     Same if there are exception-handling edges or signaling NaNs.  */
1149 	  if (optimize == 0 || optimize_bb_for_size_p (gsi_bb (*gsi))
1150 	     || stmt_can_throw_internal (cfun, gsi_stmt (*gsi))
1151 	     || flag_signaling_nans)
1152 	    {
1153 	      expand_complex_libcall (gsi, type, ar, ai, br, bi,
1154 				      MULT_EXPR, true);
1155 	      return;
1156 	    }
1157 
1158 	  if (!HONOR_NANS (inner_type))
1159 	    {
1160 	      /* If we are not worrying about NaNs expand to
1161 		 (ar*br - ai*bi) + i(ar*bi + br*ai) directly.  */
1162 	      expand_complex_multiplication_components (&stmts, loc, inner_type,
1163 							ar, ai, br, bi,
1164 							&rr, &ri);
1165 	      break;
1166 	    }
1167 
1168 	  /* Else, expand x = a * b into
1169 	     x = (ar*br - ai*bi) + i(ar*bi + br*ai);
1170 	     if (isunordered (__real__ x, __imag__ x))
1171 		x = __muldc3 (a, b);  */
1172 
1173 	  tree tmpr, tmpi;
1174 	  expand_complex_multiplication_components (&stmts, loc,
1175 						    inner_type, ar, ai,
1176 						    br, bi, &tmpr, &tmpi);
1177 	  gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1178 	  stmts = NULL;
1179 
1180 	  gimple *check
1181 	    = gimple_build_cond (UNORDERED_EXPR, tmpr, tmpi,
1182 				 NULL_TREE, NULL_TREE);
1183 
1184 	  basic_block orig_bb = gsi_bb (*gsi);
1185 	  /* We want to keep track of the original complex multiplication
1186 	     statement as we're going to modify it later in
1187 	     update_complex_assignment.  Make sure that insert_cond_bb leaves
1188 	     that statement in the join block.  */
1189 	  gsi_prev (gsi);
1190 	  basic_block cond_bb
1191 	    = insert_cond_bb (gsi_bb (*gsi), gsi_stmt (*gsi), check,
1192 			      profile_probability::very_unlikely ());
1193 
1194 	  gimple_stmt_iterator cond_bb_gsi = gsi_last_bb (cond_bb);
1195 	  gsi_insert_after (&cond_bb_gsi, gimple_build_nop (), GSI_NEW_STMT);
1196 
1197 	  tree libcall_res
1198 	    = expand_complex_libcall (&cond_bb_gsi, type, ar, ai, br,
1199 				      bi, MULT_EXPR, false);
1200 	  gimple_seq stmts2 = NULL;
1201 	  tree cond_real = gimple_build (&stmts2, loc, REALPART_EXPR,
1202 					 inner_type, libcall_res);
1203 	  tree cond_imag = gimple_build (&stmts2, loc, IMAGPART_EXPR,
1204 					 inner_type, libcall_res);
1205 	  gsi_insert_seq_before (&cond_bb_gsi, stmts2, GSI_SAME_STMT);
1206 
1207 	  basic_block join_bb = single_succ_edge (cond_bb)->dest;
1208 	  *gsi = gsi_start_nondebug_after_labels_bb (join_bb);
1209 
1210 	  /* We have a conditional block with some assignments in cond_bb.
1211 	     Wire up the PHIs to wrap up.  */
1212 	  rr = make_ssa_name (inner_type);
1213 	  ri = make_ssa_name (inner_type);
1214 	  edge cond_to_join = single_succ_edge (cond_bb);
1215 	  edge orig_to_join = find_edge (orig_bb, join_bb);
1216 
1217 	  gphi *real_phi = create_phi_node (rr, gsi_bb (*gsi));
1218 	  add_phi_arg (real_phi, cond_real, cond_to_join, UNKNOWN_LOCATION);
1219 	  add_phi_arg (real_phi, tmpr, orig_to_join, UNKNOWN_LOCATION);
1220 
1221 	  gphi *imag_phi = create_phi_node (ri, gsi_bb (*gsi));
1222 	  add_phi_arg (imag_phi, cond_imag, cond_to_join, UNKNOWN_LOCATION);
1223 	  add_phi_arg (imag_phi, tmpi, orig_to_join, UNKNOWN_LOCATION);
1224 	}
1225       else
1226 	/* If we are not worrying about NaNs expand to
1227 	  (ar*br - ai*bi) + i(ar*bi + br*ai) directly.  */
1228 	expand_complex_multiplication_components (&stmts, loc,
1229 						  inner_type, ar, ai,
1230 						  br, bi, &rr, &ri);
1231       break;
1232 
1233     default:
1234       gcc_unreachable ();
1235     }
1236 
1237   gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1238   update_complex_assignment (gsi, rr, ri);
1239 }
1240 
1241 /* Keep this algorithm in sync with fold-const.cc:const_binop().
1242 
1243    Expand complex division to scalars, straightforward algorithm.
1244 	a / b = ((ar*br + ai*bi)/t) + i((ai*br - ar*bi)/t)
1245 	    t = br*br + bi*bi
1246 */
1247 
1248 static void
expand_complex_div_straight(gimple_stmt_iterator * gsi,tree inner_type,tree ar,tree ai,tree br,tree bi,enum tree_code code)1249 expand_complex_div_straight (gimple_stmt_iterator *gsi, tree inner_type,
1250 			     tree ar, tree ai, tree br, tree bi,
1251 			     enum tree_code code)
1252 {
1253   gimple_seq stmts = NULL;
1254   location_t loc = gimple_location (gsi_stmt (*gsi));
1255   tree rr, ri, div, t1, t2, t3;
1256 
1257   t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, br, br);
1258   t2 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, bi, bi);
1259   div = gimple_build (&stmts, loc, PLUS_EXPR, inner_type, t1, t2);
1260 
1261   t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ar, br);
1262   t2 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ai, bi);
1263   t3 = gimple_build (&stmts, loc, PLUS_EXPR, inner_type, t1, t2);
1264   rr = gimple_build (&stmts, loc, code, inner_type, t3, div);
1265 
1266   t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ai, br);
1267   t2 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ar, bi);
1268   t3 = gimple_build (&stmts, loc, MINUS_EXPR, inner_type, t1, t2);
1269   ri = gimple_build (&stmts, loc, code, inner_type, t3, div);
1270 
1271   gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1272   update_complex_assignment (gsi, rr, ri);
1273 }
1274 
1275 /* Keep this algorithm in sync with fold-const.cc:const_binop().
1276 
1277    Expand complex division to scalars, modified algorithm to minimize
1278    overflow with wide input ranges.  */
1279 
1280 static void
expand_complex_div_wide(gimple_stmt_iterator * gsi,tree inner_type,tree ar,tree ai,tree br,tree bi,enum tree_code code)1281 expand_complex_div_wide (gimple_stmt_iterator *gsi, tree inner_type,
1282 			 tree ar, tree ai, tree br, tree bi,
1283 			 enum tree_code code)
1284 {
1285   tree rr, ri, ratio, div, t1, t2, tr, ti, compare;
1286   basic_block bb_cond, bb_true, bb_false, bb_join;
1287   gimple *stmt;
1288   gimple_seq stmts = NULL;
1289   location_t loc = gimple_location (gsi_stmt (*gsi));
1290 
1291   /* Examine |br| < |bi|, and branch.  */
1292   t1 = gimple_build (&stmts, loc, ABS_EXPR, inner_type, br);
1293   t2 = gimple_build (&stmts, loc, ABS_EXPR, inner_type, bi);
1294   compare = gimple_build (&stmts, loc,
1295 			  LT_EXPR, boolean_type_node, t1, t2);
1296 
1297   bb_cond = bb_true = bb_false = bb_join = NULL;
1298   rr = ri = tr = ti = NULL;
1299   if (TREE_CODE (compare) != INTEGER_CST)
1300     {
1301       edge e;
1302       gimple *stmt;
1303 
1304       gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1305       stmts = NULL;
1306       stmt = gimple_build_cond (NE_EXPR, compare, boolean_false_node,
1307 				NULL_TREE, NULL_TREE);
1308       gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1309 
1310       /* Split the original block, and create the TRUE and FALSE blocks.  */
1311       e = split_block (gsi_bb (*gsi), stmt);
1312       bb_cond = e->src;
1313       bb_join = e->dest;
1314       bb_true = create_empty_bb (bb_cond);
1315       bb_false = create_empty_bb (bb_true);
1316       bb_true->count = bb_false->count
1317 	 = bb_cond->count.apply_probability (profile_probability::even ());
1318 
1319       /* Wire the blocks together.  */
1320       e->flags = EDGE_TRUE_VALUE;
1321       /* TODO: With value profile we could add an historgram to determine real
1322 	 branch outcome.  */
1323       e->probability = profile_probability::even ();
1324       redirect_edge_succ (e, bb_true);
1325       edge e2 = make_edge (bb_cond, bb_false, EDGE_FALSE_VALUE);
1326       e2->probability = profile_probability::even ();
1327       make_single_succ_edge (bb_true, bb_join, EDGE_FALLTHRU);
1328       make_single_succ_edge (bb_false, bb_join, EDGE_FALLTHRU);
1329       add_bb_to_loop (bb_true, bb_cond->loop_father);
1330       add_bb_to_loop (bb_false, bb_cond->loop_father);
1331 
1332       /* Update dominance info.  Note that bb_join's data was
1333          updated by split_block.  */
1334       if (dom_info_available_p (CDI_DOMINATORS))
1335         {
1336           set_immediate_dominator (CDI_DOMINATORS, bb_true, bb_cond);
1337           set_immediate_dominator (CDI_DOMINATORS, bb_false, bb_cond);
1338         }
1339 
1340       rr = create_tmp_reg (inner_type);
1341       ri = create_tmp_reg (inner_type);
1342     }
1343   else
1344     {
1345       gimple_seq_discard (stmts);
1346       stmts = NULL;
1347     }
1348 
1349   /* In the TRUE branch, we compute
1350       ratio = br/bi;
1351       div = (br * ratio) + bi;
1352       tr = (ar * ratio) + ai;
1353       ti = (ai * ratio) - ar;
1354       tr = tr / div;
1355       ti = ti / div;  */
1356   if (bb_true || integer_nonzerop (compare))
1357     {
1358       if (bb_true)
1359 	{
1360 	  *gsi = gsi_last_bb (bb_true);
1361 	  gsi_insert_after (gsi, gimple_build_nop (), GSI_NEW_STMT);
1362 	}
1363 
1364       ratio = gimple_build (&stmts, loc, code, inner_type, br, bi);
1365 
1366       t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, br, ratio);
1367       div = gimple_build (&stmts, loc, PLUS_EXPR, inner_type, t1, bi);
1368 
1369       t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ar, ratio);
1370       tr = gimple_build (&stmts, loc, PLUS_EXPR, inner_type, t1, ai);
1371 
1372       t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ai, ratio);
1373       ti = gimple_build (&stmts, loc, MINUS_EXPR, inner_type, t1, ar);
1374 
1375       tr = gimple_build (&stmts, loc, code, inner_type, tr, div);
1376       ti = gimple_build (&stmts, loc, code, inner_type, ti, div);
1377       gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1378       stmts = NULL;
1379 
1380      if (bb_true)
1381        {
1382 	 stmt = gimple_build_assign (rr, tr);
1383 	 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1384 	 stmt = gimple_build_assign (ri, ti);
1385 	 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1386 	 gsi_remove (gsi, true);
1387        }
1388     }
1389 
1390   /* In the FALSE branch, we compute
1391       ratio = d/c;
1392       divisor = (d * ratio) + c;
1393       tr = (b * ratio) + a;
1394       ti = b - (a * ratio);
1395       tr = tr / div;
1396       ti = ti / div;  */
1397   if (bb_false || integer_zerop (compare))
1398     {
1399       if (bb_false)
1400 	{
1401 	  *gsi = gsi_last_bb (bb_false);
1402 	  gsi_insert_after (gsi, gimple_build_nop (), GSI_NEW_STMT);
1403 	}
1404 
1405       ratio = gimple_build (&stmts, loc, code, inner_type, bi, br);
1406 
1407       t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, bi, ratio);
1408       div = gimple_build (&stmts, loc, PLUS_EXPR, inner_type, t1, br);
1409 
1410       t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ai, ratio);
1411       tr = gimple_build (&stmts, loc, PLUS_EXPR, inner_type, t1, ar);
1412 
1413       t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ar, ratio);
1414       ti = gimple_build (&stmts, loc, MINUS_EXPR, inner_type, ai, t1);
1415 
1416       tr = gimple_build (&stmts, loc, code, inner_type, tr, div);
1417       ti = gimple_build (&stmts, loc, code, inner_type, ti, div);
1418       gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1419       stmts = NULL;
1420 
1421      if (bb_false)
1422        {
1423 	 stmt = gimple_build_assign (rr, tr);
1424 	 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1425 	 stmt = gimple_build_assign (ri, ti);
1426 	 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1427 	 gsi_remove (gsi, true);
1428        }
1429     }
1430 
1431   if (bb_join)
1432     *gsi = gsi_start_bb (bb_join);
1433   else
1434     rr = tr, ri = ti;
1435 
1436   update_complex_assignment (gsi, rr, ri);
1437 }
1438 
1439 /* Expand complex division to scalars.  */
1440 
1441 static void
expand_complex_division(gimple_stmt_iterator * gsi,tree type,tree ar,tree ai,tree br,tree bi,enum tree_code code,complex_lattice_t al,complex_lattice_t bl)1442 expand_complex_division (gimple_stmt_iterator *gsi, tree type,
1443 			 tree ar, tree ai, tree br, tree bi,
1444 			 enum tree_code code,
1445 			 complex_lattice_t al, complex_lattice_t bl)
1446 {
1447   tree rr, ri;
1448   gimple_seq stmts = NULL;
1449   location_t loc = gimple_location (gsi_stmt (*gsi));
1450 
1451   tree inner_type = TREE_TYPE (type);
1452   switch (PAIR (al, bl))
1453     {
1454     case PAIR (ONLY_REAL, ONLY_REAL):
1455       rr = gimple_build (&stmts, loc, code, inner_type, ar, br);
1456       ri = ai;
1457       break;
1458 
1459     case PAIR (ONLY_REAL, ONLY_IMAG):
1460       rr = ai;
1461       ri = gimple_build (&stmts, loc, code, inner_type, ar, bi);
1462       ri = gimple_build (&stmts, loc, NEGATE_EXPR, inner_type, ri);
1463       break;
1464 
1465     case PAIR (ONLY_IMAG, ONLY_REAL):
1466       rr = ar;
1467       ri = gimple_build (&stmts, loc, code, inner_type, ai, br);
1468       break;
1469 
1470     case PAIR (ONLY_IMAG, ONLY_IMAG):
1471       rr = gimple_build (&stmts, loc, code, inner_type, ai, bi);
1472       ri = ar;
1473       break;
1474 
1475     case PAIR (VARYING, ONLY_REAL):
1476       rr = gimple_build (&stmts, loc, code, inner_type, ar, br);
1477       ri = gimple_build (&stmts, loc, code, inner_type, ai, br);
1478       break;
1479 
1480     case PAIR (VARYING, ONLY_IMAG):
1481       rr = gimple_build (&stmts, loc, code, inner_type, ai, bi);
1482       ri = gimple_build (&stmts, loc, code, inner_type, ar, bi);
1483       ri = gimple_build (&stmts, loc, NEGATE_EXPR, inner_type, ri);
1484       break;
1485 
1486     case PAIR (ONLY_REAL, VARYING):
1487     case PAIR (ONLY_IMAG, VARYING):
1488     case PAIR (VARYING, VARYING):
1489       switch (flag_complex_method)
1490 	{
1491 	case 0:
1492 	  /* straightforward implementation of complex divide acceptable.  */
1493 	  expand_complex_div_straight (gsi, inner_type, ar, ai, br, bi, code);
1494 	  break;
1495 
1496 	case 2:
1497 	  if (SCALAR_FLOAT_TYPE_P (inner_type))
1498 	    {
1499 	      expand_complex_libcall (gsi, type, ar, ai, br, bi, code, true);
1500 	      break;
1501 	    }
1502 	  /* FALLTHRU */
1503 
1504 	case 1:
1505 	  /* wide ranges of inputs must work for complex divide.  */
1506 	  expand_complex_div_wide (gsi, inner_type, ar, ai, br, bi, code);
1507 	  break;
1508 
1509 	default:
1510 	  gcc_unreachable ();
1511 	}
1512       return;
1513 
1514     default:
1515       gcc_unreachable ();
1516     }
1517 
1518   gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1519   update_complex_assignment (gsi, rr, ri);
1520 }
1521 
1522 /* Expand complex negation to scalars:
1523 	-a = (-ar) + i(-ai)
1524 */
1525 
1526 static void
expand_complex_negation(gimple_stmt_iterator * gsi,tree inner_type,tree ar,tree ai)1527 expand_complex_negation (gimple_stmt_iterator *gsi, tree inner_type,
1528 			 tree ar, tree ai)
1529 {
1530   tree rr, ri;
1531   gimple_seq stmts = NULL;
1532   location_t loc = gimple_location (gsi_stmt (*gsi));
1533 
1534   rr = gimple_build (&stmts, loc, NEGATE_EXPR, inner_type, ar);
1535   ri = gimple_build (&stmts, loc, NEGATE_EXPR, inner_type, ai);
1536 
1537   gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1538   update_complex_assignment (gsi, rr, ri);
1539 }
1540 
1541 /* Expand complex conjugate to scalars:
1542 	~a = (ar) + i(-ai)
1543 */
1544 
1545 static void
expand_complex_conjugate(gimple_stmt_iterator * gsi,tree inner_type,tree ar,tree ai)1546 expand_complex_conjugate (gimple_stmt_iterator *gsi, tree inner_type,
1547 			  tree ar, tree ai)
1548 {
1549   tree ri;
1550   gimple_seq stmts = NULL;
1551   location_t loc = gimple_location (gsi_stmt (*gsi));
1552 
1553   ri = gimple_build (&stmts, loc, NEGATE_EXPR, inner_type, ai);
1554 
1555   gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1556   update_complex_assignment (gsi, ar, ri);
1557 }
1558 
1559 /* Expand complex comparison (EQ or NE only).  */
1560 
1561 static void
expand_complex_comparison(gimple_stmt_iterator * gsi,tree ar,tree ai,tree br,tree bi,enum tree_code code)1562 expand_complex_comparison (gimple_stmt_iterator *gsi, tree ar, tree ai,
1563 			   tree br, tree bi, enum tree_code code)
1564 {
1565   tree cr, ci, cc, type;
1566   gimple *stmt = gsi_stmt (*gsi);
1567   gimple_seq stmts = NULL;
1568   location_t loc = gimple_location (stmt);
1569 
1570   cr = gimple_build (&stmts, loc, code, boolean_type_node, ar, br);
1571   ci = gimple_build (&stmts, loc, code, boolean_type_node, ai, bi);
1572   cc = gimple_build (&stmts, loc,
1573 		     (code == EQ_EXPR ? BIT_AND_EXPR : BIT_IOR_EXPR),
1574 		     boolean_type_node, cr, ci);
1575   gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1576 
1577   switch (gimple_code (stmt))
1578     {
1579     case GIMPLE_RETURN:
1580       {
1581 	greturn *return_stmt = as_a <greturn *> (stmt);
1582 	type = TREE_TYPE (gimple_return_retval (return_stmt));
1583 	gimple_return_set_retval (return_stmt, fold_convert (type, cc));
1584       }
1585       break;
1586 
1587     case GIMPLE_ASSIGN:
1588       type = TREE_TYPE (gimple_assign_lhs (stmt));
1589       gimple_assign_set_rhs_from_tree (gsi, fold_convert (type, cc));
1590       stmt = gsi_stmt (*gsi);
1591       break;
1592 
1593     case GIMPLE_COND:
1594       {
1595 	gcond *cond_stmt = as_a <gcond *> (stmt);
1596 	gimple_cond_set_code (cond_stmt, EQ_EXPR);
1597 	gimple_cond_set_lhs (cond_stmt, cc);
1598 	gimple_cond_set_rhs (cond_stmt, boolean_true_node);
1599       }
1600       break;
1601 
1602     default:
1603       gcc_unreachable ();
1604     }
1605 
1606   update_stmt (stmt);
1607   if (maybe_clean_eh_stmt (stmt))
1608     bitmap_set_bit (need_eh_cleanup, gimple_bb (stmt)->index);
1609 }
1610 
1611 /* Expand inline asm that sets some complex SSA_NAMEs.  */
1612 
1613 static void
expand_complex_asm(gimple_stmt_iterator * gsi)1614 expand_complex_asm (gimple_stmt_iterator *gsi)
1615 {
1616   gasm *stmt = as_a <gasm *> (gsi_stmt (*gsi));
1617   unsigned int i;
1618   bool diagnosed_p = false;
1619 
1620   for (i = 0; i < gimple_asm_noutputs (stmt); ++i)
1621     {
1622       tree link = gimple_asm_output_op (stmt, i);
1623       tree op = TREE_VALUE (link);
1624       if (TREE_CODE (op) == SSA_NAME
1625 	  && TREE_CODE (TREE_TYPE (op)) == COMPLEX_TYPE)
1626 	{
1627 	  if (gimple_asm_nlabels (stmt) > 0)
1628 	    {
1629 	      if (!diagnosed_p)
1630 		{
1631 		  sorry_at (gimple_location (stmt),
1632 			    "%<asm goto%> with complex typed outputs");
1633 		  diagnosed_p = true;
1634 		}
1635 	      /* Make sure to not ICE later, see PR105165.  */
1636 	      tree zero = build_zero_cst (TREE_TYPE (TREE_TYPE (op)));
1637 	      set_component_ssa_name (op, false, zero);
1638 	      set_component_ssa_name (op, true, zero);
1639 	      continue;
1640 	    }
1641 	  tree type = TREE_TYPE (op);
1642 	  tree inner_type = TREE_TYPE (type);
1643 	  tree r = build1 (REALPART_EXPR, inner_type, op);
1644 	  tree i = build1 (IMAGPART_EXPR, inner_type, op);
1645 	  gimple_seq list = set_component_ssa_name (op, false, r);
1646 
1647 	  if (list)
1648 	    gsi_insert_seq_after (gsi, list, GSI_CONTINUE_LINKING);
1649 
1650 	  list = set_component_ssa_name (op, true, i);
1651 	  if (list)
1652 	    gsi_insert_seq_after (gsi, list, GSI_CONTINUE_LINKING);
1653 	}
1654     }
1655 }
1656 
1657 /* Process one statement.  If we identify a complex operation, expand it.  */
1658 
1659 static void
expand_complex_operations_1(gimple_stmt_iterator * gsi)1660 expand_complex_operations_1 (gimple_stmt_iterator *gsi)
1661 {
1662   gimple *stmt = gsi_stmt (*gsi);
1663   tree type, inner_type, lhs;
1664   tree ac, ar, ai, bc, br, bi;
1665   complex_lattice_t al, bl;
1666   enum tree_code code;
1667 
1668   if (gimple_code (stmt) == GIMPLE_ASM)
1669     {
1670       expand_complex_asm (gsi);
1671       return;
1672     }
1673 
1674   lhs = gimple_get_lhs (stmt);
1675   if (!lhs && gimple_code (stmt) != GIMPLE_COND)
1676     return;
1677 
1678   type = TREE_TYPE (gimple_op (stmt, 0));
1679   code = gimple_expr_code (stmt);
1680 
1681   /* Initial filter for operations we handle.  */
1682   switch (code)
1683     {
1684     case PLUS_EXPR:
1685     case MINUS_EXPR:
1686     case MULT_EXPR:
1687     case TRUNC_DIV_EXPR:
1688     case CEIL_DIV_EXPR:
1689     case FLOOR_DIV_EXPR:
1690     case ROUND_DIV_EXPR:
1691     case RDIV_EXPR:
1692     case NEGATE_EXPR:
1693     case CONJ_EXPR:
1694       if (TREE_CODE (type) != COMPLEX_TYPE)
1695 	return;
1696       inner_type = TREE_TYPE (type);
1697       break;
1698 
1699     case EQ_EXPR:
1700     case NE_EXPR:
1701       /* Note, both GIMPLE_ASSIGN and GIMPLE_COND may have an EQ_EXPR
1702 	 subcode, so we need to access the operands using gimple_op.  */
1703       inner_type = TREE_TYPE (gimple_op (stmt, 1));
1704       if (TREE_CODE (inner_type) != COMPLEX_TYPE)
1705 	return;
1706       break;
1707 
1708     default:
1709       {
1710 	tree rhs;
1711 
1712 	/* GIMPLE_COND may also fallthru here, but we do not need to
1713 	   do anything with it.  */
1714 	if (gimple_code (stmt) == GIMPLE_COND)
1715 	  return;
1716 
1717 	if (TREE_CODE (type) == COMPLEX_TYPE)
1718 	  expand_complex_move (gsi, type);
1719 	else if (is_gimple_assign (stmt)
1720 		 && (gimple_assign_rhs_code (stmt) == REALPART_EXPR
1721 		     || gimple_assign_rhs_code (stmt) == IMAGPART_EXPR)
1722 		 && TREE_CODE (lhs) == SSA_NAME)
1723 	  {
1724 	    rhs = gimple_assign_rhs1 (stmt);
1725 	    rhs = extract_component (gsi, TREE_OPERAND (rhs, 0),
1726 		                     gimple_assign_rhs_code (stmt)
1727 				       == IMAGPART_EXPR,
1728 				     false);
1729 	    gimple_assign_set_rhs_from_tree (gsi, rhs);
1730 	    stmt = gsi_stmt (*gsi);
1731 	    update_stmt (stmt);
1732 	  }
1733       }
1734       return;
1735     }
1736 
1737   /* Extract the components of the two complex values.  Make sure and
1738      handle the common case of the same value used twice specially.  */
1739   if (is_gimple_assign (stmt))
1740     {
1741       ac = gimple_assign_rhs1 (stmt);
1742       bc = (gimple_num_ops (stmt) > 2) ? gimple_assign_rhs2 (stmt) : NULL;
1743     }
1744   /* GIMPLE_CALL cannot get here.  */
1745   else
1746     {
1747       ac = gimple_cond_lhs (stmt);
1748       bc = gimple_cond_rhs (stmt);
1749     }
1750 
1751   ar = extract_component (gsi, ac, false, true);
1752   ai = extract_component (gsi, ac, true, true);
1753 
1754   if (ac == bc)
1755     br = ar, bi = ai;
1756   else if (bc)
1757     {
1758       br = extract_component (gsi, bc, 0, true);
1759       bi = extract_component (gsi, bc, 1, true);
1760     }
1761   else
1762     br = bi = NULL_TREE;
1763 
1764   al = find_lattice_value (ac);
1765   if (al == UNINITIALIZED)
1766     al = VARYING;
1767 
1768   if (TREE_CODE_CLASS (code) == tcc_unary)
1769     bl = UNINITIALIZED;
1770   else if (ac == bc)
1771     bl = al;
1772   else
1773     {
1774       bl = find_lattice_value (bc);
1775       if (bl == UNINITIALIZED)
1776 	bl = VARYING;
1777     }
1778 
1779   switch (code)
1780     {
1781     case PLUS_EXPR:
1782     case MINUS_EXPR:
1783       expand_complex_addition (gsi, inner_type, ar, ai, br, bi, code, al, bl);
1784       break;
1785 
1786     case MULT_EXPR:
1787       expand_complex_multiplication (gsi, type, ar, ai, br, bi, al, bl);
1788       break;
1789 
1790     case TRUNC_DIV_EXPR:
1791     case CEIL_DIV_EXPR:
1792     case FLOOR_DIV_EXPR:
1793     case ROUND_DIV_EXPR:
1794     case RDIV_EXPR:
1795       expand_complex_division (gsi, type, ar, ai, br, bi, code, al, bl);
1796       break;
1797 
1798     case NEGATE_EXPR:
1799       expand_complex_negation (gsi, inner_type, ar, ai);
1800       break;
1801 
1802     case CONJ_EXPR:
1803       expand_complex_conjugate (gsi, inner_type, ar, ai);
1804       break;
1805 
1806     case EQ_EXPR:
1807     case NE_EXPR:
1808       expand_complex_comparison (gsi, ar, ai, br, bi, code);
1809       break;
1810 
1811     default:
1812       gcc_unreachable ();
1813     }
1814 }
1815 
1816 
1817 /* Entry point for complex operation lowering during optimization.  */
1818 
1819 static unsigned int
tree_lower_complex(void)1820 tree_lower_complex (void)
1821 {
1822   gimple_stmt_iterator gsi;
1823   basic_block bb;
1824   int n_bbs, i;
1825   int *rpo;
1826 
1827   if (!init_dont_simulate_again ())
1828     return 0;
1829 
1830   complex_lattice_values.create (num_ssa_names);
1831   complex_lattice_values.safe_grow_cleared (num_ssa_names, true);
1832 
1833   init_parameter_lattice_values ();
1834   class complex_propagate complex_propagate;
1835   complex_propagate.ssa_propagate ();
1836 
1837   need_eh_cleanup = BITMAP_ALLOC (NULL);
1838 
1839   complex_variable_components = new int_tree_htab_type (10);
1840 
1841   complex_ssa_name_components.create (2 * num_ssa_names);
1842   complex_ssa_name_components.safe_grow_cleared (2 * num_ssa_names, true);
1843 
1844   update_parameter_components ();
1845 
1846   rpo = XNEWVEC (int, last_basic_block_for_fn (cfun));
1847   n_bbs = pre_and_rev_post_order_compute (NULL, rpo, false);
1848   for (i = 0; i < n_bbs; i++)
1849     {
1850       bb = BASIC_BLOCK_FOR_FN (cfun, rpo[i]);
1851       if (!bb)
1852 	continue;
1853       update_phi_components (bb);
1854       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1855 	expand_complex_operations_1 (&gsi);
1856     }
1857 
1858   free (rpo);
1859 
1860   if (!phis_to_revisit.is_empty ())
1861     {
1862       unsigned int n = phis_to_revisit.length ();
1863       for (unsigned int j = 0; j < n; j += 3)
1864 	for (unsigned int k = 0; k < 2; k++)
1865 	  if (gphi *phi = phis_to_revisit[j + k + 1])
1866 	    {
1867 	      unsigned int m = gimple_phi_num_args (phi);
1868 	      for (unsigned int l = 0; l < m; ++l)
1869 		{
1870 		  tree op = gimple_phi_arg_def (phi, l);
1871 		  if (TREE_CODE (op) == SSA_NAME
1872 		      || is_gimple_min_invariant (op))
1873 		    continue;
1874 		  tree arg = gimple_phi_arg_def (phis_to_revisit[j], l);
1875 		  op = extract_component (NULL, arg, k > 0, false, false);
1876 		  SET_PHI_ARG_DEF (phi, l, op);
1877 		}
1878 	    }
1879       phis_to_revisit.release ();
1880     }
1881 
1882   gsi_commit_edge_inserts ();
1883 
1884   unsigned todo
1885     = gimple_purge_all_dead_eh_edges (need_eh_cleanup) ? TODO_cleanup_cfg : 0;
1886   BITMAP_FREE (need_eh_cleanup);
1887 
1888   delete complex_variable_components;
1889   complex_variable_components = NULL;
1890   complex_ssa_name_components.release ();
1891   complex_lattice_values.release ();
1892   return todo;
1893 }
1894 
1895 namespace {
1896 
1897 const pass_data pass_data_lower_complex =
1898 {
1899   GIMPLE_PASS, /* type */
1900   "cplxlower", /* name */
1901   OPTGROUP_NONE, /* optinfo_flags */
1902   TV_NONE, /* tv_id */
1903   PROP_ssa, /* properties_required */
1904   PROP_gimple_lcx, /* properties_provided */
1905   0, /* properties_destroyed */
1906   0, /* todo_flags_start */
1907   TODO_update_ssa, /* todo_flags_finish */
1908 };
1909 
1910 class pass_lower_complex : public gimple_opt_pass
1911 {
1912 public:
pass_lower_complex(gcc::context * ctxt)1913   pass_lower_complex (gcc::context *ctxt)
1914     : gimple_opt_pass (pass_data_lower_complex, ctxt)
1915   {}
1916 
1917   /* opt_pass methods: */
clone()1918   opt_pass * clone () { return new pass_lower_complex (m_ctxt); }
execute(function *)1919   virtual unsigned int execute (function *) { return tree_lower_complex (); }
1920 
1921 }; // class pass_lower_complex
1922 
1923 } // anon namespace
1924 
1925 gimple_opt_pass *
make_pass_lower_complex(gcc::context * ctxt)1926 make_pass_lower_complex (gcc::context *ctxt)
1927 {
1928   return new pass_lower_complex (ctxt);
1929 }
1930 
1931 
1932 namespace {
1933 
1934 const pass_data pass_data_lower_complex_O0 =
1935 {
1936   GIMPLE_PASS, /* type */
1937   "cplxlower0", /* name */
1938   OPTGROUP_NONE, /* optinfo_flags */
1939   TV_NONE, /* tv_id */
1940   PROP_cfg, /* properties_required */
1941   PROP_gimple_lcx, /* properties_provided */
1942   0, /* properties_destroyed */
1943   0, /* todo_flags_start */
1944   TODO_update_ssa, /* todo_flags_finish */
1945 };
1946 
1947 class pass_lower_complex_O0 : public gimple_opt_pass
1948 {
1949 public:
pass_lower_complex_O0(gcc::context * ctxt)1950   pass_lower_complex_O0 (gcc::context *ctxt)
1951     : gimple_opt_pass (pass_data_lower_complex_O0, ctxt)
1952   {}
1953 
1954   /* opt_pass methods: */
gate(function * fun)1955   virtual bool gate (function *fun)
1956     {
1957       /* With errors, normal optimization passes are not run.  If we don't
1958 	 lower complex operations at all, rtl expansion will abort.  */
1959       return !(fun->curr_properties & PROP_gimple_lcx);
1960     }
1961 
execute(function *)1962   virtual unsigned int execute (function *) { return tree_lower_complex (); }
1963 
1964 }; // class pass_lower_complex_O0
1965 
1966 } // anon namespace
1967 
1968 gimple_opt_pass *
make_pass_lower_complex_O0(gcc::context * ctxt)1969 make_pass_lower_complex_O0 (gcc::context *ctxt)
1970 {
1971   return new pass_lower_complex_O0 (ctxt);
1972 }
1973