LCOV - code coverage report
Current view: top level - gcc - tree-complex.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 93.8 % 1056 990
Test Date: 2025-03-22 13:13:03 Functions: 100.0 % 42 42
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

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

Generated by: LCOV version 2.1-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.