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