LCOV - code coverage report
Current view: top level - gcc - tree-if-conv.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 96.2 % 1829 1760
Test Date: 2026-10-17 16:30:31 Functions: 100.0 % 71 71
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* If-conversion for vectorizer.
       2              :    Copyright (C) 2004-2026 Free Software Foundation, Inc.
       3              :    Contributed by Devang Patel <dpatel@apple.com>
       4              : 
       5              : This file is part of GCC.
       6              : 
       7              : GCC is free software; you can redistribute it and/or modify it under
       8              : the terms of the GNU General Public License as published by the Free
       9              : Software Foundation; either version 3, or (at your option) any later
      10              : version.
      11              : 
      12              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      13              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15              : for more details.
      16              : 
      17              : You should have received a copy of the GNU General Public License
      18              : along with GCC; see the file COPYING3.  If not see
      19              : <http://www.gnu.org/licenses/>.  */
      20              : 
      21              : /* This pass implements a tree level if-conversion of loops.  Its
      22              :    initial goal is to help the vectorizer to vectorize loops with
      23              :    conditions.
      24              : 
      25              :    A short description of if-conversion:
      26              : 
      27              :      o Decide if a loop is if-convertible or not.
      28              :      o Walk all loop basic blocks in breadth first order (BFS order).
      29              :        o Remove conditional statements (at the end of basic block)
      30              :          and propagate condition into destination basic blocks'
      31              :          predicate list.
      32              :        o Replace modify expression with conditional modify expression
      33              :          using current basic block's condition.
      34              :      o Merge all basic blocks
      35              :        o Replace phi nodes with conditional modify expr
      36              :        o Merge all basic blocks into header
      37              : 
      38              :      Sample transformation:
      39              : 
      40              :      INPUT
      41              :      -----
      42              : 
      43              :      # i_23 = PHI <0(0), i_18(10)>;
      44              :      <L0>:;
      45              :      j_15 = A[i_23];
      46              :      if (j_15 > 41) goto <L1>; else goto <L17>;
      47              : 
      48              :      <L17>:;
      49              :      goto <bb 3> (<L3>);
      50              : 
      51              :      <L1>:;
      52              : 
      53              :      # iftmp.2_4 = PHI <0(8), 42(2)>;
      54              :      <L3>:;
      55              :      A[i_23] = iftmp.2_4;
      56              :      i_18 = i_23 + 1;
      57              :      if (i_18 <= 15) goto <L19>; else goto <L18>;
      58              : 
      59              :      <L19>:;
      60              :      goto <bb 1> (<L0>);
      61              : 
      62              :      <L18>:;
      63              : 
      64              :      OUTPUT
      65              :      ------
      66              : 
      67              :      # i_23 = PHI <0(0), i_18(10)>;
      68              :      <L0>:;
      69              :      j_15 = A[i_23];
      70              : 
      71              :      <L3>:;
      72              :      iftmp.2_4 = j_15 > 41 ? 42 : 0;
      73              :      A[i_23] = iftmp.2_4;
      74              :      i_18 = i_23 + 1;
      75              :      if (i_18 <= 15) goto <L19>; else goto <L18>;
      76              : 
      77              :      <L19>:;
      78              :      goto <bb 1> (<L0>);
      79              : 
      80              :      <L18>:;
      81              : */
      82              : 
      83              : #include "config.h"
      84              : #include "system.h"
      85              : #include "coretypes.h"
      86              : #include "backend.h"
      87              : #include "rtl.h"
      88              : #include "tree.h"
      89              : #include "gimple.h"
      90              : #include "cfghooks.h"
      91              : #include "tree-pass.h"
      92              : #include "ssa.h"
      93              : #include "expmed.h"
      94              : #include "expr.h"
      95              : #include "optabs-tree.h"
      96              : #include "gimple-pretty-print.h"
      97              : #include "alias.h"
      98              : #include "fold-const.h"
      99              : #include "stor-layout.h"
     100              : #include "gimple-iterator.h"
     101              : #include "gimple-fold.h"
     102              : #include "gimplify.h"
     103              : #include "gimplify-me.h"
     104              : #include "tree-cfg.h"
     105              : #include "tree-into-ssa.h"
     106              : #include "tree-ssa.h"
     107              : #include "cfgloop.h"
     108              : #include "tree-data-ref.h"
     109              : #include "tree-scalar-evolution.h"
     110              : #include "tree-ssa-loop.h"
     111              : #include "tree-ssa-loop-niter.h"
     112              : #include "tree-ssa-loop-ivopts.h"
     113              : #include "tree-ssa-address.h"
     114              : #include "dbgcnt.h"
     115              : #include "tree-hash-traits.h"
     116              : #include "varasm.h"
     117              : #include "builtins.h"
     118              : #include "cfganal.h"
     119              : #include "internal-fn.h"
     120              : #include "tree-ssa-sccvn.h"
     121              : #include "tree-cfgcleanup.h"
     122              : #include "tree-ssa-dse.h"
     123              : #include "tree-vectorizer.h"
     124              : #include "tree-eh.h"
     125              : #include "cgraph.h"
     126              : 
     127              : /* For lang_hooks.types.type_for_mode.  */
     128              : #include "langhooks.h"
     129              : 
     130              : /* Only handle PHIs with no more arguments unless we are asked to by
     131              :    simd pragma.  */
     132              : #define MAX_PHI_ARG_NUM \
     133              :   ((unsigned) param_max_tree_if_conversion_phi_args)
     134              : 
     135              : /* True if we've converted a statement that was only executed when some
     136              :    condition C was true, and if for correctness we need to predicate the
     137              :    statement to ensure that it is a no-op when C is false.  See
     138              :    predicate_statements for the kinds of predication we support.  */
     139              : static bool need_to_predicate;
     140              : 
     141              : /* True if we have to rewrite stmts that may invoke undefined behavior
     142              :    when a condition C was false so it doesn't if it is always executed.
     143              :    See predicate_statements for the kinds of predication we support.  */
     144              : static bool need_to_rewrite_undefined;
     145              : 
     146              : /* Indicate if there are any complicated PHIs that need to be handled in
     147              :    if-conversion.  Complicated PHI has more than two arguments and can't
     148              :    be degenerated to two arguments PHI.  See more information in comment
     149              :    before phi_convertible_by_degenerating_args.  */
     150              : static bool any_complicated_phi;
     151              : 
     152              : /* True if we have bitfield accesses we can lower.  */
     153              : static bool need_to_lower_bitfields;
     154              : 
     155              : /* True if there is any ifcvting to be done.  */
     156              : static bool need_to_ifcvt;
     157              : 
     158              : /* Hash for struct innermost_loop_behavior.  It depends on the user to
     159              :    free the memory.  */
     160              : 
     161              : struct innermost_loop_behavior_hash : nofree_ptr_hash <innermost_loop_behavior>
     162              : {
     163              :   static inline hashval_t hash (const value_type &);
     164              :   static inline bool equal (const value_type &,
     165              :                             const compare_type &);
     166              : };
     167              : 
     168              : inline hashval_t
     169       402387 : innermost_loop_behavior_hash::hash (const value_type &e)
     170              : {
     171       402387 :   hashval_t hash;
     172              : 
     173       402387 :   hash = iterative_hash_expr (e->base_address, 0);
     174       402387 :   hash = iterative_hash_expr (e->offset, hash);
     175       402387 :   hash = iterative_hash_expr (e->init, hash);
     176       402387 :   return iterative_hash_expr (e->step, hash);
     177              : }
     178              : 
     179              : inline bool
     180       289936 : innermost_loop_behavior_hash::equal (const value_type &e1,
     181              :                                      const compare_type &e2)
     182              : {
     183       289936 :   if ((e1->base_address && !e2->base_address)
     184       289936 :       || (!e1->base_address && e2->base_address)
     185       289936 :       || (!e1->offset && e2->offset)
     186       273894 :       || (e1->offset && !e2->offset)
     187       246484 :       || (!e1->init && e2->init)
     188       246484 :       || (e1->init && !e2->init)
     189       246484 :       || (!e1->step && e2->step)
     190       246484 :       || (e1->step && !e2->step))
     191              :     return false;
     192              : 
     193       246484 :   if (e1->base_address && e2->base_address
     194       492968 :       && !operand_equal_p (e1->base_address, e2->base_address, 0))
     195              :     return false;
     196        47205 :   if (e1->offset && e2->offset
     197       125248 :       && !operand_equal_p (e1->offset, e2->offset, 0))
     198              :     return false;
     199        46943 :   if (e1->init && e2->init
     200       124724 :       && !operand_equal_p (e1->init, e2->init, 0))
     201              :     return false;
     202        17580 :   if (e1->step && e2->step
     203        65998 :       && !operand_equal_p (e1->step, e2->step, 0))
     204              :     return false;
     205              : 
     206              :   return true;
     207              : }
     208              : 
     209              : /* List of basic blocks in if-conversion-suitable order.  */
     210              : static basic_block *ifc_bbs;
     211              : 
     212              : /* Hash table to store <DR's innermost loop behavior, DR> pairs.  */
     213              : static hash_map<innermost_loop_behavior_hash,
     214              :                 data_reference_p> *innermost_DR_map;
     215              : 
     216              : /* Hash table to store <base reference, DR> pairs.  */
     217              : static hash_map<tree_operand_hash, data_reference_p> *baseref_DR_map;
     218              : 
     219              : /* List of redundant SSA names: the first should be replaced by the second.  */
     220              : static vec< std::pair<tree, tree> > redundant_ssa_names;
     221              : 
     222              : /* Structure used to predicate basic blocks.  This is attached to the
     223              :    ->aux field of the BBs in the loop to be if-converted.  */
     224              : struct bb_predicate {
     225              : 
     226              :   /* The condition under which this basic block is executed.  */
     227              :   tree predicate;
     228              : 
     229              :   /* PREDICATE is gimplified, and the sequence of statements is
     230              :      recorded here, in order to avoid the duplication of computations
     231              :      that occur in previous conditions.  See PR44483.  */
     232              :   gimple_seq predicate_gimplified_stmts;
     233              : 
     234              :   /* Records the number of statements recorded into
     235              :      PREDICATE_GIMPLIFIED_STMTS.   */
     236              :   unsigned no_predicate_stmts;
     237              : };
     238              : 
     239              : /* Returns true when the basic block BB has a predicate.  */
     240              : 
     241              : static inline bool
     242      1999956 : bb_has_predicate (basic_block bb)
     243              : {
     244      1999956 :   return bb->aux != NULL;
     245              : }
     246              : 
     247              : /* Returns the gimplified predicate for basic block BB.  */
     248              : 
     249              : static inline tree
     250       914040 : bb_predicate (basic_block bb)
     251              : {
     252       914040 :   return ((struct bb_predicate *) bb->aux)->predicate;
     253              : }
     254              : 
     255              : /* Sets the gimplified predicate COND for basic block BB.  */
     256              : 
     257              : static inline void
     258       492994 : set_bb_predicate (basic_block bb, tree cond)
     259              : {
     260       492994 :   auto aux = (struct bb_predicate *) bb->aux;
     261       492994 :   gcc_assert ((TREE_CODE (cond) == TRUTH_NOT_EXPR
     262              :                && is_gimple_val (TREE_OPERAND (cond, 0)))
     263              :               || is_gimple_val (cond));
     264       492994 :   aux->predicate = cond;
     265       492994 :   aux->no_predicate_stmts++;
     266              : 
     267       492994 :   if (dump_file && (dump_flags & TDF_DETAILS))
     268          222 :     fprintf (dump_file, "Recording block %d value %d\n", bb->index,
     269              :              aux->no_predicate_stmts);
     270       492994 : }
     271              : 
     272              : /* Returns the sequence of statements of the gimplification of the
     273              :    predicate for basic block BB.  */
     274              : 
     275              : static inline gimple_seq
     276       605924 : bb_predicate_gimplified_stmts (basic_block bb)
     277              : {
     278       605924 :   return ((struct bb_predicate *) bb->aux)->predicate_gimplified_stmts;
     279              : }
     280              : 
     281              : /* Sets the sequence of statements STMTS of the gimplification of the
     282              :    predicate for basic block BB.  If PRESERVE_COUNTS then don't clear the predicate
     283              :    counts.  */
     284              : 
     285              : static inline void
     286       293183 : set_bb_predicate_gimplified_stmts (basic_block bb, gimple_seq stmts,
     287              :                                    bool preserve_counts)
     288              : {
     289       293183 :   ((struct bb_predicate *) bb->aux)->predicate_gimplified_stmts = stmts;
     290       293183 :   if (stmts == NULL && !preserve_counts)
     291       239988 :     ((struct bb_predicate *) bb->aux)->no_predicate_stmts = 0;
     292              : }
     293              : 
     294              : /* Adds the sequence of statements STMTS to the sequence of statements
     295              :    of the predicate for basic block BB.  */
     296              : 
     297              : static inline void
     298        89580 : add_bb_predicate_gimplified_stmts (basic_block bb, gimple_seq stmts)
     299              : {
     300              :   /* We might have updated some stmts in STMTS via force_gimple_operand
     301              :      calling fold_stmt and that producing multiple stmts.  Delink immediate
     302              :      uses so update_ssa after loop versioning doesn't get confused for
     303              :      the not yet inserted predicates.
     304              :      ???  This should go away once we reliably avoid updating stmts
     305              :      not in any BB.  */
     306        89580 :   for (gimple_stmt_iterator gsi = gsi_start (stmts);
     307       221038 :        !gsi_end_p (gsi); gsi_next (&gsi))
     308              :     {
     309       131458 :       gimple *stmt = gsi_stmt (gsi);
     310       131458 :       delink_stmt_imm_use (stmt);
     311       131458 :       gimple_set_modified (stmt, true);
     312       131458 :       ((struct bb_predicate *) bb->aux)->no_predicate_stmts++;
     313              :     }
     314        89580 :   gimple_seq_add_seq_without_update
     315        89580 :     (&(((struct bb_predicate *) bb->aux)->predicate_gimplified_stmts), stmts);
     316        89580 : }
     317              : 
     318              : /* Return the number of statements the predicate of the basic block consists
     319              :    of.  */
     320              : 
     321              : static inline unsigned
     322        16292 : get_bb_num_predicate_stmts (basic_block bb)
     323              : {
     324        16292 :   return ((struct bb_predicate *) bb->aux)->no_predicate_stmts;
     325              : }
     326              : 
     327              : /* Initializes to TRUE the predicate of basic block BB.  */
     328              : 
     329              : static inline void
     330       205762 : init_bb_predicate (basic_block bb)
     331              : {
     332       205762 :   bb->aux = XNEW (struct bb_predicate);
     333       205762 :   set_bb_predicate_gimplified_stmts (bb, NULL, false);
     334       205762 :   set_bb_predicate (bb, boolean_true_node);
     335       205762 : }
     336              : 
     337              : /* Release the SSA_NAMEs associated with the predicate of basic block BB.  */
     338              : 
     339              : static inline void
     340       397556 : release_bb_predicate (basic_block bb)
     341              : {
     342       397556 :   gimple_seq stmts = bb_predicate_gimplified_stmts (bb);
     343       397556 :   if (stmts)
     344              :     {
     345              :       /* Ensure that these stmts haven't yet been added to a bb.  */
     346        34226 :       if (flag_checking)
     347        95032 :         for (gimple_stmt_iterator i = gsi_start (stmts);
     348        95032 :              !gsi_end_p (i); gsi_next (&i))
     349        60806 :           gcc_assert (! gimple_bb (gsi_stmt (i)));
     350              : 
     351              :       /* Discard them.  */
     352        34226 :       gimple_seq_discard (stmts);
     353        34226 :       set_bb_predicate_gimplified_stmts (bb, NULL, false);
     354              :     }
     355       397556 : }
     356              : 
     357              : /* Free the predicate of basic block BB.  */
     358              : 
     359              : static inline void
     360      1808162 : free_bb_predicate (basic_block bb)
     361              : {
     362      1808162 :   if (!bb_has_predicate (bb))
     363              :     return;
     364              : 
     365       205762 :   release_bb_predicate (bb);
     366       205762 :   free (bb->aux);
     367       205762 :   bb->aux = NULL;
     368              : }
     369              : 
     370              : /* Reinitialize predicate of BB with the true predicate.  */
     371              : 
     372              : static inline void
     373       191794 : reset_bb_predicate (basic_block bb)
     374              : {
     375       191794 :   if (!bb_has_predicate (bb))
     376            0 :     init_bb_predicate (bb);
     377              :   else
     378              :     {
     379       191794 :       release_bb_predicate (bb);
     380       191794 :       set_bb_predicate (bb, boolean_true_node);
     381              :     }
     382       191794 : }
     383              : 
     384              : /* Returns a new SSA_NAME of type TYPE that is assigned the value of
     385              :    the expression EXPR.  Inserts the statement created for this
     386              :    computation before GSI and leaves the iterator GSI at the same
     387              :    statement.  */
     388              : 
     389              : static tree
     390         5377 : ifc_temp_var (tree type, tree expr, gimple_stmt_iterator *gsi)
     391              : {
     392         5377 :   tree new_name = make_temp_ssa_name (type, NULL, "_ifc_");
     393         5377 :   gimple *stmt = gimple_build_assign (new_name, expr);
     394        10754 :   gimple_set_vuse (stmt, gimple_vuse (gsi_stmt (*gsi)));
     395         5377 :   gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
     396         5377 :   return new_name;
     397              : }
     398              : 
     399              : /* Return true when COND is a false predicate.  */
     400              : 
     401              : static inline bool
     402        90874 : is_false_predicate (tree cond)
     403              : {
     404        90874 :   return (cond != NULL_TREE
     405        90874 :           && (cond == boolean_false_node
     406        90874 :               || integer_zerop (cond)));
     407              : }
     408              : 
     409              : /* Return true when COND is a true predicate.  */
     410              : 
     411              : static inline bool
     412      1039238 : is_true_predicate (tree cond)
     413              : {
     414      1039238 :   return (cond == NULL_TREE
     415      1039238 :           || cond == boolean_true_node
     416      1508742 :           || integer_onep (cond));
     417              : }
     418              : 
     419              : /* Returns true when BB has a predicate that is not trivial: true or
     420              :    NULL_TREE.  */
     421              : 
     422              : static inline bool
     423       507049 : is_predicated (basic_block bb)
     424              : {
     425        12767 :   return !is_true_predicate (bb_predicate (bb));
     426              : }
     427              : 
     428              : /* Parses the predicate COND and returns its comparison code and
     429              :    operands OP0 and OP1.  */
     430              : 
     431              : static enum tree_code
     432       401022 : parse_predicate (tree cond, tree *op0, tree *op1)
     433              : {
     434       401022 :   gimple *s;
     435              : 
     436       401022 :   if (TREE_CODE (cond) == SSA_NAME
     437       401022 :       && is_gimple_assign (s = SSA_NAME_DEF_STMT (cond)))
     438              :     {
     439        64269 :       if (TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison)
     440              :         {
     441        32786 :           *op0 = gimple_assign_rhs1 (s);
     442        32786 :           *op1 = gimple_assign_rhs2 (s);
     443        32786 :           return gimple_assign_rhs_code (s);
     444              :         }
     445              : 
     446        31483 :       else if (gimple_assign_rhs_code (s) == TRUTH_NOT_EXPR)
     447              :         {
     448            0 :           tree op = gimple_assign_rhs1 (s);
     449            0 :           tree type = TREE_TYPE (op);
     450            0 :           enum tree_code code = parse_predicate (op, op0, op1);
     451              : 
     452            0 :           return code == ERROR_MARK ? ERROR_MARK
     453            0 :             : invert_tree_comparison (code, HONOR_NANS (type));
     454              :         }
     455              : 
     456              :       return ERROR_MARK;
     457              :     }
     458              : 
     459       336753 :   if (COMPARISON_CLASS_P (cond))
     460              :     {
     461          483 :       *op0 = TREE_OPERAND (cond, 0);
     462          483 :       *op1 = TREE_OPERAND (cond, 1);
     463          483 :       return TREE_CODE (cond);
     464              :     }
     465              : 
     466              :   return ERROR_MARK;
     467              : }
     468              : 
     469              : /* Returns the fold of predicate C1 OR C2 at location LOC.  */
     470              : 
     471              : static tree
     472       200511 : fold_or_predicates (location_t loc, tree c1, tree c2)
     473              : {
     474       200511 :   tree op1a, op1b, op2a, op2b;
     475       200511 :   enum tree_code code1 = parse_predicate (c1, &op1a, &op1b);
     476       200511 :   enum tree_code code2 = parse_predicate (c2, &op2a, &op2b);
     477              : 
     478       200511 :   if (code1 != ERROR_MARK && code2 != ERROR_MARK)
     479              :     {
     480         2327 :       tree t = maybe_fold_or_comparisons (boolean_type_node, code1, op1a, op1b,
     481              :                                           code2, op2a, op2b);
     482         2327 :       if (t)
     483              :         return t;
     484              :     }
     485              : 
     486       198279 :   return fold_build2_loc (loc, TRUTH_OR_EXPR, boolean_type_node, c1, c2);
     487              : }
     488              : 
     489              : /* Returns either a COND_EXPR or the folded expression if the folded
     490              :    expression is a MIN_EXPR, a MAX_EXPR, an ABS_EXPR,
     491              :    a constant or a SSA_NAME. */
     492              : 
     493              : static tree
     494        51584 : fold_build_cond_expr (tree type, tree cond, tree rhs, tree lhs)
     495              : {
     496              :   /* Short cut the case where both rhs and lhs are the same. */
     497        51584 :   if (operand_equal_p (rhs, lhs))
     498              :     return rhs;
     499              : 
     500              :   /* If COND is comparison r != 0 and r has boolean type, convert COND
     501              :      to SSA_NAME to accept by vect bool pattern.  */
     502        51584 :   if (TREE_CODE (cond) == NE_EXPR)
     503              :     {
     504            0 :       tree op0 = TREE_OPERAND (cond, 0);
     505            0 :       tree op1 = TREE_OPERAND (cond, 1);
     506            0 :       if (TREE_CODE (op0) == SSA_NAME
     507            0 :           && TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE
     508            0 :           && (integer_zerop (op1)))
     509              :         cond = op0;
     510              :     }
     511              : 
     512        51584 :   gimple_match_op cexpr (gimple_match_cond::UNCOND, COND_EXPR,
     513        51584 :                          type, cond, rhs, lhs);
     514        51584 :   if (cexpr.resimplify (NULL, follow_all_ssa_edges))
     515              :     {
     516         6647 :       if (gimple_simplified_result_is_gimple_val (&cexpr))
     517          567 :         return cexpr.ops[0];
     518         6080 :       else if (cexpr.code == ABS_EXPR)
     519            2 :         return build1 (ABS_EXPR, type, cexpr.ops[0]);
     520         6078 :       else if (cexpr.code == MIN_EXPR
     521         6078 :                || cexpr.code == MAX_EXPR)
     522         3316 :         return build2 ((tree_code)cexpr.code, type, cexpr.ops[0], cexpr.ops[1]);
     523              :     }
     524              : 
     525        47699 :   return build3 (COND_EXPR, type, cond, rhs, lhs);
     526              : }
     527              : 
     528              : /* Add condition NC to the predicate list of basic block BB.  LOOP is
     529              :    the loop to be if-converted. Use predicate of cd-equivalent block
     530              :    for join bb if it exists: we call basic blocks bb1 and bb2
     531              :    cd-equivalent if they are executed under the same condition.  */
     532              : 
     533              : static inline void
     534       164981 : add_to_predicate_list (class loop *loop, basic_block bb, tree nc)
     535              : {
     536       164981 :   tree bc, *tp;
     537       164981 :   basic_block dom_bb;
     538              : 
     539       164981 :   if (is_true_predicate (nc))
     540        73629 :     return;
     541              : 
     542              :   /* If dominance tells us this basic block is always executed,
     543              :      don't record any predicates for it.  */
     544       164969 :   if (dominated_by_p (CDI_DOMINATORS, loop->latch, bb))
     545              :     return;
     546              : 
     547        95438 :   dom_bb = get_immediate_dominator (CDI_DOMINATORS, bb);
     548              :   /* We use notion of cd equivalence to get simpler predicate for
     549              :      join block, e.g. if join block has 2 predecessors with predicates
     550              :      p1 & p2 and p1 & !p2, we'd like to get p1 for it instead of
     551              :      p1 & p2 | p1 & !p2.  */
     552        95438 :   if (dom_bb != loop->header
     553        95438 :       && get_immediate_dominator (CDI_POST_DOMINATORS, dom_bb) == bb)
     554              :     {
     555         4086 :       gcc_assert (flow_bb_inside_loop_p (loop, dom_bb));
     556         4086 :       bc = bb_predicate (dom_bb);
     557         4086 :       if (!is_true_predicate (bc))
     558         4086 :         set_bb_predicate (bb, bc);
     559              :       else
     560            0 :         gcc_assert (is_true_predicate (bb_predicate (bb)));
     561         4086 :       if (dump_file && (dump_flags & TDF_DETAILS))
     562            4 :         fprintf (dump_file, "Use predicate of bb#%d for bb#%d\n",
     563              :                  dom_bb->index, bb->index);
     564              :       return;
     565              :     }
     566              : 
     567        91352 :   if (!is_predicated (bb))
     568        87421 :     bc = nc;
     569              :   else
     570              :     {
     571         3931 :       bc = bb_predicate (bb);
     572         3931 :       bc = fold_or_predicates (EXPR_LOCATION (bc), nc, bc);
     573         3931 :       if (is_true_predicate (bc))
     574              :         {
     575            0 :           reset_bb_predicate (bb);
     576            0 :           return;
     577              :         }
     578              :     }
     579              : 
     580              :   /* Allow a TRUTH_NOT_EXPR around the main predicate.  */
     581        91352 :   if (TREE_CODE (bc) == TRUTH_NOT_EXPR)
     582        32902 :     tp = &TREE_OPERAND (bc, 0);
     583              :   else
     584              :     tp = &bc;
     585        91352 :   if (!is_gimple_val (*tp))
     586              :     {
     587        89580 :       gimple_seq stmts;
     588        89580 :       *tp = force_gimple_operand (*tp, &stmts, true, NULL_TREE);
     589        89580 :       add_bb_predicate_gimplified_stmts (bb, stmts);
     590              :     }
     591        91352 :   set_bb_predicate (bb, bc);
     592              : }
     593              : 
     594              : /* Add the condition COND to the previous condition PREV_COND, and add
     595              :    this to the predicate list of the destination of edge E.  LOOP is
     596              :    the loop to be if-converted.  */
     597              : 
     598              : static void
     599       107228 : add_to_dst_predicate_list (class loop *loop, edge e,
     600              :                            tree prev_cond, tree cond)
     601              : {
     602       107228 :   if (!flow_bb_inside_loop_p (loop, e->dest))
     603              :     return;
     604              : 
     605       107228 :   if (!is_true_predicate (prev_cond))
     606        22692 :     cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
     607              :                         prev_cond, cond);
     608              : 
     609       107228 :   if (!dominated_by_p (CDI_DOMINATORS, loop->latch, e->dest))
     610        86891 :     add_to_predicate_list (loop, e->dest, cond);
     611              : }
     612              : 
     613              : /* Return true if one of the successor edges of BB exits LOOP.  */
     614              : 
     615              : static bool
     616      3501373 : bb_with_exit_edge_p (const class loop *loop, basic_block bb)
     617              : {
     618      3501373 :   edge e;
     619      3501373 :   edge_iterator ei;
     620              : 
     621      7072546 :   FOR_EACH_EDGE (e, ei, bb->succs)
     622      4986473 :     if (loop_exit_edge_p (loop, e))
     623              :       return true;
     624              : 
     625              :   return false;
     626              : }
     627              : 
     628              : /* Given PHI which has more than two arguments, this function checks if
     629              :    it's if-convertible by degenerating its arguments.  Specifically, if
     630              :    below two conditions are satisfied:
     631              : 
     632              :      1) Number of PHI arguments with different values equals to 2 and one
     633              :         argument has the only occurrence.
     634              :      2) The edge corresponding to the unique argument isn't critical edge.
     635              : 
     636              :    Such PHI can be handled as PHIs have only two arguments.  For example,
     637              :    below PHI:
     638              : 
     639              :      res = PHI <A_1(e1), A_1(e2), A_2(e3)>;
     640              : 
     641              :    can be transformed into:
     642              : 
     643              :      res = (predicate of e3) ? A_2 : A_1;
     644              : 
     645              :    Return TRUE if it is the case, FALSE otherwise.  */
     646              : 
     647              : static bool
     648         5539 : phi_convertible_by_degenerating_args (gphi *phi)
     649              : {
     650         5539 :   edge e;
     651         5539 :   tree arg, t1 = NULL, t2 = NULL;
     652         5539 :   unsigned int i, i1 = 0, i2 = 0, n1 = 0, n2 = 0;
     653         5539 :   unsigned int num_args = gimple_phi_num_args (phi);
     654              : 
     655         5539 :   gcc_assert (num_args > 2);
     656              : 
     657        20116 :   for (i = 0; i < num_args; i++)
     658              :     {
     659        16803 :       arg = gimple_phi_arg_def (phi, i);
     660        16803 :       if (t1 == NULL || operand_equal_p (t1, arg, 0))
     661              :         {
     662         7591 :           n1++;
     663         7591 :           i1 = i;
     664         7591 :           t1 = arg;
     665              :         }
     666         9212 :       else if (t2 == NULL || operand_equal_p (t2, arg, 0))
     667              :         {
     668         6986 :           n2++;
     669         6986 :           i2 = i;
     670         6986 :           t2 = arg;
     671              :         }
     672              :       else
     673              :         return false;
     674              :     }
     675              : 
     676         3313 :   if (n1 != 1 && n2 != 1)
     677              :     return false;
     678              : 
     679              :   /* Check if the edge corresponding to the unique arg is critical.  */
     680         3253 :   e = gimple_phi_arg_edge (phi, (n1 == 1) ? i1 : i2);
     681         3253 :   if (EDGE_COUNT (e->src->succs) > 1)
     682            0 :     return false;
     683              : 
     684              :   return true;
     685              : }
     686              : 
     687              : /* Return true when PHI is if-convertible.  PHI is part of loop LOOP
     688              :    and it belongs to basic block BB.  Note at this point, it is sure
     689              :    that PHI is if-convertible.  This function updates global variable
     690              :    ANY_COMPLICATED_PHI if PHI is complicated.  */
     691              : 
     692              : static bool
     693       129336 : if_convertible_phi_p (class loop *loop, basic_block bb, gphi *phi)
     694              : {
     695       129336 :   if (dump_file && (dump_flags & TDF_DETAILS))
     696              :     {
     697           67 :       fprintf (dump_file, "-------------------------\n");
     698           67 :       print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
     699              :     }
     700              : 
     701       129336 :   if (bb != loop->header
     702        51822 :       && gimple_phi_num_args (phi) > 2
     703       134875 :       && !phi_convertible_by_degenerating_args (phi))
     704         2286 :     any_complicated_phi = true;
     705              : 
     706       129336 :   return true;
     707              : }
     708              : 
     709              : /* Records the status of a data reference.  This struct is attached to
     710              :    each DR->aux field.  */
     711              : 
     712              : struct ifc_dr {
     713              :   bool rw_unconditionally;
     714              :   bool w_unconditionally;
     715              :   bool written_at_least_once;
     716              : 
     717              :   tree rw_predicate;
     718              :   tree w_predicate;
     719              :   tree base_w_predicate;
     720              : };
     721              : 
     722              : #define IFC_DR(DR) ((struct ifc_dr *) (DR)->aux)
     723              : #define DR_BASE_W_UNCONDITIONALLY(DR) (IFC_DR (DR)->written_at_least_once)
     724              : #define DR_RW_UNCONDITIONALLY(DR) (IFC_DR (DR)->rw_unconditionally)
     725              : #define DR_W_UNCONDITIONALLY(DR) (IFC_DR (DR)->w_unconditionally)
     726              : 
     727              : /* Iterates over DR's and stores refs, DR and base refs, DR pairs in
     728              :    HASH tables.  While storing them in HASH table, it checks if the
     729              :    reference is unconditionally read or written and stores that as a flag
     730              :    information.  For base reference it checks if it is written atlest once
     731              :    unconditionally and stores it as flag information along with DR.
     732              :    In other words for every data reference A in STMT there exist other
     733              :    accesses to a data reference with the same base with predicates that
     734              :    add up (OR-up) to the true predicate: this ensures that the data
     735              :    reference A is touched (read or written) on every iteration of the
     736              :    if-converted loop.  */
     737              : static void
     738       120460 : hash_memrefs_baserefs_and_store_DRs_read_written_info (data_reference_p a)
     739              : {
     740              : 
     741       120460 :   data_reference_p *master_dr, *base_master_dr;
     742       120460 :   tree base_ref = DR_BASE_OBJECT (a);
     743       120460 :   innermost_loop_behavior *innermost = &DR_INNERMOST (a);
     744       120460 :   tree ca = bb_predicate (gimple_bb (DR_STMT (a)));
     745       120460 :   bool exist1, exist2;
     746              : 
     747       120460 :   master_dr = &innermost_DR_map->get_or_insert (innermost, &exist1);
     748       120460 :   if (!exist1)
     749        92251 :     *master_dr = a;
     750              : 
     751       120460 :   if (DR_IS_WRITE (a))
     752              :     {
     753        38031 :       IFC_DR (*master_dr)->w_predicate
     754        76062 :         = fold_or_predicates (UNKNOWN_LOCATION, ca,
     755        38031 :                               IFC_DR (*master_dr)->w_predicate);
     756        38031 :       if (is_true_predicate (IFC_DR (*master_dr)->w_predicate))
     757        21707 :         DR_W_UNCONDITIONALLY (*master_dr) = true;
     758              :     }
     759       120460 :   IFC_DR (*master_dr)->rw_predicate
     760       240920 :     = fold_or_predicates (UNKNOWN_LOCATION, ca,
     761       120460 :                           IFC_DR (*master_dr)->rw_predicate);
     762       120460 :   if (is_true_predicate (IFC_DR (*master_dr)->rw_predicate))
     763        84293 :     DR_RW_UNCONDITIONALLY (*master_dr) = true;
     764              : 
     765       120460 :   if (DR_IS_WRITE (a))
     766              :     {
     767        38031 :       base_master_dr = &baseref_DR_map->get_or_insert (base_ref, &exist2);
     768        38031 :       if (!exist2)
     769        27836 :         *base_master_dr = a;
     770        38031 :       IFC_DR (*base_master_dr)->base_w_predicate
     771        76062 :         = fold_or_predicates (UNKNOWN_LOCATION, ca,
     772        38031 :                               IFC_DR (*base_master_dr)->base_w_predicate);
     773        38031 :       if (is_true_predicate (IFC_DR (*base_master_dr)->base_w_predicate))
     774        21969 :         DR_BASE_W_UNCONDITIONALLY (*base_master_dr) = true;
     775              :     }
     776       120460 : }
     777              : 
     778              : /* Return TRUE if can prove the index IDX of an array reference REF is
     779              :    within array bound.  Return false otherwise.  */
     780              : 
     781              : static bool
     782       261584 : idx_within_array_bound (tree ref, tree *idx, void *dta)
     783              : {
     784       261584 :   wi::overflow_type overflow;
     785       261584 :   widest_int niter, valid_niter, delta, wi_step;
     786       261584 :   tree ev, init, step;
     787       261584 :   tree low, high;
     788       261584 :   class loop *loop = (class loop*) dta;
     789              : 
     790              :   /* Only support within-bound access for array references.  */
     791       261584 :   if (TREE_CODE (ref) != ARRAY_REF)
     792              :     return false;
     793              : 
     794              :   /* For arrays that might have flexible sizes, it is not guaranteed that they
     795              :      do not extend over their declared size.  */
     796       146833 :   if (array_ref_flexible_size_p (ref))
     797              :     return false;
     798              : 
     799        93831 :   ev = analyze_scalar_evolution (loop, *idx);
     800        93831 :   ev = instantiate_parameters (loop, ev);
     801        93831 :   init = initial_condition (ev);
     802        93831 :   step = evolution_part_in_loop_num (ev, loop->num);
     803              : 
     804        93831 :   if (!init || TREE_CODE (init) != INTEGER_CST
     805        83273 :       || (step && TREE_CODE (step) != INTEGER_CST))
     806              :     return false;
     807              : 
     808        83267 :   low = array_ref_low_bound (ref);
     809        83267 :   high = array_ref_up_bound (ref);
     810              : 
     811              :   /* The case of nonconstant bounds could be handled, but it would be
     812              :      complicated.  */
     813        83267 :   if (TREE_CODE (low) != INTEGER_CST
     814        83267 :       || !high || TREE_CODE (high) != INTEGER_CST)
     815              :     return false;
     816              : 
     817              :   /* Check if the initial idx is within bound.  */
     818        83199 :   if (wi::to_widest (init) < wi::to_widest (low)
     819       166390 :       || wi::to_widest (init) > wi::to_widest (high))
     820              :     return false;
     821              : 
     822              :   /* The idx is always within bound.  */
     823        83183 :   if (!step || integer_zerop (step))
     824              :     return true;
     825              : 
     826        81231 :   if (!max_loop_iterations (loop, &niter))
     827              :     return false;
     828              : 
     829        81231 :   if (wi::to_widest (step) < 0)
     830              :     {
     831          303 :       delta = wi::to_widest (init) - wi::to_widest (low);
     832          303 :       wi_step = -wi::to_widest (step);
     833              :     }
     834              :   else
     835              :     {
     836        80928 :       delta = wi::to_widest (high) - wi::to_widest (init);
     837        80928 :       wi_step = wi::to_widest (step);
     838              :     }
     839              : 
     840        81231 :   valid_niter = wi::div_floor (delta, wi_step, SIGNED, &overflow);
     841              :   /* The iteration space of idx is within array bound.  */
     842       162462 :   if (!overflow && niter <= valid_niter)
     843        80750 :     return true;
     844              : 
     845              :   return false;
     846       261584 : }
     847              : 
     848              : /* Return TRUE if ref is a within bound array reference.  */
     849              : 
     850              : bool
     851       254707 : ref_within_array_bound (gimple *stmt, tree ref)
     852              : {
     853       254707 :   class loop *loop = loop_containing_stmt (stmt);
     854              : 
     855       254707 :   gcc_assert (loop != NULL);
     856       254707 :   return for_each_index (&ref, idx_within_array_bound, loop);
     857              : }
     858              : 
     859              : 
     860              : /* Given a memory reference expression T, return TRUE if base object
     861              :    it refers to is writable.  The base object of a memory reference
     862              :    is the main object being referenced, which is returned by function
     863              :    get_base_address.  */
     864              : 
     865              : static bool
     866         2351 : base_object_writable (tree ref)
     867              : {
     868         2351 :   tree base_tree = get_base_address (ref);
     869              : 
     870         2351 :   return (base_tree
     871         2351 :           && DECL_P (base_tree)
     872         1462 :           && decl_binds_to_current_def_p (base_tree)
     873         3809 :           && !TREE_READONLY (base_tree));
     874              : }
     875              : 
     876              : /* Return true when the memory references of STMT won't trap in the
     877              :    if-converted code.  There are two things that we have to check for:
     878              : 
     879              :    - writes to memory occur to writable memory: if-conversion of
     880              :    memory writes transforms the conditional memory writes into
     881              :    unconditional writes, i.e. "if (cond) A[i] = foo" is transformed
     882              :    into "A[i] = cond ? foo : A[i]", and as the write to memory may not
     883              :    be executed at all in the original code, it may be a readonly
     884              :    memory.  To check that A is not const-qualified, we check that
     885              :    there exists at least an unconditional write to A in the current
     886              :    function.
     887              : 
     888              :    - reads or writes to memory are valid memory accesses for every
     889              :    iteration.  To check that the memory accesses are correctly formed
     890              :    and that we are allowed to read and write in these locations, we
     891              :    check that the memory accesses to be if-converted occur at every
     892              :    iteration unconditionally.
     893              : 
     894              :    Returns true for the memory reference in STMT, same memory reference
     895              :    is read or written unconditionally at least once and the base memory
     896              :    reference is written unconditionally once.  This is to check reference
     897              :    will not write fault.  Also returns true if the memory reference is
     898              :    unconditionally read once then we are conditionally writing to memory
     899              :    which is defined as read and write and is bound to the definition
     900              :    we are seeing.  */
     901              : static bool
     902        20031 : ifcvt_memrefs_wont_trap (gimple *stmt, vec<data_reference_p> drs)
     903              : {
     904              :   /* If DR didn't see a reference here we can't use it to tell
     905              :      whether the ref traps or not.  */
     906        20031 :   if (gimple_uid (stmt) == 0)
     907              :     return false;
     908              : 
     909        20030 :   data_reference_p *master_dr, *base_master_dr;
     910        20030 :   data_reference_p a = drs[gimple_uid (stmt) - 1];
     911              : 
     912        20030 :   tree base = DR_BASE_OBJECT (a);
     913        20030 :   innermost_loop_behavior *innermost = &DR_INNERMOST (a);
     914              : 
     915        20030 :   gcc_assert (DR_STMT (a) == stmt);
     916        20030 :   gcc_assert (DR_BASE_ADDRESS (a) || DR_OFFSET (a)
     917              :               || DR_INIT (a) || DR_STEP (a));
     918              : 
     919        20030 :   master_dr = innermost_DR_map->get (innermost);
     920        20030 :   gcc_assert (master_dr != NULL);
     921              : 
     922        20030 :   base_master_dr = baseref_DR_map->get (base);
     923              : 
     924              :   /* If a is unconditionally written to it doesn't trap.  */
     925        20030 :   if (DR_W_UNCONDITIONALLY (*master_dr))
     926              :     return true;
     927              : 
     928              :   /* If a is unconditionally accessed then ...
     929              : 
     930              :      Even a is conditional access, we can treat it as an unconditional
     931              :      one if it's an array reference and all its index are within array
     932              :      bound.  */
     933        18170 :   if (DR_RW_UNCONDITIONALLY (*master_dr)
     934        18170 :       || ref_within_array_bound (stmt, DR_REF (a)))
     935              :     {
     936              :       /* an unconditional read won't trap.  */
     937         6487 :       if (DR_IS_READ (a))
     938              :         return true;
     939              : 
     940              :       /* an unconditionally write won't trap if the base is written
     941              :          to unconditionally.  */
     942         2388 :       if ((base_master_dr
     943         2388 :            && DR_BASE_W_UNCONDITIONALLY (*base_master_dr))
     944              :           /* or the base is known to be not readonly.  */
     945         4739 :           || base_object_writable (DR_REF (a)))
     946         1495 :         return !ref_can_have_store_data_races (base);
     947              :     }
     948              : 
     949              :   return false;
     950              : }
     951              : 
     952              : /* Return true if STMT could be converted into a masked load or store
     953              :    (conditional load or store based on a mask computed from bb predicate).  */
     954              : 
     955              : static bool
     956        12003 : ifcvt_can_use_mask_load_store (gimple *stmt)
     957              : {
     958              :   /* Check whether this is a load or store.  */
     959        12003 :   tree lhs = gimple_assign_lhs (stmt);
     960        12003 :   bool is_load;
     961        12003 :   tree ref;
     962        12003 :   if (gimple_store_p (stmt))
     963              :     {
     964         2785 :       if (!is_gimple_val (gimple_assign_rhs1 (stmt)))
     965              :         return false;
     966              :       is_load = false;
     967              :       ref = lhs;
     968              :     }
     969         9218 :   else if (gimple_assign_load_p (stmt))
     970              :     {
     971         9217 :       is_load = true;
     972         9217 :       ref = gimple_assign_rhs1 (stmt);
     973              :     }
     974              :   else
     975              :     return false;
     976              : 
     977        12002 :   if (may_be_nonaddressable_p (ref))
     978              :     return false;
     979              : 
     980              :   /* Mask should be integer mode of the same size as the load/store
     981              :      mode.  */
     982        11943 :   machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
     983        11943 :   if (!int_mode_for_mode (mode).exists () || VECTOR_MODE_P (mode))
     984              :     return false;
     985              : 
     986        11912 :   if (can_vec_mask_load_store_p (mode, VOIDmode, is_load))
     987              :     return true;
     988              : 
     989              :   return false;
     990              : }
     991              : 
     992              : /* Return true if STMT could be converted from an operation that is
     993              :    unconditional to one that is conditional on a bb predicate mask.  */
     994              : 
     995              : static bool
     996        13935 : ifcvt_can_predicate (gimple *stmt)
     997              : {
     998        13935 :   basic_block bb = gimple_bb (stmt);
     999              : 
    1000          284 :   if (!(flag_tree_loop_vectorize || bb->loop_father->force_vectorize)
    1001        13935 :       || bb->loop_father->dont_vectorize
    1002        27870 :       || gimple_has_volatile_ops (stmt))
    1003              :     return false;
    1004              : 
    1005        13935 :   if (gimple_assign_single_p (stmt))
    1006        12003 :     return ifcvt_can_use_mask_load_store (stmt);
    1007              : 
    1008         1932 :   tree callee;
    1009         1932 :   if (gimple_call_builtin_p (stmt))
    1010          155 :     if ((callee = gimple_call_fndecl (stmt))
    1011          155 :         && fndecl_built_in_p (callee, BUILT_IN_NORMAL))
    1012              :       {
    1013          149 :         auto ifn = associated_internal_fn (callee);
    1014          149 :         auto cond_ifn = get_conditional_internal_fn (ifn);
    1015          149 :         tree type = TREE_TYPE (gimple_call_fntype (stmt));
    1016          149 :         return (cond_ifn != IFN_LAST
    1017          149 :                 && vectorized_internal_fn_supported_p (cond_ifn, type));
    1018              :       }
    1019              : 
    1020         1783 :   if (!is_gimple_assign (stmt))
    1021              :     return false;
    1022              : 
    1023         1777 :   tree_code code = gimple_assign_rhs_code (stmt);
    1024         1777 :   tree lhs_type = TREE_TYPE (gimple_assign_lhs (stmt));
    1025         1777 :   tree rhs_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
    1026         1777 :   if (!types_compatible_p (lhs_type, rhs_type))
    1027              :     return false;
    1028         1117 :   internal_fn cond_fn = get_conditional_internal_fn (code);
    1029         1117 :   return (cond_fn != IFN_LAST
    1030         1117 :           && vectorized_internal_fn_supported_p (cond_fn, lhs_type));
    1031              : }
    1032              : 
    1033              : /* Return true when STMT is if-convertible.
    1034              : 
    1035              :    GIMPLE_ASSIGN statement is not if-convertible if,
    1036              :    - it is not movable,
    1037              :    - it could trap,
    1038              :    - LHS is not var decl.  */
    1039              : 
    1040              : static bool
    1041        77248 : if_convertible_gimple_assign_stmt_p (gimple *stmt,
    1042              :                                      vec<data_reference_p> refs)
    1043              : {
    1044        77248 :   tree lhs = gimple_assign_lhs (stmt);
    1045              : 
    1046        77248 :   if (dump_file && (dump_flags & TDF_DETAILS))
    1047              :     {
    1048           26 :       fprintf (dump_file, "-------------------------\n");
    1049           26 :       print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    1050              :     }
    1051              : 
    1052        77248 :   if (!is_gimple_reg_type (TREE_TYPE (lhs)))
    1053              :     return false;
    1054              : 
    1055              :   /* Some of these constrains might be too conservative.  */
    1056        76979 :   if (stmt_ends_bb_p (stmt)
    1057        76979 :       || gimple_has_volatile_ops (stmt)
    1058        76904 :       || (TREE_CODE (lhs) == SSA_NAME
    1059        72608 :           && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
    1060       153883 :       || gimple_has_side_effects (stmt))
    1061              :     {
    1062           75 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1063            0 :         fprintf (dump_file, "stmt not suitable for ifcvt\n");
    1064              :       return false;
    1065              :     }
    1066              : 
    1067              :   /* tree-into-ssa.cc uses GF_PLF_1, so avoid it, because
    1068              :      in between if_convertible_loop_p and combine_blocks
    1069              :      we can perform loop versioning.  */
    1070        76904 :   gimple_set_plf (stmt, GF_PLF_2, false);
    1071              : 
    1072        76904 :   if ((! gimple_vuse (stmt)
    1073        20031 :        || gimple_could_trap_p_1 (stmt, false, false)
    1074        20031 :        || ! ifcvt_memrefs_wont_trap (stmt, refs))
    1075        89795 :       && gimple_could_trap_p (stmt))
    1076              :     {
    1077        13780 :       if (ifcvt_can_predicate (stmt))
    1078              :         {
    1079         2698 :           gimple_set_plf (stmt, GF_PLF_2, true);
    1080         2698 :           need_to_predicate = true;
    1081         2698 :           return true;
    1082              :         }
    1083        11082 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1084            0 :         fprintf (dump_file, "tree could trap...\n");
    1085              :       return false;
    1086              :     }
    1087        63124 :   else if (gimple_needing_rewrite_undefined (stmt))
    1088              :     /* We have to rewrite stmts with undefined overflow.  */
    1089        28460 :     need_to_rewrite_undefined = true;
    1090              : 
    1091              :   /* When if-converting stores force versioning, likewise if we
    1092              :      ended up generating store data races.  */
    1093       126248 :   if (gimple_vdef (stmt))
    1094         1511 :     need_to_predicate = true;
    1095              : 
    1096              :   return true;
    1097              : }
    1098              : 
    1099              : /* Return true when SW switch statement is equivalent to cond, that
    1100              :    all non default labels point to the same label.
    1101              : 
    1102              :    Fallthrough is not checked for and could even happen
    1103              :    with cond (using goto), so is handled.
    1104              : 
    1105              :    This is intended for switches created by the if-switch-conversion
    1106              :    pass, but can handle some programmer supplied cases too. */
    1107              : 
    1108              : static bool
    1109           70 : if_convertible_switch_p (gswitch *sw)
    1110              : {
    1111           70 :   if (gimple_switch_num_labels (sw) <= 1)
    1112              :     return false;
    1113           70 :   tree label = CASE_LABEL (gimple_switch_label (sw, 1));
    1114          762 :   for (unsigned i = 1; i < gimple_switch_num_labels (sw); i++)
    1115              :     {
    1116          698 :       if (CASE_LABEL (gimple_switch_label (sw, i)) != label)
    1117              :         return false;
    1118              :     }
    1119              :   return true;
    1120              : }
    1121              : 
    1122              : /* Return true when STMT is an if-convertible SIMD clone stmts.
    1123              : 
    1124              :    A SIMD clone statement is if-convertible if:
    1125              :     - it is an GIMPLE_CALL,
    1126              :     - it has a FNDECL,
    1127              :     - it has SIMD clones,
    1128              :     - it has at least one inbranch clone.  */
    1129              : static bool
    1130         1594 : if_convertible_simdclone_stmt_p (gimple *stmt)
    1131              : {
    1132         1594 :   if (!is_gimple_call (stmt))
    1133              :     return false;
    1134              : 
    1135         1594 :   tree fndecl = gimple_call_fndecl (stmt);
    1136         1594 :   if (fndecl)
    1137              :     {
    1138              :       /* We can vectorize some builtins and functions with SIMD "inbranch"
    1139              :          clones.  */
    1140         1326 :       struct cgraph_node *node = cgraph_node::get (fndecl);
    1141         1326 :       if (node && node->simd_clones != NULL)
    1142              :         /* Ensure that at least one clone can be "inbranch".  */
    1143         1962 :         for (struct cgraph_node *n = node->simd_clones; n != NULL;
    1144          961 :              n = n->simdclone->next_clone)
    1145         1960 :           if (n->simdclone->inbranch)
    1146              :             return true;
    1147              :     }
    1148              : 
    1149              :   return false;
    1150              : }
    1151              : 
    1152              : /* Return true when STMT is if-convertible.
    1153              : 
    1154              :    A statement is if-convertible if:
    1155              :    - it is an if-convertible GIMPLE_ASSIGN,
    1156              :    - it is a GIMPLE_LABEL or a GIMPLE_COND,
    1157              :    - it is a switch equivalent to COND
    1158              :    - it is builtins call,
    1159              :    - it is a call to a function with a SIMD clone.  */
    1160              : 
    1161              : static bool
    1162       172520 : if_convertible_stmt_p (gimple *stmt, vec<data_reference_p> refs)
    1163              : {
    1164       172520 :   switch (gimple_code (stmt))
    1165              :     {
    1166              :     case GIMPLE_LABEL:
    1167              :     case GIMPLE_DEBUG:
    1168              :     case GIMPLE_COND:
    1169              :       return true;
    1170              : 
    1171              :     case GIMPLE_SWITCH:
    1172              :       /* Checked elsewhere.  */
    1173              :       return true;
    1174              : 
    1175        77248 :     case GIMPLE_ASSIGN:
    1176        77248 :       return if_convertible_gimple_assign_stmt_p (stmt, refs);
    1177              : 
    1178         1486 :     case GIMPLE_CALL:
    1179         1486 :       {
    1180              :         /* Check if stmt is a simd clone first.  */
    1181         1486 :         if (if_convertible_simdclone_stmt_p (stmt))
    1182              :           {
    1183          999 :             gimple_set_plf (stmt, GF_PLF_2, true);
    1184          999 :             need_to_predicate = true;
    1185          999 :             return true;
    1186              :           }
    1187              : 
    1188              :         /* Check if the call can trap and if so require predication.  */
    1189          487 :         if (gimple_could_trap_p (stmt))
    1190              :           {
    1191          155 :             if (ifcvt_can_predicate (stmt))
    1192              :               {
    1193          108 :                 gimple_set_plf (stmt, GF_PLF_2, true);
    1194          108 :                 need_to_predicate = true;
    1195          108 :                 return true;
    1196              :               }
    1197              :             else
    1198              :               {
    1199           47 :                 if (dump_file && (dump_flags & TDF_DETAILS))
    1200            0 :                   fprintf (dump_file, "stmt could trap...\n");
    1201              :                 return false;
    1202              :               }
    1203              :           }
    1204              : 
    1205              :         /* Check if it's a prefetch.  Many ISAs contain vectorized and/or
    1206              :            conditional prefetches so if-convert should convert them or remove
    1207              :            them.  Mark them as supported.  */
    1208          332 :         if (gimple_call_builtin_p (stmt, BUILT_IN_PREFETCH))
    1209              :           return true;
    1210              : 
    1211              :         /* There are some IFN_s that are used to replace builtins but have the
    1212              :            same semantics.  Even if MASK_CALL cannot handle them vectorable_call
    1213              :            will insert the proper selection, so do not block conversion.  */
    1214          330 :         int flags = gimple_call_flags (stmt);
    1215          330 :         if ((flags & ECF_CONST)
    1216          330 :             && !(flags & ECF_LOOPING_CONST_OR_PURE)
    1217          660 :             && gimple_call_combined_fn (stmt) != CFN_LAST)
    1218          316 :           return true;
    1219              : 
    1220              :         return false;
    1221              :       }
    1222              : 
    1223            0 :     default:
    1224              :       /* Don't know what to do with 'em so don't do anything.  */
    1225            0 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1226              :         {
    1227            0 :           fprintf (dump_file, "don't know what to do\n");
    1228            0 :           print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    1229              :         }
    1230              :       return false;
    1231              :     }
    1232              : }
    1233              : 
    1234              : /* Assumes that BB has more than 1 predecessors.
    1235              :    Returns false if at least one successor is not on critical edge
    1236              :    and true otherwise.  */
    1237              : 
    1238              : static inline bool
    1239        83221 : all_preds_critical_p (basic_block bb)
    1240              : {
    1241        83221 :   edge e;
    1242        83221 :   edge_iterator ei;
    1243              : 
    1244       163070 :   FOR_EACH_EDGE (e, ei, bb->preds)
    1245       143462 :     if (EDGE_COUNT (e->src->succs) == 1)
    1246              :       return false;
    1247              :   return true;
    1248              : }
    1249              : 
    1250              : /* Return true when BB is if-convertible.  This routine does not check
    1251              :    basic block's statements and phis.
    1252              : 
    1253              :    A basic block is not if-convertible if:
    1254              :    - it is non-empty and it is after the exit block (in BFS order),
    1255              :    - it is after the exit block but before the latch,
    1256              :    - its edges are not normal.
    1257              : 
    1258              :    EXIT_BB is the basic block containing the exit of the LOOP.  BB is
    1259              :    inside LOOP.  */
    1260              : 
    1261              : static bool
    1262       215519 : if_convertible_bb_p (class loop *loop, basic_block bb, basic_block exit_bb)
    1263              : {
    1264       215519 :   edge e;
    1265       215519 :   edge_iterator ei;
    1266              : 
    1267       215519 :   if (dump_file && (dump_flags & TDF_DETAILS))
    1268           86 :     fprintf (dump_file, "----------[%d]-------------\n", bb->index);
    1269              : 
    1270       215519 :   if (EDGE_COUNT (bb->succs) > 2)
    1271              :     return false;
    1272              : 
    1273       430910 :   if (gcall *call = safe_dyn_cast <gcall *> (*gsi_last_bb (bb)))
    1274          194 :     if (gimple_call_ctrl_altering_p (call))
    1275              :       return false;
    1276              : 
    1277       215455 :   if (exit_bb)
    1278              :     {
    1279        39038 :       if (bb != loop->latch)
    1280              :         {
    1281          548 :           if (dump_file && (dump_flags & TDF_DETAILS))
    1282            0 :             fprintf (dump_file, "basic block after exit bb but before latch\n");
    1283              :           return false;
    1284              :         }
    1285        38490 :       else if (!empty_block_p (bb))
    1286              :         {
    1287         1450 :           if (dump_file && (dump_flags & TDF_DETAILS))
    1288            0 :             fprintf (dump_file, "non empty basic block after exit bb\n");
    1289              :           return false;
    1290              :         }
    1291        37040 :       else if (bb == loop->latch
    1292        37040 :                && bb != exit_bb
    1293        74080 :                && !dominated_by_p (CDI_DOMINATORS, bb, exit_bb))
    1294              :           {
    1295           11 :             if (dump_file && (dump_flags & TDF_DETAILS))
    1296            0 :               fprintf (dump_file, "latch is not dominated by exit_block\n");
    1297              :             return false;
    1298              :           }
    1299              :     }
    1300              : 
    1301              :   /* Be less adventurous and handle only normal edges.  */
    1302       522020 :   FOR_EACH_EDGE (e, ei, bb->succs)
    1303       308586 :     if (e->flags & (EDGE_EH | EDGE_ABNORMAL | EDGE_IRREDUCIBLE_LOOP))
    1304              :       {
    1305           12 :         if (dump_file && (dump_flags & TDF_DETAILS))
    1306            0 :           fprintf (dump_file, "Difficult to handle edges\n");
    1307              :         return false;
    1308              :       }
    1309              : 
    1310              :   return true;
    1311              : }
    1312              : 
    1313              : /* Return true when all predecessor blocks of BB are visited.  The
    1314              :    VISITED bitmap keeps track of the visited blocks.  */
    1315              : 
    1316              : static bool
    1317      2400399 : pred_blocks_visited_p (basic_block bb, bitmap *visited)
    1318              : {
    1319      2400399 :   edge e;
    1320      2400399 :   edge_iterator ei;
    1321      4125833 :   FOR_EACH_EDGE (e, ei, bb->preds)
    1322      2718924 :     if (!bitmap_bit_p (*visited, e->src->index))
    1323              :       return false;
    1324              : 
    1325              :   return true;
    1326              : }
    1327              : 
    1328              : /* Get body of a LOOP in suitable order for if-conversion.  It is
    1329              :    caller's responsibility to deallocate basic block list.
    1330              :    If-conversion suitable order is, breadth first sort (BFS) order
    1331              :    with an additional constraint: select a block only if all its
    1332              :    predecessors are already selected.  */
    1333              : 
    1334              : static basic_block *
    1335       414718 : get_loop_body_in_if_conv_order (const class loop *loop)
    1336              : {
    1337       414718 :   basic_block *blocks, *blocks_in_bfs_order;
    1338       414718 :   basic_block bb;
    1339       414718 :   bitmap visited;
    1340       414718 :   unsigned int index = 0;
    1341       414718 :   unsigned int visited_count = 0;
    1342              : 
    1343       414718 :   gcc_assert (loop->num_nodes);
    1344       414718 :   gcc_assert (loop->latch != EXIT_BLOCK_PTR_FOR_FN (cfun));
    1345              : 
    1346       414718 :   blocks = XCNEWVEC (basic_block, loop->num_nodes);
    1347       414718 :   visited = BITMAP_ALLOC (NULL);
    1348              : 
    1349       414718 :   blocks_in_bfs_order = get_loop_body_in_bfs_order (loop);
    1350              : 
    1351       414718 :   index = 0;
    1352      4174884 :   while (index < loop->num_nodes)
    1353              :     {
    1354      3345500 :       bb = blocks_in_bfs_order [index];
    1355              : 
    1356      3345500 :       if (bb->flags & BB_IRREDUCIBLE_LOOP)
    1357              :         {
    1358           52 :           free (blocks_in_bfs_order);
    1359           52 :           BITMAP_FREE (visited);
    1360           52 :           free (blocks);
    1361           52 :           return NULL;
    1362              :         }
    1363              : 
    1364      3345448 :       if (!bitmap_bit_p (visited, bb->index))
    1365              :         {
    1366      2400399 :           if (pred_blocks_visited_p (bb, &visited)
    1367      2400399 :               || bb == loop->header)
    1368              :             {
    1369              :               /* This block is now visited.  */
    1370      1821627 :               bitmap_set_bit (visited, bb->index);
    1371      1821627 :               blocks[visited_count++] = bb;
    1372              :             }
    1373              :         }
    1374              : 
    1375      3345448 :       index++;
    1376              : 
    1377      3345448 :       if (index == loop->num_nodes
    1378       478491 :           && visited_count != loop->num_nodes)
    1379              :         /* Not done yet.  */
    1380      3345448 :         index = 0;
    1381              :     }
    1382       414666 :   free (blocks_in_bfs_order);
    1383       414666 :   BITMAP_FREE (visited);
    1384              : 
    1385              :   /* Go through loop and reject if-conversion or lowering of bitfields if we
    1386              :      encounter statements we do not believe the vectorizer will be able to
    1387              :      handle.  If adding a new type of statement here, make sure
    1388              :      'ifcvt_local_dce' is also able to handle it properly.  */
    1389      2638843 :   for (index = 0; index < loop->num_nodes; index++)
    1390              :     {
    1391      1812095 :       basic_block bb = blocks[index];
    1392      1812095 :       gimple_stmt_iterator gsi;
    1393              : 
    1394      1812095 :       bool may_have_nonlocal_labels
    1395      1812095 :         = bb_with_exit_edge_p (loop, bb) || bb == loop->latch;
    1396     17163093 :       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    1397     13541487 :         switch (gimple_code (gsi_stmt (gsi)))
    1398              :           {
    1399        41102 :           case GIMPLE_LABEL:
    1400        41102 :             if (!may_have_nonlocal_labels)
    1401              :               {
    1402         6861 :                 tree label
    1403         6861 :                   = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi)));
    1404        13722 :                 if (DECL_NONLOCAL (label) || FORCED_LABEL (label))
    1405              :                   {
    1406           47 :                     free (blocks);
    1407           47 :                     return NULL;
    1408              :                   }
    1409              :               }
    1410              :             /* Fallthru.  */
    1411     13538903 :           case GIMPLE_ASSIGN:
    1412     13538903 :           case GIMPLE_CALL:
    1413     13538903 :           case GIMPLE_DEBUG:
    1414     13538903 :           case GIMPLE_COND:
    1415     13538903 :           case GIMPLE_SWITCH:
    1416     13538903 :             gimple_set_uid (gsi_stmt (gsi), 0);
    1417     13538903 :             break;
    1418         2537 :           default:
    1419         2537 :             free (blocks);
    1420         2537 :             return NULL;
    1421              :           }
    1422              :     }
    1423              :   return blocks;
    1424              : }
    1425              : 
    1426              : /* Returns true when the analysis of the predicates for all the basic
    1427              :    blocks in LOOP succeeded.
    1428              : 
    1429              :    predicate_bbs first allocates the predicates of the basic blocks.
    1430              :    These fields are then initialized with the tree expressions
    1431              :    representing the predicates under which a basic block is executed
    1432              :    in the LOOP.  As the loop->header is executed at each iteration, it
    1433              :    has the "true" predicate.  Other statements executed under a
    1434              :    condition are predicated with that condition, for example
    1435              : 
    1436              :    | if (x)
    1437              :    |   S1;
    1438              :    | else
    1439              :    |   S2;
    1440              : 
    1441              :    S1 will be predicated with "x", and
    1442              :    S2 will be predicated with "!x".  */
    1443              : 
    1444              : static void
    1445        37029 : predicate_bbs (loop_p loop)
    1446              : {
    1447        37029 :   unsigned int i;
    1448              : 
    1449       242791 :   for (i = 0; i < loop->num_nodes; i++)
    1450       205762 :     init_bb_predicate (ifc_bbs[i]);
    1451              : 
    1452       242791 :   for (i = 0; i < loop->num_nodes; i++)
    1453              :     {
    1454       205762 :       basic_block bb = ifc_bbs[i];
    1455       205762 :       tree cond;
    1456              : 
    1457              :       /* The loop latch and loop exit block are always executed and
    1458              :          have no extra conditions to be processed: skip them.  */
    1459       279820 :       if (bb == loop->latch
    1460       205762 :           || bb_with_exit_edge_p (loop, bb))
    1461              :         {
    1462        74058 :           reset_bb_predicate (bb);
    1463        74058 :           continue;
    1464              :         }
    1465              : 
    1466       131704 :       cond = bb_predicate (bb);
    1467       263408 :       if (gcond *stmt = safe_dyn_cast <gcond *> (*gsi_last_bb (bb)))
    1468              :         {
    1469        53535 :           tree c2;
    1470        53535 :           edge true_edge, false_edge;
    1471        53535 :           location_t loc = gimple_location (stmt);
    1472        53535 :           tree c;
    1473              :           /* gcc.dg/fold-bopcond-1.c shows that despite all forwprop passes
    1474              :              conditions can remain unfolded because of multiple uses so
    1475              :              try to re-fold here, especially to get precision changing
    1476              :              conversions sorted out.  Do not simply fold the stmt since
    1477              :              this is analysis only.  When conditions were embedded in
    1478              :              COND_EXPRs those were folded separately before folding the
    1479              :              COND_EXPR but as they are now outside we have to make sure
    1480              :              to fold them.  Do it here - another opportunity would be to
    1481              :              fold predicates as they are inserted.  */
    1482        53535 :           gimple_match_op cexpr (gimple_match_cond::UNCOND,
    1483        53535 :                                  gimple_cond_code (stmt),
    1484              :                                  boolean_type_node,
    1485              :                                  gimple_cond_lhs (stmt),
    1486        53535 :                                  gimple_cond_rhs (stmt));
    1487        53535 :           if (cexpr.resimplify (NULL, follow_all_ssa_edges)
    1488         4055 :               && cexpr.code.is_tree_code ()
    1489        57590 :               && TREE_CODE_CLASS ((tree_code)cexpr.code) == tcc_comparison)
    1490          560 :             c = build2_loc (loc, (tree_code)cexpr.code, boolean_type_node,
    1491              :                             cexpr.ops[0], cexpr.ops[1]);
    1492              :           else
    1493        52975 :             c = build2_loc (loc, gimple_cond_code (stmt),
    1494              :                             boolean_type_node,
    1495              :                             gimple_cond_lhs (stmt),
    1496              :                             gimple_cond_rhs (stmt));
    1497              : 
    1498              :           /* Add new condition into destination's predicate list.  */
    1499        53535 :           extract_true_false_edges_from_block (gimple_bb (stmt),
    1500              :                                                &true_edge, &false_edge);
    1501              : 
    1502              :           /* If C is true, then TRUE_EDGE is taken.  */
    1503        53535 :           add_to_dst_predicate_list (loop, true_edge, unshare_expr (cond),
    1504              :                                      unshare_expr (c));
    1505              : 
    1506              :           /* If C is false, then FALSE_EDGE is taken.  */
    1507        53535 :           c2 = build1_loc (loc, TRUTH_NOT_EXPR, boolean_type_node,
    1508              :                            unshare_expr (c));
    1509        53535 :           add_to_dst_predicate_list (loop, false_edge,
    1510              :                                      unshare_expr (cond), c2);
    1511              : 
    1512        53535 :           cond = NULL_TREE;
    1513              :         }
    1514              : 
    1515              :       /* Assumes the limited COND like switches checked for earlier.  */
    1516        78169 :       else if (gswitch *sw = safe_dyn_cast <gswitch *> (*gsi_last_bb (bb)))
    1517              :         {
    1518           79 :           location_t loc = gimple_location (*gsi_last_bb (bb));
    1519              : 
    1520           79 :           tree default_label = CASE_LABEL (gimple_switch_default_label (sw));
    1521           79 :           tree cond_label = CASE_LABEL (gimple_switch_label (sw, 1));
    1522              : 
    1523           79 :           edge false_edge = find_edge (bb, label_to_block (cfun, default_label));
    1524           79 :           edge true_edge = find_edge (bb, label_to_block (cfun, cond_label));
    1525              : 
    1526              :           /* Create chain of switch tests for each case.  */
    1527           79 :           tree switch_cond = NULL_TREE;
    1528           79 :           tree index = gimple_switch_index (sw);
    1529          802 :           for (unsigned i = 1; i < gimple_switch_num_labels (sw); i++)
    1530              :             {
    1531          723 :               tree label = gimple_switch_label (sw, i);
    1532          723 :               tree case_cond;
    1533          723 :               if (CASE_HIGH (label))
    1534              :                 {
    1535            7 :                   tree low = build2_loc (loc, GE_EXPR,
    1536              :                                          boolean_type_node,
    1537            7 :                                          index, fold_convert_loc (loc, TREE_TYPE (index),
    1538            7 :                                                  CASE_LOW (label)));
    1539           14 :                   tree high = build2_loc (loc, LE_EXPR,
    1540              :                                           boolean_type_node,
    1541            7 :                                           index, fold_convert_loc (loc, TREE_TYPE (index),
    1542            7 :                                                   CASE_HIGH (label)));
    1543            7 :                   case_cond = build2_loc (loc, TRUTH_AND_EXPR,
    1544              :                                           boolean_type_node,
    1545              :                                           low, high);
    1546              :                 }
    1547              :               else
    1548          716 :                 case_cond = build2_loc (loc, EQ_EXPR,
    1549              :                                         boolean_type_node,
    1550              :                                         index,
    1551          716 :                                         fold_convert_loc (loc, TREE_TYPE (index),
    1552          716 :                                                           CASE_LOW (label)));
    1553          723 :               if (i > 1)
    1554          644 :                 switch_cond = build2_loc (loc, TRUTH_OR_EXPR,
    1555              :                                           boolean_type_node,
    1556              :                                           case_cond, switch_cond);
    1557              :               else
    1558              :                 switch_cond = case_cond;
    1559              :             }
    1560              : 
    1561           79 :           add_to_dst_predicate_list (loop, true_edge, unshare_expr (cond),
    1562              :                                      unshare_expr (switch_cond));
    1563           79 :           switch_cond = build1_loc (loc, TRUTH_NOT_EXPR, boolean_type_node,
    1564              :                                     unshare_expr (switch_cond));
    1565           79 :           add_to_dst_predicate_list (loop, false_edge,
    1566              :                                      unshare_expr (cond), switch_cond);
    1567           79 :           cond = NULL_TREE;
    1568              :         }
    1569              : 
    1570              :       /* If current bb has only one successor, then consider it as an
    1571              :          unconditional goto.  */
    1572       283852 :       if (single_succ_p (bb))
    1573              :         {
    1574        78090 :           basic_block bb_n = single_succ (bb);
    1575              : 
    1576              :           /* The successor bb inherits the predicate of its
    1577              :              predecessor.  If there is no predicate in the predecessor
    1578              :              bb, then consider the successor bb as always executed.  */
    1579        78090 :           if (cond == NULL_TREE)
    1580            0 :             cond = boolean_true_node;
    1581              : 
    1582        78090 :           add_to_predicate_list (loop, bb_n, cond);
    1583              :         }
    1584              :     }
    1585              : 
    1586              :   /* The loop header is always executed.  */
    1587        37029 :   reset_bb_predicate (loop->header);
    1588        37029 :   gcc_assert (bb_predicate_gimplified_stmts (loop->header) == NULL
    1589              :               && bb_predicate_gimplified_stmts (loop->latch) == NULL);
    1590        37029 : }
    1591              : 
    1592              : /* Build region by adding loop pre-header and post-header blocks.  */
    1593              : 
    1594              : static vec<basic_block>
    1595        37029 : build_region (class loop *loop)
    1596              : {
    1597        37029 :   vec<basic_block> region = vNULL;
    1598        37029 :   basic_block exit_bb = NULL;
    1599              : 
    1600        37029 :   gcc_assert (ifc_bbs);
    1601              :   /* The first element is loop pre-header.  */
    1602        37029 :   region.safe_push (loop_preheader_edge (loop)->src);
    1603              : 
    1604       279820 :   for (unsigned int i = 0; i < loop->num_nodes; i++)
    1605              :     {
    1606       205762 :       basic_block bb = ifc_bbs[i];
    1607       205762 :       region.safe_push (bb);
    1608              :       /* Find loop postheader.  */
    1609       205762 :       edge e;
    1610       205762 :       edge_iterator ei;
    1611       456536 :       FOR_EACH_EDGE (e, ei, bb->succs)
    1612       287803 :         if (loop_exit_edge_p (loop, e))
    1613              :           {
    1614        37029 :               exit_bb = e->dest;
    1615        37029 :               break;
    1616              :           }
    1617              :     }
    1618              :   /* The last element is loop post-header.  */
    1619        37029 :   gcc_assert (exit_bb);
    1620        37029 :   region.safe_push (exit_bb);
    1621        37029 :   return region;
    1622              : }
    1623              : 
    1624              : /* Return true when LOOP is if-convertible.  This is a helper function
    1625              :    for if_convertible_loop_p.  REFS and DDRS are initialized and freed
    1626              :    in if_convertible_loop_p.  */
    1627              : 
    1628              : static bool
    1629        39114 : if_convertible_loop_p_1 (class loop *loop, vec<data_reference_p> *refs)
    1630              : {
    1631        39114 :   unsigned int i;
    1632        39114 :   basic_block exit_bb = NULL;
    1633        39114 :   vec<basic_block> region;
    1634              : 
    1635        39114 :   calculate_dominance_info (CDI_DOMINATORS);
    1636              : 
    1637       291662 :   for (i = 0; i < loop->num_nodes; i++)
    1638              :     {
    1639       215519 :       basic_block bb = ifc_bbs[i];
    1640              : 
    1641       215519 :       if (!if_convertible_bb_p (loop, bb, exit_bb))
    1642              :         return false;
    1643              : 
    1644       213434 :       if (bb_with_exit_edge_p (loop, bb))
    1645        39038 :         exit_bb = bb;
    1646              :     }
    1647              : 
    1648        37029 :   data_reference_p dr;
    1649              : 
    1650        37029 :   innermost_DR_map
    1651        37029 :           = new hash_map<innermost_loop_behavior_hash, data_reference_p>;
    1652        37029 :   baseref_DR_map = new hash_map<tree_operand_hash, data_reference_p>;
    1653              : 
    1654              :   /* Compute post-dominator tree locally.  */
    1655        37029 :   region = build_region (loop);
    1656        37029 :   calculate_dominance_info_for_region (CDI_POST_DOMINATORS, region);
    1657              : 
    1658        37029 :   predicate_bbs (loop);
    1659              : 
    1660              :   /* Free post-dominator tree since it is not used after predication.  */
    1661        37029 :   free_dominance_info_for_region (cfun, CDI_POST_DOMINATORS, region);
    1662        37029 :   region.release ();
    1663              : 
    1664       194518 :   for (i = 0; refs->iterate (i, &dr); i++)
    1665              :     {
    1666       120460 :       tree ref = DR_REF (dr);
    1667              : 
    1668       120460 :       dr->aux = XNEW (struct ifc_dr);
    1669       120460 :       DR_BASE_W_UNCONDITIONALLY (dr) = false;
    1670       120460 :       DR_RW_UNCONDITIONALLY (dr) = false;
    1671       120460 :       DR_W_UNCONDITIONALLY (dr) = false;
    1672       120460 :       IFC_DR (dr)->rw_predicate = boolean_false_node;
    1673       120460 :       IFC_DR (dr)->w_predicate = boolean_false_node;
    1674       120460 :       IFC_DR (dr)->base_w_predicate = boolean_false_node;
    1675       120460 :       if (gimple_uid (DR_STMT (dr)) == 0)
    1676       119781 :         gimple_set_uid (DR_STMT (dr), i + 1);
    1677              : 
    1678              :       /* If DR doesn't have innermost loop behavior or it's a compound
    1679              :          memory reference, we synthesize its innermost loop behavior
    1680              :          for hashing.  */
    1681       120460 :       if (TREE_CODE (ref) == COMPONENT_REF
    1682              :           || TREE_CODE (ref) == IMAGPART_EXPR
    1683              :           || TREE_CODE (ref) == REALPART_EXPR
    1684        83052 :           || !(DR_BASE_ADDRESS (dr) || DR_OFFSET (dr)
    1685        26792 :                || DR_INIT (dr) || DR_STEP (dr)))
    1686              :         {
    1687       110035 :           while (TREE_CODE (ref) == COMPONENT_REF
    1688        65359 :                  || TREE_CODE (ref) == IMAGPART_EXPR
    1689       174816 :                  || TREE_CODE (ref) == REALPART_EXPR)
    1690        45835 :             ref = TREE_OPERAND (ref, 0);
    1691              : 
    1692        64200 :           memset (&DR_INNERMOST (dr), 0, sizeof (DR_INNERMOST (dr)));
    1693        64200 :           DR_BASE_ADDRESS (dr) = ref;
    1694              :         }
    1695       120460 :       hash_memrefs_baserefs_and_store_DRs_read_written_info (dr);
    1696              :     }
    1697              : 
    1698       185559 :   for (i = 0; i < loop->num_nodes; i++)
    1699              :     {
    1700       160017 :       basic_block bb = ifc_bbs[i];
    1701       160017 :       gimple_stmt_iterator itr;
    1702              : 
    1703              :       /* Check the if-convertibility of statements in predicated BBs.  */
    1704       160017 :       if (!dominated_by_p (CDI_DOMINATORS, loop->latch, bb))
    1705       296509 :         for (itr = gsi_start_bb (bb); !gsi_end_p (itr); gsi_next (&itr))
    1706       172520 :           if (!if_convertible_stmt_p (gsi_stmt (itr), *refs))
    1707        39114 :             return false;
    1708              :     }
    1709              : 
    1710              :   /* Checking PHIs needs to be done after stmts, as the fact whether there
    1711              :      are any masked loads or stores affects the tests.  Also check switch
    1712              :      stmts for supported shape as that cannot be skipped for always
    1713              :      executed blocks.  */
    1714       159852 :   for (i = 0; i < loop->num_nodes; i++)
    1715              :     {
    1716       134316 :       basic_block bb = ifc_bbs[i];
    1717       134316 :       gphi_iterator itr;
    1718              : 
    1719       263652 :       for (itr = gsi_start_phis (bb); !gsi_end_p (itr); gsi_next (&itr))
    1720       129336 :         if (!if_convertible_phi_p (loop, bb, itr.phi ()))
    1721            6 :           return false;
    1722       350373 :       if (gswitch *s = safe_dyn_cast <gswitch *> (*gsi_last_bb (bb)))
    1723           70 :         if (!if_convertible_switch_p (s))
    1724            6 :           return false;
    1725              :     }
    1726              : 
    1727        25536 :   if (dump_file)
    1728           30 :     fprintf (dump_file, "Applying if-conversion\n");
    1729              : 
    1730              :   return true;
    1731              : }
    1732              : 
    1733              : /* Return true when LOOP is if-convertible.
    1734              :    LOOP is if-convertible if:
    1735              :    - it is innermost,
    1736              :    - it has two or more basic blocks,
    1737              :    - it has only one exit,
    1738              :    - loop header is not the exit edge,
    1739              :    - if its basic blocks and phi nodes are if convertible.  */
    1740              : 
    1741              : static bool
    1742        39254 : if_convertible_loop_p (class loop *loop, vec<data_reference_p> *refs)
    1743              : {
    1744        39254 :   edge e;
    1745        39254 :   edge_iterator ei;
    1746        39254 :   bool res = false;
    1747              : 
    1748              :   /* Handle only innermost loop.  */
    1749        39254 :   if (!loop || loop->inner)
    1750              :     {
    1751            0 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1752            0 :         fprintf (dump_file, "not innermost loop\n");
    1753              :       return false;
    1754              :     }
    1755              : 
    1756              :   /* If only one block, no need for if-conversion.  */
    1757        39254 :   if (loop->num_nodes <= 2)
    1758              :     {
    1759            0 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1760            0 :         fprintf (dump_file, "less than 2 basic blocks\n");
    1761              :       return false;
    1762              :     }
    1763              : 
    1764              :   /* If one of the loop header's edge is an exit edge then do not
    1765              :      apply if-conversion.  */
    1766       117643 :   FOR_EACH_EDGE (e, ei, loop->header->succs)
    1767        78529 :     if (loop_exit_edge_p (loop, e))
    1768              :       return false;
    1769              : 
    1770        39114 :   res = if_convertible_loop_p_1 (loop, refs);
    1771              : 
    1772        76143 :   delete innermost_DR_map;
    1773        39114 :   innermost_DR_map = NULL;
    1774              : 
    1775        76143 :   delete baseref_DR_map;
    1776        39114 :   baseref_DR_map = NULL;
    1777              : 
    1778        39114 :   return res;
    1779              : }
    1780              : 
    1781              : /* Return reduc_1 if has_nop.
    1782              : 
    1783              :    if (...)
    1784              :      tmp1 = (unsigned type) reduc_1;
    1785              :      tmp2 = tmp1 + rhs2;
    1786              :      reduc_3 = (signed type) tmp2.  */
    1787              : static tree
    1788        11348 : strip_nop_cond_scalar_reduction (bool has_nop, tree op)
    1789              : {
    1790        11348 :   if (!has_nop)
    1791              :     return op;
    1792              : 
    1793          414 :   if (TREE_CODE (op) != SSA_NAME)
    1794              :     return NULL_TREE;
    1795              : 
    1796          368 :   gassign *stmt = safe_dyn_cast <gassign *> (SSA_NAME_DEF_STMT (op));
    1797          368 :   if (!stmt
    1798          368 :       || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
    1799          230 :       || !tree_nop_conversion_p (TREE_TYPE (op), TREE_TYPE
    1800              :                                  (gimple_assign_rhs1 (stmt))))
    1801              :     return NULL_TREE;
    1802              : 
    1803          219 :   return gimple_assign_rhs1 (stmt);
    1804              : }
    1805              : 
    1806              : /* Returns true if def-stmt for phi argument ARG is simple increment/decrement
    1807              :    which is in predicated basic block.
    1808              :    In fact, the following PHI pattern is searching:
    1809              :       loop-header:
    1810              :         reduc_1 = PHI <..., reduc_2>
    1811              :       ...
    1812              :         if (...)
    1813              :           reduc_3 = ...
    1814              :         reduc_2 = PHI <reduc_1, reduc_3>
    1815              : 
    1816              :    ARG_0 and ARG_1 are correspondent PHI arguments.
    1817              :    REDUC, OP0 and OP1 contain reduction stmt and its operands.
    1818              :    EXTENDED is true if PHI has > 2 arguments.  */
    1819              : 
    1820              : static bool
    1821        47293 : is_cond_scalar_reduction (gimple *phi, gimple **reduc, tree arg_0, tree arg_1,
    1822              :                           tree *op0, tree *op1, bool extended, bool* has_nop,
    1823              :                           gimple **nop_reduc)
    1824              : {
    1825        47293 :   tree lhs, r_op1, r_op2, r_nop1, r_nop2;
    1826        47293 :   gimple *stmt;
    1827        47293 :   gimple *header_phi = NULL;
    1828        47293 :   enum tree_code reduction_op;
    1829        47293 :   basic_block bb = gimple_bb (phi);
    1830        47293 :   class loop *loop = bb->loop_father;
    1831        47293 :   edge latch_e = loop_latch_edge (loop);
    1832        47293 :   imm_use_iterator imm_iter;
    1833        47293 :   use_operand_p use_p;
    1834        47293 :   edge e;
    1835        47293 :   edge_iterator ei;
    1836        47293 :   bool result = *has_nop = false;
    1837        47293 :   if (TREE_CODE (arg_0) != SSA_NAME || TREE_CODE (arg_1) != SSA_NAME)
    1838              :     return false;
    1839              : 
    1840        34670 :   if (!extended && gimple_code (SSA_NAME_DEF_STMT (arg_0)) == GIMPLE_PHI)
    1841              :     {
    1842         8712 :       lhs = arg_1;
    1843         8712 :       header_phi = SSA_NAME_DEF_STMT (arg_0);
    1844         8712 :       stmt = SSA_NAME_DEF_STMT (arg_1);
    1845              :     }
    1846        25958 :   else if (gimple_code (SSA_NAME_DEF_STMT (arg_1)) == GIMPLE_PHI)
    1847              :     {
    1848        11369 :       lhs = arg_0;
    1849        11369 :       header_phi = SSA_NAME_DEF_STMT (arg_1);
    1850        11369 :       stmt = SSA_NAME_DEF_STMT (arg_0);
    1851              :     }
    1852              :   else
    1853              :     return false;
    1854        20081 :   if (gimple_bb (header_phi) != loop->header)
    1855              :     return false;
    1856              : 
    1857        19195 :   if (PHI_ARG_DEF_FROM_EDGE (header_phi, latch_e) != PHI_RESULT (phi))
    1858              :     return false;
    1859              : 
    1860        13004 :   if (gimple_code (stmt) != GIMPLE_ASSIGN
    1861        13004 :       || gimple_has_volatile_ops (stmt))
    1862              :     return false;
    1863              : 
    1864        12868 :   if (!flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
    1865              :     return false;
    1866              : 
    1867        12767 :   if (!is_predicated (gimple_bb (stmt)))
    1868              :     return false;
    1869              : 
    1870              :   /* Check that stmt-block is predecessor of phi-block.  */
    1871        10612 :   FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs)
    1872        10548 :     if (e->dest == bb)
    1873              :       {
    1874              :         result = true;
    1875              :         break;
    1876              :       }
    1877        10484 :   if (!result)
    1878              :     return false;
    1879              : 
    1880        10420 :   if (!has_single_use (lhs))
    1881              :     return false;
    1882              : 
    1883        10369 :   reduction_op = gimple_assign_rhs_code (stmt);
    1884              : 
    1885              :     /* Catch something like below
    1886              : 
    1887              :      loop-header:
    1888              :      reduc_1 = PHI <..., reduc_2>
    1889              :      ...
    1890              :      if (...)
    1891              :      tmp1 = (unsigned type) reduc_1;
    1892              :      tmp2 = tmp1 + rhs2;
    1893              :      reduc_3 = (signed type) tmp2;
    1894              : 
    1895              :      reduc_2 = PHI <reduc_1, reduc_3>
    1896              : 
    1897              :      and convert to
    1898              : 
    1899              :      reduc_2 = PHI <0, reduc_1>
    1900              :      tmp1 = (unsigned type)reduc_1;
    1901              :      ifcvt = cond_expr ? rhs2 : 0
    1902              :      tmp2 = tmp1 +/- ifcvt;
    1903              :      reduc_1 = (signed type)tmp2;  */
    1904              : 
    1905        10369 :   if (CONVERT_EXPR_CODE_P (reduction_op))
    1906              :     {
    1907          418 :       lhs = gimple_assign_rhs1 (stmt);
    1908          418 :       if (TREE_CODE (lhs) != SSA_NAME
    1909          418 :           || !has_single_use (lhs))
    1910              :         return false;
    1911              : 
    1912          230 :       *nop_reduc = stmt;
    1913          230 :       stmt = SSA_NAME_DEF_STMT (lhs);
    1914          230 :       if (gimple_bb (stmt) != gimple_bb (*nop_reduc)
    1915          230 :           || !is_gimple_assign (stmt))
    1916              :         return false;
    1917              : 
    1918          221 :       *has_nop = true;
    1919          221 :       reduction_op = gimple_assign_rhs_code (stmt);
    1920              :     }
    1921              : 
    1922        10172 :   if (reduction_op != PLUS_EXPR
    1923              :       && reduction_op != MINUS_EXPR
    1924        10172 :       && reduction_op != MULT_EXPR
    1925        10172 :       && reduction_op != BIT_IOR_EXPR
    1926              :       && reduction_op != BIT_XOR_EXPR
    1927         4613 :       && reduction_op != BIT_AND_EXPR)
    1928              :     return false;
    1929         5674 :   r_op1 = gimple_assign_rhs1 (stmt);
    1930         5674 :   r_op2 = gimple_assign_rhs2 (stmt);
    1931              : 
    1932         5674 :   r_nop1 = strip_nop_cond_scalar_reduction (*has_nop, r_op1);
    1933         5674 :   r_nop2 = strip_nop_cond_scalar_reduction (*has_nop, r_op2);
    1934              : 
    1935              :   /* Make R_OP1 to hold reduction variable.  */
    1936         5674 :   if (r_nop2 == PHI_RESULT (header_phi)
    1937         5674 :       && commutative_tree_code (reduction_op))
    1938              :     {
    1939              :       std::swap (r_op1, r_op2);
    1940              :       std::swap (r_nop1, r_nop2);
    1941              :     }
    1942         4535 :   else if (r_nop1 != PHI_RESULT (header_phi))
    1943              :     return false;
    1944              : 
    1945         5372 :   if (*has_nop)
    1946              :     {
    1947              :       /* Check that R_NOP1 is used in nop_stmt or in PHI only.  */
    1948          430 :       FOR_EACH_IMM_USE_FAST (use_p, imm_iter, r_nop1)
    1949              :         {
    1950          304 :           gimple *use_stmt = USE_STMT (use_p);
    1951          304 :           if (is_gimple_debug (use_stmt))
    1952            0 :             continue;
    1953          304 :           if (use_stmt == SSA_NAME_DEF_STMT (r_op1))
    1954          126 :             continue;
    1955          178 :           if (use_stmt != phi)
    1956           42 :             return false;
    1957          168 :         }
    1958              :     }
    1959              : 
    1960              :   /* Check that R_OP1 is used in reduction stmt or in PHI only.  */
    1961        16477 :   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, r_op1)
    1962              :     {
    1963        11406 :       gimple *use_stmt = USE_STMT (use_p);
    1964        11406 :       if (is_gimple_debug (use_stmt))
    1965           29 :         continue;
    1966        11377 :       if (use_stmt == stmt)
    1967         5096 :         continue;
    1968         6281 :       if (gimple_code (use_stmt) != GIMPLE_PHI)
    1969          259 :         return false;
    1970          259 :     }
    1971              : 
    1972         5071 :   *op0 = r_op1; *op1 = r_op2;
    1973         5071 :   *reduc = stmt;
    1974         5071 :   return true;
    1975              : }
    1976              : 
    1977              : /* Converts conditional scalar reduction into unconditional form, e.g.
    1978              :      bb_4
    1979              :        if (_5 != 0) goto bb_5 else goto bb_6
    1980              :      end_bb_4
    1981              :      bb_5
    1982              :        res_6 = res_13 + 1;
    1983              :      end_bb_5
    1984              :      bb_6
    1985              :        # res_2 = PHI <res_13(4), res_6(5)>
    1986              :      end_bb_6
    1987              : 
    1988              :    will be converted into sequence
    1989              :     _ifc__1 = _5 != 0 ? 1 : 0;
    1990              :     res_2 = res_13 + _ifc__1;
    1991              :   Argument SWAP tells that arguments of conditional expression should be
    1992              :   swapped.
    1993              :   We can assume that we versioned the loop for vectorization, so can
    1994              :   create a COND_OP.
    1995              :   Returns rhs of resulting PHI assignment.  */
    1996              : 
    1997              : static tree
    1998         5071 : convert_scalar_cond_reduction (gimple *reduc, gimple_stmt_iterator *gsi,
    1999              :                                tree cond, tree op0, tree op1, bool swap,
    2000              :                                bool has_nop, gimple* nop_reduc)
    2001              : {
    2002         5071 :   gimple_stmt_iterator stmt_it;
    2003         5071 :   gimple *new_assign;
    2004         5071 :   tree rhs;
    2005         5071 :   tree rhs1 = gimple_assign_rhs1 (reduc);
    2006         5071 :   tree lhs = gimple_assign_lhs (reduc);
    2007         5071 :   tree tmp = make_temp_ssa_name (TREE_TYPE (rhs1), NULL, "_ifc_");
    2008         5071 :   tree c;
    2009         5071 :   enum tree_code reduction_op  = gimple_assign_rhs_code (reduc);
    2010         5071 :   tree op_nochange = neutral_op_for_reduction (TREE_TYPE (rhs1), reduction_op,
    2011              :                                                NULL, false);
    2012         5071 :   gimple_seq stmts = NULL;
    2013              : 
    2014         5071 :   if (dump_file && (dump_flags & TDF_DETAILS))
    2015              :     {
    2016            2 :       fprintf (dump_file, "Found cond scalar reduction.\n");
    2017            2 :       print_gimple_stmt (dump_file, reduc, 0, TDF_SLIM);
    2018              :     }
    2019              : 
    2020              :   /* If possible create a COND_OP instead of a COND_EXPR and an OP_EXPR.
    2021              :      The COND_OP will have a neutral_op else value.  */
    2022         5071 :   internal_fn ifn;
    2023         5071 :   ifn = get_conditional_internal_fn (reduction_op);
    2024         5071 :   if (ifn != IFN_LAST
    2025         5071 :       && vectorized_internal_fn_supported_p (ifn, TREE_TYPE (lhs))
    2026         1363 :       && !VECTOR_TYPE_P (TREE_TYPE (lhs))
    2027         6434 :       && !swap)
    2028              :     {
    2029         1343 :       gcall *cond_call = gimple_build_call_internal (ifn, 4,
    2030              :                                                      unshare_expr (cond),
    2031              :                                                      op0, op1, op0);
    2032         1343 :       gsi_insert_before (gsi, cond_call, GSI_SAME_STMT);
    2033         1343 :       gimple_call_set_lhs (cond_call, tmp);
    2034              :       rhs = tmp;
    2035              :     }
    2036              :   else
    2037              :     {
    2038              :       /* Build cond expression using COND and constant operand
    2039              :          of reduction rhs.  */
    2040         7192 :       c = fold_build_cond_expr (TREE_TYPE (rhs1),
    2041              :                                 unshare_expr (cond),
    2042              :                                 swap ? op_nochange : op1,
    2043              :                                 swap ? op1 : op_nochange);
    2044              :       /* Create assignment stmt and insert it at GSI.  */
    2045         3728 :       new_assign = gimple_build_assign (tmp, c);
    2046         3728 :       gsi_insert_before (gsi, new_assign, GSI_SAME_STMT);
    2047              :       /* Build rhs for unconditional increment/decrement/logic_operation.  */
    2048         3728 :       rhs = gimple_build (&stmts, reduction_op,
    2049         3728 :                           TREE_TYPE (rhs1), op0, tmp);
    2050              :     }
    2051              : 
    2052         5071 :   if (has_nop)
    2053              :     {
    2054          126 :       rhs = gimple_convert (&stmts,
    2055          126 :                             TREE_TYPE (gimple_assign_lhs (nop_reduc)), rhs);
    2056          126 :       stmt_it = gsi_for_stmt (nop_reduc);
    2057          126 :       gsi_remove (&stmt_it, true);
    2058          126 :       release_defs (nop_reduc);
    2059              :     }
    2060         5071 :   gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
    2061              : 
    2062              :   /* Delete original reduction stmt.  */
    2063         5071 :   stmt_it = gsi_for_stmt (reduc);
    2064         5071 :   gsi_remove (&stmt_it, true);
    2065         5071 :   release_defs (reduc);
    2066         5071 :   return rhs;
    2067              : }
    2068              : 
    2069              : /* Generate a simplified conditional.  */
    2070              : 
    2071              : static tree
    2072        53583 : gen_simplified_condition (tree cond, scalar_cond_masked_set_type &cond_set)
    2073              : {
    2074              :   /* Check if the value is already live in a previous branch.  This resolves
    2075              :      nested conditionals from diamond PHI reductions.  */
    2076        53583 :   if (TREE_CODE (cond) == SSA_NAME)
    2077              :     {
    2078        53575 :       gimple *stmt = SSA_NAME_DEF_STMT (cond);
    2079        53575 :       gassign *assign = NULL;
    2080        53575 :       if ((assign = as_a <gassign *> (stmt))
    2081        53575 :            && gimple_assign_rhs_code (assign) == BIT_AND_EXPR)
    2082              :         {
    2083         3573 :           tree arg1 = gimple_assign_rhs1 (assign);
    2084         3573 :           tree arg2 = gimple_assign_rhs2 (assign);
    2085         3573 :           if (cond_set.contains ({ arg1, 1 }))
    2086          162 :             arg1 = boolean_true_node;
    2087              :           else
    2088         3411 :             arg1 = gen_simplified_condition (arg1, cond_set);
    2089              : 
    2090         3573 :           if (cond_set.contains ({ arg2, 1 }))
    2091         1788 :             arg2 = boolean_true_node;
    2092              :           else
    2093         1785 :             arg2 = gen_simplified_condition (arg2, cond_set);
    2094              : 
    2095         3573 :           cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, arg1, arg2);
    2096              :         }
    2097              :     }
    2098        53583 :   return cond;
    2099              : }
    2100              : 
    2101              : /* Structure used to track meta-data on PHI arguments used to generate
    2102              :    most efficient comparison sequence to slatten a PHI node.  */
    2103              : 
    2104              : typedef struct ifcvt_arg_entry
    2105              : {
    2106              :   /* The PHI node argument value.  */
    2107              :   tree arg;
    2108              : 
    2109              :   /* The number of compares required to reach this PHI node from start of the
    2110              :      BB being if-converted.  */
    2111              :   unsigned num_compares;
    2112              : 
    2113              :   /* The number of times this PHI node argument appears in the current PHI
    2114              :      node.  */
    2115              :   unsigned occurs;
    2116              : 
    2117              :   /* The indices at which this PHI arg occurs inside the PHI node.  */
    2118              :   vec <int> *indexes;
    2119              : } ifcvt_arg_entry_t;
    2120              : 
    2121              : /* Produce condition for all occurrences of ARG in PHI node.  Set *INVERT
    2122              :    as to whether the condition is inverted.  */
    2123              : 
    2124              : static tree
    2125         4253 : gen_phi_arg_condition (gphi *phi, ifcvt_arg_entry_t &arg,
    2126              :                        gimple_stmt_iterator *gsi,
    2127              :                        scalar_cond_masked_set_type &cond_set, bool *invert)
    2128              : {
    2129         4253 :   int len;
    2130         4253 :   int i;
    2131         4253 :   tree cond = NULL_TREE;
    2132         4253 :   tree c;
    2133         4253 :   edge e;
    2134              : 
    2135         4253 :   *invert = false;
    2136         4253 :   len = arg.indexes->length ();
    2137         4253 :   gcc_assert (len > 0);
    2138         8564 :   for (i = 0; i < len; i++)
    2139              :     {
    2140         4311 :       e = gimple_phi_arg_edge (phi, (*arg.indexes)[i]);
    2141         4311 :       c = bb_predicate (e->src);
    2142         4311 :       if (is_true_predicate (c))
    2143              :         {
    2144            0 :           cond = c;
    2145            0 :           break;
    2146              :         }
    2147              :       /* If we have just a single inverted predicate, signal that and
    2148              :          instead invert the COND_EXPR arms.  */
    2149         4311 :       if (len == 1 && TREE_CODE (c) == TRUTH_NOT_EXPR)
    2150              :         {
    2151           93 :           c = TREE_OPERAND (c, 0);
    2152           93 :           *invert = true;
    2153              :         }
    2154              : 
    2155         4311 :       c = gen_simplified_condition (c, cond_set);
    2156         4311 :       c = force_gimple_operand_gsi (gsi, unshare_expr (c),
    2157              :                                     true, NULL_TREE, true, GSI_SAME_STMT);
    2158         4311 :       if (cond != NULL_TREE)
    2159              :         {
    2160              :           /* Must build OR expression.  */
    2161           58 :           cond = fold_or_predicates (EXPR_LOCATION (c), c, cond);
    2162           58 :           cond = force_gimple_operand_gsi (gsi, unshare_expr (cond), true,
    2163              :                                            NULL_TREE, true, GSI_SAME_STMT);
    2164              :         }
    2165              :       else
    2166              :         cond = c;
    2167              : 
    2168              :       /* Register the new possibly simplified conditional.  When more than 2
    2169              :          entries in a phi node we chain entries in the false branch, so the
    2170              :          inverted condition is active.  */
    2171         4311 :       scalar_cond_masked_key pred_cond ({ cond, 1 });
    2172         4311 :       if (!*invert)
    2173         4218 :         pred_cond.inverted_p = !pred_cond.inverted_p;
    2174         4311 :       cond_set.add (pred_cond);
    2175              :     }
    2176         4253 :   gcc_assert (cond != NULL_TREE);
    2177         4253 :   return cond;
    2178              : }
    2179              : 
    2180              : /* Factors out an operation from *ARG0 and *ARG1 and
    2181              :    create the new statement at GSI. *RES is the
    2182              :    result of that new statement. Update *ARG0 and *ARG1
    2183              :    and *RES to the new values if the factoring happened.
    2184              :    Loops until all of the factoring is completed.  */
    2185              : 
    2186              : static void
    2187        44076 : factor_out_operators (tree *res, gimple_stmt_iterator *gsi,
    2188              :                       tree *arg0, tree *arg1, gphi *phi)
    2189              : {
    2190        44076 :   gimple_match_op arg0_op, arg1_op;
    2191        44076 :   bool repeated = false;
    2192              : 
    2193        44792 : again:
    2194        44792 :   if (TREE_CODE (*arg0) != SSA_NAME || TREE_CODE (*arg1) != SSA_NAME)
    2195              :     return;
    2196              : 
    2197        33170 :   if (operand_equal_p (*arg0, *arg1))
    2198              :     return;
    2199              : 
    2200              :   /* If either args have > 1 use, then this transformation actually
    2201              :      increases the number of expressions evaluated at runtime.  */
    2202        33170 :   if (repeated
    2203        33170 :       ? (!has_zero_uses (*arg0) || !has_zero_uses (*arg1))
    2204        32504 :       : (!has_single_use (*arg0) || !has_single_use (*arg1)))
    2205              :     return;
    2206              : 
    2207         5689 :   gimple *arg0_def_stmt = SSA_NAME_DEF_STMT (*arg0);
    2208         5689 :   if (!gimple_extract_op (arg0_def_stmt, &arg0_op))
    2209              :     return;
    2210              : 
    2211              :   /* Might pick up abnormals from previous bbs so stop the loop.  */
    2212         2307 :   if (arg0_op.operands_occurs_in_abnormal_phi ())
    2213              :     return;
    2214              : 
    2215         2305 :   gimple *arg1_def_stmt = SSA_NAME_DEF_STMT (*arg1);
    2216         2305 :   if (!gimple_extract_op (arg1_def_stmt, &arg1_op))
    2217              :     return;
    2218              : 
    2219              :   /* Might pick up abnormals from previous bbs so stop the loop.  */
    2220         1986 :   if (arg1_op.operands_occurs_in_abnormal_phi ())
    2221              :     return;
    2222              : 
    2223              :   /* No factoring can happen if the codes are different
    2224              :      or the number operands.  */
    2225         1986 :   if (arg1_op.code != arg0_op.code
    2226         1986 :       || arg1_op.num_ops != arg0_op.num_ops)
    2227              :     return;
    2228              : 
    2229         1005 :   tree new_arg0, new_arg1;
    2230         1005 :   int opnum = find_different_opnum (arg0_op, arg1_op, &new_arg0, &new_arg1);
    2231         1005 :   if (opnum == -1)
    2232              :     return;
    2233              : 
    2234          737 :   tree args[2] = { new_arg0, new_arg1 };
    2235          737 :   location_t locs[2];
    2236          737 :   locs[0] = gimple_location (arg0_def_stmt);
    2237          737 :   locs[1] = gimple_location (arg1_def_stmt);
    2238          737 :   if (!factor_operation_ok (arg1_op.code, opnum, args, locs, 2, true, true))
    2239              :     return;
    2240              : 
    2241          716 :   tree new_res = make_ssa_name (TREE_TYPE (new_arg0), NULL);
    2242              : 
    2243              :   /* Create the operation stmt if possible and insert it.  */
    2244              : 
    2245          716 :   gimple_match_op new_op = arg0_op;
    2246          716 :   new_op.ops[opnum] = new_res;
    2247          716 :   gimple_seq seq = NULL;
    2248          716 :   tree result = *res;
    2249          716 :   result = maybe_push_res_to_seq (&new_op, &seq, result);
    2250              : 
    2251              :   /* If we can't create the new statement, release the temp name
    2252              :      and return back.  */
    2253          716 :   if (!result)
    2254              :     {
    2255            0 :       release_ssa_name (new_res);
    2256            0 :       return;
    2257              :     }
    2258          716 :   gsi_insert_seq_before (gsi, seq, GSI_CONTINUE_LINKING);
    2259              : 
    2260          716 :   if (dump_file && (dump_flags & TDF_DETAILS))
    2261              :     {
    2262            1 :       fprintf (dump_file, "PHI ");
    2263            1 :       print_generic_expr (dump_file, gimple_phi_result (phi));
    2264            1 :       fprintf (dump_file,
    2265              :                " changed to factor operation out from COND_EXPR.\n");
    2266            1 :       fprintf (dump_file, "New stmt with OPERATION that defines ");
    2267            1 :       print_generic_expr (dump_file, result);
    2268            1 :       fprintf (dump_file, ".\n");
    2269              :     }
    2270              : 
    2271              :   /* Remove the old operation(s) that has single use.  */
    2272          716 :   gimple_stmt_iterator gsi_for_def;
    2273              : 
    2274          716 :   gsi_for_def = gsi_for_stmt (arg0_def_stmt);
    2275          716 :   gsi_remove (&gsi_for_def, true);
    2276          716 :   release_defs (arg0_def_stmt);
    2277          716 :   gsi_for_def = gsi_for_stmt (arg1_def_stmt);
    2278          716 :   gsi_remove (&gsi_for_def, true);
    2279          716 :   release_defs (arg1_def_stmt);
    2280              : 
    2281              :   /* Update the arguments and try again.  */
    2282          716 :   *arg0 = new_arg0;
    2283          716 :   *arg1 = new_arg1;
    2284          716 :   *res = new_res;
    2285              : 
    2286              :   /* Update the phi node too. */
    2287          716 :   gimple_phi_set_result (phi, new_res);
    2288          716 :   gimple_phi_arg (phi, 0)->def = new_arg0;
    2289          716 :   gimple_phi_arg (phi, 1)->def = new_arg1;
    2290          716 :   update_stmt (phi);
    2291              : 
    2292          716 :   repeated = true;
    2293          716 :   goto again;
    2294              : }
    2295              : 
    2296              : /* Create the smallest nested conditional possible.  On pre-order we record
    2297              :    which conditionals are live, and on post-order rewrite the chain by removing
    2298              :    already active conditions.
    2299              : 
    2300              :    As an example we simplify:
    2301              : 
    2302              :   _7 = a_10 < 0;
    2303              :   _21 = a_10 >= 0;
    2304              :   _22 = a_10 < e_11(D);
    2305              :   _23 = _21 & _22;
    2306              :   _ifc__42 = _23 ? t_13 : 0;
    2307              :   t_6 = _7 ? 1 : _ifc__42
    2308              : 
    2309              :   into
    2310              : 
    2311              :   _7 = a_10 < 0;
    2312              :   _22 = a_10 < e_11(D);
    2313              :   _ifc__42 = _22 ? t_13 : 0;
    2314              :   t_6 = _7 ? 1 : _ifc__42;
    2315              : 
    2316              :   which produces better code.  */
    2317              : 
    2318              : static tree
    2319         6377 : gen_phi_nest_statement (gphi *phi, gimple_stmt_iterator *gsi,
    2320              :                         scalar_cond_masked_set_type &cond_set, tree type,
    2321              :                         gimple **res_stmt, tree lhs0,
    2322              :                         vec<struct ifcvt_arg_entry> &args, unsigned idx)
    2323              : {
    2324        12754 :   if (idx == args.length ())
    2325         2124 :     return args[idx - 1].arg;
    2326              : 
    2327         4253 :   bool invert;
    2328         4253 :   tree cond = gen_phi_arg_condition (phi, args[idx - 1], gsi, cond_set,
    2329              :                                      &invert);
    2330         4253 :   tree arg1 = gen_phi_nest_statement (phi, gsi, cond_set, type, res_stmt, lhs0,
    2331              :                                       args, idx + 1);
    2332              : 
    2333         4253 :   unsigned prev = idx;
    2334         4253 :   unsigned curr = prev - 1;
    2335         4253 :   tree arg0 = args[curr].arg;
    2336         4253 :   tree rhs, lhs;
    2337         4253 :   if (idx > 1)
    2338         2129 :     lhs = make_temp_ssa_name (type, NULL, "_ifc_");
    2339              :   else
    2340              :     lhs = lhs0;
    2341              : 
    2342         4253 :   if (invert)
    2343           93 :     rhs = fold_build_cond_expr (type, unshare_expr (cond),
    2344              :                                 arg1, arg0);
    2345              :   else
    2346         4160 :     rhs = fold_build_cond_expr (type, unshare_expr (cond),
    2347              :                                 arg0, arg1);
    2348         4253 :   gassign *new_stmt = gimple_build_assign (lhs, rhs);
    2349         4253 :   gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
    2350         4253 :   update_stmt (new_stmt);
    2351         4253 :   *res_stmt = new_stmt;
    2352         4253 :   return lhs;
    2353              : }
    2354              : 
    2355              : /* When flattening a PHI node we have a choice of which conditions to test to
    2356              :    for all the paths from the start of the dominator block of the BB with the
    2357              :    PHI node.  If the PHI node has X arguments we have to only test X - 1
    2358              :    conditions as the last one is implicit.  It does matter which conditions we
    2359              :    test first.  We should test the shortest condition first (distance here is
    2360              :    measures in the number of logical operators in the condition) and the
    2361              :    longest one last.  This allows us to skip testing the most expensive
    2362              :    condition.  To accomplish this we need to sort the conditions.  P1 and P2
    2363              :    are sorted first based on the number of logical operations (num_compares)
    2364              :    and then by how often they occur in the PHI node.  */
    2365              : 
    2366              : static int
    2367        36416 : cmp_arg_entry (const void *p1, const void *p2, void * /* data.  */)
    2368              : {
    2369        36416 :   const ifcvt_arg_entry sval1 = *(const ifcvt_arg_entry *)p1;
    2370        36416 :   const ifcvt_arg_entry sval2 = *(const ifcvt_arg_entry *)p2;
    2371              : 
    2372        36416 :   if (sval1.num_compares < sval2.num_compares)
    2373              :     return -1;
    2374        12384 :   else if (sval1.num_compares > sval2.num_compares)
    2375              :     return 1;
    2376              : 
    2377          648 :   if (sval1.occurs < sval2.occurs)
    2378              :     return -1;
    2379          648 :   else if (sval1.occurs > sval2.occurs)
    2380            0 :     return 1;
    2381              : 
    2382              :   return 0;
    2383              : }
    2384              : 
    2385              : /* Replace a scalar PHI node with a COND_EXPR using COND as condition.
    2386              :    This routine can handle PHI nodes with more than two arguments.
    2387              : 
    2388              :    For example,
    2389              :      S1: A = PHI <x1(1), x2(5)>
    2390              :    is converted into,
    2391              :      S2: A = cond ? x1 : x2;
    2392              : 
    2393              :    The generated code is inserted at GSI that points to the top of
    2394              :    basic block's statement list.
    2395              :    If PHI node has more than two arguments a chain of conditional
    2396              :    expression is produced.  */
    2397              : 
    2398              : 
    2399              : static void
    2400        49476 : predicate_scalar_phi (gphi *phi, gimple_stmt_iterator *gsi)
    2401              : {
    2402        49476 :   gimple *new_stmt = NULL, *reduc, *nop_reduc;
    2403        49476 :   tree rhs, res, arg0, arg1, op0, op1, scev;
    2404        49476 :   tree cond;
    2405        49476 :   unsigned int index0;
    2406        49476 :   edge e;
    2407        49476 :   basic_block bb;
    2408        49476 :   unsigned int i;
    2409        49476 :   bool has_nop;
    2410              : 
    2411        49476 :   res = gimple_phi_result (phi);
    2412        98952 :   if (virtual_operand_p (res))
    2413        44135 :     return;
    2414              : 
    2415        49476 :   if ((rhs = degenerate_phi_result (phi))
    2416        49476 :       || ((scev = analyze_scalar_evolution (gimple_bb (phi)->loop_father,
    2417              :                                             res))
    2418        49434 :           && !chrec_contains_undetermined (scev)
    2419        49434 :           && scev != res
    2420           17 :           && (rhs = gimple_phi_arg_def (phi, 0))))
    2421              :     {
    2422           59 :       if (dump_file && (dump_flags & TDF_DETAILS))
    2423              :         {
    2424            0 :           fprintf (dump_file, "Degenerate phi!\n");
    2425            0 :           print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
    2426              :         }
    2427           59 :       new_stmt = gimple_build_assign (res, rhs);
    2428           59 :       gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
    2429           59 :       update_stmt (new_stmt);
    2430           59 :       return;
    2431              :     }
    2432              : 
    2433        49417 :   bb = gimple_bb (phi);
    2434              :   /* Keep track of conditionals already seen.  */
    2435        49417 :   scalar_cond_masked_set_type cond_set;
    2436        49417 :   if (EDGE_COUNT (bb->preds) == 2)
    2437              :     {
    2438              :       /* Predicate ordinary PHI node with 2 arguments.  */
    2439        44076 :       edge first_edge, second_edge;
    2440        44076 :       basic_block true_bb;
    2441        44076 :       first_edge = EDGE_PRED (bb, 0);
    2442        44076 :       second_edge = EDGE_PRED (bb, 1);
    2443        44076 :       cond = bb_predicate (first_edge->src);
    2444        44076 :       cond_set.add ({ cond, 1 });
    2445        44076 :       if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
    2446        22846 :         std::swap (first_edge, second_edge);
    2447        44076 :       if (EDGE_COUNT (first_edge->src->succs) > 1)
    2448              :         {
    2449        19630 :           cond = bb_predicate (second_edge->src);
    2450        19630 :           if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
    2451        10472 :             cond = TREE_OPERAND (cond, 0);
    2452              :           else
    2453              :             first_edge = second_edge;
    2454              :         }
    2455              :       else
    2456        24446 :         cond = bb_predicate (first_edge->src);
    2457              : 
    2458              :       /* Gimplify the condition to a valid cond-expr conditional operand.  */
    2459        44076 :       cond = gen_simplified_condition (cond, cond_set);
    2460        44076 :       cond = force_gimple_operand_gsi (gsi, unshare_expr (cond), true,
    2461              :                                        NULL_TREE, true, GSI_SAME_STMT);
    2462        44076 :       true_bb = first_edge->src;
    2463        44076 :       if (EDGE_PRED (bb, 1)->src == true_bb)
    2464              :         {
    2465        32004 :           arg0 = gimple_phi_arg_def (phi, 1);
    2466        32004 :           arg1 = gimple_phi_arg_def (phi, 0);
    2467              :         }
    2468              :       else
    2469              :         {
    2470        12072 :           arg0 = gimple_phi_arg_def (phi, 0);
    2471        12072 :           arg1 = gimple_phi_arg_def (phi, 1);
    2472              :         }
    2473              : 
    2474              :       /* Factor out operand if possible. This can only be done easily
    2475              :          for PHI with 2 elements.  */
    2476        44076 :       factor_out_operators (&res, gsi, &arg0, &arg1, phi);
    2477              : 
    2478        44076 :       if (is_cond_scalar_reduction (phi, &reduc, arg0, arg1,
    2479              :                                     &op0, &op1, false, &has_nop,
    2480              :                                     &nop_reduc))
    2481              :         {
    2482              :           /* Convert reduction stmt into vectorizable form.  */
    2483         8226 :           rhs = convert_scalar_cond_reduction (reduc, gsi, cond, op0, op1,
    2484         4113 :                                                true_bb != gimple_bb (reduc),
    2485              :                                                has_nop, nop_reduc);
    2486         4113 :           redundant_ssa_names.safe_push (std::make_pair (res, rhs));
    2487              :         }
    2488              :       else
    2489              :         /* Build new RHS using selected condition and arguments.  */
    2490        39963 :         rhs = fold_build_cond_expr (TREE_TYPE (res), unshare_expr (cond),
    2491              :                                     arg0, arg1);
    2492        44076 :       new_stmt = gimple_build_assign (res, rhs);
    2493        44076 :       gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
    2494        44076 :       gimple_stmt_iterator new_gsi = gsi_for_stmt (new_stmt);
    2495        44076 :       if (fold_stmt (&new_gsi, follow_all_ssa_edges))
    2496              :         {
    2497         1563 :           new_stmt = gsi_stmt (new_gsi);
    2498         1563 :           update_stmt (new_stmt);
    2499              :         }
    2500              : 
    2501        44076 :       if (dump_file && (dump_flags & TDF_DETAILS))
    2502              :         {
    2503           16 :           fprintf (dump_file, "new phi replacement stmt\n");
    2504           16 :           print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM);
    2505              :         }
    2506        44076 :       return;
    2507              :     }
    2508              : 
    2509              :   /* Create hashmap for PHI node which contain vector of argument indexes
    2510              :      having the same value.  */
    2511         5341 :   bool swap = false;
    2512         5341 :   hash_map<tree_operand_hash, auto_vec<int> > phi_arg_map;
    2513         5341 :   unsigned int num_args = gimple_phi_num_args (phi);
    2514              :   /* Vector of different PHI argument values.  */
    2515         5341 :   auto_vec<ifcvt_arg_entry_t> args;
    2516              : 
    2517              :   /* Compute phi_arg_map, determine the list of unique PHI args and the indices
    2518              :      where they are in the PHI node.  The indices will be used to determine
    2519              :      the conditions to apply and their complexity.  */
    2520        21633 :   for (i = 0; i < num_args; i++)
    2521              :     {
    2522        16292 :       tree arg;
    2523              : 
    2524        16292 :       arg = gimple_phi_arg_def (phi, i);
    2525        16292 :       if (!phi_arg_map.get (arg))
    2526        12811 :         args.safe_push ({ arg, 0, 0, NULL });
    2527        16292 :       phi_arg_map.get_or_insert (arg).safe_push (i);
    2528              :     }
    2529              : 
    2530              :   /* Determine element with max number of occurrences and complexity.  Looking
    2531              :      at only number of occurrences as a measure for complexity isn't enough as
    2532              :      all usages can be unique but the comparisons to reach the PHI node differ
    2533              :      per branch.  */
    2534        18152 :   for (unsigned i = 0; i < args.length (); i++)
    2535              :     {
    2536        12811 :       unsigned int len = 0;
    2537        12811 :       vec<int> *indices = phi_arg_map.get (args[i].arg);
    2538        54725 :       for (int index : *indices)
    2539              :         {
    2540        16292 :           edge e = gimple_phi_arg_edge (phi, index);
    2541        16292 :           len += get_bb_num_predicate_stmts (e->src);
    2542              :         }
    2543              : 
    2544        12811 :       unsigned occur = indices->length ();
    2545        12811 :       if (dump_file && (dump_flags & TDF_DETAILS))
    2546            7 :         fprintf (dump_file, "Ranking %d as len=%d, idx=%d\n", i, len, occur);
    2547        12811 :       args[i].num_compares = len;
    2548        12811 :       args[i].occurs = occur;
    2549        12811 :       args[i].indexes = indices;
    2550              :     }
    2551              : 
    2552              :   /* Sort elements based on rankings ARGS.  */
    2553         5341 :   args.stablesort (cmp_arg_entry, NULL);
    2554              : 
    2555              :   /* Handle one special case when number of arguments with different values
    2556              :      is equal 2 and one argument has the only occurrence.  Such PHI can be
    2557              :      handled as if would have only 2 arguments.  */
    2558         5341 :   if (args.length () == 2
    2559         8616 :       && args[0].indexes->length () == 1)
    2560              :     {
    2561         3217 :       index0 = (*args[0].indexes)[0];
    2562         3217 :       arg0 = args[0].arg;
    2563         3217 :       arg1 = args[1].arg;
    2564         3217 :       e = gimple_phi_arg_edge (phi, index0);
    2565         3217 :       cond = bb_predicate (e->src);
    2566         3217 :       if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
    2567              :         {
    2568           36 :           swap = true;
    2569           36 :           cond = TREE_OPERAND (cond, 0);
    2570              :         }
    2571              :       /* Gimplify the condition to a valid cond-expr conditional operand.  */
    2572         3217 :       cond = force_gimple_operand_gsi (gsi, unshare_expr (cond), true,
    2573              :                                        NULL_TREE, true, GSI_SAME_STMT);
    2574         3217 :       if (!(is_cond_scalar_reduction (phi, &reduc, arg0 , arg1,
    2575              :                                       &op0, &op1, true, &has_nop, &nop_reduc)))
    2576         4484 :         rhs = fold_build_cond_expr (TREE_TYPE (res), unshare_expr (cond),
    2577              :                                     swap ? arg1 : arg0,
    2578              :                                     swap ? arg0 : arg1);
    2579              :       else
    2580              :         {
    2581              :           /* Convert reduction stmt into vectorizable form.  */
    2582          958 :           rhs = convert_scalar_cond_reduction (reduc, gsi, cond, op0, op1,
    2583              :                                                swap, has_nop, nop_reduc);
    2584          958 :           redundant_ssa_names.safe_push (std::make_pair (res, rhs));
    2585              :         }
    2586         3217 :       new_stmt = gimple_build_assign (res, rhs);
    2587         3217 :       gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
    2588         3217 :       update_stmt (new_stmt);
    2589              :     }
    2590              :   else
    2591              :     {
    2592              :       /* Common case.  */
    2593         2124 :       tree type = TREE_TYPE (gimple_phi_result (phi));
    2594         2124 :       gen_phi_nest_statement (phi, gsi, cond_set, type, &new_stmt, res,
    2595              :                               args, 1);
    2596              :     }
    2597              : 
    2598         5341 :   if (dump_file && (dump_flags & TDF_DETAILS))
    2599              :     {
    2600            3 :       fprintf (dump_file, "new extended phi replacement stmt\n");
    2601            3 :       print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM);
    2602              :     }
    2603        49417 : }
    2604              : 
    2605              : /* Replaces in LOOP all the scalar phi nodes other than those in the
    2606              :    LOOP->header block with conditional modify expressions.  */
    2607              : 
    2608              : static void
    2609        25536 : predicate_all_scalar_phis (class loop *loop)
    2610              : {
    2611        25536 :   basic_block bb;
    2612        25536 :   unsigned int orig_loop_num_nodes = loop->num_nodes;
    2613        25536 :   unsigned int i;
    2614              : 
    2615       134310 :   for (i = 1; i < orig_loop_num_nodes; i++)
    2616              :     {
    2617       108774 :       gphi *phi;
    2618       108774 :       gimple_stmt_iterator gsi;
    2619       108774 :       gphi_iterator phi_gsi;
    2620       108774 :       bb = ifc_bbs[i];
    2621              : 
    2622       108774 :       if (bb == loop->header)
    2623        78124 :         continue;
    2624              : 
    2625       108774 :       phi_gsi = gsi_start_phis (bb);
    2626       108774 :       if (gsi_end_p (phi_gsi))
    2627        78124 :         continue;
    2628              : 
    2629        30650 :       gsi = gsi_after_labels (bb);
    2630        82472 :       while (!gsi_end_p (phi_gsi))
    2631              :         {
    2632        51822 :           phi = phi_gsi.phi ();
    2633       103644 :           if (virtual_operand_p (gimple_phi_result (phi)))
    2634         2346 :             gsi_next (&phi_gsi);
    2635              :           else
    2636              :             {
    2637        49476 :               predicate_scalar_phi (phi, &gsi);
    2638        49476 :               remove_phi_node (&phi_gsi, false);
    2639              :             }
    2640              :         }
    2641              :     }
    2642        25536 : }
    2643              : 
    2644              : /* Insert in each basic block of LOOP the statements produced by the
    2645              :    gimplification of the predicates.  */
    2646              : 
    2647              : static void
    2648        25536 : insert_gimplified_predicates (loop_p loop)
    2649              : {
    2650        25536 :   unsigned int i;
    2651              : 
    2652       159846 :   for (i = 0; i < loop->num_nodes; i++)
    2653              :     {
    2654       134310 :       basic_block bb = ifc_bbs[i];
    2655       134310 :       gimple_seq stmts;
    2656       134310 :       if (!is_predicated (bb))
    2657        80707 :         gcc_assert (bb_predicate_gimplified_stmts (bb) == NULL);
    2658       134310 :       if (!is_predicated (bb))
    2659              :         {
    2660              :           /* Do not insert statements for a basic block that is not
    2661              :              predicated.  Also make sure that the predicate of the
    2662              :              basic block is set to true.  */
    2663        80707 :           reset_bb_predicate (bb);
    2664        80707 :           continue;
    2665              :         }
    2666              : 
    2667        53603 :       stmts = bb_predicate_gimplified_stmts (bb);
    2668        53603 :       if (stmts)
    2669              :         {
    2670        53195 :           if (need_to_predicate)
    2671              :             {
    2672              :               /* Insert the predicate of the BB just after the label,
    2673              :                  as the if-conversion of memory writes will use this
    2674              :                  predicate.  */
    2675         5710 :               gimple_stmt_iterator gsi = gsi_after_labels (bb);
    2676         5710 :               gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
    2677              :             }
    2678              :           else
    2679              :             {
    2680              :               /* Insert the predicate of the BB at the end of the BB
    2681              :                  as this would reduce the register pressure: the only
    2682              :                  use of this predicate will be in successor BBs.  */
    2683        47485 :               gimple_stmt_iterator gsi = gsi_last_bb (bb);
    2684              : 
    2685        47485 :               if (gsi_end_p (gsi)
    2686        47485 :                   || stmt_ends_bb_p (gsi_stmt (gsi)))
    2687        25320 :                 gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
    2688              :               else
    2689        22165 :                 gsi_insert_seq_after (&gsi, stmts, GSI_SAME_STMT);
    2690              :             }
    2691              : 
    2692              :           /* Once the sequence is code generated, set it to NULL.  */
    2693       134310 :           set_bb_predicate_gimplified_stmts (bb, NULL, true);
    2694              :         }
    2695              :     }
    2696        25536 : }
    2697              : 
    2698              : /* Helper function for predicate_statements. Returns index of existent
    2699              :    mask if it was created for given SIZE and -1 otherwise.  */
    2700              : 
    2701              : static int
    2702          936 : mask_exists (int size, const vec<int> &vec)
    2703              : {
    2704          936 :   unsigned int ix;
    2705          936 :   int v;
    2706         1025 :   FOR_EACH_VEC_ELT (vec, ix, v)
    2707          964 :     if (v == size)
    2708          875 :       return (int) ix;
    2709              :   return -1;
    2710              : }
    2711              : 
    2712              : /* Helper function for predicate_statements.  STMT is a memory read or
    2713              :    write and it needs to be predicated by MASK.  Return a statement
    2714              :    that does so.  */
    2715              : 
    2716              : static gimple *
    2717         1992 : predicate_load_or_store (gimple_stmt_iterator *gsi, gassign *stmt, tree mask)
    2718              : {
    2719         1992 :   gcall *new_stmt;
    2720              : 
    2721         1992 :   tree lhs = gimple_assign_lhs (stmt);
    2722         1992 :   tree rhs = gimple_assign_rhs1 (stmt);
    2723         1992 :   tree ref = TREE_CODE (lhs) == SSA_NAME ? rhs : lhs;
    2724         1992 :   mark_addressable (ref);
    2725         1992 :   tree addr = force_gimple_operand_gsi (gsi, build_fold_addr_expr (ref),
    2726              :                                         true, NULL_TREE, true, GSI_SAME_STMT);
    2727         1992 :   tree ptr = build_int_cst (reference_alias_ptr_type (ref),
    2728         1992 :                             get_object_alignment (ref));
    2729              :   /* Copy points-to info if possible.  */
    2730         1992 :   if (TREE_CODE (addr) == SSA_NAME && !SSA_NAME_PTR_INFO (addr))
    2731          599 :     copy_ref_info (build2 (MEM_REF, TREE_TYPE (ref), addr, ptr),
    2732              :                    ref);
    2733         1992 :   if (TREE_CODE (lhs) == SSA_NAME)
    2734              :     {
    2735              :       /* Get a zero else value.  This might not be what a target actually uses
    2736              :          but we cannot be sure about which vector mode the vectorizer will
    2737              :          choose.  Therefore, leave the decision whether we need to force the
    2738              :          inactive elements to zero to the vectorizer.  */
    2739         1159 :       tree els = vect_get_mask_load_else (MASK_LOAD_ELSE_ZERO,
    2740         1159 :                                           TREE_TYPE (lhs));
    2741              : 
    2742         1159 :       new_stmt
    2743         1159 :         = gimple_build_call_internal (IFN_MASK_LOAD, 4, addr,
    2744              :                                       ptr, mask, els);
    2745              : 
    2746         1159 :       gimple_call_set_lhs (new_stmt, lhs);
    2747         2318 :       gimple_set_vuse (new_stmt, gimple_vuse (stmt));
    2748              :     }
    2749              :   else
    2750              :     {
    2751          833 :       new_stmt
    2752          833 :         = gimple_build_call_internal (IFN_MASK_STORE, 4, addr, ptr,
    2753              :                                       mask, rhs);
    2754          833 :       gimple_move_vops (new_stmt, stmt);
    2755              :     }
    2756         1992 :   gimple_call_set_nothrow (new_stmt, true);
    2757         1992 :   return new_stmt;
    2758              : }
    2759              : 
    2760              : /* STMT uses OP_LHS.  Check whether it is equivalent to:
    2761              : 
    2762              :      ... = OP_MASK ? OP_LHS : X;
    2763              : 
    2764              :    Return X if so, otherwise return null.  OP_MASK is an SSA_NAME that is
    2765              :    known to have value OP_COND.  */
    2766              : 
    2767              : static tree
    2768          824 : check_redundant_cond_expr (gimple *stmt, tree op_mask, tree op_cond,
    2769              :                            tree op_lhs)
    2770              : {
    2771          824 :   gassign *assign = dyn_cast <gassign *> (stmt);
    2772         1034 :   if (!assign || gimple_assign_rhs_code (assign) != COND_EXPR)
    2773              :     return NULL_TREE;
    2774              : 
    2775          203 :   tree use_cond = gimple_assign_rhs1 (assign);
    2776          203 :   tree if_true = gimple_assign_rhs2 (assign);
    2777          203 :   tree if_false = gimple_assign_rhs3 (assign);
    2778              : 
    2779           72 :   if ((use_cond == op_mask || operand_equal_p (use_cond, op_cond, 0))
    2780          203 :       && if_true == op_lhs)
    2781              :     return if_false;
    2782              : 
    2783           72 :   if (inverse_conditions_p (use_cond, op_cond) && if_false == op_lhs)
    2784            0 :     return if_true;
    2785              : 
    2786              :   return NULL_TREE;
    2787              : }
    2788              : 
    2789              : /* Return true if VALUE is available for use at STMT.  SSA_NAMES is
    2790              :    the set of SSA names defined earlier in STMT's block.  */
    2791              : 
    2792              : static bool
    2793          131 : value_available_p (gimple *stmt, hash_set<tree_ssa_name_hash> *ssa_names,
    2794              :                    tree value)
    2795              : {
    2796          131 :   if (is_gimple_min_invariant (value))
    2797              :     return true;
    2798              : 
    2799           95 :   if (TREE_CODE (value) == SSA_NAME)
    2800              :     {
    2801           95 :       if (SSA_NAME_IS_DEFAULT_DEF (value))
    2802              :         return true;
    2803              : 
    2804           95 :       basic_block def_bb = gimple_bb (SSA_NAME_DEF_STMT (value));
    2805           95 :       basic_block use_bb = gimple_bb (stmt);
    2806           95 :       return (def_bb == use_bb
    2807           95 :               ? ssa_names->contains (value)
    2808           95 :               : dominated_by_p (CDI_DOMINATORS, use_bb, def_bb));
    2809              :     }
    2810              : 
    2811              :   return false;
    2812              : }
    2813              : 
    2814              : /* Helper function for predicate_statements.  STMT is a potentially-trapping
    2815              :    arithmetic operation that needs to be predicated by MASK, an SSA_NAME that
    2816              :    has value COND.  Return a statement that does so.  SSA_NAMES is the set of
    2817              :    SSA names defined earlier in STMT's block.  */
    2818              : 
    2819              : static gimple *
    2820          619 : predicate_rhs_code (gimple *stmt, tree mask, tree cond,
    2821              :                     hash_set<tree_ssa_name_hash> *ssa_names)
    2822              : {
    2823          619 :   internal_fn cond_fn;
    2824          619 :   if (is_gimple_assign (stmt))
    2825              :     {
    2826          511 :       tree_code code = gimple_assign_rhs_code (stmt);
    2827          511 :       cond_fn = get_conditional_internal_fn (code);
    2828              :     }
    2829          108 :   else if (tree callee = gimple_call_fndecl (stmt))
    2830              :     {
    2831          108 :       auto ifn = associated_internal_fn (callee);
    2832          108 :       cond_fn = get_conditional_internal_fn (ifn);
    2833              :     }
    2834              :   else
    2835              :     return NULL;
    2836              : 
    2837          619 :   if (cond_fn == IFN_LAST)
    2838              :     {
    2839            0 :       gcc_assert (!gimple_could_trap_p (stmt));
    2840              :       return NULL;
    2841              :     }
    2842              : 
    2843          619 :   tree lhs = gimple_get_lhs (stmt);
    2844          619 :   unsigned int nops = gimple_num_args (stmt) + 1;
    2845              : 
    2846              :   /* Construct the arguments to the conditional internal function.   */
    2847          619 :   auto_vec<tree, 8> args;
    2848          619 :   args.safe_grow (nops + 1, true);
    2849          619 :   args[0] = mask;
    2850         1965 :   for (unsigned int i = 0; i < nops - 1; ++i)
    2851         1346 :     args[i+1] = gimple_arg (stmt, i);
    2852          619 :   args[nops] = NULL_TREE;
    2853              : 
    2854              :   /* Look for uses of the result to see whether they are COND_EXPRs that can
    2855              :      be folded into the conditional call.  */
    2856          619 :   imm_use_iterator imm_iter;
    2857          619 :   gimple *use_stmt;
    2858         1443 :   FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, lhs)
    2859              :     {
    2860          824 :       tree new_else = check_redundant_cond_expr (use_stmt, mask, cond, lhs);
    2861          824 :       if (new_else && value_available_p (stmt, ssa_names, new_else))
    2862              :         {
    2863          110 :           if (!args[nops])
    2864          110 :             args[nops] = new_else;
    2865          110 :           if (operand_equal_p (new_else, args[nops], 0))
    2866              :             {
    2867              :               /* We have:
    2868              : 
    2869              :                    LHS = IFN_COND (MASK, ..., ELSE);
    2870              :                    X = MASK ? LHS : ELSE;
    2871              : 
    2872              :                  which makes X equivalent to LHS.  */
    2873          110 :               tree use_lhs = gimple_assign_lhs (use_stmt);
    2874          110 :               redundant_ssa_names.safe_push (std::make_pair (use_lhs, lhs));
    2875              :             }
    2876              :         }
    2877          619 :     }
    2878          619 :   if (!args[nops])
    2879         1018 :     args[nops] = targetm.preferred_else_value (cond_fn, TREE_TYPE (lhs),
    2880          509 :                                                nops - 1, &args[1]);
    2881              : 
    2882              :   /* Create and insert the call.  */
    2883          619 :   gcall *new_stmt = gimple_build_call_internal_vec (cond_fn, args);
    2884          619 :   gimple_call_set_lhs (new_stmt, lhs);
    2885          619 :   gimple_call_set_nothrow (new_stmt, true);
    2886              : 
    2887          619 :   return new_stmt;
    2888          619 : }
    2889              : 
    2890              : /* Predicate each write to memory in LOOP.
    2891              : 
    2892              :    This function transforms control flow constructs containing memory
    2893              :    writes of the form:
    2894              : 
    2895              :    | for (i = 0; i < N; i++)
    2896              :    |   if (cond)
    2897              :    |     A[i] = expr;
    2898              : 
    2899              :    into the following form that does not contain control flow:
    2900              : 
    2901              :    | for (i = 0; i < N; i++)
    2902              :    |   A[i] = cond ? expr : A[i];
    2903              : 
    2904              :    The original CFG looks like this:
    2905              : 
    2906              :    | bb_0
    2907              :    |   i = 0
    2908              :    | end_bb_0
    2909              :    |
    2910              :    | bb_1
    2911              :    |   if (i < N) goto bb_5 else goto bb_2
    2912              :    | end_bb_1
    2913              :    |
    2914              :    | bb_2
    2915              :    |   cond = some_computation;
    2916              :    |   if (cond) goto bb_3 else goto bb_4
    2917              :    | end_bb_2
    2918              :    |
    2919              :    | bb_3
    2920              :    |   A[i] = expr;
    2921              :    |   goto bb_4
    2922              :    | end_bb_3
    2923              :    |
    2924              :    | bb_4
    2925              :    |   goto bb_1
    2926              :    | end_bb_4
    2927              : 
    2928              :    insert_gimplified_predicates inserts the computation of the COND
    2929              :    expression at the beginning of the destination basic block:
    2930              : 
    2931              :    | bb_0
    2932              :    |   i = 0
    2933              :    | end_bb_0
    2934              :    |
    2935              :    | bb_1
    2936              :    |   if (i < N) goto bb_5 else goto bb_2
    2937              :    | end_bb_1
    2938              :    |
    2939              :    | bb_2
    2940              :    |   cond = some_computation;
    2941              :    |   if (cond) goto bb_3 else goto bb_4
    2942              :    | end_bb_2
    2943              :    |
    2944              :    | bb_3
    2945              :    |   cond = some_computation;
    2946              :    |   A[i] = expr;
    2947              :    |   goto bb_4
    2948              :    | end_bb_3
    2949              :    |
    2950              :    | bb_4
    2951              :    |   goto bb_1
    2952              :    | end_bb_4
    2953              : 
    2954              :    predicate_statements is then predicating the memory write as follows:
    2955              : 
    2956              :    | bb_0
    2957              :    |   i = 0
    2958              :    | end_bb_0
    2959              :    |
    2960              :    | bb_1
    2961              :    |   if (i < N) goto bb_5 else goto bb_2
    2962              :    | end_bb_1
    2963              :    |
    2964              :    | bb_2
    2965              :    |   if (cond) goto bb_3 else goto bb_4
    2966              :    | end_bb_2
    2967              :    |
    2968              :    | bb_3
    2969              :    |   cond = some_computation;
    2970              :    |   A[i] = cond ? expr : A[i];
    2971              :    |   goto bb_4
    2972              :    | end_bb_3
    2973              :    |
    2974              :    | bb_4
    2975              :    |   goto bb_1
    2976              :    | end_bb_4
    2977              : 
    2978              :    and finally combine_blocks removes the basic block boundaries making
    2979              :    the loop vectorizable:
    2980              : 
    2981              :    | bb_0
    2982              :    |   i = 0
    2983              :    |   if (i < N) goto bb_5 else goto bb_1
    2984              :    | end_bb_0
    2985              :    |
    2986              :    | bb_1
    2987              :    |   cond = some_computation;
    2988              :    |   A[i] = cond ? expr : A[i];
    2989              :    |   if (i < N) goto bb_5 else goto bb_4
    2990              :    | end_bb_1
    2991              :    |
    2992              :    | bb_4
    2993              :    |   goto bb_1
    2994              :    | end_bb_4
    2995              : */
    2996              : 
    2997              : static void
    2998        12036 : predicate_statements (loop_p loop)
    2999              : {
    3000        12036 :   unsigned int i, orig_loop_num_nodes = loop->num_nodes;
    3001        12036 :   auto_vec<int, 1> vect_sizes;
    3002        12036 :   auto_vec<tree, 1> vect_masks;
    3003        12036 :   hash_set<tree_ssa_name_hash> ssa_names;
    3004              : 
    3005        75202 :   for (i = 1; i < orig_loop_num_nodes; i++)
    3006              :     {
    3007        51130 :       gimple_stmt_iterator gsi;
    3008        51130 :       basic_block bb = ifc_bbs[i];
    3009        51130 :       tree cond = bb_predicate (bb);
    3010        51130 :       bool swap;
    3011        51130 :       int index;
    3012              : 
    3013        51130 :       if (is_true_predicate (cond))
    3014        25392 :         continue;
    3015              : 
    3016        25738 :       swap = false;
    3017        25738 :       if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
    3018              :         {
    3019         9791 :           swap = true;
    3020         9791 :           cond = TREE_OPERAND (cond, 0);
    3021              :         }
    3022              : 
    3023        25738 :       vect_sizes.truncate (0);
    3024        25738 :       vect_masks.truncate (0);
    3025              : 
    3026       200200 :       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
    3027              :         {
    3028       148724 :           gimple *stmt = gsi_stmt (gsi);
    3029       148724 :           if (!is_gimple_assign (stmt)
    3030       148724 :               && !gimple_call_builtin_p (stmt))
    3031              :             ;
    3032        90874 :           else if (is_false_predicate (cond)
    3033        90874 :                    && gimple_vdef (stmt))
    3034              :             {
    3035            0 :               unlink_stmt_vdef (stmt);
    3036            0 :               gsi_remove (&gsi, true);
    3037            0 :               release_defs (stmt);
    3038            2 :               continue;
    3039              :             }
    3040              :           /* For now, just drop prefetches.  Do it now to remove any possible
    3041              :              aliasing check failures from the address calculations of the
    3042              :              prefetch.  Vect would be too late in that regard.  */
    3043        90874 :           else if (gimple_call_builtin_p (stmt, BUILT_IN_PREFETCH))
    3044              :             {
    3045            2 :               unlink_stmt_vdef (stmt);
    3046            2 :               gsi_remove (&gsi, true);
    3047            2 :               release_defs (stmt);
    3048            2 :               continue;
    3049              :             }
    3050        90872 :           else if (gimple_plf (stmt, GF_PLF_2)
    3051        90872 :                    && (is_gimple_assign (stmt)
    3052          108 :                        || (gimple_call_builtin_p (stmt)
    3053          108 :                            && !if_convertible_simdclone_stmt_p (stmt))))
    3054              :             {
    3055         2611 :               tree lhs = gimple_get_lhs (stmt);
    3056              :               /* ?? Assume that calls without an LHS are not data processing
    3057              :                  and so no issues with traps.  */
    3058         2611 :               if (!lhs)
    3059            0 :                 continue;
    3060         2611 :               tree mask;
    3061         2611 :               gimple *new_stmt;
    3062         2611 :               gimple_seq stmts = NULL;
    3063         2611 :               machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
    3064              :               /* We checked before setting GF_PLF_2 that an equivalent
    3065              :                  integer mode exists.  */
    3066         2611 :               int bitsize = GET_MODE_BITSIZE (mode).to_constant ();
    3067         2611 :               if (!vect_sizes.is_empty ()
    3068          936 :                   && (index = mask_exists (bitsize, vect_sizes)) != -1)
    3069              :                 /* Use created mask.  */
    3070          875 :                 mask = vect_masks[index];
    3071              :               else
    3072              :                 {
    3073         1736 :                   if (COMPARISON_CLASS_P (cond))
    3074            0 :                     mask = gimple_build (&stmts, TREE_CODE (cond),
    3075              :                                          boolean_type_node,
    3076            0 :                                          TREE_OPERAND (cond, 0),
    3077            0 :                                          TREE_OPERAND (cond, 1));
    3078              :                   else
    3079              :                     mask = cond;
    3080              : 
    3081         1736 :                   if (swap)
    3082              :                     {
    3083          391 :                       tree true_val
    3084          391 :                         = constant_boolean_node (true, TREE_TYPE (mask));
    3085          391 :                       mask = gimple_build (&stmts, BIT_XOR_EXPR,
    3086          391 :                                            TREE_TYPE (mask), mask, true_val);
    3087              :                     }
    3088         1736 :                   gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
    3089              : 
    3090              :                   /* Save mask and its size for further use.  */
    3091         1736 :                   vect_sizes.safe_push (bitsize);
    3092         1736 :                   vect_masks.safe_push (mask);
    3093              :                 }
    3094         2611 :               if (gimple_assign_single_p (stmt))
    3095         1992 :                 new_stmt = predicate_load_or_store (&gsi,
    3096              :                                                     as_a <gassign *> (stmt),
    3097              :                                                     mask);
    3098              :               else
    3099          619 :                 new_stmt = predicate_rhs_code (stmt, mask, cond, &ssa_names);
    3100              : 
    3101         2611 :               if (new_stmt)
    3102         2611 :                 gsi_replace (&gsi, new_stmt, true);
    3103              :             }
    3104        88261 :           else if (gimple_needing_rewrite_undefined (stmt))
    3105        18348 :             rewrite_to_defined_unconditional (&gsi);
    3106       139826 :           else if (gimple_vdef (stmt))
    3107              :             {
    3108         1381 :               tree lhs = gimple_assign_lhs (stmt);
    3109         1381 :               tree rhs = gimple_assign_rhs1 (stmt);
    3110         1381 :               tree type = TREE_TYPE (lhs);
    3111              : 
    3112         1381 :               lhs = ifc_temp_var (type, unshare_expr (lhs), &gsi);
    3113         1381 :               rhs = ifc_temp_var (type, unshare_expr (rhs), &gsi);
    3114         1381 :               if (swap)
    3115          481 :                 std::swap (lhs, rhs);
    3116         1381 :               cond = force_gimple_operand_gsi (&gsi, unshare_expr (cond), true,
    3117              :                                                NULL_TREE, true, GSI_SAME_STMT);
    3118         1381 :               rhs = fold_build_cond_expr (type, unshare_expr (cond), rhs, lhs);
    3119         1381 :               gimple_assign_set_rhs1 (stmt, ifc_temp_var (type, rhs, &gsi));
    3120         1381 :               update_stmt (stmt);
    3121              :             }
    3122              : 
    3123       148722 :           if (gimple_plf (gsi_stmt (gsi), GF_PLF_2)
    3124       148722 :               && is_gimple_call (gsi_stmt (gsi)))
    3125              :             {
    3126              :               /* Convert functions that have a SIMD clone to IFN_MASK_CALL.
    3127              :                  This will cause the vectorizer to match the "in branch"
    3128              :                  clone variants, and serves to build the mask vector
    3129              :                  in a natural way.  */
    3130          999 :               tree mask = cond;
    3131          999 :               gcall *call = dyn_cast <gcall *> (gsi_stmt (gsi));
    3132          999 :               tree orig_fn = gimple_call_fn (call);
    3133          999 :               int orig_nargs = gimple_call_num_args (call);
    3134          999 :               auto_vec<tree> args;
    3135          999 :               args.safe_push (orig_fn);
    3136         3012 :               for (int i = 0; i < orig_nargs; i++)
    3137         1014 :                 args.safe_push (gimple_call_arg (call, i));
    3138              :               /* If `swap', we invert the mask used for the if branch for use
    3139              :                  when masking the function call.  */
    3140          999 :               if (swap)
    3141              :                 {
    3142          948 :                   gimple_seq stmts = NULL;
    3143          948 :                   tree true_val
    3144          948 :                     = constant_boolean_node (true, TREE_TYPE (mask));
    3145          948 :                   mask = gimple_build (&stmts, BIT_XOR_EXPR,
    3146          948 :                                        TREE_TYPE (mask), mask, true_val);
    3147          948 :                   gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
    3148              :                 }
    3149          999 :               args.safe_push (mask);
    3150              : 
    3151              :               /* Replace the call with a IFN_MASK_CALL that has the extra
    3152              :                  condition parameter. */
    3153          999 :               gcall *new_call = gimple_build_call_internal_vec (IFN_MASK_CALL,
    3154              :                                                                 args);
    3155          999 :               gimple_call_set_lhs (new_call, gimple_call_lhs (call));
    3156          999 :               gsi_replace (&gsi, new_call, true);
    3157          999 :             }
    3158              : 
    3159       148722 :           tree lhs = gimple_get_lhs (gsi_stmt (gsi));
    3160       148722 :           if (lhs && TREE_CODE (lhs) == SSA_NAME)
    3161        88759 :             ssa_names.add (lhs);
    3162       148722 :           gsi_next (&gsi);
    3163              :         }
    3164        51454 :       ssa_names.empty ();
    3165              :     }
    3166        12036 : }
    3167              : 
    3168              : /* Remove all GIMPLE_CONDs and GIMPLE_LABELs and GIMPLE_SWITCH of all
    3169              :    the basic blocks other than the exit and latch of the LOOP.  Also
    3170              :    resets the GIMPLE_DEBUG information.  */
    3171              : 
    3172              : static void
    3173        25536 : remove_conditions_and_labels (loop_p loop)
    3174              : {
    3175        25536 :   gimple_stmt_iterator gsi;
    3176        25536 :   unsigned int i;
    3177              : 
    3178       159846 :   for (i = 0; i < loop->num_nodes; i++)
    3179              :     {
    3180       134310 :       basic_block bb = ifc_bbs[i];
    3181              : 
    3182       134310 :       if (bb_with_exit_edge_p (loop, bb)
    3183       134310 :           || bb == loop->latch)
    3184        51072 :         continue;
    3185              : 
    3186       710296 :       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
    3187       543820 :         switch (gimple_code (gsi_stmt (gsi)))
    3188              :           {
    3189        33606 :           case GIMPLE_COND:
    3190        33606 :           case GIMPLE_LABEL:
    3191        33606 :           case GIMPLE_SWITCH:
    3192        33606 :             gsi_remove (&gsi, true);
    3193        33606 :             break;
    3194              : 
    3195       344676 :           case GIMPLE_DEBUG:
    3196              :             /* ??? Should there be conditional GIMPLE_DEBUG_BINDs?  */
    3197       344676 :             if (gimple_debug_bind_p (gsi_stmt (gsi)))
    3198              :               {
    3199       275622 :                 gimple_debug_bind_reset_value (gsi_stmt (gsi));
    3200       275622 :                 update_stmt (gsi_stmt (gsi));
    3201              :               }
    3202       344676 :             gsi_next (&gsi);
    3203       344676 :             break;
    3204              : 
    3205       165538 :           default:
    3206       165538 :             gsi_next (&gsi);
    3207              :           }
    3208              :     }
    3209        25536 : }
    3210              : 
    3211              : /* Combine all the basic blocks from LOOP into one or two super basic
    3212              :    blocks.  Replace PHI nodes with conditional modify expressions.  */
    3213              : 
    3214              : static void
    3215        25536 : combine_blocks (class loop *loop)
    3216              : {
    3217        25536 :   basic_block bb, exit_bb, merge_target_bb;
    3218        25536 :   unsigned int orig_loop_num_nodes = loop->num_nodes;
    3219        25536 :   unsigned int i;
    3220        25536 :   edge e;
    3221        25536 :   edge_iterator ei;
    3222              : 
    3223              :   /* Reset flow-sensitive info before predicating stmts or PHIs we
    3224              :      might fold.  */
    3225       159846 :   for (i = 0; i < orig_loop_num_nodes; i++)
    3226              :     {
    3227       134310 :       bb = ifc_bbs[i];
    3228       134310 :       if (is_predicated (bb))
    3229              :         {
    3230        53603 :           for (auto gsi = gsi_start_phis (bb);
    3231        55165 :                !gsi_end_p (gsi); gsi_next (&gsi))
    3232         1562 :             reset_flow_sensitive_info (gimple_phi_result (*gsi));
    3233       226787 :           for (auto gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    3234              :             {
    3235       119581 :               gimple *stmt = gsi_stmt (gsi);
    3236       119581 :               ssa_op_iter i;
    3237       119581 :               tree op;
    3238       170547 :               FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_DEF)
    3239        50966 :                 reset_flow_sensitive_info (op);
    3240              :             }
    3241              :         }
    3242              :     }
    3243              : 
    3244        25536 :   remove_conditions_and_labels (loop);
    3245        25536 :   insert_gimplified_predicates (loop);
    3246        25536 :   predicate_all_scalar_phis (loop);
    3247              : 
    3248        25536 :   if (need_to_predicate || need_to_rewrite_undefined)
    3249        12036 :     predicate_statements (loop);
    3250              : 
    3251              :   /* Merge basic blocks.  */
    3252        25536 :   exit_bb = single_exit (loop)->src;
    3253        25536 :   gcc_assert (exit_bb != loop->latch);
    3254       159846 :   for (i = 0; i < orig_loop_num_nodes; i++)
    3255              :     {
    3256       134310 :       bb = ifc_bbs[i];
    3257       134310 :       free_bb_predicate (bb);
    3258              :     }
    3259              : 
    3260        25536 :   merge_target_bb = loop->header;
    3261              : 
    3262              :   /* Get at the virtual def valid for uses starting at the first block
    3263              :      we merge into the header.  Without a virtual PHI the loop has the
    3264              :      same virtual use on all stmts.  */
    3265        25536 :   gphi *vphi = get_virtual_phi (loop->header);
    3266        25536 :   tree last_vdef = NULL_TREE;
    3267        25536 :   if (vphi)
    3268              :     {
    3269        13695 :       last_vdef = gimple_phi_result (vphi);
    3270        27390 :       for (gimple_stmt_iterator gsi = gsi_start_bb (loop->header);
    3271       236593 :            ! gsi_end_p (gsi); gsi_next (&gsi))
    3272       286422 :         if (gimple_vdef (gsi_stmt (gsi)))
    3273       222898 :           last_vdef = gimple_vdef (gsi_stmt (gsi));
    3274              :     }
    3275       134310 :   for (i = 1; i < orig_loop_num_nodes; i++)
    3276              :     {
    3277       108774 :       gimple_stmt_iterator gsi;
    3278       108774 :       gimple_stmt_iterator last;
    3279              : 
    3280       108774 :       bb = ifc_bbs[i];
    3281              : 
    3282       108774 :       if (bb == exit_bb || bb == loop->latch)
    3283        51072 :         continue;
    3284              : 
    3285              :       /* We release virtual PHIs late because we have to propagate them
    3286              :          out using the current VUSE.  The def might be the one used
    3287              :          after the loop.  */
    3288        57702 :       vphi = get_virtual_phi (bb);
    3289        57702 :       if (vphi)
    3290              :         {
    3291              :           /* When there's just loads inside the loop a stray virtual
    3292              :              PHI merging the uses can appear, update last_vdef from
    3293              :              it.  */
    3294          674 :           if (!last_vdef)
    3295            0 :             last_vdef = gimple_phi_arg_def (vphi, 0);
    3296          674 :           imm_use_iterator iter;
    3297          674 :           use_operand_p use_p;
    3298          674 :           gimple *use_stmt;
    3299         2349 :           FOR_EACH_IMM_USE_STMT (use_stmt, iter, gimple_phi_result (vphi))
    3300              :             {
    3301         3356 :               FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
    3302         1678 :                 SET_USE (use_p, last_vdef);
    3303          674 :             }
    3304          674 :           if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_phi_result (vphi)))
    3305            0 :             SSA_NAME_OCCURS_IN_ABNORMAL_PHI (last_vdef) = 1;
    3306          674 :           gsi = gsi_for_stmt (vphi);
    3307          674 :           remove_phi_node (&gsi, true);
    3308              :         }
    3309              : 
    3310              :       /* Make stmts member of loop->header and clear range info from all stmts
    3311              :          in BB which is now no longer executed conditional on a predicate we
    3312              :          could have derived it from.  */
    3313       379146 :       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    3314              :         {
    3315       263742 :           gimple *stmt = gsi_stmt (gsi);
    3316       263742 :           gimple_set_bb (stmt, merge_target_bb);
    3317              :           /* Update virtual operands.  */
    3318       263742 :           if (last_vdef)
    3319              :             {
    3320       203612 :               use_operand_p use_p = ssa_vuse_operand (stmt);
    3321        14291 :               if (use_p
    3322        14291 :                   && USE_FROM_PTR (use_p) != last_vdef)
    3323          522 :                 SET_USE (use_p, last_vdef);
    3324       612674 :               if (gimple_vdef (stmt))
    3325              :                 last_vdef = gimple_vdef (stmt);
    3326              :             }
    3327              :           else
    3328              :             /* If this is the first load we arrive at update last_vdef
    3329              :                so we handle stray PHIs correctly.  */
    3330       304445 :             last_vdef = gimple_vuse (stmt);
    3331              :         }
    3332              : 
    3333              :       /* Update stmt list.  */
    3334        57702 :       last = gsi_last_bb (merge_target_bb);
    3335       115404 :       gsi_insert_seq_after_without_update (&last, bb_seq (bb), GSI_NEW_STMT);
    3336        57702 :       set_bb_seq (bb, NULL);
    3337              :     }
    3338              : 
    3339              :   /* Fixup virtual operands in the exit block.  */
    3340        25536 :   if (exit_bb
    3341        25536 :       && exit_bb != loop->header)
    3342              :     {
    3343              :       /* We release virtual PHIs late because we have to propagate them
    3344              :          out using the current VUSE.  The def might be the one used
    3345              :          after the loop.  */
    3346        25536 :       vphi = get_virtual_phi (exit_bb);
    3347        25536 :       if (vphi)
    3348              :         {
    3349              :           /* When there's just loads inside the loop a stray virtual
    3350              :              PHI merging the uses can appear, update last_vdef from
    3351              :              it.  */
    3352         1672 :           if (!last_vdef)
    3353            0 :             last_vdef = gimple_phi_arg_def (vphi, 0);
    3354         1672 :           imm_use_iterator iter;
    3355         1672 :           use_operand_p use_p;
    3356         1672 :           gimple *use_stmt;
    3357         5010 :           FOR_EACH_IMM_USE_STMT (use_stmt, iter, gimple_phi_result (vphi))
    3358              :             {
    3359         6676 :               FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
    3360         3338 :                 SET_USE (use_p, last_vdef);
    3361         1672 :             }
    3362         1672 :           if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_phi_result (vphi)))
    3363            0 :             SSA_NAME_OCCURS_IN_ABNORMAL_PHI (last_vdef) = 1;
    3364         1672 :           gimple_stmt_iterator gsi = gsi_for_stmt (vphi);
    3365         1672 :           remove_phi_node (&gsi, true);
    3366              :         }
    3367              :     }
    3368              : 
    3369              :   /* Now remove all the edges in the loop, except for those from the exit
    3370              :      block and delete the blocks we elided.  */
    3371       134310 :   for (i = 1; i < orig_loop_num_nodes; i++)
    3372              :     {
    3373       108774 :       bb = ifc_bbs[i];
    3374              : 
    3375       250772 :       for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei));)
    3376              :         {
    3377       141998 :           if (e->src == exit_bb)
    3378        25536 :             ei_next (&ei);
    3379              :           else
    3380       116462 :             remove_edge (e);
    3381              :         }
    3382              :     }
    3383       134310 :   for (i = 1; i < orig_loop_num_nodes; i++)
    3384              :     {
    3385       108774 :       bb = ifc_bbs[i];
    3386              : 
    3387       108774 :       if (bb == exit_bb || bb == loop->latch)
    3388        51072 :         continue;
    3389              : 
    3390        57702 :       delete_basic_block (bb);
    3391              :     }
    3392              : 
    3393              :   /* Re-connect the exit block.  */
    3394        25536 :   if (exit_bb != NULL)
    3395              :     {
    3396        25536 :       if (exit_bb != loop->header)
    3397              :         {
    3398              :           /* Connect this node to loop header.  */
    3399        25536 :           make_single_succ_edge (loop->header, exit_bb, EDGE_FALLTHRU);
    3400        25536 :           set_immediate_dominator (CDI_DOMINATORS, exit_bb, loop->header);
    3401              :         }
    3402              : 
    3403              :       /* Redirect non-exit edges to loop->latch.  */
    3404        76608 :       FOR_EACH_EDGE (e, ei, exit_bb->succs)
    3405              :         {
    3406        51072 :           if (!loop_exit_edge_p (loop, e))
    3407        25536 :             redirect_edge_and_branch (e, loop->latch);
    3408              :         }
    3409        25536 :       set_immediate_dominator (CDI_DOMINATORS, loop->latch, exit_bb);
    3410              :     }
    3411              :   else
    3412              :     {
    3413              :       /* If the loop does not have an exit, reconnect header and latch.  */
    3414            0 :       make_edge (loop->header, loop->latch, EDGE_FALLTHRU);
    3415            0 :       set_immediate_dominator (CDI_DOMINATORS, loop->latch, loop->header);
    3416              :     }
    3417              : 
    3418              :   /* If possible, merge loop header to the block with the exit edge.
    3419              :      This reduces the number of basic blocks to two, to please the
    3420              :      vectorizer that handles only loops with two nodes.  */
    3421        25536 :   if (exit_bb
    3422        25536 :       && exit_bb != loop->header)
    3423              :     {
    3424        25536 :       if (can_merge_blocks_p (loop->header, exit_bb))
    3425        25534 :         merge_blocks (loop->header, exit_bb);
    3426              :     }
    3427              : 
    3428        25536 :   free (ifc_bbs);
    3429        25536 :   ifc_bbs = NULL;
    3430        25536 : }
    3431              : 
    3432              : /* Version LOOP before if-converting it; the original loop
    3433              :    will be if-converted, the new copy of the loop will not,
    3434              :    and the LOOP_VECTORIZED internal call will be guarding which
    3435              :    loop to execute.  The vectorizer pass will fold this
    3436              :    internal call into either true or false.
    3437              : 
    3438              :    Note that this function intentionally invalidates profile.  Both edges
    3439              :    out of LOOP_VECTORIZED must have 100% probability so the profile remains
    3440              :    consistent after the condition is folded in the vectorizer.  */
    3441              : 
    3442              : static class loop *
    3443        25801 : version_loop_for_if_conversion (class loop *loop, vec<gimple *> *preds)
    3444              : {
    3445        25801 :   basic_block cond_bb;
    3446        25801 :   tree cond = make_ssa_name (boolean_type_node);
    3447        25801 :   class loop *new_loop;
    3448        25801 :   gimple *g;
    3449        25801 :   gimple_stmt_iterator gsi;
    3450        25801 :   unsigned int save_length = 0;
    3451              : 
    3452        25801 :   g = gimple_build_call_internal (IFN_LOOP_VECTORIZED, 2,
    3453        25801 :                                   build_int_cst (integer_type_node, loop->num),
    3454              :                                   integer_zero_node);
    3455        25801 :   gimple_call_set_lhs (g, cond);
    3456              : 
    3457        25801 :   void **saved_preds = NULL;
    3458        25801 :   if (any_complicated_phi || need_to_predicate)
    3459              :     {
    3460              :       /* Save BB->aux around loop_version as that uses the same field.  */
    3461         3386 :       save_length = loop->inner ? loop->inner->num_nodes : loop->num_nodes;
    3462         3386 :       saved_preds = XALLOCAVEC (void *, save_length);
    3463        25812 :       for (unsigned i = 0; i < save_length; i++)
    3464        22426 :         saved_preds[i] = ifc_bbs[i]->aux;
    3465              :     }
    3466              : 
    3467        25801 :   initialize_original_copy_tables ();
    3468              :   /* At this point we invalidate profile consistency until IFN_LOOP_VECTORIZED
    3469              :      is re-merged in the vectorizer.  */
    3470        25801 :   new_loop = loop_version (loop, cond, &cond_bb,
    3471              :                            profile_probability::always (),
    3472              :                            profile_probability::always (),
    3473              :                            profile_probability::always (),
    3474              :                            profile_probability::always (), true);
    3475        25801 :   free_original_copy_tables ();
    3476              : 
    3477        25801 :   if (any_complicated_phi || need_to_predicate)
    3478        25812 :     for (unsigned i = 0; i < save_length; i++)
    3479        22426 :       ifc_bbs[i]->aux = saved_preds[i];
    3480              : 
    3481        25801 :   if (new_loop == NULL)
    3482              :     return NULL;
    3483              : 
    3484        25801 :   new_loop->dont_vectorize = true;
    3485        25801 :   new_loop->force_vectorize = false;
    3486        25801 :   gsi = gsi_last_bb (cond_bb);
    3487        25801 :   gimple_call_set_arg (g, 1, build_int_cst (integer_type_node, new_loop->num));
    3488        25801 :   if (preds)
    3489        25801 :     preds->safe_push (g);
    3490        25801 :   gsi_insert_before (&gsi, g, GSI_SAME_STMT);
    3491        25801 :   update_ssa (TODO_update_ssa_no_phi);
    3492        25801 :   return new_loop;
    3493              : }
    3494              : 
    3495              : /* Return true when LOOP satisfies the follow conditions that will
    3496              :    allow it to be recognized by the vectorizer for outer-loop
    3497              :    vectorization:
    3498              :     - The loop is not the root node of the loop tree.
    3499              :     - The loop has exactly one inner loop.
    3500              :     - The loop has a single exit.
    3501              :     - The loop header has a single successor, which is the inner
    3502              :       loop header.
    3503              :     - Each of the inner and outer loop latches have a single
    3504              :       predecessor.
    3505              :     - The loop exit block has a single predecessor, which is the
    3506              :       inner loop's exit block.  */
    3507              : 
    3508              : static bool
    3509        25801 : versionable_outer_loop_p (class loop *loop)
    3510              : {
    3511        25801 :   if (!loop_outer (loop)
    3512         8076 :       || loop->dont_vectorize
    3513         7094 :       || !loop->inner
    3514         7094 :       || loop->inner->next
    3515         2940 :       || !single_exit (loop)
    3516         2246 :       || !single_succ_p (loop->header)
    3517          932 :       || single_succ (loop->header) != loop->inner->header
    3518          932 :       || !single_pred_p (loop->latch)
    3519        26733 :       || !single_pred_p (loop->inner->latch))
    3520              :     return false;
    3521              : 
    3522          932 :   basic_block outer_exit = single_pred (loop->latch);
    3523          932 :   basic_block inner_exit = single_pred (loop->inner->latch);
    3524              : 
    3525         1855 :   if (!single_pred_p (outer_exit) || single_pred (outer_exit) != inner_exit)
    3526              :     return false;
    3527              : 
    3528          922 :   if (dump_file)
    3529            0 :     fprintf (dump_file, "Found vectorizable outer loop for versioning\n");
    3530              : 
    3531              :   return true;
    3532              : }
    3533              : 
    3534              : /* Performs splitting of critical edges.  Skip splitting and return false
    3535              :    if LOOP will not be converted because:
    3536              : 
    3537              :      - LOOP is not well formed.
    3538              :      - LOOP has PHI with more than MAX_PHI_ARG_NUM arguments.
    3539              : 
    3540              :    Last restriction is valid only if AGGRESSIVE_IF_CONV is false.  */
    3541              : 
    3542              : static bool
    3543       320508 : ifcvt_split_critical_edges (class loop *loop, bool aggressive_if_conv)
    3544              : {
    3545       320508 :   basic_block *body;
    3546       320508 :   basic_block bb;
    3547       320508 :   unsigned int num = loop->num_nodes;
    3548       320508 :   unsigned int i;
    3549       320508 :   edge e;
    3550       320508 :   edge_iterator ei;
    3551       320508 :   auto_vec<edge> critical_edges;
    3552              : 
    3553              :   /* Loop is not well formed.  */
    3554       320508 :   if (loop->inner)
    3555              :     return false;
    3556              : 
    3557       231425 :   body = get_loop_body (loop);
    3558      1865800 :   for (i = 0; i < num; i++)
    3559              :     {
    3560      1409426 :       bb = body[i];
    3561      1409426 :       if (!aggressive_if_conv
    3562      1401295 :           && phi_nodes (bb)
    3563      1846828 :           && EDGE_COUNT (bb->preds) > MAX_PHI_ARG_NUM)
    3564              :         {
    3565         6476 :           if (dump_file && (dump_flags & TDF_DETAILS))
    3566            0 :             fprintf (dump_file,
    3567              :                      "BB %d has complicated PHI with more than %u args.\n",
    3568              :                      bb->index, MAX_PHI_ARG_NUM);
    3569              : 
    3570         6476 :           free (body);
    3571         6476 :           return false;
    3572              :         }
    3573      1402950 :       if (bb == loop->latch || bb_with_exit_edge_p (loop, bb))
    3574       797990 :         continue;
    3575              : 
    3576              :       /* Skip basic blocks not ending with conditional branch.  */
    3577      1450092 :       if (!safe_is_a <gcond *> (*gsi_last_bb (bb))
    3578       604960 :           && !safe_is_a <gswitch *> (*gsi_last_bb (bb)))
    3579       335066 :         continue;
    3580              : 
    3581       821672 :       FOR_EACH_EDGE (e, ei, bb->succs)
    3582       677512 :         if (EDGE_CRITICAL_P (e) && e->dest->loop_father == loop)
    3583       125734 :           critical_edges.safe_push (e);
    3584              :     }
    3585       224949 :   free (body);
    3586              : 
    3587       442257 :   while (critical_edges.length () > 0)
    3588              :     {
    3589       121749 :       e = critical_edges.pop ();
    3590              :       /* Don't split if bb can be predicated along non-critical edge.  */
    3591       121749 :       if (EDGE_COUNT (e->dest->preds) > 2 || all_preds_critical_p (e->dest))
    3592        58136 :         split_edge (e);
    3593              :     }
    3594              : 
    3595              :   return true;
    3596       320508 : }
    3597              : 
    3598              : /* Delete redundant statements produced by predication which prevents
    3599              :    loop vectorization.  */
    3600              : 
    3601              : static void
    3602        25801 : ifcvt_local_dce (class loop *loop)
    3603              : {
    3604        25801 :   gimple *stmt;
    3605        25801 :   gimple *stmt1;
    3606        25801 :   gimple *phi;
    3607        25801 :   gimple_stmt_iterator gsi;
    3608        25801 :   auto_vec<gimple *> worklist;
    3609        25801 :   enum gimple_code code;
    3610        25801 :   use_operand_p use_p;
    3611        25801 :   imm_use_iterator imm_iter;
    3612              : 
    3613              :   /* The loop has a single BB only.  */
    3614        25801 :   basic_block bb = loop->header;
    3615        25801 :   tree latch_vdef = NULL_TREE;
    3616              : 
    3617        25801 :   worklist.create (64);
    3618              :   /* Consider all phi as live statements.  */
    3619       104091 :   for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    3620              :     {
    3621        78290 :       phi = gsi_stmt (gsi);
    3622        78290 :       gimple_set_plf (phi, GF_PLF_2, true);
    3623        78290 :       worklist.safe_push (phi);
    3624       170473 :       if (virtual_operand_p (gimple_phi_result (phi)))
    3625        13893 :         latch_vdef = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop));
    3626              :     }
    3627              :   /* Consider load/store statements, CALL and COND as live.  */
    3628       871799 :   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    3629              :     {
    3630       820197 :       stmt = gsi_stmt (gsi);
    3631       820197 :       if (is_gimple_debug (stmt))
    3632              :         {
    3633       441776 :           gimple_set_plf (stmt, GF_PLF_2, true);
    3634       441776 :           continue;
    3635              :         }
    3636       378421 :       if (gimple_store_p (stmt) || gimple_assign_load_p (stmt))
    3637              :         {
    3638        58798 :           gimple_set_plf (stmt, GF_PLF_2, true);
    3639        58798 :           worklist.safe_push (stmt);
    3640        58798 :           continue;
    3641              :         }
    3642       319623 :       code = gimple_code (stmt);
    3643       319623 :       if (code == GIMPLE_COND || code == GIMPLE_CALL || code == GIMPLE_SWITCH)
    3644              :         {
    3645        31267 :           gimple_set_plf (stmt, GF_PLF_2, true);
    3646        31267 :           worklist.safe_push (stmt);
    3647        31267 :           continue;
    3648              :         }
    3649       288356 :       gimple_set_plf (stmt, GF_PLF_2, false);
    3650              : 
    3651       288356 :       if (code == GIMPLE_ASSIGN)
    3652              :         {
    3653       288347 :           tree lhs = gimple_assign_lhs (stmt);
    3654       668349 :           FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs)
    3655              :             {
    3656       399866 :               stmt1 = USE_STMT (use_p);
    3657       399866 :               if (!is_gimple_debug (stmt1) && gimple_bb (stmt1) != bb)
    3658              :                 {
    3659        19864 :                   gimple_set_plf (stmt, GF_PLF_2, true);
    3660        19864 :                   worklist.safe_push (stmt);
    3661        19864 :                   break;
    3662              :                 }
    3663       288347 :             }
    3664              :         }
    3665              :     }
    3666              :   /* Propagate liveness through arguments of live stmt.  */
    3667       470198 :   while (worklist.length () > 0)
    3668              :     {
    3669       444397 :       ssa_op_iter iter;
    3670       444397 :       use_operand_p use_p;
    3671       444397 :       tree use;
    3672              : 
    3673       444397 :       stmt = worklist.pop ();
    3674      1563871 :       FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE)
    3675              :         {
    3676       675077 :           use = USE_FROM_PTR (use_p);
    3677       675077 :           if (TREE_CODE (use) != SSA_NAME)
    3678        43142 :             continue;
    3679       631935 :           stmt1 = SSA_NAME_DEF_STMT (use);
    3680       631935 :           if (gimple_bb (stmt1) != bb || gimple_plf (stmt1, GF_PLF_2))
    3681       375757 :             continue;
    3682       256178 :           gimple_set_plf (stmt1, GF_PLF_2, true);
    3683       256178 :           worklist.safe_push (stmt1);
    3684              :         }
    3685              :     }
    3686              :   /* Delete dead statements.  */
    3687        25801 :   gsi = gsi_last_bb (bb);
    3688       845998 :   while (!gsi_end_p (gsi))
    3689              :     {
    3690       820197 :       gimple_stmt_iterator gsiprev = gsi;
    3691       820197 :       gsi_prev (&gsiprev);
    3692       820197 :       stmt = gsi_stmt (gsi);
    3693       820197 :       if (!gimple_has_volatile_ops (stmt)
    3694       820052 :           && gimple_store_p (stmt)
    3695       378419 :           && gimple_vdef (stmt))
    3696              :         {
    3697        12902 :           tree lhs = gimple_get_lhs (stmt);
    3698        12902 :           ao_ref write;
    3699        12902 :           ao_ref_init (&write, lhs);
    3700              : 
    3701        12902 :           if (dse_classify_store (&write, stmt, false, NULL, NULL, latch_vdef)
    3702              :               == DSE_STORE_DEAD)
    3703          270 :             delete_dead_or_redundant_assignment (&gsi, "dead");
    3704        12902 :           gsi = gsiprev;
    3705        12902 :           continue;
    3706        12902 :         }
    3707              : 
    3708       807295 :       if (gimple_plf (stmt, GF_PLF_2))
    3709              :         {
    3710       794981 :           gsi = gsiprev;
    3711       794981 :           continue;
    3712              :         }
    3713        12314 :       if (dump_file && (dump_flags & TDF_DETAILS))
    3714              :         {
    3715           16 :           fprintf (dump_file, "Delete dead stmt in bb#%d\n", bb->index);
    3716           16 :           print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    3717              :         }
    3718        12314 :       gsi_remove (&gsi, true);
    3719        12314 :       release_defs (stmt);
    3720        12314 :       gsi = gsiprev;
    3721              :     }
    3722        25801 : }
    3723              : 
    3724              : /* Return true if VALUE is already available on edge PE.  */
    3725              : 
    3726              : static bool
    3727       248605 : ifcvt_available_on_edge_p (edge pe, tree value)
    3728              : {
    3729       248605 :   if (is_gimple_min_invariant (value))
    3730              :     return true;
    3731              : 
    3732       242036 :   if (TREE_CODE (value) == SSA_NAME)
    3733              :     {
    3734       240806 :       basic_block def_bb = gimple_bb (SSA_NAME_DEF_STMT (value));
    3735       240806 :       if (!def_bb || dominated_by_p (CDI_DOMINATORS, pe->dest, def_bb))
    3736        26752 :         return true;
    3737              :     }
    3738              : 
    3739              :   return false;
    3740              : }
    3741              : 
    3742              : /* Return true if STMT can be hoisted from if-converted loop LOOP to
    3743              :    edge PE.  */
    3744              : 
    3745              : static bool
    3746       807613 : ifcvt_can_hoist (class loop *loop, edge pe, gimple *stmt)
    3747              : {
    3748       807613 :   if (auto *call = dyn_cast<gcall *> (stmt))
    3749              :     {
    3750         5472 :       if (gimple_call_internal_p (call)
    3751         5472 :           && internal_fn_mask_index (gimple_call_internal_fn (call)) >= 0)
    3752              :         return false;
    3753              :     }
    3754       802141 :   else if (auto *assign = dyn_cast<gassign *> (stmt))
    3755              :     {
    3756       394436 :       if (gimple_assign_rhs_code (assign) == COND_EXPR)
    3757              :         return false;
    3758              :     }
    3759              :   else
    3760              :     return false;
    3761              : 
    3762       290650 :   if (gimple_has_side_effects (stmt)
    3763       289474 :       || gimple_could_trap_p (stmt)
    3764       227984 :       || stmt_could_throw_p (cfun, stmt)
    3765       227982 :       || gimple_vdef (stmt)
    3766       518134 :       || gimple_vuse (stmt))
    3767              :     return false;
    3768              : 
    3769       226573 :   int num_args = gimple_num_args (stmt);
    3770       226573 :   if (pe != loop_preheader_edge (loop))
    3771              :     {
    3772       253439 :       for (int i = 0; i < num_args; ++i)
    3773       248605 :         if (!ifcvt_available_on_edge_p (pe, gimple_arg (stmt, i)))
    3774              :           return false;
    3775              :     }
    3776              :   else
    3777              :     {
    3778         8036 :       for (int i = 0; i < num_args; ++i)
    3779         7844 :         if (!expr_invariant_in_loop_p (loop, gimple_arg (stmt, i)))
    3780              :           return false;
    3781              :     }
    3782              : 
    3783              :   return true;
    3784              : }
    3785              : 
    3786              : /* Hoist invariant statements from LOOP to edge PE.  */
    3787              : 
    3788              : static void
    3789        25801 : ifcvt_hoist_invariants (class loop *loop, edge pe)
    3790              : {
    3791              :   /* Only hoist from the now unconditionally executed part of the loop.  */
    3792        25801 :   basic_block bb = loop->header;
    3793        25801 :   gimple_stmt_iterator hoist_gsi = {};
    3794       859215 :   for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
    3795              :     {
    3796       807613 :       gimple *stmt = gsi_stmt (gsi);
    3797       807613 :       if (ifcvt_can_hoist (loop, pe, stmt))
    3798              :         {
    3799              :           /* Once we've hoisted one statement, insert other statements
    3800              :              after it.  */
    3801         5026 :           gsi_remove (&gsi, false);
    3802         5026 :           if (hoist_gsi.ptr)
    3803         2653 :             gsi_insert_after (&hoist_gsi, stmt, GSI_NEW_STMT);
    3804              :           else
    3805              :             {
    3806         2373 :               gsi_insert_on_edge_immediate (pe, stmt);
    3807         2373 :               hoist_gsi = gsi_for_stmt (stmt);
    3808              :             }
    3809         5026 :           continue;
    3810              :         }
    3811       802587 :       gsi_next (&gsi);
    3812              :     }
    3813        25801 : }
    3814              : 
    3815              : /* Returns the DECL_FIELD_BIT_OFFSET of the bitfield accesse in stmt iff its
    3816              :    type mode is not BLKmode.  If BITPOS is not NULL it will hold the poly_int64
    3817              :    value of the DECL_FIELD_BIT_OFFSET of the bitfield access and STRUCT_EXPR,
    3818              :    if not NULL, will hold the tree representing the base struct of this
    3819              :    bitfield.  */
    3820              : 
    3821              : static tree
    3822         1251 : get_bitfield_rep (gassign *stmt, bool write, tree *bitpos,
    3823              :                   tree *struct_expr)
    3824              : {
    3825         1251 :   tree comp_ref = write ? gimple_assign_lhs (stmt)
    3826          384 :                         : gimple_assign_rhs1 (stmt);
    3827              : 
    3828         1251 :   tree field_decl = TREE_OPERAND (comp_ref, 1);
    3829         1251 :   tree ref_offset = component_ref_field_offset (comp_ref);
    3830         1251 :   tree rep_decl = DECL_BIT_FIELD_REPRESENTATIVE (field_decl);
    3831              : 
    3832              :   /* Bail out if the representative is not a suitable type for a scalar
    3833              :      register variable.  */
    3834         1251 :   if (!is_gimple_reg_type (TREE_TYPE (rep_decl)))
    3835              :     return NULL_TREE;
    3836              : 
    3837              :   /* Bail out if the DECL_SIZE of the field_decl isn't the same as the BF's
    3838              :      precision.  */
    3839         1236 :   unsigned HOST_WIDE_INT bf_prec
    3840         1236 :     = TYPE_PRECISION (TREE_TYPE (gimple_assign_lhs (stmt)));
    3841         1236 :   if (compare_tree_int (DECL_SIZE (field_decl), bf_prec) != 0)
    3842              :     return NULL_TREE;
    3843              : 
    3844         1236 :   if (TREE_CODE (DECL_FIELD_OFFSET (rep_decl)) != INTEGER_CST
    3845         1236 :       || TREE_CODE (ref_offset) != INTEGER_CST)
    3846              :     {
    3847            2 :       if (dump_file && (dump_flags & TDF_DETAILS))
    3848            2 :         fprintf (dump_file, "\t Bitfield NOT OK to lower,"
    3849              :                             " offset is non-constant.\n");
    3850              :       return NULL_TREE;
    3851              :     }
    3852              : 
    3853         1234 :   if (struct_expr)
    3854          617 :     *struct_expr = TREE_OPERAND (comp_ref, 0);
    3855              : 
    3856         1234 :   if (bitpos)
    3857              :     {
    3858              :       /* To calculate the bitposition of the BITFIELD_REF we have to determine
    3859              :          where our bitfield starts in relation to the container REP_DECL. The
    3860              :          DECL_FIELD_OFFSET of the original bitfield's member FIELD_DECL tells
    3861              :          us how many bytes from the start of the structure there are until the
    3862              :          start of the group of bitfield members the FIELD_DECL belongs to,
    3863              :          whereas DECL_FIELD_BIT_OFFSET will tell us how many bits from that
    3864              :          position our actual bitfield member starts.  For the container
    3865              :          REP_DECL adding DECL_FIELD_OFFSET and DECL_FIELD_BIT_OFFSET will tell
    3866              :          us the distance between the start of the structure and the start of
    3867              :          the container, though the first is in bytes and the later other in
    3868              :          bits.  With this in mind we calculate the bit position of our new
    3869              :          BITFIELD_REF by subtracting the number of bits between the start of
    3870              :          the structure and the container from the number of bits from the start
    3871              :          of the structure and the actual bitfield member. */
    3872          617 :       tree bf_pos = fold_build2 (MULT_EXPR, bitsizetype,
    3873              :                                  ref_offset,
    3874              :                                  build_int_cst (bitsizetype, BITS_PER_UNIT));
    3875          617 :       bf_pos = fold_build2 (PLUS_EXPR, bitsizetype, bf_pos,
    3876              :                             DECL_FIELD_BIT_OFFSET (field_decl));
    3877          617 :       tree rep_pos = fold_build2 (MULT_EXPR, bitsizetype,
    3878              :                                   DECL_FIELD_OFFSET (rep_decl),
    3879              :                                   build_int_cst (bitsizetype, BITS_PER_UNIT));
    3880          617 :       rep_pos = fold_build2 (PLUS_EXPR, bitsizetype, rep_pos,
    3881              :                              DECL_FIELD_BIT_OFFSET (rep_decl));
    3882              : 
    3883          617 :       *bitpos = fold_build2 (MINUS_EXPR, bitsizetype, bf_pos, rep_pos);
    3884              :     }
    3885              : 
    3886              :   return rep_decl;
    3887              : 
    3888              : }
    3889              : 
    3890              : /* Lowers the bitfield described by DATA.
    3891              :    For a write like:
    3892              : 
    3893              :    struct.bf = _1;
    3894              : 
    3895              :    lower to:
    3896              : 
    3897              :    __ifc_1 = struct.<representative>;
    3898              :    __ifc_2 = BIT_INSERT_EXPR (__ifc_1, _1, bitpos);
    3899              :    struct.<representative> = __ifc_2;
    3900              : 
    3901              :    For a read:
    3902              : 
    3903              :    _1 = struct.bf;
    3904              : 
    3905              :     lower to:
    3906              : 
    3907              :     __ifc_1 = struct.<representative>;
    3908              :     _1 =  BIT_FIELD_REF (__ifc_1, bitsize, bitpos);
    3909              : 
    3910              :     where representative is a legal load that contains the bitfield value,
    3911              :     bitsize is the size of the bitfield and bitpos the offset to the start of
    3912              :     the bitfield within the representative.  */
    3913              : 
    3914              : static void
    3915          617 : lower_bitfield (gassign *stmt, bool write)
    3916              : {
    3917          617 :   tree struct_expr;
    3918          617 :   tree bitpos;
    3919          617 :   tree rep_decl = get_bitfield_rep (stmt, write, &bitpos, &struct_expr);
    3920          617 :   tree rep_type = TREE_TYPE (rep_decl);
    3921          617 :   tree bf_type = TREE_TYPE (gimple_assign_lhs (stmt));
    3922              : 
    3923          617 :   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
    3924          617 :   if (dump_file && (dump_flags & TDF_DETAILS))
    3925              :     {
    3926            9 :       fprintf (dump_file, "Lowering:\n");
    3927            9 :       print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    3928            9 :       fprintf (dump_file, "to:\n");
    3929              :     }
    3930              : 
    3931              :   /* REP_COMP_REF is a COMPONENT_REF for the representative.  NEW_VAL is it's
    3932              :      defining SSA_NAME.  */
    3933          617 :   tree rep_comp_ref = build3 (COMPONENT_REF, rep_type, struct_expr, rep_decl,
    3934              :                               NULL_TREE);
    3935          617 :   tree new_val = ifc_temp_var (rep_type, rep_comp_ref, &gsi);
    3936              : 
    3937          617 :   if (dump_file && (dump_flags & TDF_DETAILS))
    3938            9 :     print_gimple_stmt (dump_file, SSA_NAME_DEF_STMT (new_val), 0, TDF_SLIM);
    3939              : 
    3940          617 :   if (write)
    3941              :     {
    3942          429 :       new_val = ifc_temp_var (rep_type,
    3943              :                               build3 (BIT_INSERT_EXPR, rep_type, new_val,
    3944              :                                       unshare_expr (gimple_assign_rhs1 (stmt)),
    3945              :                                       bitpos), &gsi);
    3946              : 
    3947          429 :       if (dump_file && (dump_flags & TDF_DETAILS))
    3948            0 :         print_gimple_stmt (dump_file, SSA_NAME_DEF_STMT (new_val), 0, TDF_SLIM);
    3949              : 
    3950          429 :       gimple *new_stmt = gimple_build_assign (unshare_expr (rep_comp_ref),
    3951              :                                               new_val);
    3952          429 :       gimple_move_vops (new_stmt, stmt);
    3953          429 :       gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
    3954              : 
    3955          429 :       if (dump_file && (dump_flags & TDF_DETAILS))
    3956            0 :         print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM);
    3957              :     }
    3958              :   else
    3959              :     {
    3960          188 :       tree bfr = build3 (BIT_FIELD_REF, bf_type, new_val,
    3961          188 :                          build_int_cst (bitsizetype, TYPE_PRECISION (bf_type)),
    3962              :                          bitpos);
    3963          188 :       new_val = ifc_temp_var (bf_type, bfr, &gsi);
    3964              : 
    3965          188 :       gimple *new_stmt = gimple_build_assign (gimple_assign_lhs (stmt),
    3966              :                                               new_val);
    3967          188 :       gimple_move_vops (new_stmt, stmt);
    3968          188 :       gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
    3969              : 
    3970          188 :       if (dump_file && (dump_flags & TDF_DETAILS))
    3971            9 :         print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM);
    3972              :     }
    3973              : 
    3974          617 :   gsi_remove (&gsi, true);
    3975          617 : }
    3976              : 
    3977              : /* Return TRUE if there are bitfields to lower in this LOOP.  Fill TO_LOWER
    3978              :    with data structures representing these bitfields.  */
    3979              : 
    3980              : static bool
    3981       244492 : bitfields_to_lower_p (class loop *loop,
    3982              :                       vec <gassign *> &reads_to_lower,
    3983              :                       vec <gassign *> &writes_to_lower)
    3984              : {
    3985       244492 :   gimple_stmt_iterator gsi;
    3986              : 
    3987       244492 :   if (dump_file && (dump_flags & TDF_DETAILS))
    3988              :     {
    3989           28 :       fprintf (dump_file, "Analyzing loop %d for bitfields:\n", loop->num);
    3990              :     }
    3991              : 
    3992      1026244 :   for (unsigned i = 0; i < loop->num_nodes; ++i)
    3993              :     {
    3994       781773 :       basic_block bb = ifc_bbs[i];
    3995      6789908 :       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    3996              :         {
    3997      5226383 :           gassign *stmt = dyn_cast<gassign*> (gsi_stmt (gsi));
    3998      5226383 :           if (!stmt)
    3999      5098066 :             continue;
    4000              : 
    4001      2070823 :           tree op = gimple_assign_lhs (stmt);
    4002      2070823 :           bool write = TREE_CODE (op) == COMPONENT_REF;
    4003              : 
    4004      2070823 :           if (!write)
    4005      2038840 :             op = gimple_assign_rhs1 (stmt);
    4006              : 
    4007      2070823 :           if (TREE_CODE (op) != COMPONENT_REF)
    4008      1942506 :             continue;
    4009              : 
    4010       128317 :           if (DECL_BIT_FIELD_TYPE (TREE_OPERAND (op, 1)))
    4011              :             {
    4012          638 :               if (dump_file && (dump_flags & TDF_DETAILS))
    4013           11 :                 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    4014              : 
    4015          638 :               if (TREE_THIS_VOLATILE (op))
    4016              :                 {
    4017            4 :                   if (dump_file && (dump_flags & TDF_DETAILS))
    4018            0 :                     fprintf (dump_file, "\t Bitfield NO OK to lower,"
    4019              :                                         " the access is volatile.\n");
    4020           21 :                   return false;
    4021              :                 }
    4022              : 
    4023          634 :               if (!INTEGRAL_TYPE_P (TREE_TYPE (op)))
    4024              :                 {
    4025            0 :                   if (dump_file && (dump_flags & TDF_DETAILS))
    4026            0 :                     fprintf (dump_file, "\t Bitfield NO OK to lower,"
    4027              :                                         " field type is not Integral.\n");
    4028              :                   return false;
    4029              :                 }
    4030              : 
    4031          634 :               if (!get_bitfield_rep (stmt, write, NULL, NULL))
    4032              :                 {
    4033           17 :                   if (dump_file && (dump_flags & TDF_DETAILS))
    4034            2 :                     fprintf (dump_file, "\t Bitfield NOT OK to lower,"
    4035              :                                         " representative is BLKmode.\n");
    4036              :                   return false;
    4037              :                 }
    4038              : 
    4039          617 :               if (dump_file && (dump_flags & TDF_DETAILS))
    4040            9 :                 fprintf (dump_file, "\tBitfield OK to lower.\n");
    4041          617 :               if (write)
    4042          429 :                 writes_to_lower.safe_push (stmt);
    4043              :               else
    4044          188 :                 reads_to_lower.safe_push (stmt);
    4045              :             }
    4046              :         }
    4047              :     }
    4048       488807 :   return !reads_to_lower.is_empty () || !writes_to_lower.is_empty ();
    4049              : }
    4050              : 
    4051              : 
    4052              : /* If-convert LOOP when it is legal.  For the moment this pass has no
    4053              :    profitability analysis.  Returns non-zero todo flags when something
    4054              :    changed.  */
    4055              : 
    4056              : unsigned int
    4057       509355 : tree_if_conversion (class loop *loop, vec<gimple *> *preds)
    4058              : {
    4059       509355 :   unsigned int todo = 0;
    4060       509355 :   bool aggressive_if_conv;
    4061       509355 :   class loop *rloop;
    4062       509355 :   auto_vec <gassign *, 4> reads_to_lower;
    4063       509355 :   auto_vec <gassign *, 4> writes_to_lower;
    4064       509355 :   bitmap exit_bbs;
    4065       509355 :   edge pe;
    4066       509355 :   auto_vec<data_reference_p, 10> refs;
    4067       510277 :   class loop *vloop, *nloop;
    4068              : 
    4069       510277 :  again:
    4070       510277 :   rloop = NULL;
    4071       510277 :   ifc_bbs = NULL;
    4072       510277 :   need_to_lower_bitfields = false;
    4073       510277 :   need_to_ifcvt = false;
    4074       510277 :   need_to_predicate = false;
    4075       510277 :   need_to_rewrite_undefined = false;
    4076       510277 :   any_complicated_phi = false;
    4077              : 
    4078              :   /* Apply more aggressive if-conversion when loop or its outer loop were
    4079              :      marked with simd pragma.  When that's the case, we try to if-convert
    4080              :      loop containing PHIs with more than MAX_PHI_ARG_NUM arguments.  */
    4081       510277 :   aggressive_if_conv = loop->force_vectorize;
    4082       510277 :   if (!aggressive_if_conv)
    4083              :     {
    4084       501860 :       class loop *outer_loop = loop_outer (loop);
    4085       501860 :       if (outer_loop && outer_loop->force_vectorize)
    4086         8673 :         aggressive_if_conv = true;
    4087              :     }
    4088              : 
    4089              :   /* If there are more than two BBs in the loop then there is at least one if
    4090              :      to convert.  */
    4091       510277 :   if (loop->num_nodes > 2
    4092       510277 :       && !ifcvt_split_critical_edges (loop, aggressive_if_conv))
    4093        95559 :     goto cleanup;
    4094              : 
    4095       414718 :   ifc_bbs = get_loop_body_in_if_conv_order (loop);
    4096       414718 :   if (!ifc_bbs)
    4097              :     {
    4098         2636 :       if (dump_file && (dump_flags & TDF_DETAILS))
    4099            3 :         fprintf (dump_file, "Irreducible loop\n");
    4100         2636 :       goto cleanup;
    4101              :     }
    4102              : 
    4103       412082 :   if (find_data_references_in_loop (loop, &refs) == chrec_dont_know)
    4104       153872 :     goto cleanup;
    4105              : 
    4106       258210 :   if (loop->num_nodes > 2)
    4107              :     {
    4108              :       /* More than one loop exit is too much to handle.  */
    4109       137561 :       if (!single_exit (loop))
    4110              :         {
    4111        98307 :           if (dump_file && (dump_flags & TDF_DETAILS))
    4112           10 :             fprintf (dump_file, "Can not ifcvt due to multiple exits\n");
    4113              :         }
    4114              :       else
    4115              :         {
    4116        39254 :           need_to_ifcvt = true;
    4117              : 
    4118        39254 :           if (!if_convertible_loop_p (loop, &refs)
    4119        39254 :               || !dbg_cnt (if_conversion_tree))
    4120        13718 :             goto cleanup;
    4121              :         }
    4122              :     }
    4123              : 
    4124       244492 :   need_to_lower_bitfields = bitfields_to_lower_p (loop, reads_to_lower,
    4125              :                                                   writes_to_lower);
    4126              : 
    4127       244492 :   if (!need_to_ifcvt && !need_to_lower_bitfields)
    4128       218691 :     goto cleanup;
    4129              : 
    4130              :   /* The edge to insert invariant stmts on.  */
    4131        25801 :   pe = loop_preheader_edge (loop);
    4132              : 
    4133              :   /* Since we have no cost model, always version loops.
    4134              :      Either version this loop, or if the pattern is right for outer-loop
    4135              :      vectorization, version the outer loop.  In the latter case we will
    4136              :      still if-convert the original inner loop.  */
    4137        25801 :   vloop = (versionable_outer_loop_p (loop_outer (loop))
    4138        25801 :            ? loop_outer (loop) : loop);
    4139        25801 :   nloop = version_loop_for_if_conversion (vloop, preds);
    4140        25801 :   if (nloop == NULL)
    4141            0 :     goto cleanup;
    4142        25801 :   if (vloop != loop)
    4143              :     {
    4144              :       /* If versionable_outer_loop_p decided to version the
    4145              :          outer loop, version also the inner loop of the non-vectorized
    4146              :          loop copy.  So we transform:
    4147              :              loop1
    4148              :                 loop2
    4149              :              into:
    4150              :               if (LOOP_VECTORIZED (1, 3))
    4151              :                 {
    4152              :                   loop1
    4153              :                     loop2
    4154              :                 }
    4155              :               else
    4156              :                 loop3 (copy of loop1)
    4157              :                   if (LOOP_VECTORIZED (4, 5))
    4158              :                     loop4 (copy of loop2)
    4159              :                   else
    4160              :                     loop5 (copy of loop4)  */
    4161          922 :       gcc_assert (nloop->inner && nloop->inner->next == NULL);
    4162              :       rloop = nloop->inner;
    4163              :     }
    4164              :   else
    4165              :     /* If we versioned loop then make sure to insert invariant
    4166              :        stmts before the .LOOP_VECTORIZED check since the vectorizer
    4167              :        will re-use that for things like runtime alias versioning
    4168              :        whose condition can end up using those invariants.  */
    4169        24879 :     pe = single_pred_edge (gimple_bb (preds->last ()));
    4170              : 
    4171        25801 :   if (need_to_lower_bitfields)
    4172              :     {
    4173          266 :       if (dump_file && (dump_flags & TDF_DETAILS))
    4174              :         {
    4175            9 :           fprintf (dump_file, "-------------------------\n");
    4176            9 :           fprintf (dump_file, "Start lowering bitfields\n");
    4177              :         }
    4178          454 :       while (!reads_to_lower.is_empty ())
    4179          188 :         lower_bitfield (reads_to_lower.pop (), false);
    4180          695 :       while (!writes_to_lower.is_empty ())
    4181          429 :         lower_bitfield (writes_to_lower.pop (), true);
    4182              : 
    4183          266 :       if (dump_file && (dump_flags & TDF_DETAILS))
    4184              :         {
    4185            9 :           fprintf (dump_file, "Done lowering bitfields\n");
    4186            9 :           fprintf (dump_file, "-------------------------\n");
    4187              :         }
    4188              :     }
    4189        25801 :   if (need_to_ifcvt)
    4190              :     {
    4191              :       /* Before we rewrite edges we'll record their original position in the
    4192              :          edge map such that we can map the edges between the ifcvt and the
    4193              :          non-ifcvt loop during peeling.  */
    4194        25536 :       uintptr_t idx = 0;
    4195       102144 :       for (edge exit : get_loop_exit_edges (loop))
    4196        25536 :         exit->aux = (void*)idx++;
    4197              : 
    4198              :       /* Now all statements are if-convertible.  Combine all the basic
    4199              :          blocks into one huge basic block doing the if-conversion
    4200              :          on-the-fly.  */
    4201        25536 :       combine_blocks (loop);
    4202              :     }
    4203              : 
    4204        25801 :   std::pair <tree, tree> *name_pair;
    4205        25801 :   unsigned ssa_names_idx;
    4206        30982 :   FOR_EACH_VEC_ELT (redundant_ssa_names, ssa_names_idx, name_pair)
    4207         5181 :     replace_uses_by (name_pair->first, name_pair->second);
    4208        25801 :   redundant_ssa_names.release ();
    4209              : 
    4210              :   /* Perform local CSE, this esp. helps the vectorizer analysis if loads
    4211              :      and stores are involved.  CSE only the loop body, not the entry
    4212              :      PHIs, those are to be kept in sync with the non-if-converted copy.
    4213              :      ???  We'll still keep dead stores though.  */
    4214        25801 :   exit_bbs = BITMAP_ALLOC (NULL);
    4215       103386 :   for (edge exit : get_loop_exit_edges (loop))
    4216        26001 :     bitmap_set_bit (exit_bbs, exit->dest->index);
    4217        25801 :   todo |= do_rpo_vn (cfun, loop_preheader_edge (loop), exit_bbs,
    4218              :                      false, true, true);
    4219              : 
    4220              :   /* Delete dead predicate computations.  */
    4221        25801 :   ifcvt_local_dce (loop);
    4222        25801 :   BITMAP_FREE (exit_bbs);
    4223              : 
    4224        25801 :   ifcvt_hoist_invariants (loop, pe);
    4225              : 
    4226        25801 :   todo |= TODO_cleanup_cfg;
    4227              : 
    4228       510277 :  cleanup:
    4229       510277 :   data_reference_p dr;
    4230       510277 :   unsigned int i;
    4231      1686864 :   for (i = 0; refs.iterate (i, &dr); i++)
    4232              :     {
    4233      1176587 :       free (dr->aux);
    4234      1176587 :       free_data_ref (dr);
    4235              :     }
    4236       510277 :   refs.truncate (0);
    4237              : 
    4238       510277 :   if (ifc_bbs)
    4239              :     {
    4240              :       unsigned int i;
    4241              : 
    4242      2060398 :       for (i = 0; i < loop->num_nodes; i++)
    4243      1673852 :         free_bb_predicate (ifc_bbs[i]);
    4244              : 
    4245       386546 :       free (ifc_bbs);
    4246       386546 :       ifc_bbs = NULL;
    4247              :     }
    4248       510277 :   if (rloop != NULL)
    4249              :     {
    4250          922 :       loop = rloop;
    4251          922 :       reads_to_lower.truncate (0);
    4252          922 :       writes_to_lower.truncate (0);
    4253          922 :       goto again;
    4254              :     }
    4255              : 
    4256       509355 :   return todo;
    4257       509355 : }
    4258              : 
    4259              : /* Tree if-conversion pass management.  */
    4260              : 
    4261              : namespace {
    4262              : 
    4263              : const pass_data pass_data_if_conversion =
    4264              : {
    4265              :   GIMPLE_PASS, /* type */
    4266              :   "ifcvt", /* name */
    4267              :   OPTGROUP_NONE, /* optinfo_flags */
    4268              :   TV_TREE_LOOP_IFCVT, /* tv_id */
    4269              :   ( PROP_cfg | PROP_ssa ), /* properties_required */
    4270              :   0, /* properties_provided */
    4271              :   0, /* properties_destroyed */
    4272              :   0, /* todo_flags_start */
    4273              :   0, /* todo_flags_finish */
    4274              : };
    4275              : 
    4276              : class pass_if_conversion : public gimple_opt_pass
    4277              : {
    4278              : public:
    4279       294536 :   pass_if_conversion (gcc::context *ctxt)
    4280       589072 :     : gimple_opt_pass (pass_data_if_conversion, ctxt)
    4281              :   {}
    4282              : 
    4283              :   /* opt_pass methods: */
    4284              :   bool gate (function *) final override;
    4285              :   unsigned int execute (function *) final override;
    4286              : 
    4287              : }; // class pass_if_conversion
    4288              : 
    4289              : bool
    4290       247693 : pass_if_conversion::gate (function *fun)
    4291              : {
    4292       247693 :   return flag_tree_loop_vectorize || fun->has_force_vectorize_loops;
    4293              : }
    4294              : 
    4295              : unsigned int
    4296       213732 : pass_if_conversion::execute (function *fun)
    4297              : {
    4298       213732 :   unsigned todo = 0;
    4299              : 
    4300       427464 :   if (number_of_loops (fun) <= 1)
    4301              :     return 0;
    4302              : 
    4303       213732 :   auto_vec<gimple *> preds;
    4304      1158138 :   for (auto loop : loops_list (cfun, 0))
    4305       516942 :     if ((flag_tree_loop_vectorize || loop->force_vectorize)
    4306       514078 :         && !loop->dont_vectorize)
    4307       509355 :       todo |= tree_if_conversion (loop, &preds);
    4308              : 
    4309       213732 :   if (todo)
    4310              :     {
    4311        17599 :       free_numbers_of_iterations_estimates (fun);
    4312        17599 :       scev_reset ();
    4313              :     }
    4314              : 
    4315       213732 :   if (flag_checking)
    4316              :     {
    4317       213728 :       basic_block bb;
    4318      7314316 :       FOR_EACH_BB_FN (bb, fun)
    4319      7100588 :         gcc_assert (!bb->aux);
    4320              :     }
    4321              : 
    4322              :   /* Perform IL update now, it might elide some loops.  */
    4323       213732 :   if (todo & TODO_cleanup_cfg)
    4324              :     {
    4325        17599 :       cleanup_tree_cfg ();
    4326        17599 :       if (need_ssa_update_p (fun))
    4327            0 :         todo |= TODO_update_ssa;
    4328              :     }
    4329       213732 :   if (todo & TODO_update_ssa_any)
    4330            0 :     update_ssa (todo & TODO_update_ssa_any);
    4331              : 
    4332              :   /* If if-conversion elided the loop fall back to the original one.  Likewise
    4333              :      if the loops are not nested in the same outer loop.  */
    4334       239533 :   for (unsigned i = 0; i < preds.length (); ++i)
    4335              :     {
    4336        25801 :       gimple *g = preds[i];
    4337        25801 :       if (!gimple_bb (g))
    4338            0 :         continue;
    4339        25801 :       auto ifcvt_loop = get_loop (fun, tree_to_uhwi (gimple_call_arg (g, 0)));
    4340        25801 :       auto orig_loop = get_loop (fun, tree_to_uhwi (gimple_call_arg (g, 1)));
    4341        25801 :       if (!ifcvt_loop || !orig_loop)
    4342              :         {
    4343            2 :           if (dump_file)
    4344            0 :             fprintf (dump_file, "If-converted loop vanished\n");
    4345            2 :           fold_loop_internal_call (g, boolean_false_node);
    4346              :         }
    4347        25799 :       else if (loop_outer (ifcvt_loop) != loop_outer (orig_loop))
    4348              :         {
    4349            0 :           if (dump_file)
    4350            0 :             fprintf (dump_file, "If-converted loop in different outer loop\n");
    4351            0 :           fold_loop_internal_call (g, boolean_false_node);
    4352              :         }
    4353              :     }
    4354              : 
    4355       213732 :   return 0;
    4356       213732 : }
    4357              : 
    4358              : } // anon namespace
    4359              : 
    4360              : gimple_opt_pass *
    4361       294536 : make_pass_if_conversion (gcc::context *ctxt)
    4362              : {
    4363       294536 :   return new pass_if_conversion (ctxt);
    4364              : }
        

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