Branch data Line data Source code
1 : : /* Lower complex number operations to scalar operations.
2 : : Copyright (C) 2004-2025 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 : 7694 : 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 : 34186 : cvc_lookup (unsigned int uid)
99 : : {
100 : 34186 : struct int_tree_map in;
101 : 34186 : in.uid = uid;
102 : 34186 : 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 : 11885 : cvc_insert (unsigned int uid, tree to)
109 : : {
110 : 11885 : int_tree_map h;
111 : 11885 : int_tree_map *loc;
112 : :
113 : 11885 : h.uid = uid;
114 : 11885 : loc = complex_variable_components->find_slot_with_hash (h, uid, INSERT);
115 : 11885 : loc->uid = uid;
116 : 11885 : loc->to = to;
117 : 11885 : }
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 : 113656 : some_nonzerop (tree t)
124 : : {
125 : 113656 : 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 : 113656 : if (TREE_CODE (t) == REAL_CST && !flag_signed_zeros)
131 : 2451 : zerop = real_identical (&TREE_REAL_CST (t), &dconst0);
132 : 111205 : else if (TREE_CODE (t) == FIXED_CST)
133 : 0 : zerop = fixed_zerop (t);
134 : 111205 : else if (TREE_CODE (t) == INTEGER_CST)
135 : 9137 : zerop = integer_zerop (t);
136 : :
137 : 113656 : 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 : 56828 : find_lattice_value_parts (tree real, tree imag)
146 : : {
147 : 56828 : int r, i;
148 : 56828 : complex_lattice_t ret;
149 : :
150 : 56828 : r = some_nonzerop (real);
151 : 56828 : i = some_nonzerop (imag);
152 : 56828 : 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 : 56828 : if (ret == UNINITIALIZED)
158 : : ret = ONLY_REAL;
159 : :
160 : 56828 : return ret;
161 : : }
162 : :
163 : :
164 : : /* Compute a lattice value from gimple_val T. */
165 : :
166 : : static complex_lattice_t
167 : 695892 : find_lattice_value (tree t)
168 : : {
169 : 695892 : tree real, imag;
170 : :
171 : 695892 : switch (TREE_CODE (t))
172 : : {
173 : 662720 : case SSA_NAME:
174 : 662720 : return complex_lattice_values[SSA_NAME_VERSION (t)];
175 : :
176 : 33172 : case COMPLEX_CST:
177 : 33172 : real = TREE_REALPART (t);
178 : 33172 : imag = TREE_IMAGPART (t);
179 : 33172 : break;
180 : :
181 : 0 : default:
182 : 0 : gcc_unreachable ();
183 : : }
184 : :
185 : 33172 : 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 : 37574756 : is_complex_reg (tree lhs)
193 : : {
194 : 37574756 : 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 : 7694 : init_parameter_lattice_values (void)
201 : : {
202 : 7694 : tree parm, ssa_name;
203 : :
204 : 19267 : for (parm = DECL_ARGUMENTS (cfun->decl); parm ; parm = DECL_CHAIN (parm))
205 : 11573 : if (is_complex_reg (parm)
206 : 11573 : && (ssa_name = ssa_default_def (cfun, parm)) != NULL_TREE)
207 : 1965 : complex_lattice_values[SSA_NAME_VERSION (ssa_name)] = VARYING;
208 : 7694 : }
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 : 1436719 : init_dont_simulate_again (void)
216 : : {
217 : 1436719 : basic_block bb;
218 : 1436719 : bool saw_a_complex_op = false;
219 : :
220 : 13944595 : FOR_EACH_BB_FN (bb, cfun)
221 : : {
222 : 17335646 : for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
223 : 4827770 : gsi_next (&gsi))
224 : : {
225 : 4827770 : gphi *phi = gsi.phi ();
226 : 4827770 : prop_set_simulate_again (phi,
227 : 4827770 : is_complex_reg (gimple_phi_result (phi)));
228 : : }
229 : :
230 : 110105978 : for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
231 : 85090226 : gsi_next (&gsi))
232 : : {
233 : 85090226 : gimple *stmt;
234 : 85090226 : tree op0, op1;
235 : 85090226 : bool sim_again_p;
236 : :
237 : 85090226 : stmt = gsi_stmt (gsi);
238 : 85090226 : op0 = op1 = NULL_TREE;
239 : :
240 : : /* Most control-altering statements must be initially
241 : : simulated, else we won't cover the entire cfg. */
242 : 85090226 : sim_again_p = stmt_ends_bb_p (stmt);
243 : :
244 : 85090226 : switch (gimple_code (stmt))
245 : : {
246 : 6746238 : case GIMPLE_CALL:
247 : 6746238 : if (gimple_call_lhs (stmt))
248 : : {
249 : 2314498 : sim_again_p = is_complex_reg (gimple_call_lhs (stmt));
250 : 2314498 : switch (gimple_call_combined_fn (stmt))
251 : : {
252 : 883 : CASE_CFN_CABS:
253 : : /* Expand cabs only if unsafe math and optimizing. */
254 : 883 : if (optimize && flag_unsafe_math_optimizations)
255 : 7 : saw_a_complex_op = true;
256 : : break;
257 : : default:;
258 : : }
259 : : }
260 : : break;
261 : :
262 : 30318367 : case GIMPLE_ASSIGN:
263 : 30318367 : sim_again_p = is_complex_reg (gimple_assign_lhs (stmt));
264 : 30318367 : if (gimple_assign_rhs_code (stmt) == REALPART_EXPR
265 : 30318367 : || gimple_assign_rhs_code (stmt) == IMAGPART_EXPR)
266 : 196646 : op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
267 : : else
268 : 30121721 : op0 = gimple_assign_rhs1 (stmt);
269 : 30318367 : if (gimple_num_ops (stmt) > 2)
270 : 7006308 : op1 = gimple_assign_rhs2 (stmt);
271 : : break;
272 : :
273 : 5200884 : case GIMPLE_COND:
274 : 5200884 : op0 = gimple_cond_lhs (stmt);
275 : 5200884 : op1 = gimple_cond_rhs (stmt);
276 : 5200884 : break;
277 : :
278 : : default:
279 : : break;
280 : : }
281 : :
282 : 85090226 : if (op0 || op1)
283 : 35519251 : switch (gimple_expr_code (stmt))
284 : : {
285 : 8542879 : case EQ_EXPR:
286 : 8542879 : case NE_EXPR:
287 : 8542879 : case PLUS_EXPR:
288 : 8542879 : case MINUS_EXPR:
289 : 8542879 : case MULT_EXPR:
290 : 8542879 : case TRUNC_DIV_EXPR:
291 : 8542879 : case CEIL_DIV_EXPR:
292 : 8542879 : case FLOOR_DIV_EXPR:
293 : 8542879 : case ROUND_DIV_EXPR:
294 : 8542879 : case RDIV_EXPR:
295 : 8542879 : if (TREE_CODE (TREE_TYPE (op0)) == COMPLEX_TYPE
296 : 8542879 : || TREE_CODE (TREE_TYPE (op1)) == COMPLEX_TYPE)
297 : : saw_a_complex_op = true;
298 : : break;
299 : :
300 : 52188 : case NEGATE_EXPR:
301 : 52188 : case CONJ_EXPR:
302 : 52188 : case PAREN_EXPR:
303 : 52188 : if (TREE_CODE (TREE_TYPE (op0)) == COMPLEX_TYPE)
304 : 176032 : saw_a_complex_op = true;
305 : : break;
306 : :
307 : 196646 : case REALPART_EXPR:
308 : 196646 : 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 : 196646 : if (TREE_CODE (op0) == SSA_NAME
314 : 196646 : && ssa_undefined_value_p (op0))
315 : : saw_a_complex_op = true;
316 : : break;
317 : :
318 : 26727538 : 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 : 26727538 : if (TREE_CODE (TREE_TYPE (gimple_op (stmt, 0))) == COMPLEX_TYPE)
323 : 176032 : saw_a_complex_op = true;
324 : : break;
325 : : }
326 : :
327 : 85090226 : prop_set_simulate_again (stmt, sim_again_p);
328 : : }
329 : : }
330 : :
331 : 1436719 : 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 : 302692 : complex_propagate::visit_stmt (gimple *stmt, edge *taken_edge_p ATTRIBUTE_UNUSED,
339 : : tree *result_p)
340 : : {
341 : 302692 : complex_lattice_t new_l, old_l, op1_l, op2_l;
342 : 302692 : unsigned int ver;
343 : 302692 : tree lhs;
344 : :
345 : 302692 : lhs = gimple_get_lhs (stmt);
346 : : /* Skip anything but GIMPLE_ASSIGN and GIMPLE_CALL with a lhs. */
347 : 408785 : 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 : 106090 : gcc_assert (TREE_CODE (lhs) == SSA_NAME);
353 : 106090 : gcc_assert (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE);
354 : :
355 : 106090 : *result_p = lhs;
356 : 106090 : ver = SSA_NAME_VERSION (lhs);
357 : 106090 : old_l = complex_lattice_values[ver];
358 : :
359 : 106090 : switch (gimple_expr_code (stmt))
360 : : {
361 : 5083 : case SSA_NAME:
362 : 5083 : case COMPLEX_CST:
363 : 5083 : new_l = find_lattice_value (gimple_assign_rhs1 (stmt));
364 : 5083 : break;
365 : :
366 : 23656 : case COMPLEX_EXPR:
367 : 23656 : new_l = find_lattice_value_parts (gimple_assign_rhs1 (stmt),
368 : : gimple_assign_rhs2 (stmt));
369 : 23656 : break;
370 : :
371 : 9481 : case PLUS_EXPR:
372 : 9481 : case MINUS_EXPR:
373 : 9481 : op1_l = find_lattice_value (gimple_assign_rhs1 (stmt));
374 : 9481 : 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 : 9481 : new_l = op1_l | op2_l;
379 : 9481 : break;
380 : :
381 : 8295 : case MULT_EXPR:
382 : 8295 : case RDIV_EXPR:
383 : 8295 : case TRUNC_DIV_EXPR:
384 : 8295 : case CEIL_DIV_EXPR:
385 : 8295 : case FLOOR_DIV_EXPR:
386 : 8295 : case ROUND_DIV_EXPR:
387 : 8295 : op1_l = find_lattice_value (gimple_assign_rhs1 (stmt));
388 : 8295 : op2_l = find_lattice_value (gimple_assign_rhs2 (stmt));
389 : :
390 : : /* Obviously, if either varies, so does the result. */
391 : 8295 : 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 : 106090 : if (new_l == old_l)
425 : : return SSA_PROP_NOT_INTERESTING;
426 : :
427 : 106034 : complex_lattice_values[ver] = new_l;
428 : 106034 : 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 : 7957 : complex_propagate::visit_phi (gphi *phi)
435 : : {
436 : 7957 : complex_lattice_t new_l, old_l;
437 : 7957 : unsigned int ver;
438 : 7957 : tree lhs;
439 : 7957 : int i;
440 : :
441 : 7957 : 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 : 7957 : gcc_assert (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE);
446 : :
447 : 7957 : 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 : 7952 : new_l = UNINITIALIZED;
452 : 24290 : for (i = gimple_phi_num_args (phi) - 1; i >= 0; --i)
453 : 16338 : new_l |= find_lattice_value (gimple_phi_arg_def (phi, i));
454 : :
455 : 7952 : ver = SSA_NAME_VERSION (lhs);
456 : 7952 : old_l = complex_lattice_values[ver];
457 : :
458 : 7952 : if (new_l == old_l)
459 : : return SSA_PROP_NOT_INTERESTING;
460 : :
461 : 7860 : complex_lattice_values[ver] = new_l;
462 : 7860 : 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 : 11885 : create_one_component_var (tree type, tree orig, const char *prefix,
469 : : const char *suffix, enum tree_code code)
470 : : {
471 : 11885 : tree r = create_tmp_var (type, prefix);
472 : :
473 : 11885 : DECL_SOURCE_LOCATION (r) = DECL_SOURCE_LOCATION (orig);
474 : 11885 : DECL_ARTIFICIAL (r) = 1;
475 : :
476 : 11885 : if (DECL_NAME (orig) && !DECL_IGNORED_P (orig))
477 : : {
478 : 11836 : const char *name = IDENTIFIER_POINTER (DECL_NAME (orig));
479 : 11836 : name = ACONCAT ((name, suffix, NULL));
480 : 11836 : DECL_NAME (r) = get_identifier (name);
481 : :
482 : 11836 : SET_DECL_DEBUG_EXPR (r, build1 (code, type, orig));
483 : 11836 : DECL_HAS_DEBUG_EXPR_P (r) = 1;
484 : 11836 : DECL_IGNORED_P (r) = 0;
485 : 11836 : copy_warning (r, orig);
486 : : }
487 : : else
488 : : {
489 : 49 : DECL_IGNORED_P (r) = 1;
490 : 49 : suppress_warning (r);
491 : : }
492 : :
493 : 11885 : return r;
494 : : }
495 : :
496 : : /* Retrieve a value for a complex component of VAR. */
497 : :
498 : : static tree
499 : 34186 : get_component_var (tree var, bool imag_p)
500 : : {
501 : 34186 : size_t decl_index = DECL_UID (var) * 2 + imag_p;
502 : 34186 : tree ret = cvc_lookup (decl_index);
503 : :
504 : 34186 : if (ret == NULL)
505 : : {
506 : 17852 : 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 : 11885 : cvc_insert (decl_index, ret);
511 : : }
512 : :
513 : 34186 : return ret;
514 : : }
515 : :
516 : : /* Retrieve a value for a complex component of SSA_NAME. */
517 : :
518 : : static tree
519 : 333853 : get_component_ssa_name (tree ssa_name, bool imag_p)
520 : : {
521 : 333853 : complex_lattice_t lattice = find_lattice_value (ssa_name);
522 : 333853 : size_t ssa_name_index;
523 : 333853 : tree ret;
524 : :
525 : 501137 : if (lattice == (imag_p ? ONLY_REAL : ONLY_IMAG))
526 : : {
527 : 1105 : tree inner_type = TREE_TYPE (TREE_TYPE (ssa_name));
528 : 1105 : if (SCALAR_FLOAT_TYPE_P (inner_type))
529 : 45 : return build_real (inner_type, dconst0);
530 : : else
531 : 1060 : return build_int_cst (inner_type, 0);
532 : : }
533 : :
534 : 332748 : ssa_name_index = SSA_NAME_VERSION (ssa_name) * 2 + imag_p;
535 : 332748 : ret = complex_ssa_name_components[ssa_name_index];
536 : 332748 : if (ret == NULL)
537 : : {
538 : 95213 : if (SSA_NAME_VAR (ssa_name))
539 : 24967 : ret = get_component_var (SSA_NAME_VAR (ssa_name), imag_p);
540 : : else
541 : 70246 : ret = TREE_TYPE (TREE_TYPE (ssa_name));
542 : 95213 : 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 : 95213 : SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ret)
547 : 95213 : = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssa_name);
548 : 95213 : if (SSA_NAME_IS_DEFAULT_DEF (ssa_name)
549 : 95213 : && VAR_P (SSA_NAME_VAR (ssa_name)))
550 : : {
551 : 178 : SSA_NAME_DEF_STMT (ret) = SSA_NAME_DEF_STMT (ssa_name);
552 : 178 : set_ssa_default_def (cfun, SSA_NAME_VAR (ret), ret);
553 : : }
554 : :
555 : 95213 : 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 : 216114 : set_component_ssa_name (tree ssa_name, bool imag_p, tree value)
566 : : {
567 : 216114 : complex_lattice_t lattice = find_lattice_value (ssa_name);
568 : 216114 : size_t ssa_name_index;
569 : 216114 : tree comp;
570 : 216114 : gimple *last;
571 : 216114 : 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 : 324171 : 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 : 215205 : ssa_name_index = SSA_NAME_VERSION (ssa_name) * 2 + imag_p;
584 : 215205 : comp = complex_ssa_name_components[ssa_name_index];
585 : 215205 : 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 : 209068 : else if (is_gimple_min_invariant (value)
592 : 218341 : && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssa_name))
593 : : {
594 : 9267 : complex_ssa_name_components[ssa_name_index] = value;
595 : 9267 : return NULL;
596 : : }
597 : 199801 : else if (TREE_CODE (value) == SSA_NAME
598 : 325496 : && !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 : 125695 : if (!SSA_NAME_IS_DEFAULT_DEF (value)
603 : 125335 : && SSA_NAME_VAR (ssa_name)
604 : 10324 : && (!SSA_NAME_VAR (value) || DECL_IGNORED_P (SSA_NAME_VAR (value)))
605 : 135343 : && !DECL_IGNORED_P (SSA_NAME_VAR (ssa_name)))
606 : : {
607 : 9219 : comp = get_component_var (SSA_NAME_VAR (ssa_name), imag_p);
608 : 9219 : replace_ssa_name_symbol (value, comp);
609 : : }
610 : :
611 : 125695 : complex_ssa_name_components[ssa_name_index] = value;
612 : 125695 : 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 : 74106 : comp = get_component_ssa_name (ssa_name, imag_p);
619 : :
620 : : /* Do all the work to assign VALUE to COMP. */
621 : 80243 : list = NULL;
622 : 80243 : value = force_gimple_operand (value, &list, false, NULL);
623 : 80243 : last = gimple_build_assign (comp, value);
624 : 80243 : gimple_seq_add_stmt (&list, last);
625 : 80243 : gcc_assert (SSA_NAME_DEF_STMT (comp) == last);
626 : :
627 : 80243 : 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 : 405694 : extract_component (gimple_stmt_iterator *gsi, tree t, bool imagpart_p,
636 : : bool gimple_p, bool phiarg_p = false)
637 : : {
638 : 405694 : switch (TREE_CODE (t))
639 : : {
640 : 71178 : case COMPLEX_CST:
641 : 71178 : 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 : 108 : if (gimple_p)
656 : 108 : t = force_gimple_operand_gsi (gsi, t, true, NULL, true,
657 : : GSI_SAME_STMT);
658 : : return t;
659 : : }
660 : :
661 : 89627 : case VAR_DECL:
662 : 89627 : case RESULT_DECL:
663 : 89627 : case PARM_DECL:
664 : 89627 : case COMPONENT_REF:
665 : 89627 : case ARRAY_REF:
666 : 89627 : case VIEW_CONVERT_EXPR:
667 : 89627 : case MEM_REF:
668 : 89627 : {
669 : 89627 : tree inner_type = TREE_TYPE (TREE_TYPE (t));
670 : :
671 : 134608 : t = build1 ((imagpart_p ? IMAGPART_EXPR : REALPART_EXPR),
672 : : inner_type, unshare_expr (t));
673 : :
674 : 89627 : if (gimple_p)
675 : 51540 : t = force_gimple_operand_gsi (gsi, t, true, NULL, true,
676 : : GSI_SAME_STMT);
677 : :
678 : : return t;
679 : : }
680 : :
681 : 244781 : case SSA_NAME:
682 : 244781 : t = get_component_ssa_name (t, imagpart_p);
683 : 244781 : if (TREE_CODE (t) == SSA_NAME && SSA_NAME_DEF_STMT (t) == NULL)
684 : 6769 : gcc_assert (phiarg_p);
685 : : return t;
686 : :
687 : 0 : default:
688 : 0 : gcc_unreachable ();
689 : : }
690 : : }
691 : :
692 : : /* Update the complex components of the ssa name on the lhs of STMT. */
693 : :
694 : : static void
695 : 106069 : update_complex_components (gimple_stmt_iterator *gsi, gimple *stmt, tree r,
696 : : tree i)
697 : : {
698 : 106069 : tree lhs;
699 : 106069 : gimple_seq list;
700 : :
701 : 106069 : lhs = gimple_get_lhs (stmt);
702 : :
703 : 106069 : list = set_component_ssa_name (lhs, false, r);
704 : 106069 : if (list)
705 : 38151 : gsi_insert_seq_after (gsi, list, GSI_CONTINUE_LINKING);
706 : :
707 : 106069 : list = set_component_ssa_name (lhs, true, i);
708 : 106069 : if (list)
709 : 38118 : gsi_insert_seq_after (gsi, list, GSI_CONTINUE_LINKING);
710 : 106069 : }
711 : :
712 : : static void
713 : 1980 : update_complex_components_on_edge (edge e, tree lhs, tree r, tree i)
714 : : {
715 : 1980 : gimple_seq list;
716 : :
717 : 1980 : list = set_component_ssa_name (lhs, false, r);
718 : 1980 : if (list)
719 : 1980 : gsi_insert_seq_on_edge (e, list);
720 : :
721 : 1980 : list = set_component_ssa_name (lhs, true, i);
722 : 1980 : if (list)
723 : 1980 : gsi_insert_seq_on_edge (e, list);
724 : 1980 : }
725 : :
726 : :
727 : : /* Update an assignment to a complex variable in place. */
728 : :
729 : : static void
730 : 71245 : update_complex_assignment (gimple_stmt_iterator *gsi, tree r, tree i)
731 : : {
732 : 71245 : gimple *old_stmt = gsi_stmt (*gsi);
733 : 71245 : gimple_assign_set_rhs_with_ops (gsi, COMPLEX_EXPR, r, i);
734 : 71245 : gimple *stmt = gsi_stmt (*gsi);
735 : 71245 : update_stmt (stmt);
736 : 71245 : if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
737 : 8 : bitmap_set_bit (need_eh_cleanup, gimple_bb (stmt)->index);
738 : 71245 : if (optimize)
739 : 38136 : bitmap_set_bit (dce_worklist, SSA_NAME_VERSION (gimple_assign_lhs (stmt)));
740 : :
741 : 71245 : update_complex_components (gsi, gsi_stmt (*gsi), r, i);
742 : 71245 : }
743 : :
744 : :
745 : : /* Generate code at the entry point of the function to initialize the
746 : : component variables for a complex parameter. */
747 : :
748 : : static void
749 : 7694 : update_parameter_components (void)
750 : : {
751 : 7694 : edge entry_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
752 : 7694 : tree parm;
753 : :
754 : 19267 : for (parm = DECL_ARGUMENTS (cfun->decl); parm ; parm = DECL_CHAIN (parm))
755 : : {
756 : 11573 : tree type = TREE_TYPE (parm);
757 : 11573 : tree ssa_name, r, i;
758 : :
759 : 11573 : if (TREE_CODE (type) != COMPLEX_TYPE || !is_gimple_reg (parm))
760 : 9585 : continue;
761 : :
762 : 1988 : type = TREE_TYPE (type);
763 : 1988 : ssa_name = ssa_default_def (cfun, parm);
764 : 1988 : if (!ssa_name)
765 : 23 : continue;
766 : :
767 : 1965 : r = build1 (REALPART_EXPR, type, ssa_name);
768 : 1965 : i = build1 (IMAGPART_EXPR, type, ssa_name);
769 : 1965 : update_complex_components_on_edge (entry_edge, ssa_name, r, i);
770 : : }
771 : 7694 : }
772 : :
773 : : /* Generate code to set the component variables of a complex variable
774 : : to match the PHI statements in block BB. */
775 : :
776 : : static void
777 : 254090 : update_phi_components (basic_block bb)
778 : : {
779 : 254090 : gphi_iterator gsi;
780 : :
781 : 356638 : for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
782 : : {
783 : 102548 : gphi *phi = gsi.phi ();
784 : :
785 : 102548 : if (is_complex_reg (gimple_phi_result (phi)))
786 : : {
787 : 7483 : gphi *p[2] = { NULL, NULL };
788 : 7483 : unsigned int i, j, n;
789 : 7483 : bool revisit_phi = false;
790 : :
791 : 22449 : for (j = 0; j < 2; j++)
792 : : {
793 : 14966 : tree l = get_component_ssa_name (gimple_phi_result (phi), j > 0);
794 : 14966 : if (TREE_CODE (l) == SSA_NAME)
795 : 14792 : p[j] = create_phi_node (l, bb);
796 : : }
797 : :
798 : 22882 : for (i = 0, n = gimple_phi_num_args (phi); i < n; ++i)
799 : : {
800 : 15399 : tree comp, arg = gimple_phi_arg_def (phi, i);
801 : 61596 : for (j = 0; j < 2; j++)
802 : 30798 : if (p[j])
803 : : {
804 : 30426 : comp = extract_component (NULL, arg, j > 0, false, true);
805 : 30426 : if (TREE_CODE (comp) == SSA_NAME
806 : 30426 : && SSA_NAME_DEF_STMT (comp) == NULL)
807 : : {
808 : : /* For the benefit of any gimple simplification during
809 : : this pass that might walk SSA_NAME def stmts,
810 : : don't add SSA_NAMEs without definitions into the
811 : : PHI arguments, but put a decl in there instead
812 : : temporarily, and revisit this PHI later on. */
813 : 6769 : if (SSA_NAME_VAR (comp))
814 : : comp = SSA_NAME_VAR (comp);
815 : : else
816 : 362 : comp = create_tmp_reg (TREE_TYPE (comp),
817 : : get_name (comp));
818 : : revisit_phi = true;
819 : : }
820 : 30426 : SET_PHI_ARG_DEF (p[j], i, comp);
821 : : }
822 : : }
823 : :
824 : 7483 : if (revisit_phi)
825 : : {
826 : 3417 : phis_to_revisit.safe_push (phi);
827 : 3417 : phis_to_revisit.safe_push (p[0]);
828 : 3417 : phis_to_revisit.safe_push (p[1]);
829 : : }
830 : : }
831 : : }
832 : 254090 : }
833 : :
834 : : /* Expand a complex move to scalars. */
835 : :
836 : : static void
837 : 136833 : expand_complex_move (gimple_stmt_iterator *gsi, tree type)
838 : : {
839 : 136833 : tree inner_type = TREE_TYPE (type);
840 : 136833 : tree r, i, lhs, rhs;
841 : 136833 : gimple *stmt = gsi_stmt (*gsi);
842 : :
843 : 136833 : if (is_gimple_assign (stmt))
844 : : {
845 : 131378 : lhs = gimple_assign_lhs (stmt);
846 : 131378 : if (gimple_num_ops (stmt) == 2)
847 : 107722 : rhs = gimple_assign_rhs1 (stmt);
848 : : else
849 : : rhs = NULL_TREE;
850 : : }
851 : 5455 : else if (is_gimple_call (stmt))
852 : : {
853 : 5455 : lhs = gimple_call_lhs (stmt);
854 : 5455 : rhs = NULL_TREE;
855 : : }
856 : : else
857 : 0 : gcc_unreachable ();
858 : :
859 : 136833 : if (TREE_CODE (lhs) == SSA_NAME)
860 : : {
861 : 87293 : if (is_ctrl_altering_stmt (stmt))
862 : : {
863 : 15 : edge e;
864 : :
865 : : /* The value is not assigned on the exception edges, so we need not
866 : : concern ourselves there. We do need to update on the fallthru
867 : : edge. Find it. */
868 : 15 : e = find_fallthru_edge (gsi_bb (*gsi)->succs);
869 : 15 : if (!e)
870 : 0 : gcc_unreachable ();
871 : :
872 : 15 : r = build1 (REALPART_EXPR, inner_type, lhs);
873 : 15 : i = build1 (IMAGPART_EXPR, inner_type, lhs);
874 : 15 : update_complex_components_on_edge (e, lhs, r, i);
875 : : }
876 : 87278 : else if (is_gimple_call (stmt)
877 : 87278 : || gimple_has_side_effects (stmt))
878 : : {
879 : 32720 : r = build1 (REALPART_EXPR, inner_type, lhs);
880 : 32720 : i = build1 (IMAGPART_EXPR, inner_type, lhs);
881 : 32720 : update_complex_components (gsi, stmt, r, i);
882 : : }
883 : : else
884 : : {
885 : 54558 : if (gimple_assign_rhs_code (stmt) != COMPLEX_EXPR)
886 : : {
887 : 30902 : r = extract_component (gsi, rhs, 0, true);
888 : 30902 : i = extract_component (gsi, rhs, 1, true);
889 : : }
890 : : else
891 : : {
892 : 23656 : r = gimple_assign_rhs1 (stmt);
893 : 23656 : i = gimple_assign_rhs2 (stmt);
894 : : }
895 : 54558 : update_complex_assignment (gsi, r, i);
896 : : }
897 : : }
898 : 49540 : else if (rhs
899 : 49540 : && (TREE_CODE (rhs) == SSA_NAME || TREE_CODE (rhs) == COMPLEX_CST)
900 : 96616 : && !TREE_SIDE_EFFECTS (lhs))
901 : : {
902 : 30426 : tree x;
903 : 30426 : gimple *t;
904 : 30426 : location_t loc;
905 : :
906 : 30426 : loc = gimple_location (stmt);
907 : 30426 : r = extract_component (gsi, rhs, 0, false);
908 : 30426 : i = extract_component (gsi, rhs, 1, false);
909 : :
910 : 30426 : x = build1 (REALPART_EXPR, inner_type, unshare_expr (lhs));
911 : 30426 : t = gimple_build_assign (x, r);
912 : 30426 : gimple_set_location (t, loc);
913 : 30426 : gsi_insert_before (gsi, t, GSI_SAME_STMT);
914 : :
915 : 30426 : if (stmt == gsi_stmt (*gsi))
916 : : {
917 : 30426 : x = build1 (IMAGPART_EXPR, inner_type, unshare_expr (lhs));
918 : 30426 : gimple_assign_set_lhs (stmt, x);
919 : 30426 : gimple_assign_set_rhs1 (stmt, i);
920 : : }
921 : : else
922 : : {
923 : 0 : x = build1 (IMAGPART_EXPR, inner_type, unshare_expr (lhs));
924 : 0 : t = gimple_build_assign (x, i);
925 : 0 : gimple_set_location (t, loc);
926 : 0 : gsi_insert_before (gsi, t, GSI_SAME_STMT);
927 : :
928 : 0 : stmt = gsi_stmt (*gsi);
929 : 0 : gcc_assert (gimple_code (stmt) == GIMPLE_RETURN);
930 : 0 : gimple_return_set_retval (as_a <greturn *> (stmt), lhs);
931 : : }
932 : :
933 : 30426 : update_stmt (stmt);
934 : : }
935 : 136833 : }
936 : :
937 : : /* Expand complex addition to scalars:
938 : : a + b = (ar + br) + i(ai + bi)
939 : : a - b = (ar - br) + i(ai + bi)
940 : : */
941 : :
942 : : static void
943 : 9480 : expand_complex_addition (gimple_stmt_iterator *gsi, tree inner_type,
944 : : tree ar, tree ai, tree br, tree bi,
945 : : enum tree_code code,
946 : : complex_lattice_t al, complex_lattice_t bl)
947 : : {
948 : 9480 : tree rr, ri;
949 : 9480 : gimple_seq stmts = NULL;
950 : 9480 : location_t loc = gimple_location (gsi_stmt (*gsi));
951 : :
952 : 9480 : switch (PAIR (al, bl))
953 : : {
954 : 82 : case PAIR (ONLY_REAL, ONLY_REAL):
955 : 82 : rr = gimple_build (&stmts, loc, code, inner_type, ar, br);
956 : 82 : ri = ai;
957 : 82 : break;
958 : :
959 : 6 : case PAIR (ONLY_REAL, ONLY_IMAG):
960 : 6 : rr = ar;
961 : 6 : if (code == MINUS_EXPR)
962 : 0 : ri = gimple_build (&stmts, loc, MINUS_EXPR, inner_type, ai, bi);
963 : : else
964 : : ri = bi;
965 : : break;
966 : :
967 : 7 : case PAIR (ONLY_IMAG, ONLY_REAL):
968 : 7 : if (code == MINUS_EXPR)
969 : 6 : rr = gimple_build (&stmts, loc, MINUS_EXPR, inner_type, ar, br);
970 : : else
971 : : rr = br;
972 : : ri = ai;
973 : : break;
974 : :
975 : 1 : case PAIR (ONLY_IMAG, ONLY_IMAG):
976 : 1 : rr = ar;
977 : 1 : ri = gimple_build (&stmts, loc, code, inner_type, ai, bi);
978 : 1 : break;
979 : :
980 : 1221 : case PAIR (VARYING, ONLY_REAL):
981 : 1221 : rr = gimple_build (&stmts, loc, code, inner_type, ar, br);
982 : 1221 : ri = ai;
983 : 1221 : break;
984 : :
985 : 3 : case PAIR (VARYING, ONLY_IMAG):
986 : 3 : rr = ar;
987 : 3 : ri = gimple_build (&stmts, loc, code, inner_type, ai, bi);
988 : 3 : break;
989 : :
990 : 10 : case PAIR (ONLY_REAL, VARYING):
991 : 10 : if (code == MINUS_EXPR)
992 : 1 : goto general;
993 : 9 : rr = gimple_build (&stmts, loc, code, inner_type, ar, br);
994 : 9 : ri = bi;
995 : 9 : break;
996 : :
997 : 0 : case PAIR (ONLY_IMAG, VARYING):
998 : 0 : if (code == MINUS_EXPR)
999 : 0 : goto general;
1000 : 0 : rr = br;
1001 : 0 : ri = gimple_build (&stmts, loc, code, inner_type, ai, bi);
1002 : 0 : break;
1003 : :
1004 : 8151 : case PAIR (VARYING, VARYING):
1005 : 8151 : general:
1006 : 8151 : rr = gimple_build (&stmts, loc, code, inner_type, ar, br);
1007 : : /* (a+ai) + (b+bi) -> (a+b)+(a+b)i
1008 : : small optimization to remove one new statement. */
1009 : 8151 : if (operand_equal_p (ar, ai) && operand_equal_p (br, bi))
1010 : : ri = rr;
1011 : : else
1012 : 8100 : ri = gimple_build (&stmts, loc, code, inner_type, ai, bi);
1013 : : break;
1014 : :
1015 : 0 : default:
1016 : 0 : gcc_unreachable ();
1017 : : }
1018 : :
1019 : 9480 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1020 : 9480 : update_complex_assignment (gsi, rr, ri);
1021 : 9480 : }
1022 : :
1023 : : /* Expand a complex multiplication or division to a libcall to the c99
1024 : : compliant routines. TYPE is the complex type of the operation.
1025 : : If INPLACE_P replace the statement at GSI with
1026 : : the libcall and return NULL_TREE. Else insert the call, assign its
1027 : : result to an output variable and return that variable. If INPLACE_P
1028 : : is true then the statement being replaced should be an assignment
1029 : : statement. */
1030 : :
1031 : : static tree
1032 : 4183 : expand_complex_libcall (gimple_stmt_iterator *gsi, tree type, tree ar, tree ai,
1033 : : tree br, tree bi, enum tree_code code, bool inplace_p)
1034 : : {
1035 : 4183 : machine_mode mode;
1036 : 4183 : enum built_in_function bcode;
1037 : 4183 : tree fn, lhs;
1038 : 4183 : gcall *stmt;
1039 : :
1040 : 4183 : mode = TYPE_MODE (type);
1041 : 4183 : gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
1042 : :
1043 : 4183 : if (code == MULT_EXPR)
1044 : 3490 : bcode = ((enum built_in_function)
1045 : 3490 : (BUILT_IN_COMPLEX_MUL_MIN + mode - MIN_MODE_COMPLEX_FLOAT));
1046 : 693 : else if (code == RDIV_EXPR)
1047 : 693 : bcode = ((enum built_in_function)
1048 : 693 : (BUILT_IN_COMPLEX_DIV_MIN + mode - MIN_MODE_COMPLEX_FLOAT));
1049 : : else
1050 : 0 : gcc_unreachable ();
1051 : 4183 : fn = builtin_decl_explicit (bcode);
1052 : 4183 : stmt = gimple_build_call (fn, 4, ar, ai, br, bi);
1053 : :
1054 : 4183 : if (inplace_p)
1055 : : {
1056 : 2104 : gimple *old_stmt = gsi_stmt (*gsi);
1057 : 2104 : gimple_call_set_nothrow (stmt, !stmt_could_throw_p (cfun, old_stmt));
1058 : 2104 : lhs = gimple_assign_lhs (old_stmt);
1059 : 2104 : gimple_call_set_lhs (stmt, lhs);
1060 : 2104 : gsi_replace (gsi, stmt, true);
1061 : :
1062 : 2104 : type = TREE_TYPE (type);
1063 : 2104 : if (stmt_can_throw_internal (cfun, stmt))
1064 : : {
1065 : 12 : edge_iterator ei;
1066 : 12 : edge e;
1067 : 24 : FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs)
1068 : 24 : if (!(e->flags & EDGE_EH))
1069 : : break;
1070 : 12 : basic_block bb = split_edge (e);
1071 : 12 : gimple_stmt_iterator gsi2 = gsi_start_bb (bb);
1072 : 12 : update_complex_components (&gsi2, stmt,
1073 : : build1 (REALPART_EXPR, type, lhs),
1074 : : build1 (IMAGPART_EXPR, type, lhs));
1075 : 12 : return NULL_TREE;
1076 : : }
1077 : : else
1078 : 2092 : update_complex_components (gsi, stmt,
1079 : : build1 (REALPART_EXPR, type, lhs),
1080 : : build1 (IMAGPART_EXPR, type, lhs));
1081 : 2092 : SSA_NAME_DEF_STMT (lhs) = stmt;
1082 : 2092 : return NULL_TREE;
1083 : : }
1084 : :
1085 : 2079 : gimple_call_set_nothrow (stmt, true);
1086 : 2079 : lhs = make_ssa_name (type);
1087 : 2079 : gimple_call_set_lhs (stmt, lhs);
1088 : 2079 : gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1089 : :
1090 : 2079 : return lhs;
1091 : : }
1092 : :
1093 : : /* Perform a complex multiplication on two complex constants A, B represented
1094 : : by AR, AI, BR, BI of type TYPE.
1095 : : The operation we want is: a * b = (ar*br - ai*bi) + i(ar*bi + br*ai).
1096 : : Insert the GIMPLE statements into GSI. Store the real and imaginary
1097 : : components of the result into RR and RI. */
1098 : :
1099 : : static void
1100 : 5823 : expand_complex_multiplication_components (gimple_seq *stmts, location_t loc,
1101 : : tree type, tree ar, tree ai,
1102 : : tree br, tree bi,
1103 : : tree *rr, tree *ri)
1104 : : {
1105 : 5823 : tree t1, t2, t3, t4;
1106 : :
1107 : 5823 : t1 = gimple_build (stmts, loc, MULT_EXPR, type, ar, br);
1108 : 5823 : t2 = gimple_build (stmts, loc, MULT_EXPR, type, ai, bi);
1109 : 5823 : t3 = gimple_build (stmts, loc, MULT_EXPR, type, ar, bi);
1110 : :
1111 : : /* Avoid expanding redundant multiplication for the common
1112 : : case of squaring a complex number. */
1113 : 5823 : if (ar == br && ai == bi)
1114 : : t4 = t3;
1115 : : else
1116 : 5735 : t4 = gimple_build (stmts, loc, MULT_EXPR, type, ai, br);
1117 : :
1118 : 5823 : *rr = gimple_build (stmts, loc, MINUS_EXPR, type, t1, t2);
1119 : 5823 : *ri = gimple_build (stmts, loc, PLUS_EXPR, type, t3, t4);
1120 : 5823 : }
1121 : :
1122 : : /* Expand complex multiplication to scalars:
1123 : : a * b = (ar*br - ai*bi) + i(ar*bi + br*ai)
1124 : : */
1125 : :
1126 : : static void
1127 : 7265 : expand_complex_multiplication (gimple_stmt_iterator *gsi, tree type,
1128 : : tree ar, tree ai, tree br, tree bi,
1129 : : complex_lattice_t al, complex_lattice_t bl)
1130 : : {
1131 : 7265 : tree rr, ri;
1132 : 7265 : tree inner_type = TREE_TYPE (type);
1133 : 7265 : location_t loc = gimple_location (gsi_stmt (*gsi));
1134 : 7265 : gimple_seq stmts = NULL;
1135 : :
1136 : 7265 : if (al < bl)
1137 : : {
1138 : 16 : complex_lattice_t tl;
1139 : 16 : rr = ar, ar = br, br = rr;
1140 : 16 : ri = ai, ai = bi, bi = ri;
1141 : 16 : tl = al, al = bl, bl = tl;
1142 : : }
1143 : :
1144 : 7265 : switch (PAIR (al, bl))
1145 : : {
1146 : 0 : case PAIR (ONLY_REAL, ONLY_REAL):
1147 : 0 : rr = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ar, br);
1148 : 0 : ri = ai;
1149 : 0 : break;
1150 : :
1151 : 12 : case PAIR (ONLY_IMAG, ONLY_REAL):
1152 : 12 : rr = ar;
1153 : 12 : if (TREE_CODE (ai) == REAL_CST
1154 : 12 : && real_identical (&TREE_REAL_CST (ai), &dconst1))
1155 : 0 : ri = br;
1156 : : else
1157 : 12 : ri = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ai, br);
1158 : : break;
1159 : :
1160 : 0 : case PAIR (ONLY_IMAG, ONLY_IMAG):
1161 : 0 : rr = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ai, bi);
1162 : 0 : rr = gimple_build (&stmts, loc, NEGATE_EXPR, inner_type, rr);
1163 : 0 : ri = ar;
1164 : 0 : break;
1165 : :
1166 : 19 : case PAIR (VARYING, ONLY_REAL):
1167 : 19 : rr = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ar, br);
1168 : 19 : ri = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ai, br);
1169 : 19 : break;
1170 : :
1171 : 0 : case PAIR (VARYING, ONLY_IMAG):
1172 : 0 : rr = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ai, bi);
1173 : 0 : rr = gimple_build (&stmts, loc, NEGATE_EXPR, inner_type, rr);
1174 : 0 : ri = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ar, bi);
1175 : 0 : break;
1176 : :
1177 : 7234 : case PAIR (VARYING, VARYING):
1178 : 7234 : if (flag_complex_method == 2 && SCALAR_FLOAT_TYPE_P (inner_type))
1179 : : {
1180 : : /* If optimizing for size or not at all just do a libcall.
1181 : : Same if there are exception-handling edges or signaling NaNs. */
1182 : 2831 : if (optimize == 0 || optimize_bb_for_size_p (gsi_bb (*gsi))
1183 : 2086 : || stmt_can_throw_internal (cfun, gsi_stmt (*gsi))
1184 : 5577 : || flag_signaling_nans)
1185 : : {
1186 : 1411 : expand_complex_libcall (gsi, type, ar, ai, br, bi,
1187 : : MULT_EXPR, true);
1188 : 1411 : return;
1189 : : }
1190 : :
1191 : 2083 : if (!HONOR_NANS (inner_type))
1192 : : {
1193 : : /* If we are not worrying about NaNs expand to
1194 : : (ar*br - ai*bi) + i(ar*bi + br*ai) directly. */
1195 : 4 : expand_complex_multiplication_components (&stmts, loc, inner_type,
1196 : : ar, ai, br, bi,
1197 : : &rr, &ri);
1198 : 4 : break;
1199 : : }
1200 : :
1201 : : /* Else, expand x = a * b into
1202 : : x = (ar*br - ai*bi) + i(ar*bi + br*ai);
1203 : : if (isunordered (__real__ x, __imag__ x))
1204 : : x = __muldc3 (a, b); */
1205 : :
1206 : 2079 : tree tmpr, tmpi;
1207 : 2079 : expand_complex_multiplication_components (&stmts, loc,
1208 : : inner_type, ar, ai,
1209 : : br, bi, &tmpr, &tmpi);
1210 : 2079 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1211 : 2079 : stmts = NULL;
1212 : :
1213 : 2079 : gimple *check
1214 : 2079 : = gimple_build_cond (UNORDERED_EXPR, tmpr, tmpi,
1215 : : NULL_TREE, NULL_TREE);
1216 : :
1217 : 2079 : basic_block orig_bb = gsi_bb (*gsi);
1218 : : /* We want to keep track of the original complex multiplication
1219 : : statement as we're going to modify it later in
1220 : : update_complex_assignment. Make sure that insert_cond_bb leaves
1221 : : that statement in the join block. */
1222 : 2079 : gsi_prev (gsi);
1223 : 2079 : basic_block cond_bb
1224 : 2079 : = insert_cond_bb (gsi_bb (*gsi), gsi_stmt (*gsi), check,
1225 : : profile_probability::very_unlikely ());
1226 : :
1227 : 2079 : gimple_stmt_iterator cond_bb_gsi = gsi_last_bb (cond_bb);
1228 : 2079 : gsi_insert_after (&cond_bb_gsi, gimple_build_nop (), GSI_NEW_STMT);
1229 : :
1230 : 2079 : tree libcall_res
1231 : 2079 : = expand_complex_libcall (&cond_bb_gsi, type, ar, ai, br,
1232 : : bi, MULT_EXPR, false);
1233 : 2079 : gimple_seq stmts2 = NULL;
1234 : 2079 : tree cond_real = gimple_build (&stmts2, loc, REALPART_EXPR,
1235 : : inner_type, libcall_res);
1236 : 2079 : tree cond_imag = gimple_build (&stmts2, loc, IMAGPART_EXPR,
1237 : : inner_type, libcall_res);
1238 : 2079 : gsi_insert_seq_before (&cond_bb_gsi, stmts2, GSI_SAME_STMT);
1239 : :
1240 : 2079 : basic_block join_bb = single_succ_edge (cond_bb)->dest;
1241 : 2079 : *gsi = gsi_start_nondebug_after_labels_bb (join_bb);
1242 : :
1243 : : /* We have a conditional block with some assignments in cond_bb.
1244 : : Wire up the PHIs to wrap up. */
1245 : 2079 : rr = make_ssa_name (inner_type);
1246 : 2079 : ri = make_ssa_name (inner_type);
1247 : 2079 : edge cond_to_join = single_succ_edge (cond_bb);
1248 : 2079 : edge orig_to_join = find_edge (orig_bb, join_bb);
1249 : :
1250 : 2079 : gphi *real_phi = create_phi_node (rr, gsi_bb (*gsi));
1251 : 2079 : add_phi_arg (real_phi, cond_real, cond_to_join, UNKNOWN_LOCATION);
1252 : 2079 : add_phi_arg (real_phi, tmpr, orig_to_join, UNKNOWN_LOCATION);
1253 : :
1254 : 2079 : gphi *imag_phi = create_phi_node (ri, gsi_bb (*gsi));
1255 : 2079 : add_phi_arg (imag_phi, cond_imag, cond_to_join, UNKNOWN_LOCATION);
1256 : 2079 : add_phi_arg (imag_phi, tmpi, orig_to_join, UNKNOWN_LOCATION);
1257 : 2079 : }
1258 : : else
1259 : : /* If we are not worrying about NaNs expand to
1260 : : (ar*br - ai*bi) + i(ar*bi + br*ai) directly. */
1261 : 3740 : expand_complex_multiplication_components (&stmts, loc,
1262 : : inner_type, ar, ai,
1263 : : br, bi, &rr, &ri);
1264 : : break;
1265 : :
1266 : 0 : default:
1267 : 0 : gcc_unreachable ();
1268 : : }
1269 : :
1270 : 5854 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1271 : 5854 : update_complex_assignment (gsi, rr, ri);
1272 : : }
1273 : :
1274 : : /* Keep this algorithm in sync with fold-const.cc:const_binop().
1275 : :
1276 : : Expand complex division to scalars, straightforward algorithm.
1277 : : a / b = ((ar*br + ai*bi)/t) + i((ai*br - ar*bi)/t)
1278 : : t = br*br + bi*bi
1279 : : */
1280 : :
1281 : : static void
1282 : 19 : expand_complex_div_straight (gimple_stmt_iterator *gsi, tree inner_type,
1283 : : tree ar, tree ai, tree br, tree bi,
1284 : : enum tree_code code)
1285 : : {
1286 : 19 : gimple_seq stmts = NULL;
1287 : 19 : location_t loc = gimple_location (gsi_stmt (*gsi));
1288 : 19 : tree rr, ri, div, t1, t2, t3;
1289 : :
1290 : 19 : t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, br, br);
1291 : 19 : t2 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, bi, bi);
1292 : 19 : div = gimple_build (&stmts, loc, PLUS_EXPR, inner_type, t1, t2);
1293 : :
1294 : 19 : t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ar, br);
1295 : 19 : t2 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ai, bi);
1296 : 19 : t3 = gimple_build (&stmts, loc, PLUS_EXPR, inner_type, t1, t2);
1297 : 19 : rr = gimple_build (&stmts, loc, code, inner_type, t3, div);
1298 : :
1299 : 19 : t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ai, br);
1300 : 19 : t2 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ar, bi);
1301 : 19 : t3 = gimple_build (&stmts, loc, MINUS_EXPR, inner_type, t1, t2);
1302 : 19 : ri = gimple_build (&stmts, loc, code, inner_type, t3, div);
1303 : :
1304 : 19 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1305 : 19 : update_complex_assignment (gsi, rr, ri);
1306 : 19 : }
1307 : :
1308 : : /* Keep this algorithm in sync with fold-const.cc:const_binop().
1309 : :
1310 : : Expand complex division to scalars, modified algorithm to minimize
1311 : : overflow with wide input ranges. */
1312 : :
1313 : : static void
1314 : 287 : expand_complex_div_wide (gimple_stmt_iterator *gsi, tree inner_type,
1315 : : tree ar, tree ai, tree br, tree bi,
1316 : : enum tree_code code)
1317 : : {
1318 : 287 : tree rr, ri, ratio, div, t1, t2, tr, ti, compare;
1319 : 287 : basic_block bb_cond, bb_true, bb_false, bb_join;
1320 : 287 : gimple *stmt;
1321 : 287 : gimple_seq stmts = NULL;
1322 : 287 : location_t loc = gimple_location (gsi_stmt (*gsi));
1323 : :
1324 : : /* Examine |br| < |bi|, and branch. */
1325 : 287 : t1 = gimple_build (&stmts, loc, ABS_EXPR, inner_type, br);
1326 : 287 : t2 = gimple_build (&stmts, loc, ABS_EXPR, inner_type, bi);
1327 : 287 : compare = gimple_build (&stmts, loc,
1328 : : LT_EXPR, boolean_type_node, t1, t2);
1329 : :
1330 : 287 : bb_cond = bb_true = bb_false = bb_join = NULL;
1331 : 287 : rr = ri = tr = ti = NULL;
1332 : 287 : if (TREE_CODE (compare) != INTEGER_CST)
1333 : : {
1334 : 244 : edge e;
1335 : 244 : gimple *stmt;
1336 : :
1337 : 244 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1338 : 244 : stmts = NULL;
1339 : 244 : stmt = gimple_build_cond (NE_EXPR, compare, boolean_false_node,
1340 : : NULL_TREE, NULL_TREE);
1341 : 244 : gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1342 : :
1343 : : /* Split the original block, and create the TRUE and FALSE blocks. */
1344 : 244 : e = split_block (gsi_bb (*gsi), stmt);
1345 : 244 : bb_cond = e->src;
1346 : 244 : bb_join = e->dest;
1347 : 244 : bb_true = create_empty_bb (bb_cond);
1348 : 244 : bb_false = create_empty_bb (bb_true);
1349 : 488 : bb_true->count = bb_false->count
1350 : 244 : = bb_cond->count.apply_probability (profile_probability::even ());
1351 : :
1352 : : /* Wire the blocks together. */
1353 : 244 : e->flags = EDGE_TRUE_VALUE;
1354 : : /* TODO: With value profile we could add an historgram to determine real
1355 : : branch outcome. */
1356 : 244 : e->probability = profile_probability::even ();
1357 : 244 : redirect_edge_succ (e, bb_true);
1358 : 244 : edge e2 = make_edge (bb_cond, bb_false, EDGE_FALSE_VALUE);
1359 : 244 : e2->probability = profile_probability::even ();
1360 : 244 : make_single_succ_edge (bb_true, bb_join, EDGE_FALLTHRU);
1361 : 244 : make_single_succ_edge (bb_false, bb_join, EDGE_FALLTHRU);
1362 : 244 : add_bb_to_loop (bb_true, bb_cond->loop_father);
1363 : 244 : add_bb_to_loop (bb_false, bb_cond->loop_father);
1364 : :
1365 : : /* Update dominance info. Note that bb_join's data was
1366 : : updated by split_block. */
1367 : 244 : if (dom_info_available_p (CDI_DOMINATORS))
1368 : : {
1369 : 239 : set_immediate_dominator (CDI_DOMINATORS, bb_true, bb_cond);
1370 : 239 : set_immediate_dominator (CDI_DOMINATORS, bb_false, bb_cond);
1371 : : }
1372 : :
1373 : 244 : rr = create_tmp_reg (inner_type);
1374 : 244 : ri = create_tmp_reg (inner_type);
1375 : : }
1376 : : else
1377 : : {
1378 : 43 : gimple_seq_discard (stmts);
1379 : 43 : stmts = NULL;
1380 : : }
1381 : :
1382 : : /* In the TRUE branch, we compute
1383 : : ratio = br/bi;
1384 : : div = (br * ratio) + bi;
1385 : : tr = (ar * ratio) + ai;
1386 : : ti = (ai * ratio) - ar;
1387 : : tr = tr / div;
1388 : : ti = ti / div; */
1389 : 287 : if (bb_true || integer_nonzerop (compare))
1390 : : {
1391 : 257 : if (bb_true)
1392 : : {
1393 : 244 : *gsi = gsi_last_bb (bb_true);
1394 : 244 : gsi_insert_after (gsi, gimple_build_nop (), GSI_NEW_STMT);
1395 : : }
1396 : :
1397 : 257 : ratio = gimple_build (&stmts, loc, code, inner_type, br, bi);
1398 : :
1399 : 257 : t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, br, ratio);
1400 : 257 : div = gimple_build (&stmts, loc, PLUS_EXPR, inner_type, t1, bi);
1401 : :
1402 : 257 : t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ar, ratio);
1403 : 257 : tr = gimple_build (&stmts, loc, PLUS_EXPR, inner_type, t1, ai);
1404 : :
1405 : 257 : t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ai, ratio);
1406 : 257 : ti = gimple_build (&stmts, loc, MINUS_EXPR, inner_type, t1, ar);
1407 : :
1408 : 257 : tr = gimple_build (&stmts, loc, code, inner_type, tr, div);
1409 : 257 : ti = gimple_build (&stmts, loc, code, inner_type, ti, div);
1410 : 257 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1411 : 257 : stmts = NULL;
1412 : :
1413 : 257 : if (bb_true)
1414 : : {
1415 : 244 : stmt = gimple_build_assign (rr, tr);
1416 : 244 : gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1417 : 244 : stmt = gimple_build_assign (ri, ti);
1418 : 244 : gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1419 : 244 : gsi_remove (gsi, true);
1420 : : }
1421 : : }
1422 : :
1423 : : /* In the FALSE branch, we compute
1424 : : ratio = d/c;
1425 : : divisor = (d * ratio) + c;
1426 : : tr = (b * ratio) + a;
1427 : : ti = b - (a * ratio);
1428 : : tr = tr / div;
1429 : : ti = ti / div; */
1430 : 287 : if (bb_false || integer_zerop (compare))
1431 : : {
1432 : 274 : if (bb_false)
1433 : : {
1434 : 244 : *gsi = gsi_last_bb (bb_false);
1435 : 244 : gsi_insert_after (gsi, gimple_build_nop (), GSI_NEW_STMT);
1436 : : }
1437 : :
1438 : 274 : ratio = gimple_build (&stmts, loc, code, inner_type, bi, br);
1439 : :
1440 : 274 : t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, bi, ratio);
1441 : 274 : div = gimple_build (&stmts, loc, PLUS_EXPR, inner_type, t1, br);
1442 : :
1443 : 274 : t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ai, ratio);
1444 : 274 : tr = gimple_build (&stmts, loc, PLUS_EXPR, inner_type, t1, ar);
1445 : :
1446 : 274 : t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ar, ratio);
1447 : 274 : ti = gimple_build (&stmts, loc, MINUS_EXPR, inner_type, ai, t1);
1448 : :
1449 : 274 : tr = gimple_build (&stmts, loc, code, inner_type, tr, div);
1450 : 274 : ti = gimple_build (&stmts, loc, code, inner_type, ti, div);
1451 : 274 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1452 : 274 : stmts = NULL;
1453 : :
1454 : 274 : if (bb_false)
1455 : : {
1456 : 244 : stmt = gimple_build_assign (rr, tr);
1457 : 244 : gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1458 : 244 : stmt = gimple_build_assign (ri, ti);
1459 : 244 : gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1460 : 244 : gsi_remove (gsi, true);
1461 : : }
1462 : : }
1463 : :
1464 : 287 : if (bb_join)
1465 : 488 : *gsi = gsi_start_bb (bb_join);
1466 : : else
1467 : : rr = tr, ri = ti;
1468 : :
1469 : 287 : update_complex_assignment (gsi, rr, ri);
1470 : 287 : }
1471 : :
1472 : : /* Expand complex division to scalars. */
1473 : :
1474 : : static void
1475 : 1030 : expand_complex_division (gimple_stmt_iterator *gsi, tree type,
1476 : : tree ar, tree ai, tree br, tree bi,
1477 : : enum tree_code code,
1478 : : complex_lattice_t al, complex_lattice_t bl)
1479 : : {
1480 : 1030 : tree rr, ri;
1481 : 1030 : gimple_seq stmts = NULL;
1482 : 1030 : location_t loc = gimple_location (gsi_stmt (*gsi));
1483 : :
1484 : 1030 : tree inner_type = TREE_TYPE (type);
1485 : 1030 : switch (PAIR (al, bl))
1486 : : {
1487 : 5 : case PAIR (ONLY_REAL, ONLY_REAL):
1488 : 5 : rr = gimple_build (&stmts, loc, code, inner_type, ar, br);
1489 : 5 : ri = ai;
1490 : 5 : break;
1491 : :
1492 : 0 : case PAIR (ONLY_REAL, ONLY_IMAG):
1493 : 0 : rr = ai;
1494 : 0 : ri = gimple_build (&stmts, loc, code, inner_type, ar, bi);
1495 : 0 : ri = gimple_build (&stmts, loc, NEGATE_EXPR, inner_type, ri);
1496 : 0 : break;
1497 : :
1498 : 0 : case PAIR (ONLY_IMAG, ONLY_REAL):
1499 : 0 : rr = ar;
1500 : 0 : ri = gimple_build (&stmts, loc, code, inner_type, ai, br);
1501 : 0 : break;
1502 : :
1503 : 0 : case PAIR (ONLY_IMAG, ONLY_IMAG):
1504 : 0 : rr = gimple_build (&stmts, loc, code, inner_type, ai, bi);
1505 : 0 : ri = ar;
1506 : 0 : break;
1507 : :
1508 : 17 : case PAIR (VARYING, ONLY_REAL):
1509 : 17 : rr = gimple_build (&stmts, loc, code, inner_type, ar, br);
1510 : 17 : ri = gimple_build (&stmts, loc, code, inner_type, ai, br);
1511 : 17 : break;
1512 : :
1513 : 9 : case PAIR (VARYING, ONLY_IMAG):
1514 : 9 : rr = gimple_build (&stmts, loc, code, inner_type, ai, bi);
1515 : 9 : ri = gimple_build (&stmts, loc, code, inner_type, ar, bi);
1516 : 9 : ri = gimple_build (&stmts, loc, NEGATE_EXPR, inner_type, ri);
1517 : 9 : break;
1518 : :
1519 : 999 : case PAIR (ONLY_REAL, VARYING):
1520 : 999 : case PAIR (ONLY_IMAG, VARYING):
1521 : 999 : case PAIR (VARYING, VARYING):
1522 : 999 : switch (flag_complex_method)
1523 : : {
1524 : 19 : case 0:
1525 : : /* straightforward implementation of complex divide acceptable. */
1526 : 19 : expand_complex_div_straight (gsi, inner_type, ar, ai, br, bi, code);
1527 : 19 : break;
1528 : :
1529 : 744 : case 2:
1530 : 744 : if (SCALAR_FLOAT_TYPE_P (inner_type))
1531 : : {
1532 : 693 : expand_complex_libcall (gsi, type, ar, ai, br, bi, code, true);
1533 : 693 : break;
1534 : : }
1535 : : /* FALLTHRU */
1536 : :
1537 : 287 : case 1:
1538 : : /* wide ranges of inputs must work for complex divide. */
1539 : 287 : expand_complex_div_wide (gsi, inner_type, ar, ai, br, bi, code);
1540 : 287 : break;
1541 : :
1542 : 0 : default:
1543 : 0 : gcc_unreachable ();
1544 : : }
1545 : 999 : return;
1546 : :
1547 : 0 : default:
1548 : 0 : gcc_unreachable ();
1549 : : }
1550 : :
1551 : 31 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1552 : 31 : update_complex_assignment (gsi, rr, ri);
1553 : : }
1554 : :
1555 : : /* Expand complex negation to scalars:
1556 : : -a = (-ar) + i(-ai)
1557 : : */
1558 : :
1559 : : static void
1560 : 64 : expand_complex_negation (gimple_stmt_iterator *gsi, tree inner_type,
1561 : : tree ar, tree ai)
1562 : : {
1563 : 64 : tree rr, ri;
1564 : 64 : gimple_seq stmts = NULL;
1565 : 64 : location_t loc = gimple_location (gsi_stmt (*gsi));
1566 : :
1567 : 64 : rr = gimple_build (&stmts, loc, NEGATE_EXPR, inner_type, ar);
1568 : 64 : ri = gimple_build (&stmts, loc, NEGATE_EXPR, inner_type, ai);
1569 : :
1570 : 64 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1571 : 64 : update_complex_assignment (gsi, rr, ri);
1572 : 64 : }
1573 : :
1574 : : /* Expand complex paren to scalars:
1575 : : ((a)) = ((ar)) + i((ai))
1576 : : */
1577 : :
1578 : : static void
1579 : 386 : expand_complex_paren (gimple_stmt_iterator *gsi, tree inner_type,
1580 : : tree ar, tree ai)
1581 : : {
1582 : 386 : tree rr, ri;
1583 : 386 : gimple_seq stmts = NULL;
1584 : 386 : location_t loc = gimple_location (gsi_stmt (*gsi));
1585 : :
1586 : 386 : rr = gimple_build (&stmts, loc, PAREN_EXPR, inner_type, ar);
1587 : 386 : ri = gimple_build (&stmts, loc, PAREN_EXPR, inner_type, ai);
1588 : :
1589 : 386 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1590 : 386 : update_complex_assignment (gsi, rr, ri);
1591 : 386 : }
1592 : :
1593 : : /* Expand complex conjugate to scalars:
1594 : : ~a = (ar) + i(-ai)
1595 : : */
1596 : :
1597 : : static void
1598 : 566 : expand_complex_conjugate (gimple_stmt_iterator *gsi, tree inner_type,
1599 : : tree ar, tree ai)
1600 : : {
1601 : 566 : tree ri;
1602 : 566 : gimple_seq stmts = NULL;
1603 : 566 : location_t loc = gimple_location (gsi_stmt (*gsi));
1604 : :
1605 : 566 : ri = gimple_build (&stmts, loc, NEGATE_EXPR, inner_type, ai);
1606 : :
1607 : 566 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1608 : 566 : update_complex_assignment (gsi, ar, ri);
1609 : 566 : }
1610 : :
1611 : : /* Expand complex comparison (EQ or NE only). */
1612 : :
1613 : : static void
1614 : 25750 : expand_complex_comparison (gimple_stmt_iterator *gsi, tree ar, tree ai,
1615 : : tree br, tree bi, enum tree_code code)
1616 : : {
1617 : 25750 : tree cr, ci, cc, type;
1618 : 25750 : gimple *stmt = gsi_stmt (*gsi);
1619 : 25750 : gimple_seq stmts = NULL;
1620 : 25750 : location_t loc = gimple_location (stmt);
1621 : :
1622 : 25750 : cr = gimple_build (&stmts, loc, code, boolean_type_node, ar, br);
1623 : 25750 : ci = gimple_build (&stmts, loc, code, boolean_type_node, ai, bi);
1624 : 51065 : cc = gimple_build (&stmts, loc,
1625 : : (code == EQ_EXPR ? BIT_AND_EXPR : BIT_IOR_EXPR),
1626 : : boolean_type_node, cr, ci);
1627 : 25750 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1628 : :
1629 : 25750 : switch (gimple_code (stmt))
1630 : : {
1631 : 534 : case GIMPLE_ASSIGN:
1632 : 534 : type = TREE_TYPE (gimple_assign_lhs (stmt));
1633 : 534 : gimple_assign_set_rhs_from_tree (gsi, fold_convert (type, cc));
1634 : 534 : stmt = gsi_stmt (*gsi);
1635 : 534 : break;
1636 : :
1637 : 25216 : case GIMPLE_COND:
1638 : 25216 : {
1639 : 25216 : gcond *cond_stmt = as_a <gcond *> (stmt);
1640 : 25216 : gimple_cond_set_code (cond_stmt, EQ_EXPR);
1641 : 25216 : gimple_cond_set_lhs (cond_stmt, cc);
1642 : 25216 : gimple_cond_set_rhs (cond_stmt, boolean_true_node);
1643 : : }
1644 : 25216 : break;
1645 : :
1646 : 0 : default:
1647 : 0 : gcc_unreachable ();
1648 : : }
1649 : :
1650 : 25750 : update_stmt (stmt);
1651 : 25750 : if (maybe_clean_eh_stmt (stmt))
1652 : 1 : bitmap_set_bit (need_eh_cleanup, gimple_bb (stmt)->index);
1653 : 25750 : }
1654 : :
1655 : : /* Expand inline asm that sets some complex SSA_NAMEs. */
1656 : :
1657 : : static void
1658 : 460 : expand_complex_asm (gimple_stmt_iterator *gsi)
1659 : : {
1660 : 460 : gasm *stmt = as_a <gasm *> (gsi_stmt (*gsi));
1661 : 460 : unsigned int i;
1662 : 460 : bool diagnosed_p = false;
1663 : :
1664 : 770 : for (i = 0; i < gimple_asm_noutputs (stmt); ++i)
1665 : : {
1666 : 310 : tree link = gimple_asm_output_op (stmt, i);
1667 : 310 : tree op = TREE_VALUE (link);
1668 : 310 : if (TREE_CODE (op) == SSA_NAME
1669 : 310 : && TREE_CODE (TREE_TYPE (op)) == COMPLEX_TYPE)
1670 : : {
1671 : 8 : if (gimple_asm_nlabels (stmt) > 0)
1672 : : {
1673 : 1 : if (!diagnosed_p)
1674 : : {
1675 : 1 : sorry_at (gimple_location (stmt),
1676 : : "%<asm goto%> with complex typed outputs");
1677 : 1 : diagnosed_p = true;
1678 : : }
1679 : : /* Make sure to not ICE later, see PR105165. */
1680 : 1 : tree zero = build_zero_cst (TREE_TYPE (TREE_TYPE (op)));
1681 : 1 : set_component_ssa_name (op, false, zero);
1682 : 1 : set_component_ssa_name (op, true, zero);
1683 : 1 : continue;
1684 : 1 : }
1685 : 7 : tree type = TREE_TYPE (op);
1686 : 7 : tree inner_type = TREE_TYPE (type);
1687 : 7 : tree r = build1 (REALPART_EXPR, inner_type, op);
1688 : 7 : tree i = build1 (IMAGPART_EXPR, inner_type, op);
1689 : 7 : gimple_seq list = set_component_ssa_name (op, false, r);
1690 : :
1691 : 7 : if (list)
1692 : 7 : gsi_insert_seq_after (gsi, list, GSI_CONTINUE_LINKING);
1693 : :
1694 : 7 : list = set_component_ssa_name (op, true, i);
1695 : 7 : if (list)
1696 : 7 : gsi_insert_seq_after (gsi, list, GSI_CONTINUE_LINKING);
1697 : : }
1698 : : }
1699 : 460 : }
1700 : :
1701 : :
1702 : : /* ARG is the argument to a cabs builtin call in GSI from the
1703 : : original OLD_STMT. Create a sequence of statements prior
1704 : : to GSI that calculates sqrt(R*R + I*I), where R and
1705 : : I are the real and imaginary components of ARG, respectively. */
1706 : :
1707 : : static void
1708 : 871 : gimple_expand_builtin_cabs (gimple_stmt_iterator *gsi, gimple *old_stmt)
1709 : : {
1710 : 871 : tree real_part, imag_part, addend1, addend2, sum;
1711 : 871 : tree arg = gimple_call_arg (old_stmt, 0);
1712 : 871 : tree type = TREE_TYPE (TREE_TYPE (arg));
1713 : 871 : machine_mode mode = TYPE_MODE (type);
1714 : 871 : gimple *new_stmt;
1715 : :
1716 : 871 : tree lhs = gimple_call_lhs (old_stmt);
1717 : :
1718 : 871 : real_part = extract_component (gsi, arg, false, true);
1719 : 871 : imag_part = extract_component (gsi, arg, true, true);
1720 : 871 : location_t loc = gimple_location (old_stmt);
1721 : :
1722 : 871 : gimple_seq stmts = NULL;
1723 : :
1724 : : /* cabs(x+0i) -> abs(x).
1725 : : cabs(0+xi) -> abs(x).
1726 : : These 2 can be done even without unsafe math optimizations. */
1727 : 871 : if (real_zerop (imag_part)
1728 : 871 : || real_zerop (real_part))
1729 : : {
1730 : 9 : tree other = real_zerop (imag_part) ? real_part : imag_part;
1731 : 9 : sum = gimple_build (&stmts, loc, ABS_EXPR, type, other);
1732 : 9 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1733 : 9 : new_stmt = gimple_build_assign (lhs, sum);
1734 : 9 : gimple_set_location (new_stmt, loc);
1735 : 9 : gsi_replace (gsi, new_stmt, true);
1736 : 877 : return;
1737 : : }
1738 : :
1739 : 862 : if (!flag_unsafe_math_optimizations)
1740 : : return;
1741 : :
1742 : : /* cabs(x+xi) -> fabs(x)*sqrt(2). */
1743 : 5 : if (operand_equal_p (real_part, imag_part))
1744 : : {
1745 : 2 : tree sqrt2 = build_real_truncate (type, dconst_sqrt2 ());
1746 : 2 : sum = gimple_build (&stmts, loc, ABS_EXPR, type, real_part);
1747 : 2 : sum = gimple_build (&stmts, loc, MULT_EXPR, type, sum, sqrt2);
1748 : 2 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1749 : 2 : new_stmt = gimple_build_assign (lhs, sum);
1750 : 2 : gimple_set_location (new_stmt, loc);
1751 : 2 : gsi_replace (gsi, new_stmt, true);
1752 : 2 : return;
1753 : : }
1754 : :
1755 : : /* cabs(a+bi) -> sqrt(a*a+b*b) if sqrt exists on the target
1756 : : and optimizing for speed. */
1757 : 3 : tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
1758 : 3 : if (!optimize_bb_for_speed_p (gimple_bb (old_stmt))
1759 : 3 : || !sqrtfn
1760 : 6 : || optab_handler (sqrt_optab, mode) == CODE_FOR_nothing)
1761 : 0 : return;
1762 : :
1763 : 3 : addend1 = gimple_build (&stmts, loc, MULT_EXPR, type, real_part, real_part);
1764 : 3 : addend2 = gimple_build (&stmts, loc, MULT_EXPR, type, imag_part, imag_part);
1765 : 3 : sum = gimple_build (&stmts, loc, PLUS_EXPR, type, addend1, addend2);
1766 : 3 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1767 : :
1768 : : /* Build the sqrt call. */
1769 : 3 : new_stmt = gimple_build_call (sqrtfn, 1, sum);
1770 : 3 : gimple_set_location (new_stmt, loc);
1771 : 3 : gimple_call_set_lhs (new_stmt, lhs);
1772 : 3 : gsi_replace (gsi, new_stmt, true);
1773 : : }
1774 : :
1775 : : /* Process one statement. If we identify a complex operation, expand it. */
1776 : :
1777 : : static void
1778 : 1375486 : expand_complex_operations_1 (gimple_stmt_iterator *gsi)
1779 : : {
1780 : 1375486 : gimple *stmt = gsi_stmt (*gsi);
1781 : 1375486 : tree type, inner_type, lhs;
1782 : 1375486 : tree ac, ar, ai, bc, br, bi;
1783 : 1375486 : complex_lattice_t al, bl;
1784 : 1375486 : enum tree_code code;
1785 : 1375486 : if (gimple_code (stmt) == GIMPLE_CALL)
1786 : : {
1787 : 228291 : switch (gimple_call_combined_fn (stmt))
1788 : : {
1789 : 871 : CASE_CFN_CABS:
1790 : 871 : gimple_expand_builtin_cabs (gsi, stmt);
1791 : 871 : return;
1792 : : default:;
1793 : : }
1794 : : }
1795 : :
1796 : 1374615 : if (gimple_code (stmt) == GIMPLE_ASM)
1797 : : {
1798 : 460 : expand_complex_asm (gsi);
1799 : 460 : return;
1800 : : }
1801 : :
1802 : 1374155 : lhs = gimple_get_lhs (stmt);
1803 : 1374155 : if (!lhs && gimple_code (stmt) != GIMPLE_COND)
1804 : : return;
1805 : :
1806 : 1001017 : type = TREE_TYPE (gimple_op (stmt, 0));
1807 : 1001017 : code = gimple_expr_code (stmt);
1808 : :
1809 : : /* Initial filter for operations we handle. */
1810 : 1001017 : switch (code)
1811 : : {
1812 : 127837 : case PLUS_EXPR:
1813 : 127837 : case MINUS_EXPR:
1814 : 127837 : case MULT_EXPR:
1815 : 127837 : case TRUNC_DIV_EXPR:
1816 : 127837 : case CEIL_DIV_EXPR:
1817 : 127837 : case FLOOR_DIV_EXPR:
1818 : 127837 : case ROUND_DIV_EXPR:
1819 : 127837 : case RDIV_EXPR:
1820 : 127837 : case NEGATE_EXPR:
1821 : 127837 : case PAREN_EXPR:
1822 : 127837 : case CONJ_EXPR:
1823 : 127837 : if (TREE_CODE (type) != COMPLEX_TYPE)
1824 : : return;
1825 : 18791 : inner_type = TREE_TYPE (type);
1826 : 18791 : break;
1827 : :
1828 : 126270 : case EQ_EXPR:
1829 : 126270 : case NE_EXPR:
1830 : : /* Note, both GIMPLE_ASSIGN and GIMPLE_COND may have an EQ_EXPR
1831 : : subcode, so we need to access the operands using gimple_op. */
1832 : 126270 : inner_type = TREE_TYPE (gimple_op (stmt, 1));
1833 : 126270 : if (TREE_CODE (inner_type) != COMPLEX_TYPE)
1834 : : return;
1835 : : break;
1836 : :
1837 : 746910 : default:
1838 : 746910 : {
1839 : 746910 : tree rhs;
1840 : :
1841 : : /* GIMPLE_COND may also fallthru here, but we do not need to
1842 : : do anything with it. */
1843 : 746910 : if (gimple_code (stmt) == GIMPLE_COND)
1844 : : return;
1845 : :
1846 : 725773 : if (TREE_CODE (type) == COMPLEX_TYPE)
1847 : 136833 : expand_complex_move (gsi, type);
1848 : 588940 : else if (is_gimple_assign (stmt)
1849 : 493380 : && (gimple_assign_rhs_code (stmt) == REALPART_EXPR
1850 : 458842 : || gimple_assign_rhs_code (stmt) == IMAGPART_EXPR)
1851 : 657169 : && TREE_CODE (lhs) == SSA_NAME)
1852 : : {
1853 : 68229 : rhs = gimple_assign_rhs1 (stmt);
1854 : 68229 : rhs = extract_component (gsi, TREE_OPERAND (rhs, 0),
1855 : : gimple_assign_rhs_code (stmt)
1856 : : == IMAGPART_EXPR,
1857 : : false);
1858 : 68229 : gimple_assign_set_rhs_from_tree (gsi, rhs);
1859 : 68229 : stmt = gsi_stmt (*gsi);
1860 : 68229 : update_stmt (stmt);
1861 : : }
1862 : : }
1863 : : return;
1864 : : }
1865 : :
1866 : : /* Extract the components of the two complex values. Make sure and
1867 : : handle the common case of the same value used twice specially. */
1868 : 44541 : if (is_gimple_assign (stmt))
1869 : : {
1870 : 19325 : ac = gimple_assign_rhs1 (stmt);
1871 : 19325 : bc = (gimple_num_ops (stmt) > 2) ? gimple_assign_rhs2 (stmt) : NULL;
1872 : : }
1873 : : /* GIMPLE_CALL cannot get here. */
1874 : : else
1875 : : {
1876 : 25216 : ac = gimple_cond_lhs (stmt);
1877 : 25216 : bc = gimple_cond_rhs (stmt);
1878 : : }
1879 : :
1880 : 44541 : ar = extract_component (gsi, ac, false, true);
1881 : 44541 : ai = extract_component (gsi, ac, true, true);
1882 : :
1883 : 44541 : if (ac == bc)
1884 : : br = ar, bi = ai;
1885 : 44411 : else if (bc)
1886 : : {
1887 : 43395 : br = extract_component (gsi, bc, 0, true);
1888 : 43395 : bi = extract_component (gsi, bc, 1, true);
1889 : : }
1890 : : else
1891 : : br = bi = NULL_TREE;
1892 : :
1893 : 44541 : al = find_lattice_value (ac);
1894 : 44541 : if (al == UNINITIALIZED)
1895 : 25 : al = VARYING;
1896 : :
1897 : 44541 : if (TREE_CODE_CLASS (code) == tcc_unary)
1898 : : bl = UNINITIALIZED;
1899 : 43525 : else if (ac == bc)
1900 : : bl = al;
1901 : : else
1902 : : {
1903 : 43395 : bl = find_lattice_value (bc);
1904 : 43395 : if (bl == UNINITIALIZED)
1905 : 22 : bl = VARYING;
1906 : : }
1907 : :
1908 : 44541 : switch (code)
1909 : : {
1910 : 9480 : case PLUS_EXPR:
1911 : 9480 : case MINUS_EXPR:
1912 : 9480 : expand_complex_addition (gsi, inner_type, ar, ai, br, bi, code, al, bl);
1913 : 9480 : break;
1914 : :
1915 : 7265 : case MULT_EXPR:
1916 : 7265 : expand_complex_multiplication (gsi, type, ar, ai, br, bi, al, bl);
1917 : 7265 : break;
1918 : :
1919 : 1030 : case TRUNC_DIV_EXPR:
1920 : 1030 : case CEIL_DIV_EXPR:
1921 : 1030 : case FLOOR_DIV_EXPR:
1922 : 1030 : case ROUND_DIV_EXPR:
1923 : 1030 : case RDIV_EXPR:
1924 : 1030 : expand_complex_division (gsi, type, ar, ai, br, bi, code, al, bl);
1925 : 1030 : break;
1926 : :
1927 : 64 : case NEGATE_EXPR:
1928 : 64 : expand_complex_negation (gsi, inner_type, ar, ai);
1929 : 64 : break;
1930 : :
1931 : 566 : case CONJ_EXPR:
1932 : 566 : expand_complex_conjugate (gsi, inner_type, ar, ai);
1933 : 566 : break;
1934 : :
1935 : 25750 : case EQ_EXPR:
1936 : 25750 : case NE_EXPR:
1937 : 25750 : expand_complex_comparison (gsi, ar, ai, br, bi, code);
1938 : 25750 : break;
1939 : :
1940 : 386 : case PAREN_EXPR:
1941 : 386 : expand_complex_paren (gsi, inner_type, ar, ai);
1942 : 386 : break;
1943 : :
1944 : 0 : default:
1945 : 0 : gcc_unreachable ();
1946 : : }
1947 : : }
1948 : :
1949 : :
1950 : : /* Entry point for complex operation lowering during optimization. */
1951 : :
1952 : : static unsigned int
1953 : 1436719 : tree_lower_complex (void)
1954 : : {
1955 : 1436719 : gimple_stmt_iterator gsi;
1956 : 1436719 : basic_block bb;
1957 : 1436719 : int n_bbs, i;
1958 : 1436719 : int *rpo;
1959 : :
1960 : 1436719 : if (!init_dont_simulate_again ())
1961 : : return 0;
1962 : :
1963 : 15388 : complex_lattice_values.create (num_ssa_names);
1964 : 15388 : complex_lattice_values.safe_grow_cleared (num_ssa_names, true);
1965 : :
1966 : 7694 : init_parameter_lattice_values ();
1967 : 7694 : class complex_propagate complex_propagate;
1968 : 7694 : complex_propagate.ssa_propagate ();
1969 : :
1970 : 7694 : need_eh_cleanup = BITMAP_ALLOC (NULL);
1971 : 7694 : if (optimize)
1972 : 4920 : dce_worklist = BITMAP_ALLOC (NULL);
1973 : :
1974 : 7694 : complex_variable_components = new int_tree_htab_type (10);
1975 : :
1976 : 15388 : complex_ssa_name_components.create (2 * num_ssa_names);
1977 : 15388 : complex_ssa_name_components.safe_grow_cleared (2 * num_ssa_names, true);
1978 : :
1979 : 7694 : update_parameter_components ();
1980 : :
1981 : 7694 : rpo = XNEWVEC (int, last_basic_block_for_fn (cfun));
1982 : 7694 : n_bbs = pre_and_rev_post_order_compute (NULL, rpo, false);
1983 : 269478 : for (i = 0; i < n_bbs; i++)
1984 : : {
1985 : 254090 : bb = BASIC_BLOCK_FOR_FN (cfun, rpo[i]);
1986 : 254090 : if (!bb)
1987 : 0 : continue;
1988 : 254090 : update_phi_components (bb);
1989 : 1883666 : for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1990 : 1375486 : expand_complex_operations_1 (&gsi);
1991 : : }
1992 : :
1993 : 7694 : free (rpo);
1994 : :
1995 : 7694 : if (!phis_to_revisit.is_empty ())
1996 : : {
1997 : : unsigned int n = phis_to_revisit.length ();
1998 : 3840 : for (unsigned int j = 0; j < n; j += 3)
1999 : 10251 : for (unsigned int k = 0; k < 2; k++)
2000 : 6834 : if (gphi *phi = phis_to_revisit[j + k + 1])
2001 : : {
2002 : 6769 : unsigned int m = gimple_phi_num_args (phi);
2003 : 20307 : for (unsigned int l = 0; l < m; ++l)
2004 : : {
2005 : 13538 : tree op = gimple_phi_arg_def (phi, l);
2006 : 20307 : if (TREE_CODE (op) == SSA_NAME
2007 : 13538 : || is_gimple_min_invariant (op))
2008 : 6769 : continue;
2009 : 6769 : tree arg = gimple_phi_arg_def (phis_to_revisit[j], l);
2010 : 6769 : op = extract_component (NULL, arg, k > 0, false, false);
2011 : 6769 : SET_PHI_ARG_DEF (phi, l, op);
2012 : : }
2013 : : }
2014 : 423 : phis_to_revisit.release ();
2015 : : }
2016 : :
2017 : 7694 : gsi_commit_edge_inserts ();
2018 : :
2019 : 7694 : if (optimize)
2020 : : {
2021 : 4920 : simple_dce_from_worklist (dce_worklist, need_eh_cleanup);
2022 : 4920 : BITMAP_FREE (dce_worklist);
2023 : : }
2024 : :
2025 : 7694 : unsigned todo
2026 : 7694 : = gimple_purge_all_dead_eh_edges (need_eh_cleanup) ? TODO_cleanup_cfg : 0;
2027 : 7694 : BITMAP_FREE (need_eh_cleanup);
2028 : :
2029 : 7694 : delete complex_variable_components;
2030 : 7694 : complex_variable_components = NULL;
2031 : 7694 : complex_ssa_name_components.release ();
2032 : 7694 : complex_lattice_values.release ();
2033 : 7694 : return todo;
2034 : 7694 : }
2035 : :
2036 : : namespace {
2037 : :
2038 : : const pass_data pass_data_lower_complex =
2039 : : {
2040 : : GIMPLE_PASS, /* type */
2041 : : "cplxlower", /* name */
2042 : : OPTGROUP_NONE, /* optinfo_flags */
2043 : : TV_NONE, /* tv_id */
2044 : : PROP_ssa, /* properties_required */
2045 : : PROP_gimple_lcx, /* properties_provided */
2046 : : 0, /* properties_destroyed */
2047 : : 0, /* todo_flags_start */
2048 : : TODO_update_ssa, /* todo_flags_finish */
2049 : : };
2050 : :
2051 : : class pass_lower_complex : public gimple_opt_pass
2052 : : {
2053 : : public:
2054 : 566314 : pass_lower_complex (gcc::context *ctxt)
2055 : 1132628 : : gimple_opt_pass (pass_data_lower_complex, ctxt)
2056 : : {}
2057 : :
2058 : : /* opt_pass methods: */
2059 : 283157 : opt_pass * clone () final override { return new pass_lower_complex (m_ctxt); }
2060 : 1009000 : unsigned int execute (function *) final override
2061 : : {
2062 : 1009000 : return tree_lower_complex ();
2063 : : }
2064 : :
2065 : : }; // class pass_lower_complex
2066 : :
2067 : : } // anon namespace
2068 : :
2069 : : gimple_opt_pass *
2070 : 283157 : make_pass_lower_complex (gcc::context *ctxt)
2071 : : {
2072 : 283157 : return new pass_lower_complex (ctxt);
2073 : : }
2074 : :
2075 : :
2076 : : namespace {
2077 : :
2078 : : const pass_data pass_data_lower_complex_O0 =
2079 : : {
2080 : : GIMPLE_PASS, /* type */
2081 : : "cplxlower0", /* name */
2082 : : OPTGROUP_NONE, /* optinfo_flags */
2083 : : TV_NONE, /* tv_id */
2084 : : PROP_cfg, /* 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_O0 : public gimple_opt_pass
2092 : : {
2093 : : public:
2094 : 283157 : pass_lower_complex_O0 (gcc::context *ctxt)
2095 : 566314 : : gimple_opt_pass (pass_data_lower_complex_O0, ctxt)
2096 : : {}
2097 : :
2098 : : /* opt_pass methods: */
2099 : 1436616 : bool gate (function *fun) final override
2100 : : {
2101 : : /* With errors, normal optimization passes are not run. If we don't
2102 : : lower complex operations at all, rtl expansion will abort. */
2103 : 1436616 : return !(fun->curr_properties & PROP_gimple_lcx);
2104 : : }
2105 : :
2106 : 427719 : unsigned int execute (function *) final override
2107 : : {
2108 : 427719 : return tree_lower_complex ();
2109 : : }
2110 : :
2111 : : }; // class pass_lower_complex_O0
2112 : :
2113 : : } // anon namespace
2114 : :
2115 : : gimple_opt_pass *
2116 : 283157 : make_pass_lower_complex_O0 (gcc::context *ctxt)
2117 : : {
2118 : 283157 : return new pass_lower_complex_O0 (ctxt);
2119 : : }
|