LCOV - code coverage report
Current view: top level - gcc - tree-ssa-dom.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 93.9 % 1061 996
Test Date: 2026-08-22 16:33:35 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     37022116 : 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     37022116 :   free_dom_edge_info (e);
     134     37022116 :   e->aux = this;
     135              : 
     136              :   /* And initialize the embedded vectors.  */
     137     37022116 :   simple_equivalences = vNULL;
     138     37022116 :   cond_equivalences = vNULL;
     139     37022116 : }
     140              : 
     141              : /* Destructor just needs to release the vectors.  */
     142              : 
     143     37022116 : edge_info::~edge_info (void)
     144              : {
     145     37022116 :   this->cond_equivalences.release ();
     146     37022116 :   this->simple_equivalences.release ();
     147     37022116 : }
     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     13443268 : edge_info::derive_equivalences (tree name, tree value, int recursion_limit)
     159              : {
     160     15568131 :   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     15567839 :   simple_equivalences.safe_push (equiv_pair (name, value));
     166              : 
     167              :   /* Limit how far up the use-def chains we are willing to walk.  */
     168     15567839 :   if (recursion_limit == 0)
     169              :     return;
     170              : 
     171              :   /* We can walk up the use-def chains to potentially find more
     172              :      equivalences.  */
     173     15552741 :   gimple *def_stmt = SSA_NAME_DEF_STMT (name);
     174     15552741 :   if (is_gimple_assign (def_stmt))
     175              :     {
     176     10142328 :       enum tree_code code = gimple_assign_rhs_code (def_stmt);
     177     10142328 :       switch (code)
     178              :         {
     179              :         /* If the result of an OR is zero, then its operands are, too.  */
     180       595674 :         case BIT_IOR_EXPR:
     181       595674 :           if (integer_zerop (value))
     182              :             {
     183       329502 :               tree rhs1 = gimple_assign_rhs1 (def_stmt);
     184       329502 :               tree rhs2 = gimple_assign_rhs2 (def_stmt);
     185              : 
     186       329502 :               value = build_zero_cst (TREE_TYPE (rhs1));
     187       329502 :               derive_equivalences (rhs1, value, recursion_limit - 1);
     188       329502 :               value = build_zero_cst (TREE_TYPE (rhs2));
     189       329502 :               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      1087430 :         case BIT_AND_EXPR:
     195      1087430 :           if (!integer_zerop (value))
     196              :             {
     197       457699 :               tree rhs1 = gimple_assign_rhs1 (def_stmt);
     198       457699 :               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       457699 :               if (TREE_CODE (rhs1) == SSA_NAME)
     205              :                 {
     206       457699 :                   if (ssa_name_has_boolean_range (rhs1))
     207              :                     {
     208       289424 :                       value = build_one_cst (TREE_TYPE (rhs1));
     209       289424 :                       derive_equivalences (rhs1, value, recursion_limit - 1);
     210              :                     }
     211              :                 }
     212       457699 :               if (TREE_CODE (rhs2) == SSA_NAME)
     213              :                 {
     214       291412 :                   if (ssa_name_has_boolean_range (rhs2))
     215              :                     {
     216       289138 :                       value = build_one_cst (TREE_TYPE (rhs2));
     217       289138 :                       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       444681 :         CASE_CONVERT:
     227       444681 :           {
     228       444681 :             tree rhs = gimple_assign_rhs1 (def_stmt);
     229       444681 :             tree rhs_type = TREE_TYPE (rhs);
     230       444681 :             if (INTEGRAL_TYPE_P (rhs_type)
     231       442111 :                 && (TYPE_PRECISION (TREE_TYPE (name))
     232       442111 :                     >= TYPE_PRECISION (rhs_type))
     233       690903 :                 && int_fits_type_p (value, rhs_type))
     234       234336 :               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      1048688 :         case POINTER_PLUS_EXPR:
     244      1048688 :         case PLUS_EXPR:
     245      1048688 :           {
     246      1048688 :             tree rhs1 = gimple_assign_rhs1 (def_stmt);
     247      1048688 :             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      1048688 :             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      1048688 :             else if (TREE_CODE (rhs2) == INTEGER_CST
     258       995399 :                      && TREE_CODE (rhs1) == SSA_NAME)
     259       995399 :               derive_equivalences (rhs1,
     260       995399 :                                    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        75253 :         case MINUS_EXPR:
     270        75253 :           {
     271        75253 :             tree rhs1 = gimple_assign_rhs1 (def_stmt);
     272        75253 :             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        75253 :             if (TREE_CODE (rhs1) == INTEGER_CST
     277          665 :                 && TREE_CODE (rhs2) == SSA_NAME)
     278          665 :               derive_equivalences (rhs2,
     279          665 :                                    fold_binary (MINUS_EXPR, TREE_TYPE (rhs1),
     280              :                                                 rhs1, value),
     281              :                                    recursion_limit - 1);
     282        74588 :             else if (TREE_CODE (rhs2) == INTEGER_CST
     283        29762 :                      && TREE_CODE (rhs1) == SSA_NAME)
     284        29762 :               derive_equivalences (rhs1,
     285        29762 :                                    fold_binary (PLUS_EXPR, TREE_TYPE (rhs1),
     286              :                                                 value, rhs2),
     287              :                                    recursion_limit - 1);
     288        44826 :             else if (integer_zerop (value))
     289              :               {
     290        16156 :                 tree cond = build2 (EQ_EXPR, boolean_type_node,
     291              :                                     gimple_assign_rhs1 (def_stmt),
     292              :                                     gimple_assign_rhs2 (def_stmt));
     293        16156 :                 tree inverted = invert_truthvalue (cond);
     294        16156 :                 record_conditions (&this->cond_equivalences, cond, inverted);
     295              :               }
     296              :             break;
     297              :           }
     298              : 
     299       740104 :         case EQ_EXPR:
     300       740104 :         case NE_EXPR:
     301       740104 :           {
     302       329457 :             if ((code == EQ_EXPR && integer_onep (value))
     303       876082 :                 || (code == NE_EXPR && integer_zerop (value)))
     304              :               {
     305       453551 :                 tree rhs1 = gimple_assign_rhs1 (def_stmt);
     306       453551 :                 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       453551 :                 if (TREE_CODE (rhs1) == INTEGER_CST)
     314            0 :                   derive_equivalences (rhs2, rhs1, recursion_limit - 1);
     315       453551 :                 else if (TREE_CODE (rhs2) == INTEGER_CST)
     316       231909 :                   derive_equivalences (rhs1, rhs2, recursion_limit - 1);
     317              :               }
     318              :             else
     319              :               {
     320       286553 :                 tree cond = build2 (code, boolean_type_node,
     321              :                                     gimple_assign_rhs1 (def_stmt),
     322       286553 :                                     gimple_assign_rhs2 (def_stmt));
     323       286553 :                 tree inverted = invert_truthvalue (cond);
     324       286553 :                 if (integer_zerop (value))
     325       135978 :                   std::swap (cond, inverted);
     326       286553 :                 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        14152 :         case BIT_NOT_EXPR:
     335        14152 :         case NEGATE_EXPR:
     336        14152 :           {
     337        14152 :             tree rhs = gimple_assign_rhs1 (def_stmt);
     338        14152 :             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        14152 :             if (code == BIT_NOT_EXPR
     350        13873 :                 && TREE_CODE (rhs) == SSA_NAME
     351        28025 :                 && ssa_name_has_boolean_range (rhs))
     352              :               {
     353        13370 :                 if ((TREE_INT_CST_LOW (value) & 1) == 0)
     354         6412 :                   res = build_one_cst (TREE_TYPE (rhs));
     355              :                 else
     356         6958 :                   res = build_zero_cst (TREE_TYPE (rhs));
     357              :               }
     358              :             else
     359          782 :               res = fold_build1 (code, TREE_TYPE (rhs), value);
     360        14152 :             derive_equivalences (rhs, res, recursion_limit - 1);
     361        14152 :             break;
     362              :           }
     363              : 
     364      6136346 :         default:
     365      6136346 :           {
     366      6136346 :             if (TREE_CODE_CLASS (code) == tcc_comparison)
     367              :               {
     368       536108 :                 tree cond = build2 (code, boolean_type_node,
     369              :                                     gimple_assign_rhs1 (def_stmt),
     370       536108 :                                     gimple_assign_rhs2 (def_stmt));
     371       536108 :                 tree inverted = invert_truthvalue (cond);
     372       536108 :                 if (integer_zerop (value))
     373       231241 :                   std::swap (cond, inverted);
     374       536108 :                 record_conditions (&this->cond_equivalences, cond, inverted);
     375       536108 :                 break;
     376              :               }
     377              :             break;
     378              :           }
     379              :         }
     380              :     }
     381              : }
     382              : 
     383              : void
     384     16125463 : 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     16125463 :   if (TREE_CODE (rhs) == INTEGER_CST)
     390     12824342 :     derive_equivalences (lhs, rhs, 4);
     391              :   else
     392      3301121 :     simple_equivalences.safe_push (equiv_pair (lhs, rhs));
     393     16125463 : }
     394              : 
     395              : /* Free the edge_info data attached to E, if it exists and
     396              :    clear e->aux.  */
     397              : 
     398              : void
     399    133773180 : free_dom_edge_info (edge e)
     400              : {
     401    133773180 :   class edge_info *edge_info = (class edge_info *)e->aux;
     402              : 
     403    133773180 :   if (edge_info)
     404     37022116 :     delete edge_info;
     405    133773180 :   e->aux = NULL;
     406    133773180 : }
     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      2121033 : free_all_edge_infos (void)
     416              : {
     417      2121033 :   basic_block bb;
     418      2121033 :   edge_iterator ei;
     419      2121033 :   edge e;
     420              : 
     421     24085495 :   FOR_EACH_BB_FN (bb, cfun)
     422              :     {
     423     52968757 :       FOR_EACH_EDGE (e, ei, bb->preds)
     424     31004295 :         free_dom_edge_info (e);
     425              :     }
     426      2121033 : }
     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     18524306 : single_block_loop_p (basic_block bb)
     436              : {
     437              :   /* Two preds.  */
     438     18524306 :   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      5340665 :   basic_block pred = NULL;
     444      5340665 :   unsigned int count = 0;
     445      5340665 :   if (EDGE_PRED (bb, 0)->flags & EDGE_DFS_BACK)
     446              :     {
     447      1902679 :       pred = EDGE_PRED (bb, 0)->src;
     448      1902679 :       count++;
     449              :     }
     450      5340665 :   if (EDGE_PRED (bb, 1)->flags & EDGE_DFS_BACK)
     451              :     {
     452       406448 :       pred = EDGE_PRED (bb, 1)->src;
     453       406448 :       count++;
     454              :     }
     455              : 
     456      5340665 :   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      2309127 :   if (EDGE_COUNT (pred->preds) != 1
     462      2227964 :       || EDGE_COUNT (pred->succs) != 1
     463      2225488 :       || EDGE_PRED (pred, 0)->src != bb
     464      3413210 :       || 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      1104083 :   if (! gimple_seq_empty_p (phi_nodes (pred)))
     471              :     return false;
     472              : 
     473      1099389 :   gimple_stmt_iterator gsi;
     474      2208463 :   for (gsi = gsi_last_bb (pred); !gsi_end_p (gsi); gsi_prev (&gsi))
     475              :     {
     476        67132 :       gimple *stmt = gsi_stmt (gsi);
     477              : 
     478        67132 :       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     45962244 : record_edge_info (basic_block bb)
     501              : {
     502     45962244 :   gimple_stmt_iterator gsi = gsi_last_bb (bb);
     503     45962244 :   class edge_info *edge_info;
     504              : 
     505              :   /* Free all the outgoing edge info data associated with
     506              :      BB's outgoing edges.  */
     507     45962244 :   edge e;
     508     45962244 :   edge_iterator ei;
     509    109893375 :   FOR_EACH_EDGE (e, ei, bb->succs)
     510     63931131 :     free_dom_edge_info (e);
     511              : 
     512     45962244 :   if (! gsi_end_p (gsi))
     513              :     {
     514     39687131 :       gimple *stmt = gsi_stmt (gsi);
     515     39687131 :       location_t loc = gimple_location (stmt);
     516              : 
     517     39687131 :       if (gimple_code (stmt) == GIMPLE_SWITCH)
     518              :         {
     519        70021 :           gswitch *switch_stmt = as_a <gswitch *> (stmt);
     520        70021 :           tree index = gimple_switch_index (switch_stmt);
     521              : 
     522        70021 :           if (TREE_CODE (index) == SSA_NAME)
     523              :             {
     524        70005 :               int i;
     525        70005 :               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        70005 :               tree *info = XCNEWVEC (tree, last_basic_block_for_fn (cfun));
     532              : 
     533       657315 :               for (i = 0; i < n_labels; i++)
     534              :                 {
     535       517305 :                   tree label = gimple_switch_label (switch_stmt, i);
     536       517305 :                   basic_block target_bb
     537       517305 :                     = 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       517305 :                   if (CASE_HIGH (label)
     541       493773 :                       || !CASE_LOW (label)
     542       941073 :                       || info[target_bb->index])
     543       141715 :                     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       375590 :                     info[target_bb->index] = CASE_LOW (label);
     548              :                 }
     549              : 
     550       532204 :               FOR_EACH_EDGE (e, ei, bb->succs)
     551              :                 {
     552       462199 :                   basic_block target_bb = e->dest;
     553       462199 :                   tree value = info[target_bb->index];
     554              : 
     555       462199 :                   if (value != NULL && value != error_mark_node)
     556              :                     {
     557       351085 :                       tree x = fold_convert_loc (loc, TREE_TYPE (index),
     558              :                                                  value);
     559       351085 :                       edge_info = new class edge_info (e);
     560       351085 :                       edge_info->record_simple_equiv (index, x);
     561              :                     }
     562              :                 }
     563        70005 :               free (info);
     564              :             }
     565              :         }
     566              : 
     567              :       /* A COND_EXPR may create equivalences too.  */
     568     39687131 :       if (gimple_code (stmt) == GIMPLE_COND)
     569              :         {
     570     18524306 :           edge true_edge;
     571     18524306 :           edge false_edge;
     572              : 
     573     18524306 :           tree op0 = gimple_cond_lhs (stmt);
     574     18524306 :           tree op1 = gimple_cond_rhs (stmt);
     575     18524306 :           enum tree_code code = gimple_cond_code (stmt);
     576              : 
     577     18524306 :           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     18524306 :           if ((code == EQ_EXPR || code == NE_EXPR)
     587     14162476 :               && TREE_CODE (op0) == SSA_NAME
     588     13973826 :               && ssa_name_has_boolean_range (op0)
     589      2070535 :               && is_gimple_min_invariant (op1)
     590     20531888 :               && (integer_zerop (op1) || integer_onep (op1)))
     591              :             {
     592      2007582 :               tree true_val = constant_boolean_node (true, TREE_TYPE (op0));
     593      2007582 :               tree false_val = constant_boolean_node (false, TREE_TYPE (op0));
     594              : 
     595      2007582 :               if (code == EQ_EXPR)
     596              :                 {
     597        77554 :                   edge_info = new class edge_info (true_edge);
     598       115935 :                   edge_info->record_simple_equiv (op0,
     599        77554 :                                                   (integer_zerop (op1)
     600              :                                                    ? false_val : true_val));
     601        77554 :                   edge_info = new class edge_info (false_edge);
     602       115935 :                   edge_info->record_simple_equiv (op0,
     603        77554 :                                                   (integer_zerop (op1)
     604              :                                                    ? true_val : false_val));
     605              :                 }
     606              :               else
     607              :                 {
     608      1930028 :                   edge_info = new class edge_info (true_edge);
     609      1933289 :                   edge_info->record_simple_equiv (op0,
     610      1930028 :                                                   (integer_zerop (op1)
     611              :                                                    ? true_val : false_val));
     612      1930028 :                   edge_info = new class edge_info (false_edge);
     613      1933289 :                   edge_info->record_simple_equiv (op0,
     614      1930028 :                                                   (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     16516724 :           else if (is_gimple_min_invariant (op0)
     622     16516724 :                    && 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     16516724 :           else if (TREE_CODE (op0) == SSA_NAME
     645     16516724 :                    && (TREE_CODE (op1) == SSA_NAME
     646     12175141 :                        || is_gimple_min_invariant (op1)))
     647              :             {
     648     16327541 :               tree cond = build2 (code, boolean_type_node, op0, op1);
     649     16327541 :               tree inverted = invert_truthvalue_loc (loc, cond);
     650     16327541 :               bool can_infer_simple_equiv
     651     17031718 :                 = !(HONOR_SIGNED_ZEROS (op1) && real_maybe_zerop (op1))
     652     16732973 :                   && !DECIMAL_FLOAT_MODE_P (element_mode (TREE_TYPE (op1)));
     653     16327541 :               class edge_info *edge_info;
     654              : 
     655     16327541 :               edge_info = new class edge_info (true_edge);
     656     16327541 :               record_conditions (&edge_info->cond_equivalences, cond, inverted);
     657              : 
     658     16327541 :               if (can_infer_simple_equiv && code == EQ_EXPR)
     659      5507718 :                 edge_info->record_simple_equiv (op0, op1);
     660              : 
     661     16327541 :               edge_info = new class edge_info (false_edge);
     662     16327541 :               record_conditions (&edge_info->cond_equivalences, inverted, cond);
     663              : 
     664     16327541 :               if (can_infer_simple_equiv && TREE_CODE (inverted) == EQ_EXPR)
     665      6249732 :                 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     18524306 :           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      1041145 :               if ((TREE_CODE (op0) != SSA_NAME
     678      1040330 :                    || gimple_bb (SSA_NAME_DEF_STMT (op0)) != bb)
     679      1209634 :                   && (TREE_CODE (op1) != SSA_NAME
     680       166782 :                       || 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         2647 :                   bool alternative
     688         2647 :                     = (EDGE_PRED (bb, 0)->flags & EDGE_DFS_BACK) ? 1 : 0;
     689              : 
     690         2647 :                   gphi_iterator gsi;
     691         2647 :                   for (gsi = gsi_start_phis (bb);
     692         4740 :                        !gsi_end_p (gsi);
     693         2093 :                        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         2093 :                       gphi *phi = gsi.phi ();
     700         2093 :                       tree src = PHI_ARG_DEF (phi, alternative);
     701         2093 :                       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         2093 :                       if (dst == PHI_ARG_DEF (phi, !alternative))
     706          329 :                         continue;
     707              : 
     708         1764 :                       if (EDGE_SUCC (bb, 0)->dest
     709         1764 :                           != EDGE_PRED (bb, !alternative)->src)
     710          393 :                         edge_info = (class edge_info *)EDGE_SUCC (bb, 0)->aux;
     711              :                       else
     712         1371 :                         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         1764 :                       if (edge_info == NULL)
     718          785 :                         edge_info = new class edge_info (false_edge);
     719         1764 :                       edge_info->record_simple_equiv (dst, src);
     720              :                     }
     721              :                 }
     722              :             }
     723              :         }
     724              :     }
     725     45962244 : }
     726              : 
     727              : class dom_jt_state : public jt_state
     728              : {
     729              : public:
     730      2121033 :   dom_jt_state (const_and_copies *copies, avail_exprs_stack *avails)
     731      2121033 :     : m_copies (copies), m_avails (avails)
     732              :   {
     733      2121033 :     bitmap_tree_view (m_blocks_on_stack);
     734      2121033 :   }
     735     17135405 :   void push (edge e) override
     736              :   {
     737     17135405 :     m_copies->push_marker ();
     738     17135405 :     m_avails->push_marker ();
     739     17135405 :     jt_state::push (e);
     740     17135405 :   }
     741     17135405 :   void pop () override
     742              :   {
     743     17135405 :     m_copies->pop_to_marker ();
     744     17135405 :     m_avails->pop_to_marker ();
     745     17135405 :     jt_state::pop ();
     746     17135405 :   }
     747     15881799 :   void register_equivs_edge (edge e) override
     748              :   {
     749     15881799 :     record_temporary_equivalences (e, m_copies, m_avails, m_blocks_on_stack);
     750     15881799 :   }
     751              :   void register_equiv (tree dest, tree src, bool update) override;
     752     71993346 :   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     21595188 : dom_jt_state::register_equiv (tree dest, tree src, bool)
     763              : {
     764     21595188 :   m_copies->record_const_or_copy (dest, src);
     765     21595188 : }
     766              : 
     767      2121033 : class dom_jt_simplifier : public hybrid_jt_simplifier
     768              : {
     769              : public:
     770      2121033 :   dom_jt_simplifier (avail_exprs_stack *avails, gimple_ranger *ranger,
     771              :                      path_range_query *query)
     772      4242066 :     : 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     31857270 : 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     31857270 :   tree cached_lhs =  m_avails->lookup_avail_expr (stmt, false, true);
     785     31857270 :   if (cached_lhs)
     786              :     return cached_lhs;
     787              : 
     788              :   /* Otherwise call the ranger if possible.  */
     789     31016695 :   if (state)
     790      8785645 :     return hybrid_jt_simplifier::simplify (stmt, within_stmt, bb, state);
     791              : 
     792              :   return NULL;
     793              : }
     794              : 
     795      4242066 : class dom_opt_dom_walker : public dom_walker
     796              : {
     797              : public:
     798      2121033 :   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      2121033 :     : dom_walker (direction, REACHABLE_BLOCKS)
     805              :     {
     806      2121033 :       m_ranger = ranger;
     807      2121033 :       m_state = state;
     808      2121033 :       m_dummy_cond = gimple_build_cond (NE_EXPR, integer_zero_node,
     809              :                                         integer_zero_node, NULL, NULL);
     810      2121033 :       m_const_and_copies = const_and_copies;
     811      2121033 :       m_avail_exprs_stack = avail_exprs_stack;
     812      2121033 :       m_threader = threader;
     813      2121033 :     }
     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 maintained 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       882588 :   pass_dominator (gcc::context *ctxt)
     868              :     : gimple_opt_pass (pass_data_dominator, ctxt),
     869      1765176 :       may_peel_loop_headers_p (false)
     870              :   {}
     871              : 
     872              :   /* opt_pass methods: */
     873       588392 :   opt_pass * clone () final override { return new pass_dominator (m_ctxt); }
     874       882588 :   void set_pass_param (unsigned int n, bool param) final override
     875              :     {
     876       882588 :       gcc_assert (n == 0);
     877       882588 :       may_peel_loop_headers_p = param;
     878       882588 :     }
     879      2121819 :   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      2121033 : pass_dominator::execute (function *fun)
     892              : {
     893      2121033 :   memset (&opt_stats, 0, sizeof (opt_stats));
     894              : 
     895              :   /* Create our hash tables.  */
     896      2121033 :   hash_table<expr_elt_hasher> *avail_exprs
     897      2121033 :     = new hash_table<expr_elt_hasher> (1024);
     898      2121033 :   class avail_exprs_stack *avail_exprs_stack
     899      2121033 :     = new class avail_exprs_stack (avail_exprs);
     900      2121033 :   class const_and_copies *const_and_copies = new class const_and_copies ();
     901      2121033 :   need_eh_cleanup = BITMAP_ALLOC (NULL);
     902      2121033 :   need_noreturn_fixup.create (0);
     903              : 
     904      2121033 :   calculate_dominance_info (CDI_DOMINATORS);
     905      2121033 :   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      2121033 :   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      2121033 :   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      2121033 :   basic_block bb;
     932     24085495 :   FOR_EACH_BB_FN (bb, fun)
     933     21964462 :     record_edge_info (bb);
     934              : 
     935              :   /* Recursively walk the dominator tree optimizing statements.  */
     936      2121033 :   gimple_ranger *ranger = enable_ranger (fun);
     937      2121033 :   path_range_query path_query (*ranger);
     938      2121033 :   dom_jt_simplifier simplifier (avail_exprs_stack, ranger, &path_query);
     939      2121033 :   dom_jt_state state (const_and_copies, avail_exprs_stack);
     940      2121033 :   jump_threader threader (&simplifier, &state);
     941      2121033 :   dom_opt_dom_walker walker (CDI_DOMINATORS,
     942              :                              &threader,
     943              :                              &state,
     944              :                              ranger,
     945              :                              const_and_copies,
     946      2121033 :                              avail_exprs_stack);
     947      2121033 :   walker.walk (fun->cfg->x_entry_block_ptr);
     948              : 
     949      2121033 :   ranger->export_global_ranges ();
     950      2121033 :   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      2121033 :   if (cfg_altered)
     956              :     {
     957      5048066 :       FOR_EACH_BB_FN (bb, fun)
     958              :         {
     959      4983469 :           edge_iterator ei;
     960      4983469 :           edge e;
     961              : 
     962              :           /* First see if there are any edges without EDGE_EXECUTABLE
     963              :              set.  */
     964      4983469 :           bool found = false;
     965     11951337 :           FOR_EACH_EDGE (e, ei, bb->succs)
     966              :             {
     967      7210915 :               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      4983469 :           if (found)
     977       709180 :             FOR_EACH_EDGE (e, ei, bb->succs)
     978       466133 :               threader.remove_jump_threads_including (e);
     979              :         }
     980              :     }
     981              : 
     982      2121033 :   {
     983      2121033 :     gimple_stmt_iterator gsi;
     984      2121033 :     basic_block bb;
     985     24085495 :     FOR_EACH_BB_FN (bb, fun)
     986              :       {
     987    227976735 :         for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
     988    184047811 :           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      2121033 :   update_ssa (TODO_update_ssa);
     998              : 
     999      2121033 :   free_all_edge_infos ();
    1000              : 
    1001              :   /* Thread jumps, creating duplicate blocks as needed.  */
    1002      2121033 :   cfg_altered |= threader.thread_through_all_blocks (may_peel_loop_headers_p);
    1003              : 
    1004      2121033 :   if (cfg_altered)
    1005       132068 :     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      2121033 :   if (!bitmap_empty_p (need_eh_cleanup))
    1010              :     {
    1011          641 :       unsigned i;
    1012          641 :       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         2055 :       EXECUTE_IF_SET_IN_BITMAP (need_eh_cleanup, 0, i, bi)
    1020              :         {
    1021         1414 :           basic_block bb = BASIC_BLOCK_FOR_FN (fun, i);
    1022         1414 :           if (bb == NULL)
    1023            0 :             continue;
    1024         2907 :           while (single_succ_p (bb)
    1025         1548 :                  && (single_succ_edge (bb)->flags
    1026          151 :                      & (EDGE_EH|EDGE_DFS_BACK)) == 0)
    1027          134 :             bb = single_succ (bb);
    1028         1414 :           if (bb == EXIT_BLOCK_PTR_FOR_FN (fun))
    1029           55 :             continue;
    1030         1359 :           if ((unsigned) bb->index != i)
    1031           59 :             bitmap_set_bit (need_eh_cleanup, bb->index);
    1032              :         }
    1033              : 
    1034          641 :       gimple_purge_all_dead_eh_edges (need_eh_cleanup);
    1035          641 :       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              :      inadvertently remove a stmt we want to fixup by visiting a dominating
    1042              :      now noreturn call first.  */
    1043      2121036 :   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      2121033 :   statistics_counter_event (fun, "Redundant expressions eliminated",
    1056      2121033 :                             opt_stats.num_re);
    1057      2121033 :   statistics_counter_event (fun, "Constants propagated",
    1058      2121033 :                             opt_stats.num_const_prop);
    1059      2121033 :   statistics_counter_event (fun, "Copies propagated",
    1060      2121033 :                             opt_stats.num_copy_prop);
    1061              : 
    1062              :   /* Debugging dumps.  */
    1063      2121033 :   if (dump_file && (dump_flags & TDF_STATS))
    1064           35 :     dump_dominator_optimization_stats (dump_file, avail_exprs);
    1065              : 
    1066      2121033 :   loop_optimizer_finalize ();
    1067              : 
    1068              :   /* Delete our main hashtable.  */
    1069      2121033 :   delete avail_exprs;
    1070      2121033 :   avail_exprs = NULL;
    1071              : 
    1072              :   /* Free asserted bitmaps and stacks.  */
    1073      2121033 :   BITMAP_FREE (need_eh_cleanup);
    1074      2121033 :   need_noreturn_fixup.release ();
    1075      2121033 :   delete avail_exprs_stack;
    1076      2121033 :   delete const_and_copies;
    1077              : 
    1078      2121033 :   return 0;
    1079      2121033 : }
    1080              : 
    1081              : } // anon namespace
    1082              : 
    1083              : gimple_opt_pass *
    1084       294196 : make_pass_dominator (gcc::context *ctxt)
    1085              : {
    1086       294196 :   return new pass_dominator (ctxt);
    1087              : }
    1088              : 
    1089              : /* Valueize hook for gimple_fold_stmt_to_constant_1.  */
    1090              : 
    1091              : static tree
    1092     35106538 : dom_valueize (tree t)
    1093              : {
    1094     35106538 :   if (TREE_CODE (t) == SSA_NAME)
    1095              :     {
    1096     25224426 :       tree tem = SSA_NAME_VALUE (t);
    1097     20069564 :       if (tem)
    1098      3204912 :         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     12300602 : back_propagate_equivalences (tree lhs, edge e,
    1108              :                              class const_and_copies *const_and_copies,
    1109              :                              bitmap domby)
    1110              : {
    1111     12300602 :   use_operand_p use_p;
    1112     12300602 :   imm_use_iterator iter;
    1113     12300602 :   basic_block dest = e->dest;
    1114     12300602 :   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     53539421 :   FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
    1123              :     {
    1124     41238819 :       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     41238819 :       if (dest == gimple_bb (use_stmt))
    1129       501861 :         continue;
    1130              : 
    1131              :       /* Filter out statements that can never produce a useful
    1132              :          equivalence.  */
    1133     40736958 :       tree lhs2 = gimple_get_lhs (use_stmt);
    1134     40736958 :       if (!lhs2 || TREE_CODE (lhs2) != SSA_NAME)
    1135     29887231 :         continue;
    1136              : 
    1137     10849727 :       if (domok)
    1138              :         {
    1139      5647885 :           if (!dominated_by_p (CDI_DOMINATORS, dest, gimple_bb (use_stmt)))
    1140      2858974 :             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      5201842 :           if (!bitmap_bit_p (domby, gimple_bb (use_stmt)->index))
    1150      3813374 :             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      4177379 :       tree res = gimple_fold_stmt_to_constant_1 (use_stmt, dom_valueize,
    1157              :                                                  no_follow_ssa_edges);
    1158      4177379 :       if (res && (TREE_CODE (res) == SSA_NAME || is_gimple_min_invariant (res)))
    1159      2486601 :         record_equality (lhs2, res, const_and_copies);
    1160     12300602 :     }
    1161     12300602 : }
    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     33736722 : 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     33736722 :   int i;
    1174     33736722 :   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     33736722 :   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     93303743 :       for (i = 0; edge_info->cond_equivalences.iterate (i, &eq); ++i)
    1184     68991912 :         avail_exprs_stack->record_cond (eq);
    1185              : 
    1186              :       edge_info::equiv_pair *seq;
    1187     36612433 :       for (i = 0; edge_info->simple_equivalences.iterate (i, &seq); ++i)
    1188              :         {
    1189     12300602 :           tree lhs = seq->first;
    1190     12300602 :           if (!lhs || TREE_CODE (lhs) != SSA_NAME)
    1191            0 :             continue;
    1192              : 
    1193              :           /* Record the simple NAME = VALUE equivalence.  */
    1194     12300602 :           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     12300602 :           if (TREE_CODE (lhs) == SSA_NAME && TREE_CODE (rhs) == SSA_NAME)
    1203              :             {
    1204      1756210 :               gimple *rhs_def = SSA_NAME_DEF_STMT (rhs);
    1205      1756210 :               int rhs_cost = estimate_num_insns (rhs_def, &eni_size_weights);
    1206              : 
    1207      1756210 :               gimple *lhs_def = SSA_NAME_DEF_STMT (lhs);
    1208      1756210 :               int lhs_cost = estimate_num_insns (lhs_def, &eni_size_weights);
    1209              : 
    1210      1756210 :               if (rhs_cost > lhs_cost)
    1211       192226 :                 record_equality (rhs, lhs, const_and_copies);
    1212      1563984 :               else if (rhs_cost < lhs_cost)
    1213       473191 :                 record_equality (lhs, rhs, const_and_copies);
    1214              :             }
    1215              :           else
    1216     10544392 :             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     12300602 :           back_propagate_equivalences (lhs, e, const_and_copies,
    1223              :                                        blocks_on_stack);
    1224              :         }
    1225              :     }
    1226     33736722 : }
    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     23997782 : record_equivalences_from_phis (basic_block bb)
    1236              : {
    1237     23997782 :   gphi_iterator gsi;
    1238              : 
    1239     33457894 :   for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); )
    1240              :     {
    1241      9460112 :       gphi *phi = gsi.phi ();
    1242              : 
    1243              :       /* We might eliminate the PHI, so advance GSI now.  */
    1244      9460112 :       gsi_next (&gsi);
    1245              : 
    1246      9460112 :       tree lhs = gimple_phi_result (phi);
    1247      9460112 :       tree rhs = NULL;
    1248      9460112 :       size_t i;
    1249              : 
    1250     17117407 :       for (i = 0; i < gimple_phi_num_args (phi); i++)
    1251              :         {
    1252     16024926 :           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     16024926 :           if (lhs == t)
    1258        30679 :             continue;
    1259              : 
    1260              :           /* If the associated edge is not marked as executable, then it
    1261              :              can be ignored.  */
    1262     15994247 :           if ((gimple_phi_arg_edge (phi, i)->flags & EDGE_EXECUTABLE) == 0)
    1263       138266 :             continue;
    1264              : 
    1265     15855981 :           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     15855981 :           if (TREE_CODE (t) == SSA_NAME
    1270     15855981 :               && (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     12798264 :           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      5874594 :           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      9460112 :       if (!rhs)
    1287      2536442 :         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      9460112 :       if (i == gimple_phi_num_args (phi))
    1296              :         {
    1297      1092481 :           if (may_propagate_copy (lhs, rhs))
    1298       603189 :             set_ssa_name_value (lhs, rhs);
    1299       978584 :           else if (virtual_operand_p (lhs))
    1300              :             {
    1301       488849 :               gimple *use_stmt;
    1302       488849 :               imm_use_iterator iter;
    1303       488849 :               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      1466268 :               FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
    1307      2017254 :                 FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
    1308      1008627 :                   SET_USE (use_p, rhs);
    1309       488849 :               if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
    1310           70 :                 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs) = 1;
    1311       488849 :               gimple_stmt_iterator tmp_gsi = gsi_for_stmt (phi);
    1312       488849 :               remove_phi_node (&tmp_gsi, true);
    1313              :             }
    1314              :         }
    1315              :     }
    1316     23997782 : }
    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       422520 : all_uses_feed_or_dominated_by_stmt (tree name, gimple *stmt)
    1323              : {
    1324       422520 :   use_operand_p use_p, use2_p;
    1325       422520 :   imm_use_iterator iter;
    1326       422520 :   basic_block stmt_bb = gimple_bb (stmt);
    1327              : 
    1328      1716792 :   FOR_EACH_IMM_USE_FAST (use_p, iter, name)
    1329              :     {
    1330      1524826 :       gimple *use_stmt = USE_STMT (use_p), *use_stmt2;
    1331      2810617 :       if (use_stmt == stmt
    1332      1384309 :           || is_gimple_debug (use_stmt)
    1333      2278361 :           || (gimple_bb (use_stmt) != stmt_bb
    1334       585353 :               && dominated_by_p (CDI_DOMINATORS,
    1335       585353 :                                  gimple_bb (use_stmt), stmt_bb)))
    1336      1285791 :         continue;
    1337              :       while (use_stmt != stmt
    1338       445732 :              && is_gimple_assign (use_stmt)
    1339       389871 :              && TREE_CODE (gimple_assign_lhs (use_stmt)) == SSA_NAME
    1340       830286 :              && single_imm_use (gimple_assign_lhs (use_stmt),
    1341              :                                 &use2_p, &use_stmt2))
    1342       215178 :         use_stmt = use_stmt2;
    1343       239035 :       if (use_stmt != stmt)
    1344       230554 :         return false;
    1345       230554 :     }
    1346       191966 :   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       171219 : maybe_set_nonzero_bits (edge e, tree var)
    1364              : {
    1365       171219 :   basic_block cond_bb = e->src;
    1366       342438 :   gcond *cond = safe_dyn_cast <gcond *> (*gsi_last_bb (cond_bb));
    1367       171219 :   tree cst;
    1368              : 
    1369       171219 :   if (cond == NULL
    1370       171219 :       || gimple_cond_code (cond) != ((e->flags & EDGE_TRUE_VALUE)
    1371       171219 :                                      ? EQ_EXPR : NE_EXPR)
    1372        50530 :       || TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
    1373         1882 :       || !integer_zerop (gimple_cond_rhs (cond)))
    1374              :     return;
    1375              : 
    1376         1731 :   gimple *stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (cond));
    1377         1731 :   if (!is_gimple_assign (stmt)
    1378         1709 :       || gimple_assign_rhs_code (stmt) != BIT_AND_EXPR
    1379         1756 :       || 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     23997782 : dom_opt_dom_walker::set_global_ranges_from_unreachable_edges (basic_block bb)
    1429              : {
    1430     23997782 :   edge pred_e = single_pred_edge_ignoring_loop_edges (bb, false);
    1431     23997782 :   if (!pred_e)
    1432              :     return;
    1433              : 
    1434     17849612 :   gimple *stmt = *gsi_last_bb (pred_e->src);
    1435     17849612 :   if (!stmt
    1436     15022543 :       || gimple_code (stmt) != GIMPLE_COND
    1437     30263236 :       || !assert_unreachable_fallthru_edge_p (pred_e))
    1438              :     return;
    1439              : 
    1440              :   // Bail if the condition leading to the unreachable edge has 2 ssa-names.
    1441              :   // See PR 125501.
    1442       234764 :   if ((TREE_CODE (gimple_cond_lhs (stmt)) == SSA_NAME
    1443       234764 :       && TREE_CODE (gimple_cond_rhs (stmt)) == SSA_NAME))
    1444              :     return;
    1445              : 
    1446       231996 :   tree name;
    1447       654516 :   FOR_EACH_GORI_EXPORT_NAME (m_ranger->gori_ssa (), pred_e->src, name)
    1448       422520 :     if (all_uses_feed_or_dominated_by_stmt (name, stmt)
    1449              :         // The condition must post-dominate the definition point.
    1450       614486 :         && (SSA_NAME_IS_DEFAULT_DEF (name)
    1451       191843 :             || (gimple_bb (SSA_NAME_DEF_STMT (name))
    1452       191843 :                 == pred_e->src)))
    1453              :       {
    1454       186296 :         value_range r (TREE_TYPE (name));
    1455              : 
    1456       186296 :         if (m_ranger->range_on_edge (r, pred_e, name)
    1457       186296 :             && !r.varying_p ()
    1458       357584 :             && !r.undefined_p ())
    1459              :           {
    1460       171219 :             set_range_info (name, r);
    1461       171219 :             maybe_set_nonzero_bits (pred_e, name);
    1462              :           }
    1463       186296 :       }
    1464              : }
    1465              : 
    1466              : /* Record any equivalences created by the incoming edge to BB into
    1467              :    CONST_AND_COPIES and AVAIL_EXPRS_STACK.  If BB has more than one
    1468              :    incoming edge, then no equivalence is created.  */
    1469              : 
    1470              : static void
    1471     23997782 : record_equivalences_from_incoming_edge (basic_block bb,
    1472              :     class const_and_copies *const_and_copies,
    1473              :     class avail_exprs_stack *avail_exprs_stack,
    1474              :     bitmap blocks_on_stack)
    1475              : {
    1476     23997782 :   edge e;
    1477     23997782 :   basic_block parent;
    1478              : 
    1479              :   /* If our parent block ended with a control statement, then we may be
    1480              :      able to record some equivalences based on which outgoing edge from
    1481              :      the parent was followed.  */
    1482     23997782 :   parent = get_immediate_dominator (CDI_DOMINATORS, bb);
    1483              : 
    1484     23997782 :   e = single_pred_edge_ignoring_loop_edges (bb, true);
    1485              : 
    1486              :   /* If we had a single incoming edge from our parent block, then enter
    1487              :      any data associated with the edge into our tables.  */
    1488     23997782 :   if (e && e->src == parent)
    1489     17854923 :     record_temporary_equivalences (e, const_and_copies, avail_exprs_stack,
    1490              :                                    blocks_on_stack);
    1491     23997782 : }
    1492              : 
    1493              : /* Dump statistics for the hash table HTAB.  */
    1494              : 
    1495              : static void
    1496           35 : htab_statistics (FILE *file, const hash_table<expr_elt_hasher> &htab)
    1497              : {
    1498           66 :   fprintf (file, "size " HOST_SIZE_T_PRINT_DEC ", " HOST_SIZE_T_PRINT_DEC
    1499              :            " elements, %f collision/search ratio\n",
    1500           35 :            (fmt_size_t) htab.size (),
    1501           35 :            (fmt_size_t) htab.elements (),
    1502              :            htab.collisions ());
    1503           35 : }
    1504              : 
    1505              : /* Dump SSA statistics on FILE.  */
    1506              : 
    1507              : static void
    1508           35 : dump_dominator_optimization_stats (FILE *file,
    1509              :                                    hash_table<expr_elt_hasher> *avail_exprs)
    1510              : {
    1511           35 :   fprintf (file, "Total number of statements:                   %6ld\n\n",
    1512              :            opt_stats.num_stmts);
    1513           35 :   fprintf (file, "Exprs considered for dominator optimizations: %6ld\n",
    1514              :            opt_stats.num_exprs_considered);
    1515              : 
    1516           35 :   fprintf (file, "\nHash table statistics:\n");
    1517              : 
    1518           35 :   fprintf (file, "    avail_exprs: ");
    1519           35 :   htab_statistics (file, *avail_exprs);
    1520           35 : }
    1521              : 
    1522              : 
    1523              : /* Similarly, but assume that X and Y are the two operands of an EQ_EXPR.
    1524              :    This constrains the cases in which we may treat this as assignment.  */
    1525              : 
    1526              : static void
    1527     13696410 : record_equality (tree x, tree y, class const_and_copies *const_and_copies)
    1528              : {
    1529     13696410 :   tree prev_x = NULL, prev_y = NULL;
    1530              : 
    1531     13696410 :   if (tree_swap_operands_p (x, y))
    1532       625868 :     std::swap (x, y);
    1533              : 
    1534              :   /* Most of the time tree_swap_operands_p does what we want.  But there
    1535              :      are cases where we know one operand is better for copy propagation than
    1536              :      the other.  Given no other code cares about ordering of equality
    1537              :      comparison operators for that purpose, we just handle the special cases
    1538              :      here.  */
    1539     13696410 :   if (TREE_CODE (x) == SSA_NAME && TREE_CODE (y) == SSA_NAME)
    1540              :     {
    1541              :       /* If one operand is a single use operand, then make it
    1542              :          X.  This will preserve its single use properly and if this
    1543              :          conditional is eliminated, the computation of X can be
    1544              :          eliminated as well.  */
    1545      1147155 :       if (has_single_use (y) && ! has_single_use (x))
    1546              :         std::swap (x, y);
    1547              :     }
    1548     13696410 :   if (TREE_CODE (x) == SSA_NAME)
    1549     13696410 :     prev_x = SSA_NAME_VALUE (x);
    1550     13696410 :   if (TREE_CODE (y) == SSA_NAME)
    1551      1147155 :     prev_y = SSA_NAME_VALUE (y);
    1552              : 
    1553              :   /* If one of the previous values is invariant, or invariant in more loops
    1554              :      (by depth), then use that.
    1555              :      Otherwise it doesn't matter which value we choose, just so
    1556              :      long as we canonicalize on one value.  */
    1557     13696410 :   if (is_gimple_min_invariant (y))
    1558              :     ;
    1559      1147155 :   else if (is_gimple_min_invariant (x))
    1560              :     prev_x = x, x = y, y = prev_x, prev_x = prev_y;
    1561      1147155 :   else if (prev_x && is_gimple_min_invariant (prev_x))
    1562              :     x = y, y = prev_x, prev_x = prev_y;
    1563      1057737 :   else if (prev_y)
    1564     13696410 :     y = prev_y;
    1565              : 
    1566              :   /* After the swapping, we must have one SSA_NAME.  */
    1567     13696410 :   if (TREE_CODE (x) != SSA_NAME)
    1568              :     return;
    1569              : 
    1570              :   /* For IEEE, -0.0 == 0.0, so we don't necessarily know the sign of a
    1571              :      variable compared against zero.  If we're honoring signed zeros,
    1572              :      then we cannot record this value unless we know that the value is
    1573              :      nonzero.  */
    1574     13696410 :   if (HONOR_SIGNED_ZEROS (x)
    1575     13696410 :       && (TREE_CODE (y) != REAL_CST
    1576       171837 :           || real_equal (&dconst0, &TREE_REAL_CST (y))))
    1577              :     return;
    1578              : 
    1579     13696068 :   const_and_copies->record_const_or_copy (x, y, prev_x);
    1580              : }
    1581              : 
    1582              : /* Returns true when STMT is a simple iv increment.  It detects the
    1583              :    following situation:
    1584              : 
    1585              :    i_1 = phi (..., i_k)
    1586              :    [...]
    1587              :    i_j = i_{j-1}  for each j : 2 <= j <= k-1
    1588              :    [...]
    1589              :    i_k = i_{k-1} +/- ...  */
    1590              : 
    1591              : bool
    1592     43975196 : simple_iv_increment_p (gimple *stmt)
    1593              : {
    1594     43975196 :   enum tree_code code;
    1595     43975196 :   tree lhs, preinc;
    1596     43975196 :   gimple *phi;
    1597     43975196 :   size_t i;
    1598              : 
    1599     43975196 :   if (gimple_code (stmt) != GIMPLE_ASSIGN)
    1600              :     return false;
    1601              : 
    1602     33800716 :   lhs = gimple_assign_lhs (stmt);
    1603     33800716 :   if (TREE_CODE (lhs) != SSA_NAME)
    1604              :     return false;
    1605              : 
    1606     33800716 :   code = gimple_assign_rhs_code (stmt);
    1607     33800716 :   if (code != PLUS_EXPR
    1608     33800716 :       && code != MINUS_EXPR
    1609     33800716 :       && code != POINTER_PLUS_EXPR)
    1610              :     return false;
    1611              : 
    1612      8086729 :   preinc = gimple_assign_rhs1 (stmt);
    1613      8086729 :   if (TREE_CODE (preinc) != SSA_NAME)
    1614              :     return false;
    1615              : 
    1616      7795934 :   phi = SSA_NAME_DEF_STMT (preinc);
    1617      7821546 :   while (gimple_code (phi) != GIMPLE_PHI)
    1618              :     {
    1619              :       /* Follow trivial copies, but not the DEF used in a back edge,
    1620              :          so that we don't prevent coalescing.  */
    1621      5304824 :       if (!gimple_assign_ssa_name_copy_p (phi))
    1622              :         return false;
    1623        25612 :       preinc = gimple_assign_rhs1 (phi);
    1624        25612 :       phi = SSA_NAME_DEF_STMT (preinc);
    1625              :     }
    1626              : 
    1627      4964712 :   for (i = 0; i < gimple_phi_num_args (phi); i++)
    1628      4019870 :     if (gimple_phi_arg_def (phi, i) == lhs)
    1629              :       return true;
    1630              : 
    1631              :   return false;
    1632              : }
    1633              : 
    1634              : /* Propagate know values from SSA_NAME_VALUE into the PHI nodes of the
    1635              :    successors of BB.  */
    1636              : 
    1637              : static void
    1638     23997782 : cprop_into_successor_phis (basic_block bb,
    1639              :                            class const_and_copies *const_and_copies)
    1640              : {
    1641     23997782 :   edge e;
    1642     23997782 :   edge_iterator ei;
    1643              : 
    1644     56977584 :   FOR_EACH_EDGE (e, ei, bb->succs)
    1645              :     {
    1646     32979802 :       int indx;
    1647     32979802 :       gphi_iterator gsi;
    1648              : 
    1649              :       /* If this is an abnormal edge, then we do not want to copy propagate
    1650              :          into the PHI alternative associated with this edge.  */
    1651     32979802 :       if (e->flags & EDGE_ABNORMAL)
    1652     19418273 :         continue;
    1653              : 
    1654     32965881 :       gsi = gsi_start_phis (e->dest);
    1655     32965881 :       if (gsi_end_p (gsi))
    1656     19404352 :         continue;
    1657              : 
    1658              :       /* We may have an equivalence associated with this edge.  While
    1659              :          we cannot propagate it into non-dominated blocks, we can
    1660              :          propagate them into PHIs in non-dominated blocks.  */
    1661              : 
    1662              :       /* Push the unwind marker so we can reset the const and copies
    1663              :          table back to its original state after processing this edge.  */
    1664     13561529 :       const_and_copies->push_marker ();
    1665              : 
    1666              :       /* Extract and record any simple NAME = VALUE equivalences.
    1667              : 
    1668              :          Don't bother with [01] = COND equivalences, they're not useful
    1669              :          here.  */
    1670     13561529 :       class edge_info *edge_info = (class edge_info *) e->aux;
    1671              : 
    1672     13561529 :       if (edge_info)
    1673              :         {
    1674              :           edge_info::equiv_pair *seq;
    1675      8509142 :           for (int i = 0; edge_info->simple_equivalences.iterate (i, &seq); ++i)
    1676              :             {
    1677      3260520 :               tree lhs = seq->first;
    1678      3260520 :               tree rhs = seq->second;
    1679              : 
    1680      3260520 :               if (lhs && TREE_CODE (lhs) == SSA_NAME)
    1681      3260520 :                 const_and_copies->record_const_or_copy (lhs, rhs);
    1682              :             }
    1683              : 
    1684              :         }
    1685              : 
    1686     13561529 :       indx = e->dest_idx;
    1687     37376433 :       for ( ; !gsi_end_p (gsi); gsi_next (&gsi))
    1688              :         {
    1689     23814904 :           tree new_val;
    1690     23814904 :           use_operand_p orig_p;
    1691     23814904 :           tree orig_val;
    1692     23814904 :           gphi *phi = gsi.phi ();
    1693              : 
    1694              :           /* The alternative may be associated with a constant, so verify
    1695              :              it is an SSA_NAME before doing anything with it.  */
    1696     23814904 :           orig_p = gimple_phi_arg_imm_use_ptr (phi, indx);
    1697     23814904 :           orig_val = get_use_from_ptr (orig_p);
    1698     23814904 :           if (TREE_CODE (orig_val) != SSA_NAME)
    1699      3229701 :             continue;
    1700              : 
    1701              :           /* If we have *ORIG_P in our constant/copy table, then replace
    1702              :              ORIG_P with its value in our constant/copy table.  */
    1703     20585203 :           new_val = SSA_NAME_VALUE (orig_val);
    1704     20585203 :           if (new_val
    1705     20585203 :               && new_val != orig_val
    1706     20585203 :               && may_propagate_copy (orig_val, new_val))
    1707      1202761 :             propagate_value (orig_p, new_val);
    1708              :         }
    1709              : 
    1710     13561529 :       const_and_copies->pop_to_marker ();
    1711              :     }
    1712     23997782 : }
    1713              : 
    1714              : edge
    1715     23997782 : dom_opt_dom_walker::before_dom_children (basic_block bb)
    1716              : {
    1717     23997782 :   gimple_stmt_iterator gsi;
    1718              : 
    1719     23997782 :   if (dump_file && (dump_flags & TDF_DETAILS))
    1720          748 :     fprintf (dump_file, "\n\nOptimizing block #%d\n\n", bb->index);
    1721              : 
    1722              :   /* Push a marker on the stacks of local information so that we know how
    1723              :      far to unwind when we finalize this block.  */
    1724     23997782 :   m_avail_exprs_stack->push_marker ();
    1725     23997782 :   m_const_and_copies->push_marker ();
    1726     23997782 :   bitmap_set_bit (m_state->get_blocks_on_stack (), bb->index);
    1727              : 
    1728     23997782 :   record_equivalences_from_incoming_edge (bb, m_const_and_copies,
    1729              :                                           m_avail_exprs_stack,
    1730     23997782 :                                           m_state->get_blocks_on_stack ());
    1731     23997782 :   set_global_ranges_from_unreachable_edges (bb);
    1732              : 
    1733              :   /* PHI nodes can create equivalences too.  */
    1734     23997782 :   record_equivalences_from_phis (bb);
    1735              : 
    1736              :   /* Create equivalences from redundant PHIs.  PHIs are only truly
    1737              :      redundant when they exist in the same block, so push another
    1738              :      marker and unwind right afterwards.  */
    1739     23997782 :   m_avail_exprs_stack->push_marker ();
    1740     32969045 :   for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    1741      8971263 :     eliminate_redundant_computations (&gsi, m_const_and_copies,
    1742              :                                       m_avail_exprs_stack);
    1743     23997782 :   m_avail_exprs_stack->pop_to_marker ();
    1744              : 
    1745     23997782 :   edge taken_edge = NULL;
    1746              :   /* Initialize visited flag ahead of us, it has undefined state on
    1747              :      pass entry.  */
    1748    230958114 :   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    1749    182962550 :     gimple_set_visited (gsi_stmt (gsi), false);
    1750    389799043 :   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
    1751              :     {
    1752              :       /* Do not optimize a stmt twice, substitution might end up with
    1753              :          _3 = _3 which is not valid.  */
    1754    365801261 :       if (gimple_visited_p (gsi_stmt (gsi)))
    1755              :         {
    1756    182838504 :           gsi_next (&gsi);
    1757    182838504 :           continue;
    1758              :         }
    1759              : 
    1760    182962757 :       bool removed_p = false;
    1761    182962757 :       taken_edge = this->optimize_stmt (bb, &gsi, &removed_p);
    1762    182962757 :       if (!removed_p)
    1763    182838504 :         gimple_set_visited (gsi_stmt (gsi), true);
    1764              : 
    1765              :       /* Go back and visit stmts inserted by folding after substituting
    1766              :          into the stmt at gsi.  */
    1767    182962757 :       if (gsi_end_p (gsi))
    1768              :         {
    1769         2838 :           gcc_checking_assert (removed_p);
    1770         2838 :           gsi = gsi_last_bb (bb);
    1771         2838 :           while (!gsi_end_p (gsi) && !gimple_visited_p (gsi_stmt (gsi)))
    1772            0 :             gsi_prev (&gsi);
    1773              :         }
    1774              :       else
    1775              :         {
    1776    182960126 :           do
    1777              :             {
    1778    182960126 :               gsi_prev (&gsi);
    1779              :             }
    1780    365920045 :           while (!gsi_end_p (gsi) && !gimple_visited_p (gsi_stmt (gsi)));
    1781              :         }
    1782    182962757 :       if (gsi_end_p (gsi))
    1783     39634564 :         gsi = gsi_start_bb (bb);
    1784              :       else
    1785    163145475 :         gsi_next (&gsi);
    1786              :     }
    1787              : 
    1788              :   /* Now prepare to process dominated blocks.  */
    1789     23997782 :   record_edge_info (bb);
    1790     23997782 :   cprop_into_successor_phis (bb, m_const_and_copies);
    1791     23997782 :   if (taken_edge && !dbg_cnt (dom_unreachable_edges))
    1792            0 :     return NULL;
    1793              : 
    1794              :   return taken_edge;
    1795              : }
    1796              : 
    1797              : /* We have finished processing the dominator children of BB, perform
    1798              :    any finalization actions in preparation for leaving this node in
    1799              :    the dominator tree.  */
    1800              : 
    1801              : void
    1802     23997782 : dom_opt_dom_walker::after_dom_children (basic_block bb)
    1803              : {
    1804     23997782 :   if (param_dom_jump_threading)
    1805     23997076 :     m_threader->thread_outgoing_edges (bb);
    1806     23997782 :   bitmap_clear_bit (m_state->get_blocks_on_stack (), bb->index);
    1807     23997782 :   m_avail_exprs_stack->pop_to_marker ();
    1808     23997782 :   m_const_and_copies->pop_to_marker ();
    1809     23997782 : }
    1810              : 
    1811              : /* Search for redundant computations in STMT.  If any are found, then
    1812              :    replace them with the variable holding the result of the computation.
    1813              : 
    1814              :    If safe, record this expression into AVAIL_EXPRS_STACK and
    1815              :    CONST_AND_COPIES.  */
    1816              : 
    1817              : static void
    1818     64992728 : eliminate_redundant_computations (gimple_stmt_iterator* gsi,
    1819              :                                   class const_and_copies *const_and_copies,
    1820              :                                   class avail_exprs_stack *avail_exprs_stack)
    1821              : {
    1822     64992728 :   tree expr_type;
    1823     64992728 :   tree cached_lhs;
    1824     64992728 :   tree def;
    1825     64992728 :   bool insert = true;
    1826     64992728 :   bool assigns_var_p = false;
    1827              : 
    1828     64992728 :   gimple *stmt = gsi_stmt (*gsi);
    1829              : 
    1830     64992728 :   if (gimple_code (stmt) == GIMPLE_PHI)
    1831      8971263 :     def = gimple_phi_result (stmt);
    1832              :   else
    1833     56021465 :     def = gimple_get_lhs (stmt);
    1834              : 
    1835              :   /* Certain expressions on the RHS can be optimized away, but cannot
    1836              :      themselves be entered into the hash tables.  */
    1837     64992728 :   if (! def
    1838     55822776 :       || TREE_CODE (def) != SSA_NAME
    1839     42847872 :       || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def)
    1840     33875326 :       || gimple_vdef (stmt)
    1841              :       /* Do not record equivalences for increments of ivs.  This would create
    1842              :          overlapping live ranges for a very questionable gain.  */
    1843    107829912 :       || simple_iv_increment_p (stmt))
    1844              :     insert = false;
    1845              : 
    1846              :   /* Check if the expression has been computed before.  */
    1847     64992728 :   cached_lhs = avail_exprs_stack->lookup_avail_expr (stmt, insert, true);
    1848              : 
    1849     64992728 :   opt_stats.num_exprs_considered++;
    1850              : 
    1851              :   /* Get the type of the expression we are trying to optimize.  */
    1852     64992728 :   if (is_gimple_assign (stmt))
    1853              :     {
    1854     45576822 :       expr_type = TREE_TYPE (gimple_assign_lhs (stmt));
    1855     45576822 :       assigns_var_p = true;
    1856              :     }
    1857     19415906 :   else if (gimple_code (stmt) == GIMPLE_COND)
    1858      9134949 :     expr_type = boolean_type_node;
    1859     10280957 :   else if (is_gimple_call (stmt))
    1860              :     {
    1861      1274691 :       gcc_assert (gimple_call_lhs (stmt));
    1862      1274691 :       expr_type = TREE_TYPE (gimple_call_lhs (stmt));
    1863      1274691 :       assigns_var_p = true;
    1864              :     }
    1865      9006266 :   else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt))
    1866        35003 :     expr_type = TREE_TYPE (gimple_switch_index (swtch_stmt));
    1867      8971263 :   else if (gimple_code (stmt) == GIMPLE_PHI)
    1868              :     /* We can't propagate into a phi, so the logic below doesn't apply.
    1869              :        Instead record an equivalence between the cached LHS and the
    1870              :        PHI result of this statement, provided they are in the same block.
    1871              :        This should be sufficient to kill the redundant phi.  */
    1872              :     {
    1873      8971263 :       if (def && cached_lhs)
    1874        24369 :         const_and_copies->record_const_or_copy (def, cached_lhs);
    1875              :       return;
    1876              :     }
    1877              :   else
    1878            0 :     gcc_unreachable ();
    1879              : 
    1880     56021465 :   if (!cached_lhs)
    1881              :     return;
    1882              : 
    1883              :   /* It is safe to ignore types here since we have already done
    1884              :      type checking in the hashing and equality routines.  In fact
    1885              :      type checking here merely gets in the way of constant
    1886              :      propagation.  Also, make sure that it is safe to propagate
    1887              :      CACHED_LHS into the expression in STMT.  */
    1888       451180 :   if ((TREE_CODE (cached_lhs) != SSA_NAME
    1889        44222 :        && (assigns_var_p
    1890         6698 :            || useless_type_conversion_p (expr_type, TREE_TYPE (cached_lhs))))
    1891       451180 :       || may_propagate_copy_into_stmt (stmt, cached_lhs))
    1892              :   {
    1893       436232 :       gcc_checking_assert (TREE_CODE (cached_lhs) == SSA_NAME
    1894              :                            || is_gimple_min_invariant (cached_lhs));
    1895              : 
    1896       436232 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1897              :         {
    1898           16 :           fprintf (dump_file, "  Replaced redundant expr '");
    1899           16 :           print_gimple_expr (dump_file, stmt, 0, dump_flags);
    1900           16 :           fprintf (dump_file, "' with '");
    1901           16 :           print_generic_expr (dump_file, cached_lhs, dump_flags);
    1902           16 :           fprintf (dump_file, "'\n");
    1903              :         }
    1904              : 
    1905       436232 :       opt_stats.num_re++;
    1906              : 
    1907       436232 :       if (assigns_var_p
    1908       436232 :           && !useless_type_conversion_p (expr_type, TREE_TYPE (cached_lhs)))
    1909            0 :         cached_lhs = fold_convert (expr_type, cached_lhs);
    1910              : 
    1911       436232 :       propagate_tree_value_into_stmt (gsi, cached_lhs);
    1912              : 
    1913              :       /* Since it is always necessary to mark the result as modified,
    1914              :          perhaps we should move this into propagate_tree_value_into_stmt
    1915              :          itself.  */
    1916       436232 :       gimple_set_modified (gsi_stmt (*gsi), true);
    1917              :   }
    1918              : }
    1919              : 
    1920              : /* STMT, a GIMPLE_ASSIGN, may create certain equivalences, in either
    1921              :    the available expressions table or the const_and_copies table.
    1922              :    Detect and record those equivalences into AVAIL_EXPRS_STACK.
    1923              : 
    1924              :    We handle only very simple copy equivalences here.  The heavy
    1925              :    lifing is done by eliminate_redundant_computations.  */
    1926              : 
    1927              : static void
    1928     49128168 : record_equivalences_from_stmt (gimple *stmt, int may_optimize_p,
    1929              :                                class avail_exprs_stack *avail_exprs_stack)
    1930              : {
    1931     49128168 :   tree lhs;
    1932     49128168 :   enum tree_code lhs_code;
    1933              : 
    1934     49128168 :   gcc_assert (is_gimple_assign (stmt));
    1935              : 
    1936     49128168 :   lhs = gimple_assign_lhs (stmt);
    1937     49128168 :   lhs_code = TREE_CODE (lhs);
    1938              : 
    1939     49128168 :   if (lhs_code == SSA_NAME
    1940     49128168 :       && gimple_assign_single_p (stmt))
    1941              :     {
    1942     16183263 :       tree rhs = gimple_assign_rhs1 (stmt);
    1943              : 
    1944              :       /* If the RHS of the assignment is a constant or another variable that
    1945              :          may be propagated, register it in the CONST_AND_COPIES table.  We
    1946              :          do not need to record unwind data for this, since this is a true
    1947              :          assignment and not an equivalence inferred from a comparison.  All
    1948              :          uses of this ssa name are dominated by this assignment, so unwinding
    1949              :          just costs time and space.  */
    1950     16183263 :       if (may_optimize_p
    1951     16183263 :           && (TREE_CODE (rhs) == SSA_NAME
    1952     14072300 :               || is_gimple_min_invariant (rhs)))
    1953              :         {
    1954      2117134 :           rhs = dom_valueize (rhs);
    1955              : 
    1956      2117134 :           if (dump_file && (dump_flags & TDF_DETAILS))
    1957              :             {
    1958           72 :               fprintf (dump_file, "==== ASGN ");
    1959           72 :               print_generic_expr (dump_file, lhs);
    1960           72 :               fprintf (dump_file, " = ");
    1961           72 :               print_generic_expr (dump_file, rhs);
    1962           72 :               fprintf (dump_file, "\n");
    1963              :             }
    1964              : 
    1965      2117134 :           set_ssa_name_value (lhs, rhs);
    1966              :         }
    1967              :     }
    1968              : 
    1969              :   /* Make sure we can propagate &x + CST.  */
    1970     49128168 :   if (lhs_code == SSA_NAME
    1971     33255695 :       && gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR
    1972      1671722 :       && TREE_CODE (gimple_assign_rhs1 (stmt)) == ADDR_EXPR
    1973     49328808 :       && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST)
    1974              :     {
    1975         7351 :       tree op0 = gimple_assign_rhs1 (stmt);
    1976         7351 :       tree op1 = gimple_assign_rhs2 (stmt);
    1977         7351 :       tree new_rhs
    1978        14702 :         = build1 (ADDR_EXPR, TREE_TYPE (op0),
    1979         7351 :                   fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (op0)),
    1980              :                                unshare_expr (op0), fold_convert (ptr_type_node,
    1981              :                                                                  op1)));
    1982         7351 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1983              :         {
    1984            0 :           fprintf (dump_file, "==== ASGN ");
    1985            0 :           print_generic_expr (dump_file, lhs);
    1986            0 :           fprintf (dump_file, " = ");
    1987            0 :           print_generic_expr (dump_file, new_rhs);
    1988            0 :           fprintf (dump_file, "\n");
    1989              :         }
    1990              : 
    1991         7351 :       set_ssa_name_value (lhs, new_rhs);
    1992              :     }
    1993              : 
    1994              :   /* A memory store, even an aliased store, creates a useful
    1995              :      equivalence.  By exchanging the LHS and RHS, creating suitable
    1996              :      vops and recording the result in the available expression table,
    1997              :      we may be able to expose more redundant loads.  */
    1998     94589223 :   if (!gimple_has_volatile_ops (stmt)
    1999     73750904 :       && gimple_references_memory_p (stmt)
    2000     24622736 :       && gimple_assign_single_p (stmt)
    2001     24622736 :       && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
    2002     19252729 :           || is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
    2003     60941425 :       && !is_gimple_reg (lhs))
    2004              :     {
    2005     11640946 :       tree rhs = gimple_assign_rhs1 (stmt);
    2006     11640946 :       gassign *new_stmt;
    2007              : 
    2008              :       /* Build a new statement with the RHS and LHS exchanged.  */
    2009     11640946 :       if (TREE_CODE (rhs) == SSA_NAME)
    2010              :         {
    2011              :           /* NOTE tuples.  The call to gimple_build_assign below replaced
    2012              :              a call to build_gimple_modify_stmt, which did not set the
    2013              :              SSA_NAME_DEF_STMT on the LHS of the assignment.  Doing so
    2014              :              may cause an SSA validation failure, as the LHS may be a
    2015              :              default-initialized name and should have no definition.  I'm
    2016              :              a bit dubious of this, as the artificial statement that we
    2017              :              generate here may in fact be ill-formed, but it is simply
    2018              :              used as an internal device in this pass, and never becomes
    2019              :              part of the CFG.  */
    2020      5230392 :           gimple *defstmt = SSA_NAME_DEF_STMT (rhs);
    2021      5230392 :           new_stmt = gimple_build_assign (rhs, lhs);
    2022      5230392 :           SSA_NAME_DEF_STMT (rhs) = defstmt;
    2023              :         }
    2024              :       else
    2025      6410554 :         new_stmt = gimple_build_assign (rhs, lhs);
    2026              : 
    2027     23281892 :       gimple_set_vuse (new_stmt, gimple_vdef (stmt));
    2028              : 
    2029              :       /* Finally enter the statement into the available expression
    2030              :          table.  */
    2031     11640946 :       avail_exprs_stack->lookup_avail_expr (new_stmt, true, true);
    2032              :     }
    2033     49128168 : }
    2034              : 
    2035              : /* Replace *OP_P in STMT with any known equivalent value for *OP_P from
    2036              :    CONST_AND_COPIES.  */
    2037              : 
    2038              : static void
    2039     82547843 : cprop_operand (gimple *stmt, use_operand_p op_p, range_query *query)
    2040              : {
    2041     82547843 :   tree val;
    2042     82547843 :   tree op = USE_FROM_PTR (op_p);
    2043              : 
    2044              :   /* If the operand has a known constant value or it is known to be a
    2045              :      copy of some other variable, use the value or copy stored in
    2046              :      CONST_AND_COPIES.  */
    2047     82547843 :   val = SSA_NAME_VALUE (op);
    2048     56049724 :   if (!val)
    2049              :     {
    2050     78378045 :       value_range r (TREE_TYPE (op));
    2051     78378045 :       tree single;
    2052    154272397 :       if (query->range_of_expr (r, op, stmt) && r.singleton_p (&single))
    2053        24985 :         val = single;
    2054     78378045 :     }
    2055              : 
    2056     82547843 :   if (val && val != op)
    2057              :     {
    2058              :       /* Certain operands are not allowed to be copy propagated due
    2059              :          to their interaction with exception handling and some GCC
    2060              :          extensions.  */
    2061      4192909 :       if (!may_propagate_copy (op, val))
    2062              :         return;
    2063              : 
    2064              :       /* Do not propagate copies into BIVs.
    2065              :          See PR23821 and PR62217 for how this can disturb IV and
    2066              :          number of iteration analysis.  */
    2067      4191361 :       if (TREE_CODE (val) != INTEGER_CST)
    2068              :         {
    2069      3398290 :           gimple *def = SSA_NAME_DEF_STMT (op);
    2070      3398290 :           if (gimple_code (def) == GIMPLE_PHI
    2071      3398290 :               && gimple_bb (def)->loop_father->header == gimple_bb (def))
    2072              :             return;
    2073              :         }
    2074              : 
    2075              :       /* Dump details.  */
    2076      4180147 :       if (dump_file && (dump_flags & TDF_DETAILS))
    2077              :         {
    2078           74 :           fprintf (dump_file, "  Replaced '");
    2079           74 :           print_generic_expr (dump_file, op, dump_flags);
    2080           74 :           fprintf (dump_file, "' with %s '",
    2081           74 :                    (TREE_CODE (val) != SSA_NAME ? "constant" : "variable"));
    2082           74 :           print_generic_expr (dump_file, val, dump_flags);
    2083           74 :           fprintf (dump_file, "'\n");
    2084              :         }
    2085              : 
    2086      4180147 :       if (TREE_CODE (val) != SSA_NAME)
    2087       987760 :         opt_stats.num_const_prop++;
    2088              :       else
    2089      3192387 :         opt_stats.num_copy_prop++;
    2090              : 
    2091      4180147 :       propagate_value (op_p, val);
    2092              : 
    2093              :       /* And note that we modified this statement.  This is now
    2094              :          safe, even if we changed virtual operands since we will
    2095              :          rescan the statement and rewrite its operands again.  */
    2096      4180147 :       gimple_set_modified (stmt, true);
    2097              :     }
    2098              : }
    2099              : 
    2100              : /* CONST_AND_COPIES is a table which maps an SSA_NAME to the current
    2101              :    known value for that SSA_NAME (or NULL if no value is known).
    2102              : 
    2103              :    Propagate values from CONST_AND_COPIES into the uses, vuses and
    2104              :    vdef_ops of STMT.  */
    2105              : 
    2106              : static void
    2107    182962757 : cprop_into_stmt (gimple *stmt, range_query *query)
    2108              : {
    2109    182962757 :   use_operand_p op_p;
    2110    182962757 :   ssa_op_iter iter;
    2111    182962757 :   tree last_copy_propagated_op = NULL;
    2112              : 
    2113    265511239 :   FOR_EACH_SSA_USE_OPERAND (op_p, stmt, iter, SSA_OP_USE)
    2114              :     {
    2115     82548482 :       tree old_op = USE_FROM_PTR (op_p);
    2116              : 
    2117              :       /* If we have A = B and B = A in the copy propagation tables
    2118              :          (due to an equality comparison), avoid substituting B for A
    2119              :          then A for B in the trivially discovered cases.   This allows
    2120              :          optimization of statements were A and B appear as input
    2121              :          operands.  */
    2122     82548482 :       if (old_op != last_copy_propagated_op)
    2123              :         {
    2124     82547843 :           cprop_operand (stmt, op_p, query);
    2125              : 
    2126     82547843 :           tree new_op = USE_FROM_PTR (op_p);
    2127     82547843 :           if (new_op != old_op && TREE_CODE (new_op) == SSA_NAME)
    2128     82548482 :             last_copy_propagated_op = new_op;
    2129              :         }
    2130              :     }
    2131    182962757 : }
    2132              : 
    2133              : /* If STMT contains a relational test, try to convert it into an
    2134              :    equality test if there is only a single value which can ever
    2135              :    make the test true.
    2136              : 
    2137              :    For example, if the expression hash table contains:
    2138              : 
    2139              :     TRUE = (i <= 1)
    2140              : 
    2141              :    And we have a test within statement of i >= 1, then we can safely
    2142              :    rewrite the test as i == 1 since there only a single value where
    2143              :    the test is true.
    2144              : 
    2145              :    This is similar to code in VRP.  */
    2146              : 
    2147              : void
    2148     55897212 : dom_opt_dom_walker::test_for_singularity (gimple *stmt,
    2149              :                                           avail_exprs_stack *avail_exprs_stack)
    2150              : {
    2151              :   /* We want to support gimple conditionals as well as assignments
    2152              :      where the RHS contains a conditional.  */
    2153     55897212 :   if (is_gimple_assign (stmt) || gimple_code (stmt) == GIMPLE_COND)
    2154              :     {
    2155     54596004 :       enum tree_code code = ERROR_MARK;
    2156     54596004 :       tree lhs, rhs;
    2157              : 
    2158              :       /* Extract the condition of interest from both forms we support.  */
    2159     54596004 :       if (is_gimple_assign (stmt))
    2160              :         {
    2161     45461055 :           code = gimple_assign_rhs_code (stmt);
    2162     45461055 :           lhs = gimple_assign_rhs1 (stmt);
    2163     45461055 :           rhs = gimple_assign_rhs2 (stmt);
    2164              :         }
    2165      9134949 :       else if (gimple_code (stmt) == GIMPLE_COND)
    2166              :         {
    2167      9134949 :           code = gimple_cond_code (as_a <gcond *> (stmt));
    2168      9134949 :           lhs = gimple_cond_lhs (as_a <gcond *> (stmt));
    2169      9134949 :           rhs = gimple_cond_rhs (as_a <gcond *> (stmt));
    2170              :         }
    2171              : 
    2172              :       /* We're looking for a relational test using LE/GE.  Also note we can
    2173              :          canonicalize LT/GT tests against constants into LE/GT tests.  */
    2174     54596004 :       if (code == LE_EXPR || code == GE_EXPR
    2175     53914191 :           || ((code == LT_EXPR || code == GT_EXPR)
    2176      1762170 :                && TREE_CODE (rhs) == INTEGER_CST))
    2177              :         {
    2178              :           /* For LT_EXPR and GT_EXPR, canonicalize to LE_EXPR and GE_EXPR.  */
    2179       950782 :           if (code == LT_EXPR)
    2180       138495 :             rhs = fold_build2 (MINUS_EXPR, TREE_TYPE (rhs),
    2181              :                                rhs, build_int_cst (TREE_TYPE (rhs), 1));
    2182              : 
    2183      1632595 :           if (code == GT_EXPR)
    2184       812287 :             rhs = fold_build2 (PLUS_EXPR, TREE_TYPE (rhs),
    2185              :                                rhs, build_int_cst (TREE_TYPE (rhs), 1));
    2186              : 
    2187              :           /* Determine the code we want to check for in the hash table.  */
    2188      1632595 :           enum tree_code test_code;
    2189      1632595 :           if (code == GE_EXPR || code == GT_EXPR)
    2190              :             test_code = LE_EXPR;
    2191              :           else
    2192       561582 :             test_code = GE_EXPR;
    2193              : 
    2194              :           /* Update the dummy statement so we can query the hash tables.  */
    2195      1632595 :           gimple_cond_set_code (m_dummy_cond, test_code);
    2196      1632595 :           gimple_cond_set_lhs (m_dummy_cond, lhs);
    2197      1632595 :           gimple_cond_set_rhs (m_dummy_cond, rhs);
    2198      1632595 :           tree cached_lhs
    2199      1632595 :             = avail_exprs_stack->lookup_avail_expr (m_dummy_cond,
    2200              :                                                     false, false);
    2201              : 
    2202              :           /* If the lookup returned 1 (true), then the expression we
    2203              :              queried was in the hash table.  As a result there is only
    2204              :              one value that makes the original conditional true.  Update
    2205              :              STMT accordingly.  */
    2206      1632595 :           if (cached_lhs && integer_onep (cached_lhs))
    2207              :             {
    2208         1406 :               if (is_gimple_assign (stmt))
    2209              :                 {
    2210           88 :                   gimple_assign_set_rhs_code (stmt, EQ_EXPR);
    2211           88 :                   gimple_assign_set_rhs2 (stmt, rhs);
    2212           88 :                   gimple_set_modified (stmt, true);
    2213              :                 }
    2214              :               else
    2215              :                 {
    2216         1318 :                   gimple_set_modified (stmt, true);
    2217         1318 :                   gimple_cond_set_code (as_a <gcond *> (stmt), EQ_EXPR);
    2218         1318 :                   gimple_cond_set_rhs (as_a <gcond *> (stmt), rhs);
    2219         1318 :                   gimple_set_modified (stmt, true);
    2220              :                 }
    2221              :             }
    2222              :         }
    2223              :     }
    2224     55897212 : }
    2225              : 
    2226              : /* If STMT is a comparison of two uniform vectors reduce it to a comparison
    2227              :    of scalar objects, otherwise leave STMT unchanged.  */
    2228              : 
    2229              : static void
    2230    182962757 : reduce_vector_comparison_to_scalar_comparison (gimple *stmt)
    2231              : {
    2232    182962757 :   if (gimple_code (stmt) == GIMPLE_COND)
    2233              :     {
    2234      9244499 :       tree lhs = gimple_cond_lhs (stmt);
    2235      9244499 :       tree rhs = gimple_cond_rhs (stmt);
    2236              : 
    2237              :       /* We may have a vector comparison where both arms are uniform
    2238              :          vectors.  If so, we can simplify the vector comparison down
    2239              :          to a scalar comparison.  */
    2240      9244499 :       if (VECTOR_TYPE_P (TREE_TYPE (lhs))
    2241      9244499 :           && VECTOR_TYPE_P (TREE_TYPE (rhs)))
    2242              :         {
    2243              :           /* If either operand is an SSA_NAME, then look back to its
    2244              :              defining statement to try and get at a suitable source.  */
    2245         2513 :           if (TREE_CODE (rhs) == SSA_NAME)
    2246              :             {
    2247            0 :               gimple *def_stmt = SSA_NAME_DEF_STMT (rhs);
    2248            0 :               if (gimple_assign_single_p (def_stmt))
    2249            0 :                 rhs = gimple_assign_rhs1 (def_stmt);
    2250              :             }
    2251              : 
    2252         2513 :           if (TREE_CODE (lhs) == SSA_NAME)
    2253              :             {
    2254         2513 :               gimple *def_stmt = SSA_NAME_DEF_STMT (lhs);
    2255         2513 :               if (gimple_assign_single_p (def_stmt))
    2256            6 :                 lhs = gimple_assign_rhs1 (def_stmt);
    2257              :             }
    2258              : 
    2259              :           /* Now see if they are both uniform vectors and if so replace
    2260              :              the vector comparison with a scalar comparison.  */
    2261         2513 :           tree rhs_elem = rhs ? uniform_vector_p (rhs) : NULL_TREE;
    2262         2513 :           tree lhs_elem = lhs ? uniform_vector_p (lhs) : NULL_TREE;
    2263         2513 :           if (rhs_elem && lhs_elem)
    2264              :             {
    2265            3 :               if (dump_file && dump_flags & TDF_DETAILS)
    2266              :                 {
    2267            0 :                   fprintf (dump_file, "Reducing vector comparison: ");
    2268            0 :                   print_gimple_stmt (dump_file, stmt, 0);
    2269              :                 }
    2270              : 
    2271            3 :               gimple_cond_set_rhs (as_a <gcond *>(stmt), rhs_elem);
    2272            3 :               gimple_cond_set_lhs (as_a <gcond *>(stmt), lhs_elem);
    2273            3 :               gimple_set_modified (stmt, true);
    2274              : 
    2275            3 :               if (dump_file && dump_flags & TDF_DETAILS)
    2276              :                 {
    2277            0 :                   fprintf (dump_file, "To scalar equivalent: ");
    2278            0 :                   print_gimple_stmt (dump_file, stmt, 0);
    2279            0 :                   fprintf (dump_file, "\n");
    2280              :                 }
    2281              :             }
    2282              :         }
    2283              :     }
    2284    182962757 : }
    2285              : 
    2286              : /* If possible, rewrite the conditional as TRUE or FALSE, and return
    2287              :    the taken edge.  Otherwise, return NULL.  */
    2288              : 
    2289              : edge
    2290      9172786 : dom_opt_dom_walker::fold_cond (gcond *cond)
    2291              : {
    2292      9172786 :   simplify_using_ranges simplify (m_ranger);
    2293      9172786 :   if (simplify.fold_cond (cond))
    2294              :     {
    2295       109550 :       basic_block bb = gimple_bb (cond);
    2296       109550 :       if (gimple_cond_true_p (cond))
    2297        27093 :         return find_taken_edge (bb, boolean_true_node);
    2298        82457 :       if (gimple_cond_false_p (cond))
    2299        82457 :         return find_taken_edge (bb, boolean_false_node);
    2300              :     }
    2301              :   return NULL;
    2302      9172786 : }
    2303              : 
    2304              : /* Optimize the statement in block BB pointed to by iterator SI.
    2305              : 
    2306              :    We try to perform some simplistic global redundancy elimination and
    2307              :    constant propagation:
    2308              : 
    2309              :    1- To detect global redundancy, we keep track of expressions that have
    2310              :       been computed in this block and its dominators.  If we find that the
    2311              :       same expression is computed more than once, we eliminate repeated
    2312              :       computations by using the target of the first one.
    2313              : 
    2314              :    2- Constant values and copy assignments.  This is used to do very
    2315              :       simplistic constant and copy propagation.  When a constant or copy
    2316              :       assignment is found, we map the value on the RHS of the assignment to
    2317              :       the variable in the LHS in the CONST_AND_COPIES table.
    2318              : 
    2319              :    3- Very simple redundant store elimination is performed.
    2320              : 
    2321              :    4- We can simplify a condition to a constant or from a relational
    2322              :       condition to an equality condition.  */
    2323              : 
    2324              : edge
    2325    182962757 : dom_opt_dom_walker::optimize_stmt (basic_block bb, gimple_stmt_iterator *si,
    2326              :                                    bool *removed_p)
    2327              : {
    2328    182962757 :   gimple *stmt, *old_stmt;
    2329    182962757 :   bool may_optimize_p;
    2330    182962757 :   bool modified_p = false;
    2331    182962757 :   bool was_noreturn;
    2332    182962757 :   edge retval = NULL;
    2333              : 
    2334    182962757 :   old_stmt = stmt = gsi_stmt (*si);
    2335    182962757 :   was_noreturn = is_gimple_call (stmt) && gimple_call_noreturn_p (stmt);
    2336              : 
    2337    182962757 :   if (dump_file && (dump_flags & TDF_DETAILS))
    2338              :     {
    2339         1597 :       fprintf (dump_file, "Optimizing statement ");
    2340         1597 :       print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    2341              :     }
    2342              : 
    2343              :   /* STMT may be a comparison of uniform vectors that we can simplify
    2344              :      down to a comparison of scalars.  Do that transformation first
    2345              :      so that all the scalar optimizations from here onward apply.  */
    2346    182962757 :   reduce_vector_comparison_to_scalar_comparison (stmt);
    2347              : 
    2348    182962757 :   update_stmt_if_modified (stmt);
    2349    182962757 :   opt_stats.num_stmts++;
    2350              : 
    2351              :   /* Const/copy propagate into USES, VUSES and the RHS of VDEFs.  */
    2352    182962757 :   cprop_into_stmt (stmt, m_ranger);
    2353              : 
    2354              :   /* If the statement has been modified with constant replacements,
    2355              :      fold its RHS before checking for redundant computations.  */
    2356    365603517 :   if (gimple_modified_p (stmt))
    2357              :     {
    2358      4008539 :       tree rhs = NULL;
    2359              : 
    2360              :       /* Try to fold the statement making sure that STMT is kept
    2361              :          up to date.  */
    2362      4008539 :       if (fold_stmt (si))
    2363              :         {
    2364       413823 :           stmt = gsi_stmt (*si);
    2365       413823 :           gimple_set_modified (stmt, true);
    2366              : 
    2367       413823 :           if (dump_file && (dump_flags & TDF_DETAILS))
    2368              :             {
    2369           10 :               fprintf (dump_file, "  Folded to: ");
    2370           10 :               print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    2371              :             }
    2372              :         }
    2373              : 
    2374              :       /* We only need to consider cases that can yield a gimple operand.  */
    2375      4008539 :       if (gimple_assign_single_p (stmt))
    2376      1482052 :         rhs = gimple_assign_rhs1 (stmt);
    2377      2526487 :       else if (gimple_code (stmt) == GIMPLE_GOTO)
    2378            2 :         rhs = gimple_goto_dest (stmt);
    2379    182964757 :       else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt))
    2380              :         /* This should never be an ADDR_EXPR.  */
    2381         2000 :         rhs = gimple_switch_index (swtch_stmt);
    2382              : 
    2383      1484054 :       if (rhs && TREE_CODE (rhs) == ADDR_EXPR)
    2384        86986 :         recompute_tree_invariant_for_addr_expr (rhs);
    2385              : 
    2386              :       /* Indicate that maybe_clean_or_replace_eh_stmt needs to be called,
    2387              :          even if fold_stmt updated the stmt already and thus cleared
    2388              :          gimple_modified_p flag on it.  */
    2389              :       modified_p = true;
    2390              :     }
    2391              : 
    2392              :   /* Check for redundant computations.  Do this optimization only
    2393              :      for assignments that have no volatile ops and conditionals.  */
    2394    182962757 :   may_optimize_p = (!gimple_has_side_effects (stmt)
    2395    182962757 :                     && (is_gimple_assign (stmt)
    2396    123888315 :                         || (is_gimple_call (stmt)
    2397      1279126 :                             && gimple_call_lhs (stmt) != NULL_TREE)
    2398    122609553 :                         || gimple_code (stmt) == GIMPLE_COND
    2399    113365054 :                         || gimple_code (stmt) == GIMPLE_SWITCH));
    2400              : 
    2401              :   if (may_optimize_p)
    2402              :     {
    2403     56131015 :       if (gimple_code (stmt) == GIMPLE_CALL)
    2404              :         {
    2405              :           /* Resolve __builtin_constant_p.  If it hasn't been
    2406              :              folded to integer_one_node by now, it's fairly
    2407              :              certain that the value simply isn't constant.  */
    2408      1278762 :           tree callee = gimple_call_fndecl (stmt);
    2409      1278762 :           if (callee
    2410      1278762 :               && fndecl_built_in_p (callee, BUILT_IN_CONSTANT_P))
    2411              :             {
    2412         4071 :               propagate_tree_value_into_stmt (si, integer_zero_node);
    2413         4071 :               stmt = gsi_stmt (*si);
    2414              :             }
    2415              :         }
    2416              : 
    2417     56131015 :       if (gimple_code (stmt) == GIMPLE_COND)
    2418              :         {
    2419      9244499 :           tree lhs = gimple_cond_lhs (stmt);
    2420      9244499 :           tree rhs = gimple_cond_rhs (stmt);
    2421              : 
    2422              :           /* If the LHS has a range [0..1] and the RHS has a range ~[0..1],
    2423              :              then this conditional is computable at compile time.  We can just
    2424              :              shove either 0 or 1 into the LHS, mark the statement as modified
    2425              :              and all the right things will just happen below.
    2426              : 
    2427              :              Note this would apply to any case where LHS has a range
    2428              :              narrower than its type implies and RHS is outside that
    2429              :              narrower range.  Future work.  */
    2430      9244499 :           if (TREE_CODE (lhs) == SSA_NAME
    2431      9172810 :               && ssa_name_has_boolean_range (lhs)
    2432      1015131 :               && TREE_CODE (rhs) == INTEGER_CST
    2433     10227834 :               && ! (integer_zerop (rhs) || integer_onep (rhs)))
    2434              :             {
    2435           24 :               gimple_cond_set_lhs (as_a <gcond *> (stmt),
    2436           24 :                                    fold_convert (TREE_TYPE (lhs),
    2437              :                                                  integer_zero_node));
    2438           24 :               gimple_set_modified (stmt, true);
    2439              :             }
    2440      9244475 :           else if (TREE_CODE (lhs) == SSA_NAME)
    2441              :             {
    2442              :               /* Exploiting EVRP data is not yet fully integrated into DOM
    2443              :                  but we need to do something for this case to avoid regressing
    2444              :                  udr4.f90 and new1.C which have unexecutable blocks with
    2445              :                  undefined behavior that get diagnosed if they're left in the
    2446              :                  IL because we've attached range information to new
    2447              :                  SSA_NAMES.  */
    2448      9172786 :               update_stmt_if_modified (stmt);
    2449      9172786 :               edge taken_edge = fold_cond (as_a <gcond *> (stmt));
    2450      9172786 :               if (taken_edge)
    2451              :                 {
    2452       109550 :                   gimple_set_modified (stmt, true);
    2453       109550 :                   update_stmt (stmt);
    2454       109550 :                   cfg_altered = true;
    2455       109550 :                   return taken_edge;
    2456              :                 }
    2457              :             }
    2458              :         }
    2459              : 
    2460     56021465 :       update_stmt_if_modified (stmt);
    2461     56021465 :       eliminate_redundant_computations (si, m_const_and_copies,
    2462              :                                         m_avail_exprs_stack);
    2463     56021465 :       stmt = gsi_stmt (*si);
    2464              : 
    2465              :       /* Perform simple redundant store elimination.  */
    2466     56021465 :       if (gimple_assign_single_p (stmt)
    2467     28512876 :           && TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME
    2468     68934348 :           && (TREE_CODE (gimple_assign_lhs (stmt)) != VAR_DECL
    2469      1046327 :               || !DECL_HARD_REGISTER (gimple_assign_lhs (stmt))))
    2470              :         {
    2471     12910865 :           tree lhs = gimple_assign_lhs (stmt);
    2472     12910865 :           tree rhs = gimple_assign_rhs1 (stmt);
    2473     12910865 :           tree cached_lhs;
    2474     12910865 :           gassign *new_stmt;
    2475     12910865 :           rhs = dom_valueize (rhs);
    2476              :           /* Build a new statement with the RHS and LHS exchanged.  */
    2477     12910865 :           if (TREE_CODE (rhs) == SSA_NAME)
    2478              :             {
    2479      5350762 :               gimple *defstmt = SSA_NAME_DEF_STMT (rhs);
    2480      5350762 :               new_stmt = gimple_build_assign (rhs, lhs);
    2481      5350762 :               SSA_NAME_DEF_STMT (rhs) = defstmt;
    2482              :             }
    2483              :           else
    2484      7560103 :             new_stmt = gimple_build_assign (rhs, lhs);
    2485     25821730 :           gimple_set_vuse (new_stmt, gimple_vuse (stmt));
    2486     12910865 :           expr_hash_elt *elt = NULL;
    2487     12910865 :           cached_lhs = m_avail_exprs_stack->lookup_avail_expr (new_stmt, false,
    2488              :                                                                false, &elt);
    2489     12910865 :           if (cached_lhs
    2490       848731 :               && operand_equal_p (rhs, cached_lhs, 0)
    2491     13168099 :               && refs_same_for_tbaa_p (elt->expr ()->kind == EXPR_SINGLE
    2492       128617 :                                        ? elt->expr ()->ops.single.rhs
    2493              :                                        : NULL_TREE, lhs))
    2494              :             {
    2495       124253 :               basic_block bb = gimple_bb (stmt);
    2496       124253 :               unlink_stmt_vdef (stmt);
    2497       124253 :               if (gsi_remove (si, true))
    2498              :                 {
    2499            0 :                   bitmap_set_bit (need_eh_cleanup, bb->index);
    2500            0 :                   if (dump_file && (dump_flags & TDF_DETAILS))
    2501            0 :                     fprintf (dump_file, "  Flagged to clear EH edges.\n");
    2502              :                 }
    2503       124253 :               release_defs (stmt);
    2504       124253 :               *removed_p = true;
    2505       124253 :               return retval;
    2506              :             }
    2507              :         }
    2508              : 
    2509              :       /* If this statement was not redundant, we may still be able to simplify
    2510              :          it, which may in turn allow other part of DOM or other passes to do
    2511              :          a better job.  */
    2512     55897212 :       test_for_singularity (stmt, m_avail_exprs_stack);
    2513              :     }
    2514              : 
    2515              :   /* Record any additional equivalences created by this statement.  */
    2516    182728954 :   if (is_gimple_assign (stmt))
    2517     49128168 :     record_equivalences_from_stmt (stmt, may_optimize_p, m_avail_exprs_stack);
    2518              : 
    2519              :   /* If STMT is a COND_EXPR or SWITCH_EXPR and it was modified, then we may
    2520              :      know where it goes.  */
    2521    365457908 :   if (gimple_modified_p (stmt) || modified_p)
    2522              :     {
    2523      4304049 :       tree val = NULL;
    2524              : 
    2525      4304049 :       if (gimple_code (stmt) == GIMPLE_COND)
    2526       474350 :         val = fold_binary_loc (gimple_location (stmt),
    2527              :                                gimple_cond_code (stmt), boolean_type_node,
    2528              :                                gimple_cond_lhs (stmt),
    2529              :                                gimple_cond_rhs (stmt));
    2530      3829699 :       else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt))
    2531         2000 :         val = gimple_switch_index (swtch_stmt);
    2532              : 
    2533       476350 :       if (val && TREE_CODE (val) == INTEGER_CST)
    2534              :         {
    2535        77206 :           retval = find_taken_edge (bb, val);
    2536        77206 :           if (retval)
    2537              :             {
    2538              :               /* Fix the condition to be either true or false.  */
    2539        77206 :               if (gimple_code (stmt) == GIMPLE_COND)
    2540              :                 {
    2541        77190 :                   if (integer_zerop (val))
    2542        39567 :                     gimple_cond_make_false (as_a <gcond *> (stmt));
    2543        37623 :                   else if (integer_onep (val))
    2544        37623 :                     gimple_cond_make_true (as_a <gcond *> (stmt));
    2545              :                   else
    2546            0 :                     gcc_unreachable ();
    2547              : 
    2548        77190 :                   gimple_set_modified (stmt, true);
    2549              :                 }
    2550              : 
    2551              :               /* Further simplifications may be possible.  */
    2552        77206 :               cfg_altered = true;
    2553              :             }
    2554              :         }
    2555              : 
    2556      4304049 :       update_stmt_if_modified (stmt);
    2557              : 
    2558              :       /* If we simplified a statement in such a way as to be shown that it
    2559              :          cannot trap, update the eh information and the cfg to match.  */
    2560      4304049 :       if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
    2561              :         {
    2562         1581 :           bitmap_set_bit (need_eh_cleanup, bb->index);
    2563         1581 :           if (dump_file && (dump_flags & TDF_DETAILS))
    2564            0 :             fprintf (dump_file, "  Flagged to clear EH edges.\n");
    2565              :         }
    2566              : 
    2567      4304049 :       if (!was_noreturn
    2568      4304049 :           && is_gimple_call (stmt) && gimple_call_noreturn_p (stmt))
    2569            3 :         need_noreturn_fixup.safe_push (stmt);
    2570              :     }
    2571              :   return retval;
    2572              : }
        

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.