LCOV - code coverage report
Current view: top level - gcc - tree-complex.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 93.9 % 1080 1014
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 42 42
Legend: Lines:     hit not hit

            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              : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.