LCOV - code coverage report
Current view: top level - gcc - tree-ssa-dom.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 94.1 % 1063 1000
Test Date: 2026-05-30 15:37:04 Functions: 100.0 % 43 43
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* SSA Dominator optimizations for trees
       2              :    Copyright (C) 2001-2026 Free Software Foundation, Inc.
       3              :    Contributed by Diego Novillo <dnovillo@redhat.com>
       4              : 
       5              : This file is part of GCC.
       6              : 
       7              : GCC is free software; you can redistribute it and/or modify
       8              : it under the terms of the GNU General Public License as published by
       9              : the Free Software Foundation; either version 3, or (at your option)
      10              : any later version.
      11              : 
      12              : GCC is distributed in the hope that it will be useful,
      13              : but WITHOUT ANY WARRANTY; without even the implied warranty of
      14              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15              : GNU General Public License 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              : #include "config.h"
      22              : #include "system.h"
      23              : #include "coretypes.h"
      24              : #include "backend.h"
      25              : #include "tree.h"
      26              : #include "gimple.h"
      27              : #include "tree-pass.h"
      28              : #include "ssa.h"
      29              : #include "gimple-pretty-print.h"
      30              : #include "fold-const.h"
      31              : #include "cfganal.h"
      32              : #include "cfgloop.h"
      33              : #include "gimple-iterator.h"
      34              : #include "gimple-fold.h"
      35              : #include "tree-eh.h"
      36              : #include "tree-inline.h"
      37              : #include "tree-cfg.h"
      38              : #include "tree-into-ssa.h"
      39              : #include "domwalk.h"
      40              : #include "tree-ssa-propagate.h"
      41              : #include "tree-ssa-threadupdate.h"
      42              : #include "tree-ssa-scopedtables.h"
      43              : #include "tree-ssa-threadedge.h"
      44              : #include "tree-ssa-dom.h"
      45              : #include "tree-cfgcleanup.h"
      46              : #include "dbgcnt.h"
      47              : #include "alloc-pool.h"
      48              : #include "tree-vrp.h"
      49              : #include "vr-values.h"
      50              : #include "gimple-range.h"
      51              : #include "gimple-range-path.h"
      52              : #include "alias.h"
      53              : 
      54              : /* This file implements optimizations on the dominator tree.  */
      55              : 
      56              : /* Structure for recording edge equivalences.
      57              : 
      58              :    Computing and storing the edge equivalences instead of creating
      59              :    them on-demand can save significant amounts of time, particularly
      60              :    for pathological cases involving switch statements.
      61              : 
      62              :    These structures live for a single iteration of the dominator
      63              :    optimizer in the edge's AUX field.  At the end of an iteration we
      64              :    free each of these structures.  */
      65              : class edge_info
      66              : {
      67              :  public:
      68              :   typedef std::pair <tree, tree> equiv_pair;
      69              :   edge_info (edge);
      70              :   ~edge_info ();
      71              : 
      72              :   /* Record a simple LHS = RHS equivalence.  This may trigger
      73              :      calls to derive_equivalences.  */
      74              :   void record_simple_equiv (tree, tree);
      75              : 
      76              :   /* If traversing this edge creates simple equivalences, we store
      77              :      them as LHS/RHS pairs within this vector.  */
      78              :   vec<equiv_pair> simple_equivalences;
      79              : 
      80              :   /* Traversing an edge may also indicate one or more particular conditions
      81              :      are true or false.  */
      82              :   vec<cond_equivalence> cond_equivalences;
      83              : 
      84              :  private:
      85              :   /* Derive equivalences by walking the use-def chains.  */
      86              :   void derive_equivalences (tree, tree, int);
      87              : };
      88              : 
      89              : /* Track whether or not we have changed the control flow graph.  */
      90              : static bool cfg_altered;
      91              : 
      92              : /* Bitmap of blocks that have had EH statements cleaned.  We should
      93              :    remove their dead edges eventually.  */
      94              : static bitmap need_eh_cleanup;
      95              : static vec<gimple *> need_noreturn_fixup;
      96              : 
      97              : /* Statistics for dominator optimizations.  */
      98              : struct opt_stats_d
      99              : {
     100              :   long num_stmts;
     101              :   long num_exprs_considered;
     102              :   long num_re;
     103              :   long num_const_prop;
     104              :   long num_copy_prop;
     105              : };
     106              : 
     107              : static struct opt_stats_d opt_stats;
     108              : 
     109              : /* Local functions.  */
     110              : static void record_equality (tree, tree, class const_and_copies *);
     111              : static void record_equivalences_from_phis (basic_block);
     112              : static void record_equivalences_from_incoming_edge (basic_block,
     113              :                                                     class const_and_copies *,
     114              :                                                     class avail_exprs_stack *,
     115              :                                                     bitmap blocks_on_stack);
     116              : static void eliminate_redundant_computations (gimple_stmt_iterator *,
     117              :                                               class const_and_copies *,
     118              :                                               class avail_exprs_stack *);
     119              : static void record_equivalences_from_stmt (gimple *, int,
     120              :                                            class avail_exprs_stack *);
     121              : static void dump_dominator_optimization_stats (FILE *file,
     122              :                                                hash_table<expr_elt_hasher> *);
     123              : static void record_temporary_equivalences (edge, class const_and_copies *,
     124              :                                            class avail_exprs_stack *, bitmap);
     125              : 
     126              : /* Constructor for EDGE_INFO.  An EDGE_INFO instance is always
     127              :    associated with an edge E.  */
     128              : 
     129     36059603 : edge_info::edge_info (edge e)
     130              : {
     131              :   /* Free the old one associated with E, if it exists and
     132              :      associate our new object with E.  */
     133     36059603 :   free_dom_edge_info (e);
     134     36059603 :   e->aux = this;
     135              : 
     136              :   /* And initialize the embedded vectors.  */
     137     36059603 :   simple_equivalences = vNULL;
     138     36059603 :   cond_equivalences = vNULL;
     139     36059603 : }
     140              : 
     141              : /* Destructor just needs to release the vectors.  */
     142              : 
     143     36059603 : edge_info::~edge_info (void)
     144              : {
     145     36059603 :   this->cond_equivalences.release ();
     146     36059603 :   this->simple_equivalences.release ();
     147     36059603 : }
     148              : 
     149              : /* NAME is known to have the value VALUE, which must be a constant.
     150              : 
     151              :    Walk through its use-def chain to see if there are other equivalences
     152              :    we might be able to derive.
     153              : 
     154              :    RECURSION_LIMIT controls how far back we recurse through the use-def
     155              :    chains.  */
     156              : 
     157              : void
     158     13105348 : edge_info::derive_equivalences (tree name, tree value, int recursion_limit)
     159              : {
     160     15086536 :   if (TREE_CODE (name) != SSA_NAME || TREE_CODE (value) != INTEGER_CST)
     161              :     return;
     162              : 
     163              :   /* This records the equivalence for the toplevel object.  Do
     164              :      this before checking the recursion limit.  */
     165     15086256 :   simple_equivalences.safe_push (equiv_pair (name, value));
     166              : 
     167              :   /* Limit how far up the use-def chains we are willing to walk.  */
     168     15086256 :   if (recursion_limit == 0)
     169              :     return;
     170              : 
     171              :   /* We can walk up the use-def chains to potentially find more
     172              :      equivalences.  */
     173     15071895 :   gimple *def_stmt = SSA_NAME_DEF_STMT (name);
     174     15071895 :   if (is_gimple_assign (def_stmt))
     175              :     {
     176      9667592 :       enum tree_code code = gimple_assign_rhs_code (def_stmt);
     177      9667592 :       switch (code)
     178              :         {
     179              :         /* If the result of an OR is zero, then its operands are, too.  */
     180       577476 :         case BIT_IOR_EXPR:
     181       577476 :           if (integer_zerop (value))
     182              :             {
     183       319288 :               tree rhs1 = gimple_assign_rhs1 (def_stmt);
     184       319288 :               tree rhs2 = gimple_assign_rhs2 (def_stmt);
     185              : 
     186       319288 :               value = build_zero_cst (TREE_TYPE (rhs1));
     187       319288 :               derive_equivalences (rhs1, value, recursion_limit - 1);
     188       319288 :               value = build_zero_cst (TREE_TYPE (rhs2));
     189       319288 :               derive_equivalences (rhs2, value, recursion_limit - 1);
     190              :             }
     191              :           break;
     192              : 
     193              :         /* If the result of an AND is nonzero, then its operands are, too.  */
     194      1013275 :         case BIT_AND_EXPR:
     195      1013275 :           if (!integer_zerop (value))
     196              :             {
     197       422511 :               tree rhs1 = gimple_assign_rhs1 (def_stmt);
     198       422511 :               tree rhs2 = gimple_assign_rhs2 (def_stmt);
     199              : 
     200              :               /* If either operand has a boolean range, then we
     201              :                  know its value must be one, otherwise we just know it
     202              :                  is nonzero.  The former is clearly useful, I haven't
     203              :                  seen cases where the latter is helpful yet.  */
     204       422511 :               if (TREE_CODE (rhs1) == SSA_NAME)
     205              :                 {
     206       422511 :                   if (ssa_name_has_boolean_range (rhs1))
     207              :                     {
     208       258538 :                       value = build_one_cst (TREE_TYPE (rhs1));
     209       258538 :                       derive_equivalences (rhs1, value, recursion_limit - 1);
     210              :                     }
     211              :                 }
     212       422511 :               if (TREE_CODE (rhs2) == SSA_NAME)
     213              :                 {
     214       260483 :                   if (ssa_name_has_boolean_range (rhs2))
     215              :                     {
     216       258255 :                       value = build_one_cst (TREE_TYPE (rhs2));
     217       258255 :                       derive_equivalences (rhs2, value, recursion_limit - 1);
     218              :                     }
     219              :                 }
     220              :             }
     221              :           break;
     222              : 
     223              :         /* If LHS is an SSA_NAME and RHS is a constant integer and LHS was
     224              :            set via a widening type conversion, then we may be able to record
     225              :            additional equivalences.  */
     226       428596 :         CASE_CONVERT:
     227       428596 :           {
     228       428596 :             tree rhs = gimple_assign_rhs1 (def_stmt);
     229       428596 :             tree rhs_type = TREE_TYPE (rhs);
     230       428596 :             if (INTEGRAL_TYPE_P (rhs_type)
     231       426201 :                 && (TYPE_PRECISION (TREE_TYPE (name))
     232       426201 :                     >= TYPE_PRECISION (rhs_type))
     233       660507 :                 && int_fits_type_p (value, rhs_type))
     234       222171 :               derive_equivalences (rhs,
     235              :                                    fold_convert (rhs_type, value),
     236              :                                    recursion_limit - 1);
     237              :             break;
     238              :           }
     239              : 
     240              :         /* We can invert the operation of these codes trivially if
     241              :            one of the RHS operands is a constant to produce a known
     242              :            value for the other RHS operand.  */
     243      1010972 :         case POINTER_PLUS_EXPR:
     244      1010972 :         case PLUS_EXPR:
     245      1010972 :           {
     246      1010972 :             tree rhs1 = gimple_assign_rhs1 (def_stmt);
     247      1010972 :             tree rhs2 = gimple_assign_rhs2 (def_stmt);
     248              : 
     249              :             /* If either argument is a constant, then we can compute
     250              :                a constant value for the nonconstant argument.  */
     251      1010972 :             if (TREE_CODE (rhs1) == INTEGER_CST
     252            0 :                 && TREE_CODE (rhs2) == SSA_NAME)
     253            0 :               derive_equivalences (rhs2,
     254            0 :                                    fold_binary (MINUS_EXPR, TREE_TYPE (rhs1),
     255              :                                                 value, rhs1),
     256              :                                    recursion_limit - 1);
     257      1010972 :             else if (TREE_CODE (rhs2) == INTEGER_CST
     258       958579 :                      && TREE_CODE (rhs1) == SSA_NAME)
     259       958579 :               derive_equivalences (rhs1,
     260       958579 :                                    fold_binary (MINUS_EXPR, TREE_TYPE (rhs1),
     261              :                                                 value, rhs2),
     262              :                                    recursion_limit - 1);
     263              :             break;
     264              :           }
     265              : 
     266              :         /* If one of the operands is a constant, then we can compute
     267              :            the value of the other operand.  If both operands are
     268              :            SSA_NAMEs, then they must be equal if the result is zero.  */
     269        74430 :         case MINUS_EXPR:
     270        74430 :           {
     271        74430 :             tree rhs1 = gimple_assign_rhs1 (def_stmt);
     272        74430 :             tree rhs2 = gimple_assign_rhs2 (def_stmt);
     273              : 
     274              :             /* If either argument is a constant, then we can compute
     275              :                a constant value for the nonconstant argument.  */
     276        74430 :             if (TREE_CODE (rhs1) == INTEGER_CST
     277          634 :                 && TREE_CODE (rhs2) == SSA_NAME)
     278          634 :               derive_equivalences (rhs2,
     279          634 :                                    fold_binary (MINUS_EXPR, TREE_TYPE (rhs1),
     280              :                                                 rhs1, value),
     281              :                                    recursion_limit - 1);
     282        73796 :             else if (TREE_CODE (rhs2) == INTEGER_CST
     283        29524 :                      && TREE_CODE (rhs1) == SSA_NAME)
     284        29524 :               derive_equivalences (rhs1,
     285        29524 :                                    fold_binary (PLUS_EXPR, TREE_TYPE (rhs1),
     286              :                                                 value, rhs2),
     287              :                                    recursion_limit - 1);
     288        44272 :             else if (integer_zerop (value))
     289              :               {
     290        16075 :                 tree cond = build2 (EQ_EXPR, boolean_type_node,
     291              :                                     gimple_assign_rhs1 (def_stmt),
     292              :                                     gimple_assign_rhs2 (def_stmt));
     293        16075 :                 tree inverted = invert_truthvalue (cond);
     294        16075 :                 record_conditions (&this->cond_equivalences, cond, inverted);
     295              :               }
     296              :             break;
     297              :           }
     298              : 
     299       667482 :         case EQ_EXPR:
     300       667482 :         case NE_EXPR:
     301       667482 :           {
     302       266991 :             if ((code == EQ_EXPR && integer_onep (value))
     303       794701 :                 || (code == NE_EXPR && integer_zerop (value)))
     304              :               {
     305       393517 :                 tree rhs1 = gimple_assign_rhs1 (def_stmt);
     306       393517 :                 tree rhs2 = gimple_assign_rhs2 (def_stmt);
     307              : 
     308              :                 /* If either argument is a constant, then record the
     309              :                    other argument as being the same as that constant.
     310              : 
     311              :                    If neither operand is a constant, then we have a
     312              :                    conditional name == name equivalence.  */
     313       393517 :                 if (TREE_CODE (rhs1) == INTEGER_CST)
     314            0 :                   derive_equivalences (rhs2, rhs1, recursion_limit - 1);
     315       393517 :                 else if (TREE_CODE (rhs2) == INTEGER_CST)
     316       179406 :                   derive_equivalences (rhs1, rhs2, recursion_limit - 1);
     317              :               }
     318              :             else
     319              :               {
     320       273965 :                 tree cond = build2 (code, boolean_type_node,
     321              :                                     gimple_assign_rhs1 (def_stmt),
     322       273965 :                                     gimple_assign_rhs2 (def_stmt));
     323       273965 :                 tree inverted = invert_truthvalue (cond);
     324       273965 :                 if (integer_zerop (value))
     325       127219 :                   std::swap (cond, inverted);
     326       273965 :                 record_conditions (&this->cond_equivalences, cond, inverted);
     327              :               }
     328              :             break;
     329              :           }
     330              : 
     331              :         /* For BIT_NOT and NEGATE, we can just apply the operation to the
     332              :            VALUE to get the new equivalence.  It will always be a constant
     333              :            so we can recurse.  */
     334        13331 :         case BIT_NOT_EXPR:
     335        13331 :         case NEGATE_EXPR:
     336        13331 :           {
     337        13331 :             tree rhs = gimple_assign_rhs1 (def_stmt);
     338        13331 :             tree res;
     339              :             /* If this is a NOT and the operand has a boolean range, then we
     340              :                know its value must be zero or one.  We are not supposed to
     341              :                have a BIT_NOT_EXPR for boolean types with precision > 1 in
     342              :                the general case, see e.g. the handling of TRUTH_NOT_EXPR in
     343              :                the gimplifier, but it can be generated by match.pd out of
     344              :                a BIT_XOR_EXPR wrapped in a BIT_AND_EXPR.  Now the handling
     345              :                of BIT_AND_EXPR above already forces a specific semantics for
     346              :                boolean types with precision > 1 so we must do the same here,
     347              :                otherwise we could change the semantics of TRUTH_NOT_EXPR for
     348              :                boolean types with precision > 1.  */
     349        13331 :             if (code == BIT_NOT_EXPR
     350        13117 :                 && TREE_CODE (rhs) == SSA_NAME
     351        26448 :                 && ssa_name_has_boolean_range (rhs))
     352              :               {
     353        12678 :                 if ((TREE_INT_CST_LOW (value) & 1) == 0)
     354         5864 :                   res = build_one_cst (TREE_TYPE (rhs));
     355              :                 else
     356         6814 :                   res = build_zero_cst (TREE_TYPE (rhs));
     357              :               }
     358              :             else
     359          653 :               res = fold_build1 (code, TREE_TYPE (rhs), value);
     360        13331 :             derive_equivalences (rhs, res, recursion_limit - 1);
     361        13331 :             break;
     362              :           }
     363              : 
     364      5882030 :         default:
     365      5882030 :           {
     366      5882030 :             if (TREE_CODE_CLASS (code) == tcc_comparison)
     367              :               {
     368       527957 :                 tree cond = build2 (code, boolean_type_node,
     369              :                                     gimple_assign_rhs1 (def_stmt),
     370       527957 :                                     gimple_assign_rhs2 (def_stmt));
     371       527957 :                 tree inverted = invert_truthvalue (cond);
     372       527957 :                 if (integer_zerop (value))
     373       227959 :                   std::swap (cond, inverted);
     374       527957 :                 record_conditions (&this->cond_equivalences, cond, inverted);
     375       527957 :                 break;
     376              :               }
     377              :             break;
     378              :           }
     379              :         }
     380              :     }
     381              : }
     382              : 
     383              : void
     384     15752094 : edge_info::record_simple_equiv (tree lhs, tree rhs)
     385              : {
     386              :   /* If the RHS is a constant, then we may be able to derive
     387              :      further equivalences.  Else just record the name = name
     388              :      equivalence.  */
     389     15752094 :   if (TREE_CODE (rhs) == INTEGER_CST)
     390     12527522 :     derive_equivalences (lhs, rhs, 4);
     391              :   else
     392      3224572 :     simple_equivalences.safe_push (equiv_pair (lhs, rhs));
     393     15752094 : }
     394              : 
     395              : /* Free the edge_info data attached to E, if it exists and
     396              :    clear e->aux.  */
     397              : 
     398              : void
     399    130002629 : free_dom_edge_info (edge e)
     400              : {
     401    130002629 :   class edge_info *edge_info = (class edge_info *)e->aux;
     402              : 
     403    130002629 :   if (edge_info)
     404     36059603 :     delete edge_info;
     405    130002629 :   e->aux = NULL;
     406    130002629 : }
     407              : 
     408              : /* Free all EDGE_INFO structures associated with edges in the CFG.
     409              :    If a particular edge can be threaded, copy the redirection
     410              :    target from the EDGE_INFO structure into the edge's AUX field
     411              :    as required by code to update the CFG and SSA graph for
     412              :    jump threading.  */
     413              : 
     414              : static void
     415      2088904 : free_all_edge_infos (void)
     416              : {
     417      2088904 :   basic_block bb;
     418      2088904 :   edge_iterator ei;
     419      2088904 :   edge e;
     420              : 
     421     23420318 :   FOR_EACH_BB_FN (bb, cfun)
     422              :     {
     423     51434205 :       FOR_EACH_EDGE (e, ei, bb->preds)
     424     30102791 :         free_dom_edge_info (e);
     425              :     }
     426      2088904 : }
     427              : 
     428              : /* Return TRUE if BB has precisely two preds, one of which
     429              :    is a backedge from a forwarder block where the forwarder
     430              :    block is a direct successor of BB.  Being a forwarder
     431              :    block, it has no side effects other than transfer of
     432              :    control.  Otherwise return FALSE.  */
     433              : 
     434              : static bool
     435     18047579 : single_block_loop_p (basic_block bb)
     436              : {
     437              :   /* Two preds.  */
     438     18047579 :   if (EDGE_COUNT (bb->preds) != 2)
     439              :     return false;
     440              : 
     441              :   /* One and only one of the edges must be marked with
     442              :      EDGE_DFS_BACK.  */
     443      5254173 :   basic_block pred = NULL;
     444      5254173 :   unsigned int count = 0;
     445      5254173 :   if (EDGE_PRED (bb, 0)->flags & EDGE_DFS_BACK)
     446              :     {
     447      1871779 :       pred = EDGE_PRED (bb, 0)->src;
     448      1871779 :       count++;
     449              :     }
     450      5254173 :   if (EDGE_PRED (bb, 1)->flags & EDGE_DFS_BACK)
     451              :     {
     452       402368 :       pred = EDGE_PRED (bb, 1)->src;
     453       402368 :       count++;
     454              :     }
     455              : 
     456      5254173 :   if (count != 1)
     457              :     return false;
     458              : 
     459              :   /* Now examine PRED.  It should have a single predecessor which
     460              :      is BB and a single successor that is also BB.  */
     461      2274147 :   if (EDGE_COUNT (pred->preds) != 1
     462     19207931 :       || EDGE_COUNT (pred->succs) != 1
     463      2193619 :       || EDGE_PRED (pred, 0)->src != bb
     464      3369334 :       || EDGE_SUCC (pred, 0)->dest != bb)
     465              :     return false;
     466              : 
     467              :   /* This looks good from a CFG standpoint.  Now look at the guts
     468              :      of PRED.  Basically we want to verify there are no PHI nodes
     469              :      and no real statements.  */
     470      1095187 :   if (! gimple_seq_empty_p (phi_nodes (pred)))
     471              :     return false;
     472              : 
     473      1090537 :   gimple_stmt_iterator gsi;
     474      2203928 :   for (gsi = gsi_last_bb (pred); !gsi_end_p (gsi); gsi_prev (&gsi))
     475              :     {
     476        68697 :       gimple *stmt = gsi_stmt (gsi);
     477              : 
     478        68697 :       switch (gimple_code (stmt))
     479              :         {
     480            0 :           case GIMPLE_LABEL:
     481            0 :             if (DECL_NONLOCAL (gimple_label_label (as_a <glabel *> (stmt))))
     482              :               return false;
     483              :             break;
     484              : 
     485              :           case GIMPLE_DEBUG:
     486              :             break;
     487              : 
     488              :           default:
     489              :             return false;
     490              :         }
     491              :     }
     492              : 
     493              :   return true;
     494              : }
     495              : 
     496              : /* We have finished optimizing BB, record any information implied by
     497              :    taking a specific outgoing edge from BB.  */
     498              : 
     499              : static void
     500     44681135 : record_edge_info (basic_block bb)
     501              : {
     502     44681135 :   gimple_stmt_iterator gsi = gsi_last_bb (bb);
     503     44681135 :   class edge_info *edge_info;
     504              : 
     505              :   /* Free all the outgoing edge info data associated with
     506              :      BB's outgoing edges.  */
     507     44681135 :   edge e;
     508     44681135 :   edge_iterator ei;
     509    106806700 :   FOR_EACH_EDGE (e, ei, bb->succs)
     510     62125565 :     free_dom_edge_info (e);
     511              : 
     512     44681135 :   if (! gsi_end_p (gsi))
     513              :     {
     514     38510523 :       gimple *stmt = gsi_stmt (gsi);
     515     38510523 :       location_t loc = gimple_location (stmt);
     516              : 
     517     38510523 :       if (gimple_code (stmt) == GIMPLE_SWITCH)
     518              :         {
     519        66053 :           gswitch *switch_stmt = as_a <gswitch *> (stmt);
     520        66053 :           tree index = gimple_switch_index (switch_stmt);
     521              : 
     522        66053 :           if (TREE_CODE (index) == SSA_NAME)
     523              :             {
     524        66037 :               int i;
     525        66037 :               int n_labels = gimple_switch_num_labels (switch_stmt);
     526              :               /* info contains NULL, error_mark_node or a value.
     527              :                  error_mark signifies there are multiple values already.
     528              :                  A NULL signifies there it is uninitialized.
     529              :                  A value signifies that is the only value on that edge
     530              :                  to that bb.  */
     531        66037 :               tree *info = XCNEWVEC (tree, last_basic_block_for_fn (cfun));
     532              : 
     533       534938 :               for (i = 0; i < n_labels; i++)
     534              :                 {
     535       468901 :                   tree label = gimple_switch_label (switch_stmt, i);
     536       468901 :                   basic_block target_bb
     537       468901 :                     = label_to_block (cfun, CASE_LABEL (label));
     538              :                   /* The default case is a case with multiple values.
     539              :                      If the value is already set then it has multiple values.  */
     540       468901 :                   if (CASE_HIGH (label)
     541       442795 :                       || !CASE_LOW (label)
     542       845659 :                       || info[target_bb->index])
     543       141573 :                     info[target_bb->index] = error_mark_node;
     544              :                   else
     545              :                     /* Record the one value that can be on that edge to the
     546              :                        target_bb.  */
     547       327328 :                     info[target_bb->index] = CASE_LOW (label);
     548              :                 }
     549              : 
     550       478692 :               FOR_EACH_EDGE (e, ei, bb->succs)
     551              :                 {
     552       412655 :                   basic_block target_bb = e->dest;
     553       412655 :                   tree value = info[target_bb->index];
     554              : 
     555       412655 :                   if (value != NULL && value != error_mark_node)
     556              :                     {
     557       300509 :                       tree x = fold_convert_loc (loc, TREE_TYPE (index),
     558              :                                                  value);
     559       300509 :                       edge_info = new class edge_info (e);
     560       300509 :                       edge_info->record_simple_equiv (index, x);
     561              :                     }
     562              :                 }
     563        66037 :               free (info);
     564              :             }
     565              :         }
     566              : 
     567              :       /* A COND_EXPR may create equivalences too.  */
     568     38510523 :       if (gimple_code (stmt) == GIMPLE_COND)
     569              :         {
     570     18047579 :           edge true_edge;
     571     18047579 :           edge false_edge;
     572              : 
     573     18047579 :           tree op0 = gimple_cond_lhs (stmt);
     574     18047579 :           tree op1 = gimple_cond_rhs (stmt);
     575     18047579 :           enum tree_code code = gimple_cond_code (stmt);
     576              : 
     577     18047579 :           extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
     578              : 
     579              :           /* Special case comparing booleans against a constant as we
     580              :              know the value of OP0 on both arms of the branch.  i.e., we
     581              :              can record an equivalence for OP0 rather than COND.
     582              : 
     583              :              However, don't do this if the constant isn't zero or one.
     584              :              Such conditionals will get optimized more thoroughly during
     585              :              the domwalk.  */
     586     18047579 :           if ((code == EQ_EXPR || code == NE_EXPR)
     587     13833673 :               && TREE_CODE (op0) == SSA_NAME
     588     13665856 :               && ssa_name_has_boolean_range (op0)
     589      2053424 :               && is_gimple_min_invariant (op1)
     590     20038792 :               && (integer_zerop (op1) || integer_onep (op1)))
     591              :             {
     592      1991213 :               tree true_val = constant_boolean_node (true, TREE_TYPE (op0));
     593      1991213 :               tree false_val = constant_boolean_node (false, TREE_TYPE (op0));
     594              : 
     595      1991213 :               if (code == EQ_EXPR)
     596              :                 {
     597        80085 :                   edge_info = new class edge_info (true_edge);
     598       118514 :                   edge_info->record_simple_equiv (op0,
     599        80085 :                                                   (integer_zerop (op1)
     600              :                                                    ? false_val : true_val));
     601        80085 :                   edge_info = new class edge_info (false_edge);
     602       118514 :                   edge_info->record_simple_equiv (op0,
     603        80085 :                                                   (integer_zerop (op1)
     604              :                                                    ? true_val : false_val));
     605              :                 }
     606              :               else
     607              :                 {
     608      1911128 :                   edge_info = new class edge_info (true_edge);
     609      1914376 :                   edge_info->record_simple_equiv (op0,
     610      1911128 :                                                   (integer_zerop (op1)
     611              :                                                    ? true_val : false_val));
     612      1911128 :                   edge_info = new class edge_info (false_edge);
     613      1914376 :                   edge_info->record_simple_equiv (op0,
     614      1911128 :                                                   (integer_zerop (op1)
     615              :                                                    ? false_val : true_val));
     616              :                 }
     617              :             }
     618              :           /* This can show up in the IL as a result of copy propagation
     619              :              it will eventually be canonicalized, but we have to cope
     620              :              with this case within the pass.  */
     621     16056366 :           else if (is_gimple_min_invariant (op0)
     622     16056366 :                    && TREE_CODE (op1) == SSA_NAME)
     623              :             {
     624            0 :               tree cond = build2 (code, boolean_type_node, op0, op1);
     625            0 :               tree inverted = invert_truthvalue_loc (loc, cond);
     626            0 :               bool can_infer_simple_equiv
     627            0 :                 = !(HONOR_SIGNED_ZEROS (op0) && real_maybe_zerop (op0))
     628            0 :                   && !DECIMAL_FLOAT_MODE_P (element_mode (TREE_TYPE (op0)));
     629            0 :               class edge_info *edge_info;
     630              : 
     631            0 :               edge_info = new class edge_info (true_edge);
     632            0 :               record_conditions (&edge_info->cond_equivalences, cond, inverted);
     633              : 
     634            0 :               if (can_infer_simple_equiv && code == EQ_EXPR)
     635            0 :                 edge_info->record_simple_equiv (op1, op0);
     636              : 
     637            0 :               edge_info = new class edge_info (false_edge);
     638            0 :               record_conditions (&edge_info->cond_equivalences, inverted, cond);
     639              : 
     640            0 :               if (can_infer_simple_equiv && TREE_CODE (inverted) == EQ_EXPR)
     641            0 :                 edge_info->record_simple_equiv (op1, op0);
     642              :             }
     643              : 
     644     16056366 :           else if (TREE_CODE (op0) == SSA_NAME
     645     16056366 :                    && (TREE_CODE (op1) == SSA_NAME
     646     11791919 :                        || is_gimple_min_invariant (op1)))
     647              :             {
     648     15888016 :               tree cond = build2 (code, boolean_type_node, op0, op1);
     649     15888016 :               tree inverted = invert_truthvalue_loc (loc, cond);
     650     15888016 :               bool can_infer_simple_equiv
     651     16581031 :                 = !(HONOR_SIGNED_ZEROS (op1) && real_maybe_zerop (op1))
     652     16284694 :                   && !DECIMAL_FLOAT_MODE_P (element_mode (TREE_TYPE (op1)));
     653     15888016 :               class edge_info *edge_info;
     654              : 
     655     15888016 :               edge_info = new class edge_info (true_edge);
     656     15888016 :               record_conditions (&edge_info->cond_equivalences, cond, inverted);
     657              : 
     658     15888016 :               if (can_infer_simple_equiv && code == EQ_EXPR)
     659      5367844 :                 edge_info->record_simple_equiv (op0, op1);
     660              : 
     661     15888016 :               edge_info = new class edge_info (false_edge);
     662     15888016 :               record_conditions (&edge_info->cond_equivalences, inverted, cond);
     663              : 
     664     15888016 :               if (can_infer_simple_equiv && TREE_CODE (inverted) == EQ_EXPR)
     665      6099992 :                 edge_info->record_simple_equiv (op0, op1);
     666              :             }
     667              : 
     668              :           /* If this block is a single block loop, then we may be able to
     669              :              record some equivalences on the loop's exit edge.  */
     670     18047579 :           if (single_block_loop_p (bb))
     671              :             {
     672              :               /* We know it's a single block loop.  Now look at the loop
     673              :                  exit condition.  What we're looking for is whether or not
     674              :                  the exit condition is loop invariant which we can detect
     675              :                  by checking if all the SSA_NAMEs referenced are defined
     676              :                  outside the loop.  */
     677      1033267 :               if ((TREE_CODE (op0) != SSA_NAME
     678      1032588 :                    || gimple_bb (SSA_NAME_DEF_STMT (op0)) != bb)
     679      1199305 :                   && (TREE_CODE (op1) != SSA_NAME
     680       164359 :                       || gimple_bb (SSA_NAME_DEF_STMT (op1)) != bb))
     681              :                 {
     682              :                   /* At this point we know the exit condition is loop
     683              :                      invariant.  The only way to get out of the loop is
     684              :                      if it never traverses the backedge to begin with.  This
     685              :                      implies that any PHI nodes create equivalances that we
     686              :                      can attach to the loop exit edge.  */
     687         2483 :                   bool alternative
     688         2483 :                     = (EDGE_PRED (bb, 0)->flags & EDGE_DFS_BACK) ? 1 : 0;
     689              : 
     690         2483 :                   gphi_iterator gsi;
     691         2483 :                   for (gsi = gsi_start_phis (bb);
     692         4165 :                        !gsi_end_p (gsi);
     693         1682 :                        gsi_next (&gsi))
     694              :                     {
     695              :                       /* Now get the EDGE_INFO class so we can append
     696              :                          it to our list.  We want the successor edge
     697              :                          where the destination is not the source of
     698              :                          an incoming edge.  */
     699         1682 :                       gphi *phi = gsi.phi ();
     700         1682 :                       tree src = PHI_ARG_DEF (phi, alternative);
     701         1682 :                       tree dst = PHI_RESULT (phi);
     702              : 
     703              :                       /* If the other alternative is the same as the result,
     704              :                          then this is a degenerate and can be ignored.  */
     705         1682 :                       if (dst == PHI_ARG_DEF (phi, !alternative))
     706          359 :                         continue;
     707              : 
     708         1323 :                       if (EDGE_SUCC (bb, 0)->dest
     709         1323 :                           != EDGE_PRED (bb, !alternative)->src)
     710          369 :                         edge_info = (class edge_info *)EDGE_SUCC (bb, 0)->aux;
     711              :                       else
     712          954 :                         edge_info = (class edge_info *)EDGE_SUCC (bb, 1)->aux;
     713              : 
     714              :                       /* Note that since this processing is done independently
     715              :                          of other edge equivalency processing, we may not
     716              :                          have an EDGE_INFO structure set up yet.  */
     717         1323 :                       if (edge_info == NULL)
     718          636 :                         edge_info = new class edge_info (false_edge);
     719         1323 :                       edge_info->record_simple_equiv (dst, src);
     720              :                     }
     721              :                 }
     722              :             }
     723              :         }
     724              :     }
     725     44681135 : }
     726              : 
     727              : class dom_jt_state : public jt_state
     728              : {
     729              : public:
     730      2088904 :   dom_jt_state (const_and_copies *copies, avail_exprs_stack *avails)
     731      2088904 :     : m_copies (copies), m_avails (avails)
     732              :   {
     733      2088904 :     bitmap_tree_view (m_blocks_on_stack);
     734      2088904 :   }
     735     16580831 :   void push (edge e) override
     736              :   {
     737     16580831 :     m_copies->push_marker ();
     738     16580831 :     m_avails->push_marker ();
     739     16580831 :     jt_state::push (e);
     740     16580831 :   }
     741     16580831 :   void pop () override
     742              :   {
     743     16580831 :     m_copies->pop_to_marker ();
     744     16580831 :     m_avails->pop_to_marker ();
     745     16580831 :     jt_state::pop ();
     746     16580831 :   }
     747     15342707 :   void register_equivs_edge (edge e) override
     748              :   {
     749     15342707 :     record_temporary_equivalences (e, m_copies, m_avails, m_blocks_on_stack);
     750     15342707 :   }
     751              :   void register_equiv (tree dest, tree src, bool update) override;
     752     70049163 :   bitmap get_blocks_on_stack () { return m_blocks_on_stack; }
     753              : private:
     754              :   const_and_copies *m_copies;
     755              :   avail_exprs_stack *m_avails;
     756              :   /* Set of blocks on the stack, to be used for medium-fast
     757              :      dominance queries in back_propagate_equivalences.  */
     758              :   auto_bitmap m_blocks_on_stack;
     759              : };
     760              : 
     761              : void
     762     20752217 : dom_jt_state::register_equiv (tree dest, tree src, bool)
     763              : {
     764     20752217 :   m_copies->record_const_or_copy (dest, src);
     765     20752217 : }
     766              : 
     767      2088904 : class dom_jt_simplifier : public hybrid_jt_simplifier
     768              : {
     769              : public:
     770      2088904 :   dom_jt_simplifier (avail_exprs_stack *avails, gimple_ranger *ranger,
     771              :                      path_range_query *query)
     772      4177808 :     : hybrid_jt_simplifier (ranger, query), m_avails (avails) { }
     773              : 
     774              : private:
     775              :   tree simplify (gimple *, gimple *, basic_block, jt_state *) override;
     776              :   avail_exprs_stack *m_avails;
     777              : };
     778              : 
     779              : tree
     780     30744032 : dom_jt_simplifier::simplify (gimple *stmt, gimple *within_stmt,
     781              :                              basic_block bb, jt_state *state)
     782              : {
     783              :   /* First see if the conditional is in the hash table.  */
     784     30744032 :   tree cached_lhs =  m_avails->lookup_avail_expr (stmt, false, true);
     785     30744032 :   if (cached_lhs)
     786              :     return cached_lhs;
     787              : 
     788              :   /* Otherwise call the ranger if possible.  */
     789     29946112 :   if (state)
     790      8482171 :     return hybrid_jt_simplifier::simplify (stmt, within_stmt, bb, state);
     791              : 
     792              :   return NULL;
     793              : }
     794              : 
     795      4177808 : class dom_opt_dom_walker : public dom_walker
     796              : {
     797              : public:
     798      2088904 :   dom_opt_dom_walker (cdi_direction direction,
     799              :                       jump_threader *threader,
     800              :                       dom_jt_state *state,
     801              :                       gimple_ranger *ranger,
     802              :                       const_and_copies *const_and_copies,
     803              :                       avail_exprs_stack *avail_exprs_stack)
     804      2088904 :     : dom_walker (direction, REACHABLE_BLOCKS)
     805              :     {
     806      2088904 :       m_ranger = ranger;
     807      2088904 :       m_state = state;
     808      2088904 :       m_dummy_cond = gimple_build_cond (NE_EXPR, integer_zero_node,
     809              :                                         integer_zero_node, NULL, NULL);
     810      2088904 :       m_const_and_copies = const_and_copies;
     811      2088904 :       m_avail_exprs_stack = avail_exprs_stack;
     812      2088904 :       m_threader = threader;
     813      2088904 :     }
     814              : 
     815              :   edge before_dom_children (basic_block) final override;
     816              :   void after_dom_children (basic_block) final override;
     817              : 
     818              : private:
     819              : 
     820              :   /* Unwindable equivalences, both const/copy and expression varieties.  */
     821              :   class const_and_copies *m_const_and_copies;
     822              :   class avail_exprs_stack *m_avail_exprs_stack;
     823              : 
     824              :   /* Dummy condition to avoid creating lots of throw away statements.  */
     825              :   gcond *m_dummy_cond;
     826              : 
     827              :   /* Optimize a single statement within a basic block using the
     828              :      various tables mantained by DOM.  Returns the taken edge if
     829              :      the statement is a conditional with a statically determined
     830              :      value.  */
     831              :   edge optimize_stmt (basic_block, gimple_stmt_iterator *, bool *);
     832              : 
     833              :   void set_global_ranges_from_unreachable_edges (basic_block);
     834              : 
     835              :   void test_for_singularity (gimple *, avail_exprs_stack *);
     836              :   edge fold_cond (gcond *cond);
     837              : 
     838              :   jump_threader *m_threader;
     839              :   gimple_ranger *m_ranger;
     840              :   dom_jt_state *m_state;
     841              : };
     842              : 
     843              : /* Jump threading, redundancy elimination and const/copy propagation.
     844              : 
     845              :    This pass may expose new symbols that need to be renamed into SSA.  For
     846              :    every new symbol exposed, its corresponding bit will be set in
     847              :    VARS_TO_RENAME.  */
     848              : 
     849              : namespace {
     850              : 
     851              : const pass_data pass_data_dominator =
     852              : {
     853              :   GIMPLE_PASS, /* type */
     854              :   "dom", /* name */
     855              :   OPTGROUP_NONE, /* optinfo_flags */
     856              :   TV_TREE_SSA_DOMINATOR_OPTS, /* tv_id */
     857              :   ( PROP_cfg | PROP_ssa ), /* properties_required */
     858              :   0, /* properties_provided */
     859              :   0, /* properties_destroyed */
     860              :   0, /* todo_flags_start */
     861              :   ( TODO_cleanup_cfg | TODO_update_ssa ), /* todo_flags_finish */
     862              : };
     863              : 
     864              : class pass_dominator : public gimple_opt_pass
     865              : {
     866              : public:
     867       866301 :   pass_dominator (gcc::context *ctxt)
     868       866301 :     : gimple_opt_pass (pass_data_dominator, ctxt),
     869      1732602 :       may_peel_loop_headers_p (false)
     870              :   {}
     871              : 
     872              :   /* opt_pass methods: */
     873       577534 :   opt_pass * clone () final override { return new pass_dominator (m_ctxt); }
     874       866301 :   void set_pass_param (unsigned int n, bool param) final override
     875              :     {
     876       866301 :       gcc_assert (n == 0);
     877       866301 :       may_peel_loop_headers_p = param;
     878       866301 :     }
     879      2089691 :   bool gate (function *) final override { return flag_tree_dom != 0; }
     880              :   unsigned int execute (function *) final override;
     881              : 
     882              :  private:
     883              :   /* This flag is used to prevent loops from being peeled repeatedly in jump
     884              :      threading; it will be removed once we preserve loop structures throughout
     885              :      the compilation -- we will be able to mark the affected loops directly in
     886              :      jump threading, and avoid peeling them next time.  */
     887              :   bool may_peel_loop_headers_p;
     888              : }; // class pass_dominator
     889              : 
     890              : unsigned int
     891      2088904 : pass_dominator::execute (function *fun)
     892              : {
     893      2088904 :   memset (&opt_stats, 0, sizeof (opt_stats));
     894              : 
     895              :   /* Create our hash tables.  */
     896      2088904 :   hash_table<expr_elt_hasher> *avail_exprs
     897      2088904 :     = new hash_table<expr_elt_hasher> (1024);
     898      2088904 :   class avail_exprs_stack *avail_exprs_stack
     899      2088904 :     = new class avail_exprs_stack (avail_exprs);
     900      2088904 :   class const_and_copies *const_and_copies = new class const_and_copies ();
     901      2088904 :   need_eh_cleanup = BITMAP_ALLOC (NULL);
     902      2088904 :   need_noreturn_fixup.create (0);
     903              : 
     904      2088904 :   calculate_dominance_info (CDI_DOMINATORS);
     905      2088904 :   cfg_altered = false;
     906              : 
     907              :   /* We need to know loop structures in order to avoid destroying them
     908              :      in jump threading.  Note that we still can e.g. thread through loop
     909              :      headers to an exit edge, or through loop header to the loop body, assuming
     910              :      that we update the loop info.
     911              : 
     912              :      TODO: We don't need to set LOOPS_HAVE_PREHEADERS generally, but due
     913              :      to several overly conservative bail-outs in jump threading, case
     914              :      gcc.dg/tree-ssa/pr21417.c can't be threaded if loop preheader is
     915              :      missing.  We should improve jump threading in future then
     916              :      LOOPS_HAVE_PREHEADERS won't be needed here.  */
     917      2088904 :   loop_optimizer_init (LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES
     918              :                        | LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS);
     919              : 
     920              :   /* We need accurate information regarding back edges in the CFG
     921              :      for jump threading; this may include back edges that are not part of
     922              :      a single loop.  */
     923      2088904 :   mark_dfs_back_edges ();
     924              : 
     925              :   /* We want to create the edge info structures before the dominator walk
     926              :      so that they'll be in place for the jump threader, particularly when
     927              :      threading through a join block.
     928              : 
     929              :      The conditions will be lazily updated with global equivalences as
     930              :      we reach them during the dominator walk.  */
     931      2088904 :   basic_block bb;
     932     23420318 :   FOR_EACH_BB_FN (bb, fun)
     933     21331414 :     record_edge_info (bb);
     934              : 
     935              :   /* Recursively walk the dominator tree optimizing statements.  */
     936      2088904 :   gimple_ranger *ranger = enable_ranger (fun);
     937      2088904 :   path_range_query path_query (*ranger);
     938      2088904 :   dom_jt_simplifier simplifier (avail_exprs_stack, ranger, &path_query);
     939      2088904 :   dom_jt_state state (const_and_copies, avail_exprs_stack);
     940      2088904 :   jump_threader threader (&simplifier, &state);
     941      2088904 :   dom_opt_dom_walker walker (CDI_DOMINATORS,
     942              :                              &threader,
     943              :                              &state,
     944              :                              ranger,
     945              :                              const_and_copies,
     946      2088904 :                              avail_exprs_stack);
     947      2088904 :   walker.walk (fun->cfg->x_entry_block_ptr);
     948              : 
     949      2088904 :   ranger->export_global_ranges ();
     950      2088904 :   disable_ranger (fun);
     951              : 
     952              :   /* Look for blocks where we cleared EDGE_EXECUTABLE on an outgoing
     953              :      edge.  When found, remove jump threads which contain any outgoing
     954              :      edge from the affected block.  */
     955      2088904 :   if (cfg_altered)
     956              :     {
     957      4362536 :       FOR_EACH_BB_FN (bb, fun)
     958              :         {
     959      4305220 :           edge_iterator ei;
     960      4305220 :           edge e;
     961              : 
     962              :           /* First see if there are any edges without EDGE_EXECUTABLE
     963              :              set.  */
     964      4305220 :           bool found = false;
     965     10319556 :           FOR_EACH_EDGE (e, ei, bb->succs)
     966              :             {
     967      6220663 :               if ((e->flags & EDGE_EXECUTABLE) == 0)
     968              :                 {
     969              :                   found = true;
     970              :                   break;
     971              :                 }
     972              :             }
     973              : 
     974              :           /* If there were any such edges found, then remove jump threads
     975              :              containing any edge leaving BB.  */
     976      4305220 :           if (found)
     977       602237 :             FOR_EACH_EDGE (e, ei, bb->succs)
     978       395910 :               threader.remove_jump_threads_including (e);
     979              :         }
     980              :     }
     981              : 
     982      2088904 :   {
     983      2088904 :     gimple_stmt_iterator gsi;
     984      2088904 :     basic_block bb;
     985     23420318 :     FOR_EACH_BB_FN (bb, fun)
     986              :       {
     987    214806923 :         for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
     988    172144095 :           update_stmt_if_modified (gsi_stmt (gsi));
     989              :       }
     990              :   }
     991              : 
     992              :   /* If we exposed any new variables, go ahead and put them into
     993              :      SSA form now, before we handle jump threading.  This simplifies
     994              :      interactions between rewriting of _DECL nodes into SSA form
     995              :      and rewriting SSA_NAME nodes into SSA form after block
     996              :      duplication and CFG manipulation.  */
     997      2088904 :   update_ssa (TODO_update_ssa);
     998              : 
     999      2088904 :   free_all_edge_infos ();
    1000              : 
    1001              :   /* Thread jumps, creating duplicate blocks as needed.  */
    1002      2088904 :   cfg_altered |= threader.thread_through_all_blocks (may_peel_loop_headers_p);
    1003              : 
    1004      2088904 :   if (cfg_altered)
    1005       133205 :     free_dominance_info (CDI_DOMINATORS);
    1006              : 
    1007              :   /* Removal of statements may make some EH edges dead.  Purge
    1008              :      such edges from the CFG as needed.  */
    1009      2088904 :   if (!bitmap_empty_p (need_eh_cleanup))
    1010              :     {
    1011          624 :       unsigned i;
    1012          624 :       bitmap_iterator bi;
    1013              : 
    1014              :       /* Jump threading may have created forwarder blocks from blocks
    1015              :          needing EH cleanup; the new successor of these blocks, which
    1016              :          has inherited from the original block, needs the cleanup.
    1017              :          Don't clear bits in the bitmap, as that can break the bitmap
    1018              :          iterator.  */
    1019         1996 :       EXECUTE_IF_SET_IN_BITMAP (need_eh_cleanup, 0, i, bi)
    1020              :         {
    1021         1372 :           basic_block bb = BASIC_BLOCK_FOR_FN (fun, i);
    1022         1372 :           if (bb == NULL)
    1023            0 :             continue;
    1024         2815 :           while (single_succ_p (bb)
    1025         1486 :                  && (single_succ_edge (bb)->flags
    1026          123 :                      & (EDGE_EH|EDGE_DFS_BACK)) == 0)
    1027          114 :             bb = single_succ (bb);
    1028         1372 :           if (bb == EXIT_BLOCK_PTR_FOR_FN (fun))
    1029           43 :             continue;
    1030         1329 :           if ((unsigned) bb->index != i)
    1031           55 :             bitmap_set_bit (need_eh_cleanup, bb->index);
    1032              :         }
    1033              : 
    1034          624 :       gimple_purge_all_dead_eh_edges (need_eh_cleanup);
    1035          624 :       bitmap_clear (need_eh_cleanup);
    1036              :     }
    1037              : 
    1038              :   /* Fixup stmts that became noreturn calls.  This may require splitting
    1039              :      blocks and thus isn't possible during the dominator walk or before
    1040              :      jump threading finished.  Do this in reverse order so we don't
    1041              :      inadvertedly remove a stmt we want to fixup by visiting a dominating
    1042              :      now noreturn call first.  */
    1043      2088907 :   while (!need_noreturn_fixup.is_empty ())
    1044              :     {
    1045            3 :       gimple *stmt = need_noreturn_fixup.pop ();
    1046            3 :       if (dump_file && dump_flags & TDF_DETAILS)
    1047              :         {
    1048            0 :           fprintf (dump_file, "Fixing up noreturn call ");
    1049            0 :           print_gimple_stmt (dump_file, stmt, 0);
    1050            0 :           fprintf (dump_file, "\n");
    1051              :         }
    1052            3 :       fixup_noreturn_call (stmt);
    1053              :     }
    1054              : 
    1055      2088904 :   statistics_counter_event (fun, "Redundant expressions eliminated",
    1056      2088904 :                             opt_stats.num_re);
    1057      2088904 :   statistics_counter_event (fun, "Constants propagated",
    1058      2088904 :                             opt_stats.num_const_prop);
    1059      2088904 :   statistics_counter_event (fun, "Copies propagated",
    1060      2088904 :                             opt_stats.num_copy_prop);
    1061              : 
    1062              :   /* Debugging dumps.  */
    1063      2088904 :   if (dump_file && (dump_flags & TDF_STATS))
    1064           35 :     dump_dominator_optimization_stats (dump_file, avail_exprs);
    1065              : 
    1066      2088904 :   loop_optimizer_finalize ();
    1067              : 
    1068              :   /* Delete our main hashtable.  */
    1069      2088904 :   delete avail_exprs;
    1070      2088904 :   avail_exprs = NULL;
    1071              : 
    1072              :   /* Free asserted bitmaps and stacks.  */
    1073      2088904 :   BITMAP_FREE (need_eh_cleanup);
    1074      2088904 :   need_noreturn_fixup.release ();
    1075      2088904 :   delete avail_exprs_stack;
    1076      2088904 :   delete const_and_copies;
    1077              : 
    1078      2088904 :   return 0;
    1079      2088904 : }
    1080              : 
    1081              : } // anon namespace
    1082              : 
    1083              : gimple_opt_pass *
    1084       288767 : make_pass_dominator (gcc::context *ctxt)
    1085              : {
    1086       288767 :   return new pass_dominator (ctxt);
    1087              : }
    1088              : 
    1089              : /* Valueize hook for gimple_fold_stmt_to_constant_1.  */
    1090              : 
    1091              : static tree
    1092     33776853 : dom_valueize (tree t)
    1093              : {
    1094     33776853 :   if (TREE_CODE (t) == SSA_NAME)
    1095              :     {
    1096     24206075 :       tree tem = SSA_NAME_VALUE (t);
    1097     19111264 :       if (tem)
    1098      2985473 :         return tem;
    1099              :     }
    1100              :   return t;
    1101              : }
    1102              : 
    1103              : /* We have just found an equivalence for LHS on an edge E.
    1104              :    Look backwards to other uses of LHS and see if we can derive
    1105              :    additional equivalences that are valid on edge E.  */
    1106              : static void
    1107     11893157 : back_propagate_equivalences (tree lhs, edge e,
    1108              :                              class const_and_copies *const_and_copies,
    1109              :                              bitmap domby)
    1110              : {
    1111     11893157 :   use_operand_p use_p;
    1112     11893157 :   imm_use_iterator iter;
    1113     11893157 :   basic_block dest = e->dest;
    1114     11893157 :   bool domok = (dom_info_state (CDI_DOMINATORS) == DOM_OK);
    1115              : 
    1116              :   /* Iterate over the uses of LHS to see if any dominate E->dest.
    1117              :      If so, they may create useful equivalences too.
    1118              : 
    1119              :      ???  If the code gets re-organized to a worklist to catch more
    1120              :      indirect opportunities and it is made to handle PHIs then this
    1121              :      should only consider use_stmts in basic-blocks we have already visited.  */
    1122     63197495 :   FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
    1123              :     {
    1124     39411181 :       gimple *use_stmt = USE_STMT (use_p);
    1125              : 
    1126              :       /* Often the use is in DEST, which we trivially know we can't use.
    1127              :          This is cheaper than the dominator set tests below.  */
    1128     39411181 :       if (dest == gimple_bb (use_stmt))
    1129       477872 :         continue;
    1130              : 
    1131              :       /* Filter out statements that can never produce a useful
    1132              :          equivalence.  */
    1133     38933309 :       tree lhs2 = gimple_get_lhs (use_stmt);
    1134     38933309 :       if (!lhs2 || TREE_CODE (lhs2) != SSA_NAME)
    1135     28842916 :         continue;
    1136              : 
    1137     10090393 :       if (domok)
    1138              :         {
    1139      5807157 :           if (!dominated_by_p (CDI_DOMINATORS, dest, gimple_bb (use_stmt)))
    1140      2934425 :             continue;
    1141              :         }
    1142              :       else
    1143              :         {
    1144              :           /* We can use the set of BBs on the stack from a domwalk
    1145              :              for a medium fast way to query dominance.  Profiling
    1146              :              has shown non-fast query dominance tests here can be fairly
    1147              :              expensive.  */
    1148              :           /* This tests if USE_STMT does not dominate DEST.  */
    1149      4283236 :           if (!bitmap_bit_p (domby, gimple_bb (use_stmt)->index))
    1150      3228114 :             continue;
    1151              :         }
    1152              : 
    1153              :       /* At this point USE_STMT dominates DEST and may result in a
    1154              :          useful equivalence.  Try to simplify its RHS to a constant
    1155              :          or SSA_NAME.  */
    1156      3927854 :       tree res = gimple_fold_stmt_to_constant_1 (use_stmt, dom_valueize,
    1157              :                                                  no_follow_ssa_edges);
    1158      3927854 :       if (res && (TREE_CODE (res) == SSA_NAME || is_gimple_min_invariant (res)))
    1159      2301748 :         record_equality (lhs2, res, const_and_copies);
    1160     11893157 :     }
    1161     11893157 : }
    1162              : 
    1163              : /* Record into CONST_AND_COPIES and AVAIL_EXPRS_STACK any equivalences implied
    1164              :    by traversing edge E (which are cached in E->aux).
    1165              : 
    1166              :    Callers are responsible for managing the unwinding markers.  */
    1167              : static void
    1168     32689753 : record_temporary_equivalences (edge e,
    1169              :                                class const_and_copies *const_and_copies,
    1170              :                                class avail_exprs_stack *avail_exprs_stack,
    1171              :                                bitmap blocks_on_stack)
    1172              : {
    1173     32689753 :   int i;
    1174     32689753 :   class edge_info *edge_info = (class edge_info *) e->aux;
    1175              : 
    1176              :   /* If we have info associated with this edge, record it into
    1177              :      our equivalence tables.  */
    1178     32689753 :   if (edge_info)
    1179              :     {
    1180              :       cond_equivalence *eq;
    1181              :       /* If we have 0 = COND or 1 = COND equivalences, record them
    1182              :          into our expression hash tables.  */
    1183     90577292 :       for (i = 0; edge_info->cond_equivalences.iterate (i, &eq); ++i)
    1184     66991000 :         avail_exprs_stack->record_cond (eq);
    1185              : 
    1186              :       edge_info::equiv_pair *seq;
    1187     35479449 :       for (i = 0; edge_info->simple_equivalences.iterate (i, &seq); ++i)
    1188              :         {
    1189     11893157 :           tree lhs = seq->first;
    1190     11893157 :           if (!lhs || TREE_CODE (lhs) != SSA_NAME)
    1191            0 :             continue;
    1192              : 
    1193              :           /* Record the simple NAME = VALUE equivalence.  */
    1194     11893157 :           tree rhs = seq->second;
    1195              : 
    1196              :           /* If this is a SSA_NAME = SSA_NAME equivalence and one operand is
    1197              :              cheaper to compute than the other, then set up the equivalence
    1198              :              such that we replace the expensive one with the cheap one.
    1199              : 
    1200              :              If they are the same cost to compute, then do not record
    1201              :              anything.  */
    1202     11893157 :           if (TREE_CODE (lhs) == SSA_NAME && TREE_CODE (rhs) == SSA_NAME)
    1203              :             {
    1204      1702203 :               gimple *rhs_def = SSA_NAME_DEF_STMT (rhs);
    1205      1702203 :               int rhs_cost = estimate_num_insns (rhs_def, &eni_size_weights);
    1206              : 
    1207      1702203 :               gimple *lhs_def = SSA_NAME_DEF_STMT (lhs);
    1208      1702203 :               int lhs_cost = estimate_num_insns (lhs_def, &eni_size_weights);
    1209              : 
    1210      1702203 :               if (rhs_cost > lhs_cost)
    1211       180624 :                 record_equality (rhs, lhs, const_and_copies);
    1212      1521579 :               else if (rhs_cost < lhs_cost)
    1213       446026 :                 record_equality (lhs, rhs, const_and_copies);
    1214              :             }
    1215              :           else
    1216     10190954 :             record_equality (lhs, rhs, const_and_copies);
    1217              : 
    1218              : 
    1219              :           /* Any equivalence found for LHS may result in additional
    1220              :              equivalences for other uses of LHS that we have already
    1221              :              processed.  */
    1222     11893157 :           back_propagate_equivalences (lhs, e, const_and_copies,
    1223              :                                        blocks_on_stack);
    1224              :         }
    1225              :     }
    1226     32689753 : }
    1227              : 
    1228              : /* PHI nodes can create equivalences too.
    1229              : 
    1230              :    Ignoring any alternatives which are the same as the result, if
    1231              :    all the alternatives are equal, then the PHI node creates an
    1232              :    equivalence.  */
    1233              : 
    1234              : static void
    1235     23349721 : record_equivalences_from_phis (basic_block bb)
    1236              : {
    1237     23349721 :   gphi_iterator gsi;
    1238              : 
    1239     32409352 :   for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); )
    1240              :     {
    1241      9059631 :       gphi *phi = gsi.phi ();
    1242              : 
    1243              :       /* We might eliminate the PHI, so advance GSI now.  */
    1244      9059631 :       gsi_next (&gsi);
    1245              : 
    1246      9059631 :       tree lhs = gimple_phi_result (phi);
    1247      9059631 :       tree rhs = NULL;
    1248      9059631 :       size_t i;
    1249              : 
    1250     16296868 :       for (i = 0; i < gimple_phi_num_args (phi); i++)
    1251              :         {
    1252     15385230 :           tree t = gimple_phi_arg_def (phi, i);
    1253              : 
    1254              :           /* Ignore alternatives which are the same as our LHS.  Since
    1255              :              LHS is a PHI_RESULT, it is known to be a SSA_NAME, so we
    1256              :              can simply compare pointers.  */
    1257     15385230 :           if (lhs == t)
    1258        26331 :             continue;
    1259              : 
    1260              :           /* If the associated edge is not marked as executable, then it
    1261              :              can be ignored.  */
    1262     15358899 :           if ((gimple_phi_arg_edge (phi, i)->flags & EDGE_EXECUTABLE) == 0)
    1263       113264 :             continue;
    1264              : 
    1265     15245635 :           t = dom_valueize (t);
    1266              : 
    1267              :           /* If T is an SSA_NAME and its associated edge is a backedge,
    1268              :              then quit as we cannot utilize this equivalence.  */
    1269     15245635 :           if (TREE_CODE (t) == SSA_NAME
    1270     15245635 :               && (gimple_phi_arg_edge (phi, i)->flags & EDGE_DFS_BACK))
    1271              :             break;
    1272              : 
    1273              :           /* If we have not processed an alternative yet, then set
    1274              :              RHS to this alternative.  */
    1275     12258316 :           if (rhs == NULL)
    1276              :             rhs = t;
    1277              :           /* If we have processed an alternative (stored in RHS), then
    1278              :              see if it is equal to this one.  If it isn't, then stop
    1279              :              the search.  */
    1280      5669891 :           else if (! operand_equal_for_phi_arg_p (rhs, t))
    1281              :             break;
    1282              :         }
    1283              : 
    1284              :       /* If we had no interesting alternatives, then all the RHS alternatives
    1285              :          must have been the same as LHS.  */
    1286      9059631 :       if (!rhs)
    1287      2471206 :         rhs = lhs;
    1288              : 
    1289              :       /* If we managed to iterate through each PHI alternative without
    1290              :          breaking out of the loop, then we have a PHI which may create
    1291              :          a useful equivalence.  We do not need to record unwind data for
    1292              :          this, since this is a true assignment and not an equivalence
    1293              :          inferred from a comparison.  All uses of this ssa name are dominated
    1294              :          by this assignment, so unwinding just costs time and space.  */
    1295      9059631 :       if (i == gimple_phi_num_args (phi))
    1296              :         {
    1297       911638 :           if (may_propagate_copy (lhs, rhs))
    1298       473620 :             set_ssa_name_value (lhs, rhs);
    1299       876036 :           else if (virtual_operand_p (lhs))
    1300              :             {
    1301       437708 :               gimple *use_stmt;
    1302       437708 :               imm_use_iterator iter;
    1303       437708 :               use_operand_p use_p;
    1304              :               /* For virtual operands we have to propagate into all uses as
    1305              :                  otherwise we will create overlapping life-ranges.  */
    1306      1721899 :               FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
    1307      2586439 :                 FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
    1308       869978 :                   SET_USE (use_p, rhs);
    1309       437708 :               if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
    1310           72 :                 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs) = 1;
    1311       437708 :               gimple_stmt_iterator tmp_gsi = gsi_for_stmt (phi);
    1312       437708 :               remove_phi_node (&tmp_gsi, true);
    1313              :             }
    1314              :         }
    1315              :     }
    1316     23349721 : }
    1317              : 
    1318              : /* Return true if all uses of NAME are dominated by STMT or feed STMT
    1319              :    via a chain of single immediate uses.  */
    1320              : 
    1321              : static bool
    1322       405651 : all_uses_feed_or_dominated_by_stmt (tree name, gimple *stmt)
    1323              : {
    1324       405651 :   use_operand_p use_p, use2_p;
    1325       405651 :   imm_use_iterator iter;
    1326       405651 :   basic_block stmt_bb = gimple_bb (stmt);
    1327              : 
    1328      2031260 :   FOR_EACH_IMM_USE_FAST (use_p, iter, name)
    1329              :     {
    1330      1443110 :       gimple *use_stmt = USE_STMT (use_p), *use_stmt2;
    1331      2654605 :       if (use_stmt == stmt
    1332      1310119 :           || is_gimple_debug (use_stmt)
    1333      2164340 :           || (gimple_bb (use_stmt) != stmt_bb
    1334       557751 :               && dominated_by_p (CDI_DOMINATORS,
    1335       557751 :                                  gimple_bb (use_stmt), stmt_bb)))
    1336      1211495 :         continue;
    1337              :       while (use_stmt != stmt
    1338       444106 :              && is_gimple_assign (use_stmt)
    1339       391040 :              && TREE_CODE (gimple_assign_lhs (use_stmt)) == SSA_NAME
    1340       831800 :              && single_imm_use (gimple_assign_lhs (use_stmt),
    1341              :                                 &use2_p, &use_stmt2))
    1342       220954 :         use_stmt = use_stmt2;
    1343       231615 :       if (use_stmt != stmt)
    1344       223152 :         return false;
    1345       223152 :     }
    1346       182499 :   return true;
    1347              : }
    1348              : 
    1349              : /* Handle
    1350              :    _4 = x_3 & 31;
    1351              :    if (_4 != 0)
    1352              :      goto <bb 6>;
    1353              :    else
    1354              :      goto <bb 7>;
    1355              :    <bb 6>:
    1356              :    __builtin_unreachable ();
    1357              :    <bb 7>:
    1358              : 
    1359              :    If x_3 has no other immediate uses (checked by caller), var is the
    1360              :    x_3 var, we can clear low 5 bits from the non-zero bitmask.  */
    1361              : 
    1362              : static void
    1363       162851 : maybe_set_nonzero_bits (edge e, tree var)
    1364              : {
    1365       162851 :   basic_block cond_bb = e->src;
    1366       325702 :   gcond *cond = safe_dyn_cast <gcond *> (*gsi_last_bb (cond_bb));
    1367       162851 :   tree cst;
    1368              : 
    1369       162851 :   if (cond == NULL
    1370       162851 :       || gimple_cond_code (cond) != ((e->flags & EDGE_TRUE_VALUE)
    1371       162851 :                                      ? EQ_EXPR : NE_EXPR)
    1372        49553 :       || TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
    1373         1745 :       || !integer_zerop (gimple_cond_rhs (cond)))
    1374       161310 :     return;
    1375              : 
    1376         1541 :   gimple *stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (cond));
    1377         1541 :   if (!is_gimple_assign (stmt)
    1378         1519 :       || gimple_assign_rhs_code (stmt) != BIT_AND_EXPR
    1379         1558 :       || TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST)
    1380              :     return;
    1381            1 :   if (gimple_assign_rhs1 (stmt) != var)
    1382              :     {
    1383            1 :       gimple *stmt2;
    1384              : 
    1385            1 :       if (TREE_CODE (gimple_assign_rhs1 (stmt)) != SSA_NAME)
    1386              :         return;
    1387            1 :       stmt2 = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
    1388            1 :       if (!gimple_assign_cast_p (stmt2)
    1389            0 :           || gimple_assign_rhs1 (stmt2) != var
    1390            0 :           || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt2))
    1391            1 :           || (TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (stmt)))
    1392            0 :                               != TYPE_PRECISION (TREE_TYPE (var))))
    1393              :         return;
    1394              :     }
    1395            0 :   cst = gimple_assign_rhs2 (stmt);
    1396            0 :   if (POINTER_TYPE_P (TREE_TYPE (var)))
    1397              :     {
    1398            0 :       struct ptr_info_def *pi = SSA_NAME_PTR_INFO (var);
    1399            0 :       if (pi && pi->misalign)
    1400            0 :         return;
    1401            0 :       wide_int w = wi::bit_not (wi::to_wide (cst));
    1402            0 :       unsigned int bits = wi::ctz (w);
    1403            0 :       if (bits == 0 || bits >= HOST_BITS_PER_INT)
    1404            0 :         return;
    1405            0 :       unsigned int align = 1U << bits;
    1406            0 :       if (pi == NULL || pi->align < align)
    1407            0 :         set_ptr_info_alignment (get_ptr_info (var), align, 0);
    1408            0 :     }
    1409              :   else
    1410            0 :     set_nonzero_bits (var, wi::bit_and_not (get_nonzero_bits (var),
    1411            0 :                                             wi::to_wide (cst)));
    1412              : }
    1413              : 
    1414              : /* Set global ranges that can be determined from the C->M edge:
    1415              : 
    1416              :    <bb C>:
    1417              :    ...
    1418              :    if (something)
    1419              :      goto <bb N>;
    1420              :    else
    1421              :      goto <bb M>;
    1422              :    <bb N>:
    1423              :    __builtin_unreachable ();
    1424              :    <bb M>:
    1425              : */
    1426              : 
    1427              : void
    1428     23349721 : dom_opt_dom_walker::set_global_ranges_from_unreachable_edges (basic_block bb)
    1429              : {
    1430     23349721 :   edge pred_e = single_pred_edge_ignoring_loop_edges (bb, false);
    1431     23349721 :   if (!pred_e)
    1432              :     return;
    1433              : 
    1434     17341503 :   gimple *stmt = *gsi_last_bb (pred_e->src);
    1435     17341503 :   if (!stmt
    1436     14554088 :       || gimple_code (stmt) != GIMPLE_COND
    1437     29396224 :       || !assert_unreachable_fallthru_edge_p (pred_e))
    1438     17122845 :     return;
    1439              : 
    1440       218658 :   tree name;
    1441       624309 :   FOR_EACH_GORI_EXPORT_NAME (m_ranger->gori_ssa (), pred_e->src, name)
    1442       405651 :     if (all_uses_feed_or_dominated_by_stmt (name, stmt)
    1443              :         // The condition must post-dominate the definition point.
    1444       588150 :         && (SSA_NAME_IS_DEFAULT_DEF (name)
    1445       182053 :             || (gimple_bb (SSA_NAME_DEF_STMT (name))
    1446       182053 :                 == pred_e->src)))
    1447              :       {
    1448       177259 :         value_range r (TREE_TYPE (name));
    1449              : 
    1450       177259 :         if (m_ranger->range_on_edge (r, pred_e, name)
    1451       177259 :             && !r.varying_p ()
    1452       340183 :             && !r.undefined_p ())
    1453              :           {
    1454       162851 :             set_range_info (name, r);
    1455       162851 :             maybe_set_nonzero_bits (pred_e, name);
    1456              :           }
    1457       177259 :       }
    1458              : }
    1459              : 
    1460              : /* Record any equivalences created by the incoming edge to BB into
    1461              :    CONST_AND_COPIES and AVAIL_EXPRS_STACK.  If BB has more than one
    1462              :    incoming edge, then no equivalence is created.  */
    1463              : 
    1464              : static void
    1465     23349721 : record_equivalences_from_incoming_edge (basic_block bb,
    1466              :     class const_and_copies *const_and_copies,
    1467              :     class avail_exprs_stack *avail_exprs_stack,
    1468              :     bitmap blocks_on_stack)
    1469              : {
    1470     23349721 :   edge e;
    1471     23349721 :   basic_block parent;
    1472              : 
    1473              :   /* If our parent block ended with a control statement, then we may be
    1474              :      able to record some equivalences based on which outgoing edge from
    1475              :      the parent was followed.  */
    1476     23349721 :   parent = get_immediate_dominator (CDI_DOMINATORS, bb);
    1477              : 
    1478     23349721 :   e = single_pred_edge_ignoring_loop_edges (bb, true);
    1479              : 
    1480              :   /* If we had a single incoming edge from our parent block, then enter
    1481              :      any data associated with the edge into our tables.  */
    1482     23349721 :   if (e && e->src == parent)
    1483     17347046 :     record_temporary_equivalences (e, const_and_copies, avail_exprs_stack,
    1484              :                                    blocks_on_stack);
    1485     23349721 : }
    1486              : 
    1487              : /* Dump statistics for the hash table HTAB.  */
    1488              : 
    1489              : static void
    1490           35 : htab_statistics (FILE *file, const hash_table<expr_elt_hasher> &htab)
    1491              : {
    1492           66 :   fprintf (file, "size " HOST_SIZE_T_PRINT_DEC ", " HOST_SIZE_T_PRINT_DEC
    1493              :            " elements, %f collision/search ratio\n",
    1494           35 :            (fmt_size_t) htab.size (),
    1495           35 :            (fmt_size_t) htab.elements (),
    1496              :            htab.collisions ());
    1497           35 : }
    1498              : 
    1499              : /* Dump SSA statistics on FILE.  */
    1500              : 
    1501              : static void
    1502           35 : dump_dominator_optimization_stats (FILE *file,
    1503              :                                    hash_table<expr_elt_hasher> *avail_exprs)
    1504              : {
    1505           35 :   fprintf (file, "Total number of statements:                   %6ld\n\n",
    1506              :            opt_stats.num_stmts);
    1507           35 :   fprintf (file, "Exprs considered for dominator optimizations: %6ld\n",
    1508              :            opt_stats.num_exprs_considered);
    1509              : 
    1510           35 :   fprintf (file, "\nHash table statistics:\n");
    1511              : 
    1512           35 :   fprintf (file, "    avail_exprs: ");
    1513           35 :   htab_statistics (file, *avail_exprs);
    1514           35 : }
    1515              : 
    1516              : 
    1517              : /* Similarly, but assume that X and Y are the two operands of an EQ_EXPR.
    1518              :    This constrains the cases in which we may treat this as assignment.  */
    1519              : 
    1520              : static void
    1521     13119352 : record_equality (tree x, tree y, class const_and_copies *const_and_copies)
    1522              : {
    1523     13119352 :   tree prev_x = NULL, prev_y = NULL;
    1524              : 
    1525     13119352 :   if (tree_swap_operands_p (x, y))
    1526       596979 :     std::swap (x, y);
    1527              : 
    1528              :   /* Most of the time tree_swap_operands_p does what we want.  But there
    1529              :      are cases where we know one operand is better for copy propagation than
    1530              :      the other.  Given no other code cares about ordering of equality
    1531              :      comparison operators for that purpose, we just handle the special cases
    1532              :      here.  */
    1533     13119352 :   if (TREE_CODE (x) == SSA_NAME && TREE_CODE (y) == SSA_NAME)
    1534              :     {
    1535              :       /* If one operand is a single use operand, then make it
    1536              :          X.  This will preserve its single use properly and if this
    1537              :          conditional is eliminated, the computation of X can be
    1538              :          eliminated as well.  */
    1539      1084281 :       if (has_single_use (y) && ! has_single_use (x))
    1540              :         std::swap (x, y);
    1541              :     }
    1542     13119352 :   if (TREE_CODE (x) == SSA_NAME)
    1543     13119352 :     prev_x = SSA_NAME_VALUE (x);
    1544     13119352 :   if (TREE_CODE (y) == SSA_NAME)
    1545      1084281 :     prev_y = SSA_NAME_VALUE (y);
    1546              : 
    1547              :   /* If one of the previous values is invariant, or invariant in more loops
    1548              :      (by depth), then use that.
    1549              :      Otherwise it doesn't matter which value we choose, just so
    1550              :      long as we canonicalize on one value.  */
    1551     13119352 :   if (is_gimple_min_invariant (y))
    1552              :     ;
    1553      1084281 :   else if (is_gimple_min_invariant (x))
    1554              :     prev_x = x, x = y, y = prev_x, prev_x = prev_y;
    1555      1084281 :   else if (prev_x && is_gimple_min_invariant (prev_x))
    1556              :     x = y, y = prev_x, prev_x = prev_y;
    1557       996490 :   else if (prev_y)
    1558     13119352 :     y = prev_y;
    1559              : 
    1560              :   /* After the swapping, we must have one SSA_NAME.  */
    1561     13119352 :   if (TREE_CODE (x) != SSA_NAME)
    1562              :     return;
    1563              : 
    1564              :   /* For IEEE, -0.0 == 0.0, so we don't necessarily know the sign of a
    1565              :      variable compared against zero.  If we're honoring signed zeros,
    1566              :      then we cannot record this value unless we know that the value is
    1567              :      nonzero.  */
    1568     13119352 :   if (HONOR_SIGNED_ZEROS (x)
    1569     13119352 :       && (TREE_CODE (y) != REAL_CST
    1570       170365 :           || real_equal (&dconst0, &TREE_REAL_CST (y))))
    1571          505 :     return;
    1572              : 
    1573     13118847 :   const_and_copies->record_const_or_copy (x, y, prev_x);
    1574              : }
    1575              : 
    1576              : /* Returns true when STMT is a simple iv increment.  It detects the
    1577              :    following situation:
    1578              : 
    1579              :    i_1 = phi (..., i_k)
    1580              :    [...]
    1581              :    i_j = i_{j-1}  for each j : 2 <= j <= k-1
    1582              :    [...]
    1583              :    i_k = i_{k-1} +/- ...  */
    1584              : 
    1585              : bool
    1586     42491068 : simple_iv_increment_p (gimple *stmt)
    1587              : {
    1588     42491068 :   enum tree_code code;
    1589     42491068 :   tree lhs, preinc;
    1590     42491068 :   gimple *phi;
    1591     42491068 :   size_t i;
    1592              : 
    1593     42491068 :   if (gimple_code (stmt) != GIMPLE_ASSIGN)
    1594              :     return false;
    1595              : 
    1596     32676242 :   lhs = gimple_assign_lhs (stmt);
    1597     32676242 :   if (TREE_CODE (lhs) != SSA_NAME)
    1598              :     return false;
    1599              : 
    1600     32676242 :   code = gimple_assign_rhs_code (stmt);
    1601     32676242 :   if (code != PLUS_EXPR
    1602     32676242 :       && code != MINUS_EXPR
    1603     32676242 :       && code != POINTER_PLUS_EXPR)
    1604              :     return false;
    1605              : 
    1606      7896368 :   preinc = gimple_assign_rhs1 (stmt);
    1607      7896368 :   if (TREE_CODE (preinc) != SSA_NAME)
    1608              :     return false;
    1609              : 
    1610      7620053 :   phi = SSA_NAME_DEF_STMT (preinc);
    1611      7645022 :   while (gimple_code (phi) != GIMPLE_PHI)
    1612              :     {
    1613              :       /* Follow trivial copies, but not the DEF used in a back edge,
    1614              :          so that we don't prevent coalescing.  */
    1615      5192343 :       if (!gimple_assign_ssa_name_copy_p (phi))
    1616              :         return false;
    1617        24969 :       preinc = gimple_assign_rhs1 (phi);
    1618        24969 :       phi = SSA_NAME_DEF_STMT (preinc);
    1619              :     }
    1620              : 
    1621      4812844 :   for (i = 0; i < gimple_phi_num_args (phi); i++)
    1622      3892429 :     if (gimple_phi_arg_def (phi, i) == lhs)
    1623              :       return true;
    1624              : 
    1625              :   return false;
    1626              : }
    1627              : 
    1628              : /* Propagate know values from SSA_NAME_VALUE into the PHI nodes of the
    1629              :    successors of BB.  */
    1630              : 
    1631              : static void
    1632     23349721 : cprop_into_successor_phis (basic_block bb,
    1633              :                            class const_and_copies *const_and_copies)
    1634              : {
    1635     23349721 :   edge e;
    1636     23349721 :   edge_iterator ei;
    1637              : 
    1638     55424921 :   FOR_EACH_EDGE (e, ei, bb->succs)
    1639              :     {
    1640     32075200 :       int indx;
    1641     32075200 :       gphi_iterator gsi;
    1642              : 
    1643              :       /* If this is an abnormal edge, then we do not want to copy propagate
    1644              :          into the PHI alternative associated with this edge.  */
    1645     32075200 :       if (e->flags & EDGE_ABNORMAL)
    1646     18943406 :         continue;
    1647              : 
    1648     32061312 :       gsi = gsi_start_phis (e->dest);
    1649     32061312 :       if (gsi_end_p (gsi))
    1650     18929518 :         continue;
    1651              : 
    1652              :       /* We may have an equivalence associated with this edge.  While
    1653              :          we cannot propagate it into non-dominated blocks, we can
    1654              :          propagate them into PHIs in non-dominated blocks.  */
    1655              : 
    1656              :       /* Push the unwind marker so we can reset the const and copies
    1657              :          table back to its original state after processing this edge.  */
    1658     13131794 :       const_and_copies->push_marker ();
    1659              : 
    1660              :       /* Extract and record any simple NAME = VALUE equivalences.
    1661              : 
    1662              :          Don't bother with [01] = COND equivalences, they're not useful
    1663              :          here.  */
    1664     13131794 :       class edge_info *edge_info = (class edge_info *) e->aux;
    1665              : 
    1666     13131794 :       if (edge_info)
    1667              :         {
    1668              :           edge_info::equiv_pair *seq;
    1669      8227904 :           for (int i = 0; edge_info->simple_equivalences.iterate (i, &seq); ++i)
    1670              :             {
    1671      3129486 :               tree lhs = seq->first;
    1672      3129486 :               tree rhs = seq->second;
    1673              : 
    1674      3129486 :               if (lhs && TREE_CODE (lhs) == SSA_NAME)
    1675      3129486 :                 const_and_copies->record_const_or_copy (lhs, rhs);
    1676              :             }
    1677              : 
    1678              :         }
    1679              : 
    1680     13131794 :       indx = e->dest_idx;
    1681     36024771 :       for ( ; !gsi_end_p (gsi); gsi_next (&gsi))
    1682              :         {
    1683     22892977 :           tree new_val;
    1684     22892977 :           use_operand_p orig_p;
    1685     22892977 :           tree orig_val;
    1686     22892977 :           gphi *phi = gsi.phi ();
    1687              : 
    1688              :           /* The alternative may be associated with a constant, so verify
    1689              :              it is an SSA_NAME before doing anything with it.  */
    1690     22892977 :           orig_p = gimple_phi_arg_imm_use_ptr (phi, indx);
    1691     22892977 :           orig_val = get_use_from_ptr (orig_p);
    1692     22892977 :           if (TREE_CODE (orig_val) != SSA_NAME)
    1693      3131904 :             continue;
    1694              : 
    1695              :           /* If we have *ORIG_P in our constant/copy table, then replace
    1696              :              ORIG_P with its value in our constant/copy table.  */
    1697     19761073 :           new_val = SSA_NAME_VALUE (orig_val);
    1698     19761073 :           if (new_val
    1699     19761073 :               && new_val != orig_val
    1700     19761073 :               && may_propagate_copy (orig_val, new_val))
    1701      1056934 :             propagate_value (orig_p, new_val);
    1702              :         }
    1703              : 
    1704     13131794 :       const_and_copies->pop_to_marker ();
    1705              :     }
    1706     23349721 : }
    1707              : 
    1708              : edge
    1709     23349721 : dom_opt_dom_walker::before_dom_children (basic_block bb)
    1710              : {
    1711     23349721 :   gimple_stmt_iterator gsi;
    1712              : 
    1713     23349721 :   if (dump_file && (dump_flags & TDF_DETAILS))
    1714          736 :     fprintf (dump_file, "\n\nOptimizing block #%d\n\n", bb->index);
    1715              : 
    1716              :   /* Push a marker on the stacks of local information so that we know how
    1717              :      far to unwind when we finalize this block.  */
    1718     23349721 :   m_avail_exprs_stack->push_marker ();
    1719     23349721 :   m_const_and_copies->push_marker ();
    1720     23349721 :   bitmap_set_bit (m_state->get_blocks_on_stack (), bb->index);
    1721              : 
    1722     23349721 :   record_equivalences_from_incoming_edge (bb, m_const_and_copies,
    1723              :                                           m_avail_exprs_stack,
    1724     23349721 :                                           m_state->get_blocks_on_stack ());
    1725     23349721 :   set_global_ranges_from_unreachable_edges (bb);
    1726              : 
    1727              :   /* PHI nodes can create equivalences too.  */
    1728     23349721 :   record_equivalences_from_phis (bb);
    1729              : 
    1730              :   /* Create equivalences from redundant PHIs.  PHIs are only truly
    1731              :      redundant when they exist in the same block, so push another
    1732              :      marker and unwind right afterwards.  */
    1733     23349721 :   m_avail_exprs_stack->push_marker ();
    1734     31971644 :   for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    1735      8621923 :     eliminate_redundant_computations (&gsi, m_const_and_copies,
    1736              :                                       m_avail_exprs_stack);
    1737     23349721 :   m_avail_exprs_stack->pop_to_marker ();
    1738              : 
    1739     23349721 :   edge taken_edge = NULL;
    1740              :   /* Initialize visited flag ahead of us, it has undefined state on
    1741              :      pass entry.  */
    1742    218103537 :   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    1743    171404095 :     gimple_set_visited (gsi_stmt (gsi), false);
    1744    366036677 :   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
    1745              :     {
    1746              :       /* Do not optimize a stmt twice, substitution might end up with
    1747              :          _3 = _3 which is not valid.  */
    1748    342686956 :       if (gimple_visited_p (gsi_stmt (gsi)))
    1749              :         {
    1750    171282660 :           gsi_next (&gsi);
    1751    171282660 :           continue;
    1752              :         }
    1753              : 
    1754    171404296 :       bool removed_p = false;
    1755    171404296 :       taken_edge = this->optimize_stmt (bb, &gsi, &removed_p);
    1756    171404296 :       if (!removed_p)
    1757    171282660 :         gimple_set_visited (gsi_stmt (gsi), true);
    1758              : 
    1759              :       /* Go back and visit stmts inserted by folding after substituting
    1760              :          into the stmt at gsi.  */
    1761    171404296 :       if (gsi_end_p (gsi))
    1762              :         {
    1763         2787 :           gcc_checking_assert (removed_p);
    1764         2787 :           gsi = gsi_last_bb (bb);
    1765         5174 :           while (!gsi_end_p (gsi) && !gimple_visited_p (gsi_stmt (gsi)))
    1766         2787 :             gsi_prev (&gsi);
    1767              :         }
    1768              :       else
    1769              :         {
    1770    171401710 :           do
    1771              :             {
    1772    171401710 :               gsi_prev (&gsi);
    1773              :             }
    1774    342803219 :           while (!gsi_end_p (gsi) && !gimple_visited_p (gsi_stmt (gsi)));
    1775              :         }
    1776    171404296 :       if (gsi_end_p (gsi))
    1777     38474694 :         gsi = gsi_start_bb (bb);
    1778              :       else
    1779    152166949 :         gsi_next (&gsi);
    1780              :     }
    1781              : 
    1782              :   /* Now prepare to process dominated blocks.  */
    1783     23349721 :   record_edge_info (bb);
    1784     23349721 :   cprop_into_successor_phis (bb, m_const_and_copies);
    1785     23349721 :   if (taken_edge && !dbg_cnt (dom_unreachable_edges))
    1786              :     return NULL;
    1787              : 
    1788              :   return taken_edge;
    1789              : }
    1790              : 
    1791              : /* We have finished processing the dominator children of BB, perform
    1792              :    any finalization actions in preparation for leaving this node in
    1793              :    the dominator tree.  */
    1794              : 
    1795              : void
    1796     23349721 : dom_opt_dom_walker::after_dom_children (basic_block bb)
    1797              : {
    1798     23349721 :   m_threader->thread_outgoing_edges (bb);
    1799     23349721 :   bitmap_clear_bit (m_state->get_blocks_on_stack (), bb->index);
    1800     23349721 :   m_avail_exprs_stack->pop_to_marker ();
    1801     23349721 :   m_const_and_copies->pop_to_marker ();
    1802     23349721 : }
    1803              : 
    1804              : /* Search for redundant computations in STMT.  If any are found, then
    1805              :    replace them with the variable holding the result of the computation.
    1806              : 
    1807              :    If safe, record this expression into AVAIL_EXPRS_STACK and
    1808              :    CONST_AND_COPIES.  */
    1809              : 
    1810              : static void
    1811     62973264 : eliminate_redundant_computations (gimple_stmt_iterator* gsi,
    1812              :                                   class const_and_copies *const_and_copies,
    1813              :                                   class avail_exprs_stack *avail_exprs_stack)
    1814              : {
    1815     62973264 :   tree expr_type;
    1816     62973264 :   tree cached_lhs;
    1817     62973264 :   tree def;
    1818     62973264 :   bool insert = true;
    1819     62973264 :   bool assigns_var_p = false;
    1820              : 
    1821     62973264 :   gimple *stmt = gsi_stmt (*gsi);
    1822              : 
    1823     62973264 :   if (gimple_code (stmt) == GIMPLE_PHI)
    1824      8621923 :     def = gimple_phi_result (stmt);
    1825              :   else
    1826     54351341 :     def = gimple_get_lhs (stmt);
    1827              : 
    1828              :   /* Certain expressions on the RHS can be optimized away, but cannot
    1829              :      themselves be entered into the hash tables.  */
    1830     62973264 :   if (! def
    1831     54030296 :       || TREE_CODE (def) != SSA_NAME
    1832     41397223 :       || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def)
    1833     32774027 :       || gimple_vdef (stmt)
    1834              :       /* Do not record equivalences for increments of ivs.  This would create
    1835              :          overlapping live ranges for a very questionable gain.  */
    1836    104359857 :       || simple_iv_increment_p (stmt))
    1837              :     insert = false;
    1838              : 
    1839              :   /* Check if the expression has been computed before.  */
    1840     62973264 :   cached_lhs = avail_exprs_stack->lookup_avail_expr (stmt, insert, true);
    1841              : 
    1842     62973264 :   opt_stats.num_exprs_considered++;
    1843              : 
    1844              :   /* Get the type of the expression we are trying to optimize.  */
    1845     62973264 :   if (is_gimple_assign (stmt))
    1846              :     {
    1847     44156507 :       expr_type = TREE_TYPE (gimple_assign_lhs (stmt));
    1848     44156507 :       assigns_var_p = true;
    1849              :     }
    1850     18816757 :   else if (gimple_code (stmt) == GIMPLE_COND)
    1851      8909949 :     expr_type = boolean_type_node;
    1852      9906808 :   else if (is_gimple_call (stmt))
    1853              :     {
    1854      1251866 :       gcc_assert (gimple_call_lhs (stmt));
    1855      1251866 :       expr_type = TREE_TYPE (gimple_call_lhs (stmt));
    1856      1251866 :       assigns_var_p = true;
    1857              :     }
    1858      8654942 :   else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt))
    1859        33019 :     expr_type = TREE_TYPE (gimple_switch_index (swtch_stmt));
    1860      8621923 :   else if (gimple_code (stmt) == GIMPLE_PHI)
    1861              :     /* We can't propagate into a phi, so the logic below doesn't apply.
    1862              :        Instead record an equivalence between the cached LHS and the
    1863              :        PHI result of this statement, provided they are in the same block.
    1864              :        This should be sufficient to kill the redundant phi.  */
    1865              :     {
    1866      8621923 :       if (def && cached_lhs)
    1867        20218 :         const_and_copies->record_const_or_copy (def, cached_lhs);
    1868      8621923 :       return;
    1869              :     }
    1870              :   else
    1871            0 :     gcc_unreachable ();
    1872              : 
    1873     54351341 :   if (!cached_lhs)
    1874              :     return;
    1875              : 
    1876              :   /* It is safe to ignore types here since we have already done
    1877              :      type checking in the hashing and equality routines.  In fact
    1878              :      type checking here merely gets in the way of constant
    1879              :      propagation.  Also, make sure that it is safe to propagate
    1880              :      CACHED_LHS into the expression in STMT.  */
    1881       427309 :   if ((TREE_CODE (cached_lhs) != SSA_NAME
    1882        38317 :        && (assigns_var_p
    1883         3378 :            || useless_type_conversion_p (expr_type, TREE_TYPE (cached_lhs))))
    1884       427309 :       || may_propagate_copy_into_stmt (stmt, cached_lhs))
    1885              :   {
    1886       414037 :       gcc_checking_assert (TREE_CODE (cached_lhs) == SSA_NAME
    1887              :                            || is_gimple_min_invariant (cached_lhs));
    1888              : 
    1889       414037 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1890              :         {
    1891           16 :           fprintf (dump_file, "  Replaced redundant expr '");
    1892           16 :           print_gimple_expr (dump_file, stmt, 0, dump_flags);
    1893           16 :           fprintf (dump_file, "' with '");
    1894           16 :           print_generic_expr (dump_file, cached_lhs, dump_flags);
    1895           16 :           fprintf (dump_file, "'\n");
    1896              :         }
    1897              : 
    1898       414037 :       opt_stats.num_re++;
    1899              : 
    1900       414037 :       if (assigns_var_p
    1901       414037 :           && !useless_type_conversion_p (expr_type, TREE_TYPE (cached_lhs)))
    1902            0 :         cached_lhs = fold_convert (expr_type, cached_lhs);
    1903              : 
    1904       414037 :       propagate_tree_value_into_stmt (gsi, cached_lhs);
    1905              : 
    1906              :       /* Since it is always necessary to mark the result as modified,
    1907              :          perhaps we should move this into propagate_tree_value_into_stmt
    1908              :          itself.  */
    1909       414037 :       gimple_set_modified (gsi_stmt (*gsi), true);
    1910              :   }
    1911              : }
    1912              : 
    1913              : /* STMT, a GIMPLE_ASSIGN, may create certain equivalences, in either
    1914              :    the available expressions table or the const_and_copies table.
    1915              :    Detect and record those equivalences into AVAIL_EXPRS_STACK.
    1916              : 
    1917              :    We handle only very simple copy equivalences here.  The heavy
    1918              :    lifing is done by eliminate_redundant_computations.  */
    1919              : 
    1920              : static void
    1921     47527751 : record_equivalences_from_stmt (gimple *stmt, int may_optimize_p,
    1922              :                                class avail_exprs_stack *avail_exprs_stack)
    1923              : {
    1924     47527751 :   tree lhs;
    1925     47527751 :   enum tree_code lhs_code;
    1926              : 
    1927     47527751 :   gcc_assert (is_gimple_assign (stmt));
    1928              : 
    1929     47527751 :   lhs = gimple_assign_lhs (stmt);
    1930     47527751 :   lhs_code = TREE_CODE (lhs);
    1931              : 
    1932     47527751 :   if (lhs_code == SSA_NAME
    1933     47527751 :       && gimple_assign_single_p (stmt))
    1934              :     {
    1935     15603243 :       tree rhs = gimple_assign_rhs1 (stmt);
    1936              : 
    1937              :       /* If the RHS of the assignment is a constant or another variable that
    1938              :          may be propagated, register it in the CONST_AND_COPIES table.  We
    1939              :          do not need to record unwind data for this, since this is a true
    1940              :          assignment and not an equivalence inferred from a comparison.  All
    1941              :          uses of this ssa name are dominated by this assignment, so unwinding
    1942              :          just costs time and space.  */
    1943     15603243 :       if (may_optimize_p
    1944     15603243 :           && (TREE_CODE (rhs) == SSA_NAME
    1945     13574516 :               || is_gimple_min_invariant (rhs)))
    1946              :         {
    1947      1983554 :           rhs = dom_valueize (rhs);
    1948              : 
    1949      1983554 :           if (dump_file && (dump_flags & TDF_DETAILS))
    1950              :             {
    1951           74 :               fprintf (dump_file, "==== ASGN ");
    1952           74 :               print_generic_expr (dump_file, lhs);
    1953           74 :               fprintf (dump_file, " = ");
    1954           74 :               print_generic_expr (dump_file, rhs);
    1955           74 :               fprintf (dump_file, "\n");
    1956              :             }
    1957              : 
    1958      1983554 :           set_ssa_name_value (lhs, rhs);
    1959              :         }
    1960              :     }
    1961              : 
    1962              :   /* Make sure we can propagate &x + CST.  */
    1963     47527751 :   if (lhs_code == SSA_NAME
    1964     32159215 :       && gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR
    1965      1624260 :       && TREE_CODE (gimple_assign_rhs1 (stmt)) == ADDR_EXPR
    1966     47718370 :       && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST)
    1967              :     {
    1968         4280 :       tree op0 = gimple_assign_rhs1 (stmt);
    1969         4280 :       tree op1 = gimple_assign_rhs2 (stmt);
    1970         4280 :       tree new_rhs
    1971         8560 :         = build1 (ADDR_EXPR, TREE_TYPE (op0),
    1972         4280 :                   fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (op0)),
    1973              :                                unshare_expr (op0), fold_convert (ptr_type_node,
    1974              :                                                                  op1)));
    1975         4280 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1976              :         {
    1977            0 :           fprintf (dump_file, "==== ASGN ");
    1978            0 :           print_generic_expr (dump_file, lhs);
    1979            0 :           fprintf (dump_file, " = ");
    1980            0 :           print_generic_expr (dump_file, new_rhs);
    1981            0 :           fprintf (dump_file, "\n");
    1982              :         }
    1983              : 
    1984         4280 :       set_ssa_name_value (lhs, new_rhs);
    1985              :     }
    1986              : 
    1987              :   /* A memory store, even an aliased store, creates a useful
    1988              :      equivalence.  By exchanging the LHS and RHS, creating suitable
    1989              :      vops and recording the result in the available expression table,
    1990              :      we may be able to expose more redundant loads.  */
    1991     91568078 :   if (!gimple_has_volatile_ops (stmt)
    1992     71492032 :       && gimple_references_memory_p (stmt)
    1993     23964281 :       && gimple_assign_single_p (stmt)
    1994     23964281 :       && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
    1995     18739506 :           || is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
    1996     59032610 :       && !is_gimple_reg (lhs))
    1997              :     {
    1998     11334168 :       tree rhs = gimple_assign_rhs1 (stmt);
    1999     11334168 :       gassign *new_stmt;
    2000              : 
    2001              :       /* Build a new statement with the RHS and LHS exchanged.  */
    2002     11334168 :       if (TREE_CODE (rhs) == SSA_NAME)
    2003              :         {
    2004              :           /* NOTE tuples.  The call to gimple_build_assign below replaced
    2005              :              a call to build_gimple_modify_stmt, which did not set the
    2006              :              SSA_NAME_DEF_STMT on the LHS of the assignment.  Doing so
    2007              :              may cause an SSA validation failure, as the LHS may be a
    2008              :              default-initialized name and should have no definition.  I'm
    2009              :              a bit dubious of this, as the artificial statement that we
    2010              :              generate here may in fact be ill-formed, but it is simply
    2011              :              used as an internal device in this pass, and never becomes
    2012              :              part of the CFG.  */
    2013      5084555 :           gimple *defstmt = SSA_NAME_DEF_STMT (rhs);
    2014      5084555 :           new_stmt = gimple_build_assign (rhs, lhs);
    2015      5084555 :           SSA_NAME_DEF_STMT (rhs) = defstmt;
    2016              :         }
    2017              :       else
    2018      6249613 :         new_stmt = gimple_build_assign (rhs, lhs);
    2019              : 
    2020     22668336 :       gimple_set_vuse (new_stmt, gimple_vdef (stmt));
    2021              : 
    2022              :       /* Finally enter the statement into the available expression
    2023              :          table.  */
    2024     11334168 :       avail_exprs_stack->lookup_avail_expr (new_stmt, true, true);
    2025              :     }
    2026     47527751 : }
    2027              : 
    2028              : /* Replace *OP_P in STMT with any known equivalent value for *OP_P from
    2029              :    CONST_AND_COPIES.  */
    2030              : 
    2031              : static void
    2032     79518347 : cprop_operand (gimple *stmt, use_operand_p op_p, range_query *query)
    2033              : {
    2034     79518347 :   tree val;
    2035     79518347 :   tree op = USE_FROM_PTR (op_p);
    2036              : 
    2037              :   /* If the operand has a known constant value or it is known to be a
    2038              :      copy of some other variable, use the value or copy stored in
    2039              :      CONST_AND_COPIES.  */
    2040     79518347 :   val = SSA_NAME_VALUE (op);
    2041     53437367 :   if (!val)
    2042              :     {
    2043     75688580 :       value_range r (TREE_TYPE (op));
    2044     75688580 :       tree single;
    2045    149084810 :       if (query->range_of_expr (r, op, stmt) && r.singleton_p (&single))
    2046        22999 :         val = single;
    2047     75688580 :     }
    2048              : 
    2049     79518347 :   if (val && val != op)
    2050              :     {
    2051              :       /* Certain operands are not allowed to be copy propagated due
    2052              :          to their interaction with exception handling and some GCC
    2053              :          extensions.  */
    2054      3851036 :       if (!may_propagate_copy (op, val))
    2055              :         return;
    2056              : 
    2057              :       /* Do not propagate copies into BIVs.
    2058              :          See PR23821 and PR62217 for how this can disturb IV and
    2059              :          number of iteration analysis.  */
    2060      3849473 :       if (TREE_CODE (val) != INTEGER_CST)
    2061              :         {
    2062      3144729 :           gimple *def = SSA_NAME_DEF_STMT (op);
    2063      3144729 :           if (gimple_code (def) == GIMPLE_PHI
    2064      3144729 :               && gimple_bb (def)->loop_father->header == gimple_bb (def))
    2065              :             return;
    2066              :         }
    2067              : 
    2068              :       /* Dump details.  */
    2069      3839464 :       if (dump_file && (dump_flags & TDF_DETAILS))
    2070              :         {
    2071           76 :           fprintf (dump_file, "  Replaced '");
    2072           76 :           print_generic_expr (dump_file, op, dump_flags);
    2073           76 :           fprintf (dump_file, "' with %s '",
    2074           76 :                    (TREE_CODE (val) != SSA_NAME ? "constant" : "variable"));
    2075           76 :           print_generic_expr (dump_file, val, dump_flags);
    2076           76 :           fprintf (dump_file, "'\n");
    2077              :         }
    2078              : 
    2079      3839464 :       if (TREE_CODE (val) != SSA_NAME)
    2080       877958 :         opt_stats.num_const_prop++;
    2081              :       else
    2082      2961506 :         opt_stats.num_copy_prop++;
    2083              : 
    2084      3839464 :       propagate_value (op_p, val);
    2085              : 
    2086              :       /* And note that we modified this statement.  This is now
    2087              :          safe, even if we changed virtual operands since we will
    2088              :          rescan the statement and rewrite its operands again.  */
    2089      3839464 :       gimple_set_modified (stmt, true);
    2090              :     }
    2091              : }
    2092              : 
    2093              : /* CONST_AND_COPIES is a table which maps an SSA_NAME to the current
    2094              :    known value for that SSA_NAME (or NULL if no value is known).
    2095              : 
    2096              :    Propagate values from CONST_AND_COPIES into the uses, vuses and
    2097              :    vdef_ops of STMT.  */
    2098              : 
    2099              : static void
    2100    171404296 : cprop_into_stmt (gimple *stmt, range_query *query)
    2101              : {
    2102    171404296 :   use_operand_p op_p;
    2103    171404296 :   ssa_op_iter iter;
    2104    171404296 :   tree last_copy_propagated_op = NULL;
    2105              : 
    2106    250923246 :   FOR_EACH_SSA_USE_OPERAND (op_p, stmt, iter, SSA_OP_USE)
    2107              :     {
    2108     79518950 :       tree old_op = USE_FROM_PTR (op_p);
    2109              : 
    2110              :       /* If we have A = B and B = A in the copy propagation tables
    2111              :          (due to an equality comparison), avoid substituting B for A
    2112              :          then A for B in the trivially discovered cases.   This allows
    2113              :          optimization of statements were A and B appear as input
    2114              :          operands.  */
    2115     79518950 :       if (old_op != last_copy_propagated_op)
    2116              :         {
    2117     79518347 :           cprop_operand (stmt, op_p, query);
    2118              : 
    2119     79518347 :           tree new_op = USE_FROM_PTR (op_p);
    2120     79518347 :           if (new_op != old_op && TREE_CODE (new_op) == SSA_NAME)
    2121     79518950 :             last_copy_propagated_op = new_op;
    2122              :         }
    2123              :     }
    2124    171404296 : }
    2125              : 
    2126              : /* If STMT contains a relational test, try to convert it into an
    2127              :    equality test if there is only a single value which can ever
    2128              :    make the test true.
    2129              : 
    2130              :    For example, if the expression hash table contains:
    2131              : 
    2132              :     TRUE = (i <= 1)
    2133              : 
    2134              :    And we have a test within statement of i >= 1, then we can safely
    2135              :    rewrite the test as i == 1 since there only a single value where
    2136              :    the test is true.
    2137              : 
    2138              :    This is similar to code in VRP.  */
    2139              : 
    2140              : void
    2141     54229705 : dom_opt_dom_walker::test_for_singularity (gimple *stmt,
    2142              :                                           avail_exprs_stack *avail_exprs_stack)
    2143              : {
    2144              :   /* We want to support gimple conditionals as well as assignments
    2145              :      where the RHS contains a conditional.  */
    2146     54229705 :   if (is_gimple_assign (stmt) || gimple_code (stmt) == GIMPLE_COND)
    2147              :     {
    2148     52950276 :       enum tree_code code = ERROR_MARK;
    2149     52950276 :       tree lhs, rhs;
    2150              : 
    2151              :       /* Extract the condition of interest from both forms we support.  */
    2152     52950276 :       if (is_gimple_assign (stmt))
    2153              :         {
    2154     44040327 :           code = gimple_assign_rhs_code (stmt);
    2155     44040327 :           lhs = gimple_assign_rhs1 (stmt);
    2156     44040327 :           rhs = gimple_assign_rhs2 (stmt);
    2157              :         }
    2158      8909949 :       else if (gimple_code (stmt) == GIMPLE_COND)
    2159              :         {
    2160      8909949 :           code = gimple_cond_code (as_a <gcond *> (stmt));
    2161      8909949 :           lhs = gimple_cond_lhs (as_a <gcond *> (stmt));
    2162      8909949 :           rhs = gimple_cond_rhs (as_a <gcond *> (stmt));
    2163              :         }
    2164              : 
    2165              :       /* We're looking for a relational test using LE/GE.  Also note we can
    2166              :          canonicalize LT/GT tests against constants into LE/GT tests.  */
    2167     52950276 :       if (code == LE_EXPR || code == GE_EXPR
    2168     52287820 :           || ((code == LT_EXPR || code == GT_EXPR)
    2169      1706538 :                && TREE_CODE (rhs) == INTEGER_CST))
    2170              :         {
    2171              :           /* For LT_EXPR and GT_EXPR, canonicalize to LE_EXPR and GE_EXPR.  */
    2172       905406 :           if (code == LT_EXPR)
    2173       132856 :             rhs = fold_build2 (MINUS_EXPR, TREE_TYPE (rhs),
    2174              :                                rhs, build_int_cst (TREE_TYPE (rhs), 1));
    2175              : 
    2176      1567862 :           if (code == GT_EXPR)
    2177       772550 :             rhs = fold_build2 (PLUS_EXPR, TREE_TYPE (rhs),
    2178              :                                rhs, build_int_cst (TREE_TYPE (rhs), 1));
    2179              : 
    2180              :           /* Determine the code we want to check for in the hash table.  */
    2181      1567862 :           enum tree_code test_code;
    2182      1567862 :           if (code == GE_EXPR || code == GT_EXPR)
    2183              :             test_code = LE_EXPR;
    2184              :           else
    2185       537493 :             test_code = GE_EXPR;
    2186              : 
    2187              :           /* Update the dummy statement so we can query the hash tables.  */
    2188      1567862 :           gimple_cond_set_code (m_dummy_cond, test_code);
    2189      1567862 :           gimple_cond_set_lhs (m_dummy_cond, lhs);
    2190      1567862 :           gimple_cond_set_rhs (m_dummy_cond, rhs);
    2191      1567862 :           tree cached_lhs
    2192      1567862 :             = avail_exprs_stack->lookup_avail_expr (m_dummy_cond,
    2193              :                                                     false, false);
    2194              : 
    2195              :           /* If the lookup returned 1 (true), then the expression we
    2196              :              queried was in the hash table.  As a result there is only
    2197              :              one value that makes the original conditional true.  Update
    2198              :              STMT accordingly.  */
    2199      1567862 :           if (cached_lhs && integer_onep (cached_lhs))
    2200              :             {
    2201         1357 :               if (is_gimple_assign (stmt))
    2202              :                 {
    2203           96 :                   gimple_assign_set_rhs_code (stmt, EQ_EXPR);
    2204           96 :                   gimple_assign_set_rhs2 (stmt, rhs);
    2205           96 :                   gimple_set_modified (stmt, true);
    2206              :                 }
    2207              :               else
    2208              :                 {
    2209         1261 :                   gimple_set_modified (stmt, true);
    2210         1261 :                   gimple_cond_set_code (as_a <gcond *> (stmt), EQ_EXPR);
    2211         1261 :                   gimple_cond_set_rhs (as_a <gcond *> (stmt), rhs);
    2212         1261 :                   gimple_set_modified (stmt, true);
    2213              :                 }
    2214              :             }
    2215              :         }
    2216              :     }
    2217     54229705 : }
    2218              : 
    2219              : /* If STMT is a comparison of two uniform vectors reduce it to a comparison
    2220              :    of scalar objects, otherwise leave STMT unchanged.  */
    2221              : 
    2222              : static void
    2223    171404296 : reduce_vector_comparison_to_scalar_comparison (gimple *stmt)
    2224              : {
    2225    171404296 :   if (gimple_code (stmt) == GIMPLE_COND)
    2226              :     {
    2227      9012414 :       tree lhs = gimple_cond_lhs (stmt);
    2228      9012414 :       tree rhs = gimple_cond_rhs (stmt);
    2229              : 
    2230              :       /* We may have a vector comparison where both arms are uniform
    2231              :          vectors.  If so, we can simplify the vector comparison down
    2232              :          to a scalar comparison.  */
    2233      9012414 :       if (VECTOR_TYPE_P (TREE_TYPE (lhs))
    2234      9012414 :           && VECTOR_TYPE_P (TREE_TYPE (rhs)))
    2235              :         {
    2236              :           /* If either operand is an SSA_NAME, then look back to its
    2237              :              defining statement to try and get at a suitable source.  */
    2238         2497 :           if (TREE_CODE (rhs) == SSA_NAME)
    2239              :             {
    2240            0 :               gimple *def_stmt = SSA_NAME_DEF_STMT (rhs);
    2241            0 :               if (gimple_assign_single_p (def_stmt))
    2242            0 :                 rhs = gimple_assign_rhs1 (def_stmt);
    2243              :             }
    2244              : 
    2245         2497 :           if (TREE_CODE (lhs) == SSA_NAME)
    2246              :             {
    2247         2497 :               gimple *def_stmt = SSA_NAME_DEF_STMT (lhs);
    2248         2497 :               if (gimple_assign_single_p (def_stmt))
    2249            6 :                 lhs = gimple_assign_rhs1 (def_stmt);
    2250              :             }
    2251              : 
    2252              :           /* Now see if they are both uniform vectors and if so replace
    2253              :              the vector comparison with a scalar comparison.  */
    2254         2497 :           tree rhs_elem = rhs ? uniform_vector_p (rhs) : NULL_TREE;
    2255         2497 :           tree lhs_elem = lhs ? uniform_vector_p (lhs) : NULL_TREE;
    2256         2497 :           if (rhs_elem && lhs_elem)
    2257              :             {
    2258            3 :               if (dump_file && dump_flags & TDF_DETAILS)
    2259              :                 {
    2260            0 :                   fprintf (dump_file, "Reducing vector comparison: ");
    2261            0 :                   print_gimple_stmt (dump_file, stmt, 0);
    2262              :                 }
    2263              : 
    2264            3 :               gimple_cond_set_rhs (as_a <gcond *>(stmt), rhs_elem);
    2265            3 :               gimple_cond_set_lhs (as_a <gcond *>(stmt), lhs_elem);
    2266            3 :               gimple_set_modified (stmt, true);
    2267              : 
    2268            3 :               if (dump_file && dump_flags & TDF_DETAILS)
    2269              :                 {
    2270            0 :                   fprintf (dump_file, "To scalar equivalent: ");
    2271            0 :                   print_gimple_stmt (dump_file, stmt, 0);
    2272            0 :                   fprintf (dump_file, "\n");
    2273              :                 }
    2274              :             }
    2275              :         }
    2276              :     }
    2277    171404296 : }
    2278              : 
    2279              : /* If possible, rewrite the conditional as TRUE or FALSE, and return
    2280              :    the taken edge.  Otherwise, return NULL.  */
    2281              : 
    2282              : edge
    2283      8951146 : dom_opt_dom_walker::fold_cond (gcond *cond)
    2284              : {
    2285      8951146 :   simplify_using_ranges simplify (m_ranger);
    2286      8951146 :   if (simplify.fold_cond (cond))
    2287              :     {
    2288       102465 :       basic_block bb = gimple_bb (cond);
    2289       102465 :       if (gimple_cond_true_p (cond))
    2290        23595 :         return find_taken_edge (bb, boolean_true_node);
    2291        78870 :       if (gimple_cond_false_p (cond))
    2292        78870 :         return find_taken_edge (bb, boolean_false_node);
    2293              :     }
    2294              :   return NULL;
    2295      8951146 : }
    2296              : 
    2297              : /* Optimize the statement in block BB pointed to by iterator SI.
    2298              : 
    2299              :    We try to perform some simplistic global redundancy elimination and
    2300              :    constant propagation:
    2301              : 
    2302              :    1- To detect global redundancy, we keep track of expressions that have
    2303              :       been computed in this block and its dominators.  If we find that the
    2304              :       same expression is computed more than once, we eliminate repeated
    2305              :       computations by using the target of the first one.
    2306              : 
    2307              :    2- Constant values and copy assignments.  This is used to do very
    2308              :       simplistic constant and copy propagation.  When a constant or copy
    2309              :       assignment is found, we map the value on the RHS of the assignment to
    2310              :       the variable in the LHS in the CONST_AND_COPIES table.
    2311              : 
    2312              :    3- Very simple redundant store elimination is performed.
    2313              : 
    2314              :    4- We can simplify a condition to a constant or from a relational
    2315              :       condition to an equality condition.  */
    2316              : 
    2317              : edge
    2318    171404296 : dom_opt_dom_walker::optimize_stmt (basic_block bb, gimple_stmt_iterator *si,
    2319              :                                    bool *removed_p)
    2320              : {
    2321    171404296 :   gimple *stmt, *old_stmt;
    2322    171404296 :   bool may_optimize_p;
    2323    171404296 :   bool modified_p = false;
    2324    171404296 :   bool was_noreturn;
    2325    171404296 :   edge retval = NULL;
    2326              : 
    2327    171404296 :   old_stmt = stmt = gsi_stmt (*si);
    2328    171404296 :   was_noreturn = is_gimple_call (stmt) && gimple_call_noreturn_p (stmt);
    2329              : 
    2330    171404296 :   if (dump_file && (dump_flags & TDF_DETAILS))
    2331              :     {
    2332         1606 :       fprintf (dump_file, "Optimizing statement ");
    2333         1606 :       print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    2334              :     }
    2335              : 
    2336              :   /* STMT may be a comparison of uniform vectors that we can simplify
    2337              :      down to a comparison of scalars.  Do that transformation first
    2338              :      so that all the scalar optimizations from here onward apply.  */
    2339    171404296 :   reduce_vector_comparison_to_scalar_comparison (stmt);
    2340              : 
    2341    171404296 :   update_stmt_if_modified (stmt);
    2342    171404296 :   opt_stats.num_stmts++;
    2343              : 
    2344              :   /* Const/copy propagate into USES, VUSES and the RHS of VDEFs.  */
    2345    171404296 :   cprop_into_stmt (stmt, m_ranger);
    2346              : 
    2347              :   /* If the statement has been modified with constant replacements,
    2348              :      fold its RHS before checking for redundant computations.  */
    2349    342507665 :   if (gimple_modified_p (stmt))
    2350              :     {
    2351      3679484 :       tree rhs = NULL;
    2352              : 
    2353              :       /* Try to fold the statement making sure that STMT is kept
    2354              :          up to date.  */
    2355      3679484 :       if (fold_stmt (si))
    2356              :         {
    2357       374618 :           stmt = gsi_stmt (*si);
    2358       374618 :           gimple_set_modified (stmt, true);
    2359              : 
    2360       374618 :           if (dump_file && (dump_flags & TDF_DETAILS))
    2361              :             {
    2362           12 :               fprintf (dump_file, "  Folded to: ");
    2363           12 :               print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    2364              :             }
    2365              :         }
    2366              : 
    2367              :       /* We only need to consider cases that can yield a gimple operand.  */
    2368      3679484 :       if (gimple_assign_single_p (stmt))
    2369      1386411 :         rhs = gimple_assign_rhs1 (stmt);
    2370      2293073 :       else if (gimple_code (stmt) == GIMPLE_GOTO)
    2371            1 :         rhs = gimple_goto_dest (stmt);
    2372    173697368 :       else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt))
    2373              :         /* This should never be an ADDR_EXPR.  */
    2374         2130 :         rhs = gimple_switch_index (swtch_stmt);
    2375              : 
    2376      1388542 :       if (rhs && TREE_CODE (rhs) == ADDR_EXPR)
    2377        80021 :         recompute_tree_invariant_for_addr_expr (rhs);
    2378              : 
    2379              :       /* Indicate that maybe_clean_or_replace_eh_stmt needs to be called,
    2380              :          even if fold_stmt updated the stmt already and thus cleared
    2381              :          gimple_modified_p flag on it.  */
    2382              :       modified_p = true;
    2383              :     }
    2384              : 
    2385              :   /* Check for redundant computations.  Do this optimization only
    2386              :      for assignments that have no volatile ops and conditionals.  */
    2387    171404296 :   may_optimize_p = (!gimple_has_side_effects (stmt)
    2388    171404296 :                     && (is_gimple_assign (stmt)
    2389    114164735 :                         || (is_gimple_call (stmt)
    2390      1254103 :                             && gimple_call_lhs (stmt) != NULL_TREE)
    2391    112910961 :                         || gimple_code (stmt) == GIMPLE_COND
    2392    103898547 :                         || gimple_code (stmt) == GIMPLE_SWITCH));
    2393              : 
    2394     54453806 :   if (may_optimize_p)
    2395              :     {
    2396     54453806 :       if (gimple_code (stmt) == GIMPLE_CALL)
    2397              :         {
    2398              :           /* Resolve __builtin_constant_p.  If it hasn't been
    2399              :              folded to integer_one_node by now, it's fairly
    2400              :              certain that the value simply isn't constant.  */
    2401      1253774 :           tree callee = gimple_call_fndecl (stmt);
    2402      1253774 :           if (callee
    2403      1253774 :               && fndecl_built_in_p (callee, BUILT_IN_CONSTANT_P))
    2404              :             {
    2405         1908 :               propagate_tree_value_into_stmt (si, integer_zero_node);
    2406         1908 :               stmt = gsi_stmt (*si);
    2407              :             }
    2408              :         }
    2409              : 
    2410     54453806 :       if (gimple_code (stmt) == GIMPLE_COND)
    2411              :         {
    2412      9012414 :           tree lhs = gimple_cond_lhs (stmt);
    2413      9012414 :           tree rhs = gimple_cond_rhs (stmt);
    2414              : 
    2415              :           /* If the LHS has a range [0..1] and the RHS has a range ~[0..1],
    2416              :              then this conditional is computable at compile time.  We can just
    2417              :              shove either 0 or 1 into the LHS, mark the statement as modified
    2418              :              and all the right things will just happen below.
    2419              : 
    2420              :              Note this would apply to any case where LHS has a range
    2421              :              narrower than its type implies and RHS is outside that
    2422              :              narrower range.  Future work.  */
    2423      9012414 :           if (TREE_CODE (lhs) == SSA_NAME
    2424      8951170 :               && ssa_name_has_boolean_range (lhs)
    2425      1006681 :               && TREE_CODE (rhs) == INTEGER_CST
    2426      9987783 :               && ! (integer_zerop (rhs) || integer_onep (rhs)))
    2427              :             {
    2428           24 :               gimple_cond_set_lhs (as_a <gcond *> (stmt),
    2429           24 :                                    fold_convert (TREE_TYPE (lhs),
    2430              :                                                  integer_zero_node));
    2431           24 :               gimple_set_modified (stmt, true);
    2432              :             }
    2433      9012390 :           else if (TREE_CODE (lhs) == SSA_NAME)
    2434              :             {
    2435              :               /* Exploiting EVRP data is not yet fully integrated into DOM
    2436              :                  but we need to do something for this case to avoid regressing
    2437              :                  udr4.f90 and new1.C which have unexecutable blocks with
    2438              :                  undefined behavior that get diagnosed if they're left in the
    2439              :                  IL because we've attached range information to new
    2440              :                  SSA_NAMES.  */
    2441      8951146 :               update_stmt_if_modified (stmt);
    2442      8951146 :               edge taken_edge = fold_cond (as_a <gcond *> (stmt));
    2443      8951146 :               if (taken_edge)
    2444              :                 {
    2445       102465 :                   gimple_set_modified (stmt, true);
    2446       102465 :                   update_stmt (stmt);
    2447       102465 :                   cfg_altered = true;
    2448       102465 :                   return taken_edge;
    2449              :                 }
    2450              :             }
    2451              :         }
    2452              : 
    2453     54351341 :       update_stmt_if_modified (stmt);
    2454     54351341 :       eliminate_redundant_computations (si, m_const_and_copies,
    2455              :                                         m_avail_exprs_stack);
    2456     54351341 :       stmt = gsi_stmt (*si);
    2457              : 
    2458              :       /* Perform simple redundant store elimination.  */
    2459     54351341 :       if (gimple_assign_single_p (stmt)
    2460     27605991 :           && TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME
    2461     66934856 :           && (TREE_CODE (gimple_assign_lhs (stmt)) != VAR_DECL
    2462      1013980 :               || !DECL_HARD_REGISTER (gimple_assign_lhs (stmt))))
    2463              :         {
    2464     12581497 :           tree lhs = gimple_assign_lhs (stmt);
    2465     12581497 :           tree rhs = gimple_assign_rhs1 (stmt);
    2466     12581497 :           tree cached_lhs;
    2467     12581497 :           gassign *new_stmt;
    2468     12581497 :           rhs = dom_valueize (rhs);
    2469              :           /* Build a new statement with the RHS and LHS exchanged.  */
    2470     12581497 :           if (TREE_CODE (rhs) == SSA_NAME)
    2471              :             {
    2472      5202390 :               gimple *defstmt = SSA_NAME_DEF_STMT (rhs);
    2473      5202390 :               new_stmt = gimple_build_assign (rhs, lhs);
    2474      5202390 :               SSA_NAME_DEF_STMT (rhs) = defstmt;
    2475              :             }
    2476              :           else
    2477      7379107 :             new_stmt = gimple_build_assign (rhs, lhs);
    2478     25162994 :           gimple_set_vuse (new_stmt, gimple_vuse (stmt));
    2479     12581497 :           expr_hash_elt *elt = NULL;
    2480     12581497 :           cached_lhs = m_avail_exprs_stack->lookup_avail_expr (new_stmt, false,
    2481              :                                                                false, &elt);
    2482     12581497 :           if (cached_lhs
    2483       823682 :               && operand_equal_p (rhs, cached_lhs, 0)
    2484     12830219 :               && refs_same_for_tbaa_p (elt->expr ()->kind == EXPR_SINGLE
    2485       124361 :                                        ? elt->expr ()->ops.single.rhs
    2486              :                                        : NULL_TREE, lhs))
    2487              :             {
    2488       121636 :               basic_block bb = gimple_bb (stmt);
    2489       121636 :               unlink_stmt_vdef (stmt);
    2490       121636 :               if (gsi_remove (si, true))
    2491              :                 {
    2492            0 :                   bitmap_set_bit (need_eh_cleanup, bb->index);
    2493            0 :                   if (dump_file && (dump_flags & TDF_DETAILS))
    2494            0 :                     fprintf (dump_file, "  Flagged to clear EH edges.\n");
    2495              :                 }
    2496       121636 :               release_defs (stmt);
    2497       121636 :               *removed_p = true;
    2498       121636 :               return retval;
    2499              :             }
    2500              :         }
    2501              : 
    2502              :       /* If this statement was not redundant, we may still be able to simplify
    2503              :          it, which may in turn allow other part of DOM or other passes to do
    2504              :          a better job.  */
    2505     54229705 :       test_for_singularity (stmt, m_avail_exprs_stack);
    2506              :     }
    2507              : 
    2508              :   /* Record any additional equivalences created by this statement.  */
    2509    171180195 :   if (is_gimple_assign (stmt))
    2510     47527751 :     record_equivalences_from_stmt (stmt, may_optimize_p, m_avail_exprs_stack);
    2511              : 
    2512              :   /* If STMT is a COND_EXPR or SWITCH_EXPR and it was modified, then we may
    2513              :      know where it goes.  */
    2514    342360390 :   if (gimple_modified_p (stmt) || modified_p)
    2515              :     {
    2516      3962065 :       tree val = NULL;
    2517              : 
    2518      3962065 :       if (gimple_code (stmt) == GIMPLE_COND)
    2519       434968 :         val = fold_binary_loc (gimple_location (stmt),
    2520              :                                gimple_cond_code (stmt), boolean_type_node,
    2521              :                                gimple_cond_lhs (stmt),
    2522              :                                gimple_cond_rhs (stmt));
    2523      3527097 :       else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt))
    2524         2130 :         val = gimple_switch_index (swtch_stmt);
    2525              : 
    2526       437098 :       if (val && TREE_CODE (val) == INTEGER_CST)
    2527              :         {
    2528        63424 :           retval = find_taken_edge (bb, val);
    2529        63424 :           if (retval)
    2530              :             {
    2531              :               /* Fix the condition to be either true or false.  */
    2532        63424 :               if (gimple_code (stmt) == GIMPLE_COND)
    2533              :                 {
    2534        63408 :                   if (integer_zerop (val))
    2535        32574 :                     gimple_cond_make_false (as_a <gcond *> (stmt));
    2536        30834 :                   else if (integer_onep (val))
    2537        30834 :                     gimple_cond_make_true (as_a <gcond *> (stmt));
    2538              :                   else
    2539            0 :                     gcc_unreachable ();
    2540              : 
    2541        63408 :                   gimple_set_modified (stmt, true);
    2542              :                 }
    2543              : 
    2544              :               /* Further simplifications may be possible.  */
    2545        63424 :               cfg_altered = true;
    2546              :             }
    2547              :         }
    2548              : 
    2549      3962065 :       update_stmt_if_modified (stmt);
    2550              : 
    2551              :       /* If we simplified a statement in such a way as to be shown that it
    2552              :          cannot trap, update the eh information and the cfg to match.  */
    2553      3962065 :       if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
    2554              :         {
    2555         1506 :           bitmap_set_bit (need_eh_cleanup, bb->index);
    2556         1506 :           if (dump_file && (dump_flags & TDF_DETAILS))
    2557            0 :             fprintf (dump_file, "  Flagged to clear EH edges.\n");
    2558              :         }
    2559              : 
    2560      3962065 :       if (!was_noreturn
    2561      3962065 :           && is_gimple_call (stmt) && gimple_call_noreturn_p (stmt))
    2562            3 :         need_noreturn_fixup.safe_push (stmt);
    2563              :     }
    2564              :   return retval;
    2565              : }
        

Generated by: LCOV version 2.4-beta

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