LCOV - code coverage report
Current view: top level - gcc - tree-ssa-dom.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 94.1 % 1065 1002
Test Date: 2026-06-20 15:32:29 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     35741993 : 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     35741993 :   free_dom_edge_info (e);
     134     35741993 :   e->aux = this;
     135              : 
     136              :   /* And initialize the embedded vectors.  */
     137     35741993 :   simple_equivalences = vNULL;
     138     35741993 :   cond_equivalences = vNULL;
     139     35741993 : }
     140              : 
     141              : /* Destructor just needs to release the vectors.  */
     142              : 
     143     35741993 : edge_info::~edge_info (void)
     144              : {
     145     35741993 :   this->cond_equivalences.release ();
     146     35741993 :   this->simple_equivalences.release ();
     147     35741993 : }
     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     13077705 : edge_info::derive_equivalences (tree name, tree value, int recursion_limit)
     159              : {
     160     15061408 :   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     15061128 :   simple_equivalences.safe_push (equiv_pair (name, value));
     166              : 
     167              :   /* Limit how far up the use-def chains we are willing to walk.  */
     168     15061128 :   if (recursion_limit == 0)
     169              :     return;
     170              : 
     171              :   /* We can walk up the use-def chains to potentially find more
     172              :      equivalences.  */
     173     15046767 :   gimple *def_stmt = SSA_NAME_DEF_STMT (name);
     174     15046767 :   if (is_gimple_assign (def_stmt))
     175              :     {
     176      9669564 :       enum tree_code code = gimple_assign_rhs_code (def_stmt);
     177      9669564 :       switch (code)
     178              :         {
     179              :         /* If the result of an OR is zero, then its operands are, too.  */
     180       576480 :         case BIT_IOR_EXPR:
     181       576480 :           if (integer_zerop (value))
     182              :             {
     183       318751 :               tree rhs1 = gimple_assign_rhs1 (def_stmt);
     184       318751 :               tree rhs2 = gimple_assign_rhs2 (def_stmt);
     185              : 
     186       318751 :               value = build_zero_cst (TREE_TYPE (rhs1));
     187       318751 :               derive_equivalences (rhs1, value, recursion_limit - 1);
     188       318751 :               value = build_zero_cst (TREE_TYPE (rhs2));
     189       318751 :               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      1015550 :         case BIT_AND_EXPR:
     195      1015550 :           if (!integer_zerop (value))
     196              :             {
     197       423383 :               tree rhs1 = gimple_assign_rhs1 (def_stmt);
     198       423383 :               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       423383 :               if (TREE_CODE (rhs1) == SSA_NAME)
     205              :                 {
     206       423383 :                   if (ssa_name_has_boolean_range (rhs1))
     207              :                     {
     208       258160 :                       value = build_one_cst (TREE_TYPE (rhs1));
     209       258160 :                       derive_equivalences (rhs1, value, recursion_limit - 1);
     210              :                     }
     211              :                 }
     212       423383 :               if (TREE_CODE (rhs2) == SSA_NAME)
     213              :                 {
     214       260105 :                   if (ssa_name_has_boolean_range (rhs2))
     215              :                     {
     216       257877 :                       value = build_one_cst (TREE_TYPE (rhs2));
     217       257877 :                       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       426894 :         CASE_CONVERT:
     227       426894 :           {
     228       426894 :             tree rhs = gimple_assign_rhs1 (def_stmt);
     229       426894 :             tree rhs_type = TREE_TYPE (rhs);
     230       426894 :             if (INTEGRAL_TYPE_P (rhs_type)
     231       424499 :                 && (TYPE_PRECISION (TREE_TYPE (name))
     232       424499 :                     >= TYPE_PRECISION (rhs_type))
     233       657129 :                 && int_fits_type_p (value, rhs_type))
     234       221038 :               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      1015273 :         case POINTER_PLUS_EXPR:
     244      1015273 :         case PLUS_EXPR:
     245      1015273 :           {
     246      1015273 :             tree rhs1 = gimple_assign_rhs1 (def_stmt);
     247      1015273 :             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      1015273 :             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      1015273 :             else if (TREE_CODE (rhs2) == INTEGER_CST
     258       962735 :                      && TREE_CODE (rhs1) == SSA_NAME)
     259       962735 :               derive_equivalences (rhs1,
     260       962735 :                                    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        74116 :         case MINUS_EXPR:
     270        74116 :           {
     271        74116 :             tree rhs1 = gimple_assign_rhs1 (def_stmt);
     272        74116 :             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        74116 :             if (TREE_CODE (rhs1) == INTEGER_CST
     277          635 :                 && TREE_CODE (rhs2) == SSA_NAME)
     278          635 :               derive_equivalences (rhs2,
     279          635 :                                    fold_binary (MINUS_EXPR, TREE_TYPE (rhs1),
     280              :                                                 rhs1, value),
     281              :                                    recursion_limit - 1);
     282        73481 :             else if (TREE_CODE (rhs2) == INTEGER_CST
     283        29808 :                      && TREE_CODE (rhs1) == SSA_NAME)
     284        29808 :               derive_equivalences (rhs1,
     285        29808 :                                    fold_binary (PLUS_EXPR, TREE_TYPE (rhs1),
     286              :                                                 value, rhs2),
     287              :                                    recursion_limit - 1);
     288        43673 :             else if (integer_zerop (value))
     289              :               {
     290        15840 :                 tree cond = build2 (EQ_EXPR, boolean_type_node,
     291              :                                     gimple_assign_rhs1 (def_stmt),
     292              :                                     gimple_assign_rhs2 (def_stmt));
     293        15840 :                 tree inverted = invert_truthvalue (cond);
     294        15840 :                 record_conditions (&this->cond_equivalences, cond, inverted);
     295              :               }
     296              :             break;
     297              :           }
     298              : 
     299       666545 :         case EQ_EXPR:
     300       666545 :         case NE_EXPR:
     301       666545 :           {
     302       266661 :             if ((code == EQ_EXPR && integer_onep (value))
     303       793500 :                 || (code == NE_EXPR && integer_zerop (value)))
     304              :               {
     305       393442 :                 tree rhs1 = gimple_assign_rhs1 (def_stmt);
     306       393442 :                 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       393442 :                 if (TREE_CODE (rhs1) == INTEGER_CST)
     314            0 :                   derive_equivalences (rhs2, rhs1, recursion_limit - 1);
     315       393442 :                 else if (TREE_CODE (rhs2) == INTEGER_CST)
     316       179452 :                   derive_equivalences (rhs1, rhs2, recursion_limit - 1);
     317              :               }
     318              :             else
     319              :               {
     320       273103 :                 tree cond = build2 (code, boolean_type_node,
     321              :                                     gimple_assign_rhs1 (def_stmt),
     322       273103 :                                     gimple_assign_rhs2 (def_stmt));
     323       273103 :                 tree inverted = invert_truthvalue (cond);
     324       273103 :                 if (integer_zerop (value))
     325       126955 :                   std::swap (cond, inverted);
     326       273103 :                 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        13407 :         case BIT_NOT_EXPR:
     335        13407 :         case NEGATE_EXPR:
     336        13407 :           {
     337        13407 :             tree rhs = gimple_assign_rhs1 (def_stmt);
     338        13407 :             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        13407 :             if (code == BIT_NOT_EXPR
     350        13193 :                 && TREE_CODE (rhs) == SSA_NAME
     351        26600 :                 && ssa_name_has_boolean_range (rhs))
     352              :               {
     353        12754 :                 if ((TREE_INT_CST_LOW (value) & 1) == 0)
     354         5902 :                   res = build_one_cst (TREE_TYPE (rhs));
     355              :                 else
     356         6852 :                   res = build_zero_cst (TREE_TYPE (rhs));
     357              :               }
     358              :             else
     359          653 :               res = fold_build1 (code, TREE_TYPE (rhs), value);
     360        13407 :             derive_equivalences (rhs, res, recursion_limit - 1);
     361        13407 :             break;
     362              :           }
     363              : 
     364      5881299 :         default:
     365      5881299 :           {
     366      5881299 :             if (TREE_CODE_CLASS (code) == tcc_comparison)
     367              :               {
     368       526953 :                 tree cond = build2 (code, boolean_type_node,
     369              :                                     gimple_assign_rhs1 (def_stmt),
     370       526953 :                                     gimple_assign_rhs2 (def_stmt));
     371       526953 :                 tree inverted = invert_truthvalue (cond);
     372       526953 :                 if (integer_zerop (value))
     373       227311 :                   std::swap (cond, inverted);
     374       526953 :                 record_conditions (&this->cond_equivalences, cond, inverted);
     375       526953 :                 break;
     376              :               }
     377              :             break;
     378              :           }
     379              :         }
     380              :     }
     381              : }
     382              : 
     383              : void
     384     15672941 : 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     15672941 :   if (TREE_CODE (rhs) == INTEGER_CST)
     390     12500794 :     derive_equivalences (lhs, rhs, 4);
     391              :   else
     392      3172147 :     simple_equivalences.safe_push (equiv_pair (lhs, rhs));
     393     15672941 : }
     394              : 
     395              : /* Free the edge_info data attached to E, if it exists and
     396              :    clear e->aux.  */
     397              : 
     398              : void
     399    128854331 : free_dom_edge_info (edge e)
     400              : {
     401    128854331 :   class edge_info *edge_info = (class edge_info *)e->aux;
     402              : 
     403    128854331 :   if (edge_info)
     404     35741993 :     delete edge_info;
     405    128854331 :   e->aux = NULL;
     406    128854331 : }
     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      2079882 : free_all_edge_infos (void)
     416              : {
     417      2079882 :   basic_block bb;
     418      2079882 :   edge_iterator ei;
     419      2079882 :   edge e;
     420              : 
     421     23215489 :   FOR_EACH_BB_FN (bb, cfun)
     422              :     {
     423     50969477 :       FOR_EACH_EDGE (e, ei, bb->preds)
     424     29833870 :         free_dom_edge_info (e);
     425              :     }
     426      2079882 : }
     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     17872316 : single_block_loop_p (basic_block bb)
     436              : {
     437              :   /* Two preds.  */
     438     17872316 :   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      5210360 :   basic_block pred = NULL;
     444      5210360 :   unsigned int count = 0;
     445      5210360 :   if (EDGE_PRED (bb, 0)->flags & EDGE_DFS_BACK)
     446              :     {
     447      1862962 :       pred = EDGE_PRED (bb, 0)->src;
     448      1862962 :       count++;
     449              :     }
     450      5210360 :   if (EDGE_PRED (bb, 1)->flags & EDGE_DFS_BACK)
     451              :     {
     452       402140 :       pred = EDGE_PRED (bb, 1)->src;
     453       402140 :       count++;
     454              :     }
     455              : 
     456      5210360 :   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      2265102 :   if (EDGE_COUNT (pred->preds) != 1
     462     19027055 :       || EDGE_COUNT (pred->succs) != 1
     463      2184268 :       || EDGE_PRED (pred, 0)->src != bb
     464      3356375 :       || 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      1091273 :   if (! gimple_seq_empty_p (phi_nodes (pred)))
     471              :     return false;
     472              : 
     473      1086611 :   gimple_stmt_iterator gsi;
     474      2196402 :   for (gsi = gsi_last_bb (pred); !gsi_end_p (gsi); gsi_prev (&gsi))
     475              :     {
     476        68672 :       gimple *stmt = gsi_stmt (gsi);
     477              : 
     478        68672 :       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     44280111 : record_edge_info (basic_block bb)
     501              : {
     502     44280111 :   gimple_stmt_iterator gsi = gsi_last_bb (bb);
     503     44280111 :   class edge_info *edge_info;
     504              : 
     505              :   /* Free all the outgoing edge info data associated with
     506              :      BB's outgoing edges.  */
     507     44280111 :   edge e;
     508     44280111 :   edge_iterator ei;
     509    105857855 :   FOR_EACH_EDGE (e, ei, bb->succs)
     510     61577744 :     free_dom_edge_info (e);
     511              : 
     512     44280111 :   if (! gsi_end_p (gsi))
     513              :     {
     514     38131035 :       gimple *stmt = gsi_stmt (gsi);
     515     38131035 :       location_t loc = gimple_location (stmt);
     516              : 
     517     38131035 :       if (gimple_code (stmt) == GIMPLE_SWITCH)
     518              :         {
     519        68911 :           gswitch *switch_stmt = as_a <gswitch *> (stmt);
     520        68911 :           tree index = gimple_switch_index (switch_stmt);
     521              : 
     522        68911 :           if (TREE_CODE (index) == SSA_NAME)
     523              :             {
     524        68895 :               int i;
     525        68895 :               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        68895 :               tree *info = XCNEWVEC (tree, last_basic_block_for_fn (cfun));
     532              : 
     533       571976 :               for (i = 0; i < n_labels; i++)
     534              :                 {
     535       503081 :                   tree label = gimple_switch_label (switch_stmt, i);
     536       503081 :                   basic_block target_bb
     537       503081 :                     = 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       503081 :                   if (CASE_HIGH (label)
     541       476969 :                       || !CASE_LOW (label)
     542       911155 :                       || info[target_bb->index])
     543       144453 :                     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       358628 :                     info[target_bb->index] = CASE_LOW (label);
     548              :                 }
     549              : 
     550       515704 :               FOR_EACH_EDGE (e, ei, bb->succs)
     551              :                 {
     552       446809 :                   basic_block target_bb = e->dest;
     553       446809 :                   tree value = info[target_bb->index];
     554              : 
     555       446809 :                   if (value != NULL && value != error_mark_node)
     556              :                     {
     557       331781 :                       tree x = fold_convert_loc (loc, TREE_TYPE (index),
     558              :                                                  value);
     559       331781 :                       edge_info = new class edge_info (e);
     560       331781 :                       edge_info->record_simple_equiv (index, x);
     561              :                     }
     562              :                 }
     563        68895 :               free (info);
     564              :             }
     565              :         }
     566              : 
     567              :       /* A COND_EXPR may create equivalences too.  */
     568     38131035 :       if (gimple_code (stmt) == GIMPLE_COND)
     569              :         {
     570     17872316 :           edge true_edge;
     571     17872316 :           edge false_edge;
     572              : 
     573     17872316 :           tree op0 = gimple_cond_lhs (stmt);
     574     17872316 :           tree op1 = gimple_cond_rhs (stmt);
     575     17872316 :           enum tree_code code = gimple_cond_code (stmt);
     576              : 
     577     17872316 :           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     17872316 :           if ((code == EQ_EXPR || code == NE_EXPR)
     587     13729092 :               && TREE_CODE (op0) == SSA_NAME
     588     13562096 :               && ssa_name_has_boolean_range (op0)
     589      2047153 :               && is_gimple_min_invariant (op1)
     590     19857120 :               && (integer_zerop (op1) || integer_onep (op1)))
     591              :             {
     592      1984804 :               tree true_val = constant_boolean_node (true, TREE_TYPE (op0));
     593      1984804 :               tree false_val = constant_boolean_node (false, TREE_TYPE (op0));
     594              : 
     595      1984804 :               if (code == EQ_EXPR)
     596              :                 {
     597        80219 :                   edge_info = new class edge_info (true_edge);
     598       118658 :                   edge_info->record_simple_equiv (op0,
     599        80219 :                                                   (integer_zerop (op1)
     600              :                                                    ? false_val : true_val));
     601        80219 :                   edge_info = new class edge_info (false_edge);
     602       118658 :                   edge_info->record_simple_equiv (op0,
     603        80219 :                                                   (integer_zerop (op1)
     604              :                                                    ? true_val : false_val));
     605              :                 }
     606              :               else
     607              :                 {
     608      1904585 :                   edge_info = new class edge_info (true_edge);
     609      1907868 :                   edge_info->record_simple_equiv (op0,
     610      1904585 :                                                   (integer_zerop (op1)
     611              :                                                    ? true_val : false_val));
     612      1904585 :                   edge_info = new class edge_info (false_edge);
     613      1907868 :                   edge_info->record_simple_equiv (op0,
     614      1904585 :                                                   (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     15887512 :           else if (is_gimple_min_invariant (op0)
     622     15887512 :                    && 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     15887512 :           else if (TREE_CODE (op0) == SSA_NAME
     645     15887512 :                    && (TREE_CODE (op1) == SSA_NAME
     646     11651256 :                        || is_gimple_min_invariant (op1)))
     647              :             {
     648     15719983 :               tree cond = build2 (code, boolean_type_node, op0, op1);
     649     15719983 :               tree inverted = invert_truthvalue_loc (loc, cond);
     650     15719983 :               bool can_infer_simple_equiv
     651     16413436 :                 = !(HONOR_SIGNED_ZEROS (op1) && real_maybe_zerop (op1))
     652     16117091 :                   && !DECIMAL_FLOAT_MODE_P (element_mode (TREE_TYPE (op1)));
     653     15719983 :               class edge_info *edge_info;
     654              : 
     655     15719983 :               edge_info = new class edge_info (true_edge);
     656     15719983 :               record_conditions (&edge_info->cond_equivalences, cond, inverted);
     657              : 
     658     15719983 :               if (can_infer_simple_equiv && code == EQ_EXPR)
     659      5297317 :                 edge_info->record_simple_equiv (op0, op1);
     660              : 
     661     15719983 :               edge_info = new class edge_info (false_edge);
     662     15719983 :               record_conditions (&edge_info->cond_equivalences, inverted, cond);
     663              : 
     664     15719983 :               if (can_infer_simple_equiv && TREE_CODE (inverted) == EQ_EXPR)
     665      6072904 :                 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     17872316 :           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      1029529 :               if ((TREE_CODE (op0) != SSA_NAME
     678      1028845 :                    || gimple_bb (SSA_NAME_DEF_STMT (op0)) != bb)
     679      1195425 :                   && (TREE_CODE (op1) != SSA_NAME
     680       164215 :                       || 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         2490 :                   bool alternative
     688         2490 :                     = (EDGE_PRED (bb, 0)->flags & EDGE_DFS_BACK) ? 1 : 0;
     689              : 
     690         2490 :                   gphi_iterator gsi;
     691         2490 :                   for (gsi = gsi_start_phis (bb);
     692         4187 :                        !gsi_end_p (gsi);
     693         1697 :                        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         1697 :                       gphi *phi = gsi.phi ();
     700         1697 :                       tree src = PHI_ARG_DEF (phi, alternative);
     701         1697 :                       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         1697 :                       if (dst == PHI_ARG_DEF (phi, !alternative))
     706          366 :                         continue;
     707              : 
     708         1331 :                       if (EDGE_SUCC (bb, 0)->dest
     709         1331 :                           != EDGE_PRED (bb, !alternative)->src)
     710          371 :                         edge_info = (class edge_info *)EDGE_SUCC (bb, 0)->aux;
     711              :                       else
     712          960 :                         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         1331 :                       if (edge_info == NULL)
     718          638 :                         edge_info = new class edge_info (false_edge);
     719         1331 :                       edge_info->record_simple_equiv (dst, src);
     720              :                     }
     721              :                 }
     722              :             }
     723              :         }
     724              :     }
     725     44280111 : }
     726              : 
     727              : class dom_jt_state : public jt_state
     728              : {
     729              : public:
     730      2079882 :   dom_jt_state (const_and_copies *copies, avail_exprs_stack *avails)
     731      2079882 :     : m_copies (copies), m_avails (avails)
     732              :   {
     733      2079882 :     bitmap_tree_view (m_blocks_on_stack);
     734      2079882 :   }
     735     16503085 :   void push (edge e) override
     736              :   {
     737     16503085 :     m_copies->push_marker ();
     738     16503085 :     m_avails->push_marker ();
     739     16503085 :     jt_state::push (e);
     740     16503085 :   }
     741     16503085 :   void pop () override
     742              :   {
     743     16503085 :     m_copies->pop_to_marker ();
     744     16503085 :     m_avails->pop_to_marker ();
     745     16503085 :     jt_state::pop ();
     746     16503085 :   }
     747     15272688 :   void register_equivs_edge (edge e) override
     748              :   {
     749     15272688 :     record_temporary_equivalences (e, m_copies, m_avails, m_blocks_on_stack);
     750     15272688 :   }
     751              :   void register_equiv (tree dest, tree src, bool update) override;
     752     69433512 :   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     20693177 : dom_jt_state::register_equiv (tree dest, tree src, bool)
     763              : {
     764     20693177 :   m_copies->record_const_or_copy (dest, src);
     765     20693177 : }
     766              : 
     767      2079882 : class dom_jt_simplifier : public hybrid_jt_simplifier
     768              : {
     769              : public:
     770      2079882 :   dom_jt_simplifier (avail_exprs_stack *avails, gimple_ranger *ranger,
     771              :                      path_range_query *query)
     772      4159764 :     : 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     30536764 : 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     30536764 :   tree cached_lhs =  m_avails->lookup_avail_expr (stmt, false, true);
     785     30536764 :   if (cached_lhs)
     786              :     return cached_lhs;
     787              : 
     788              :   /* Otherwise call the ranger if possible.  */
     789     29747256 :   if (state)
     790      8417737 :     return hybrid_jt_simplifier::simplify (stmt, within_stmt, bb, state);
     791              : 
     792              :   return NULL;
     793              : }
     794              : 
     795      4159764 : class dom_opt_dom_walker : public dom_walker
     796              : {
     797              : public:
     798      2079882 :   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      2079882 :     : dom_walker (direction, REACHABLE_BLOCKS)
     805              :     {
     806      2079882 :       m_ranger = ranger;
     807      2079882 :       m_state = state;
     808      2079882 :       m_dummy_cond = gimple_build_cond (NE_EXPR, integer_zero_node,
     809              :                                         integer_zero_node, NULL, NULL);
     810      2079882 :       m_const_and_copies = const_and_copies;
     811      2079882 :       m_avail_exprs_stack = avail_exprs_stack;
     812      2079882 :       m_threader = threader;
     813      2079882 :     }
     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       896484 :   pass_dominator (gcc::context *ctxt)
     868       896484 :     : gimple_opt_pass (pass_data_dominator, ctxt),
     869      1792968 :       may_peel_loop_headers_p (false)
     870              :   {}
     871              : 
     872              :   /* opt_pass methods: */
     873       597656 :   opt_pass * clone () final override { return new pass_dominator (m_ctxt); }
     874       896484 :   void set_pass_param (unsigned int n, bool param) final override
     875              :     {
     876       896484 :       gcc_assert (n == 0);
     877       896484 :       may_peel_loop_headers_p = param;
     878       896484 :     }
     879      2080679 :   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      2079882 : pass_dominator::execute (function *fun)
     892              : {
     893      2079882 :   memset (&opt_stats, 0, sizeof (opt_stats));
     894              : 
     895              :   /* Create our hash tables.  */
     896      2079882 :   hash_table<expr_elt_hasher> *avail_exprs
     897      2079882 :     = new hash_table<expr_elt_hasher> (1024);
     898      2079882 :   class avail_exprs_stack *avail_exprs_stack
     899      2079882 :     = new class avail_exprs_stack (avail_exprs);
     900      2079882 :   class const_and_copies *const_and_copies = new class const_and_copies ();
     901      2079882 :   need_eh_cleanup = BITMAP_ALLOC (NULL);
     902      2079882 :   need_noreturn_fixup.create (0);
     903              : 
     904      2079882 :   calculate_dominance_info (CDI_DOMINATORS);
     905      2079882 :   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      2079882 :   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      2079882 :   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      2079882 :   basic_block bb;
     932     23215489 :   FOR_EACH_BB_FN (bb, fun)
     933     21135607 :     record_edge_info (bb);
     934              : 
     935              :   /* Recursively walk the dominator tree optimizing statements.  */
     936      2079882 :   gimple_ranger *ranger = enable_ranger (fun);
     937      2079882 :   path_range_query path_query (*ranger);
     938      2079882 :   dom_jt_simplifier simplifier (avail_exprs_stack, ranger, &path_query);
     939      2079882 :   dom_jt_state state (const_and_copies, avail_exprs_stack);
     940      2079882 :   jump_threader threader (&simplifier, &state);
     941      2079882 :   dom_opt_dom_walker walker (CDI_DOMINATORS,
     942              :                              &threader,
     943              :                              &state,
     944              :                              ranger,
     945              :                              const_and_copies,
     946      2079882 :                              avail_exprs_stack);
     947      2079882 :   walker.walk (fun->cfg->x_entry_block_ptr);
     948              : 
     949      2079882 :   ranger->export_global_ranges ();
     950      2079882 :   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      2079882 :   if (cfg_altered)
     956              :     {
     957      4390176 :       FOR_EACH_BB_FN (bb, fun)
     958              :         {
     959      4332359 :           edge_iterator ei;
     960      4332359 :           edge e;
     961              : 
     962              :           /* First see if there are any edges without EDGE_EXECUTABLE
     963              :              set.  */
     964      4332359 :           bool found = false;
     965     10382684 :           FOR_EACH_EDGE (e, ei, bb->succs)
     966              :             {
     967      6256656 :               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      4332359 :           if (found)
     977       601700 :             FOR_EACH_EDGE (e, ei, bb->succs)
     978       395369 :               threader.remove_jump_threads_including (e);
     979              :         }
     980              :     }
     981              : 
     982      2079882 :   {
     983      2079882 :     gimple_stmt_iterator gsi;
     984      2079882 :     basic_block bb;
     985     23215489 :     FOR_EACH_BB_FN (bb, fun)
     986              :       {
     987    210685854 :         for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
     988    168414640 :           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      2079882 :   update_ssa (TODO_update_ssa);
     998              : 
     999      2079882 :   free_all_edge_infos ();
    1000              : 
    1001              :   /* Thread jumps, creating duplicate blocks as needed.  */
    1002      2079882 :   cfg_altered |= threader.thread_through_all_blocks (may_peel_loop_headers_p);
    1003              : 
    1004      2079882 :   if (cfg_altered)
    1005       131610 :     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      2079882 :   if (!bitmap_empty_p (need_eh_cleanup))
    1010              :     {
    1011          624 :       unsigned i;
    1012          624 :       bitmap_iterator bi;
    1013              : 
    1014              :       /* Jump threading may have created forwarder blocks from blocks
    1015              :          needing EH cleanup; the new successor of these blocks, which
    1016              :          has inherited from the original block, needs the cleanup.
    1017              :          Don't clear bits in the bitmap, as that can break the bitmap
    1018              :          iterator.  */
    1019         1996 :       EXECUTE_IF_SET_IN_BITMAP (need_eh_cleanup, 0, i, bi)
    1020              :         {
    1021         1372 :           basic_block bb = BASIC_BLOCK_FOR_FN (fun, i);
    1022         1372 :           if (bb == NULL)
    1023            0 :             continue;
    1024         2815 :           while (single_succ_p (bb)
    1025         1486 :                  && (single_succ_edge (bb)->flags
    1026          123 :                      & (EDGE_EH|EDGE_DFS_BACK)) == 0)
    1027          114 :             bb = single_succ (bb);
    1028         1372 :           if (bb == EXIT_BLOCK_PTR_FOR_FN (fun))
    1029           43 :             continue;
    1030         1329 :           if ((unsigned) bb->index != i)
    1031           55 :             bitmap_set_bit (need_eh_cleanup, bb->index);
    1032              :         }
    1033              : 
    1034          624 :       gimple_purge_all_dead_eh_edges (need_eh_cleanup);
    1035          624 :       bitmap_clear (need_eh_cleanup);
    1036              :     }
    1037              : 
    1038              :   /* Fixup stmts that became noreturn calls.  This may require splitting
    1039              :      blocks and thus isn't possible during the dominator walk or before
    1040              :      jump threading finished.  Do this in reverse order so we don't
    1041              :      inadvertently remove a stmt we want to fixup by visiting a dominating
    1042              :      now noreturn call first.  */
    1043      2079885 :   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      2079882 :   statistics_counter_event (fun, "Redundant expressions eliminated",
    1056      2079882 :                             opt_stats.num_re);
    1057      2079882 :   statistics_counter_event (fun, "Constants propagated",
    1058      2079882 :                             opt_stats.num_const_prop);
    1059      2079882 :   statistics_counter_event (fun, "Copies propagated",
    1060      2079882 :                             opt_stats.num_copy_prop);
    1061              : 
    1062              :   /* Debugging dumps.  */
    1063      2079882 :   if (dump_file && (dump_flags & TDF_STATS))
    1064           35 :     dump_dominator_optimization_stats (dump_file, avail_exprs);
    1065              : 
    1066      2079882 :   loop_optimizer_finalize ();
    1067              : 
    1068              :   /* Delete our main hashtable.  */
    1069      2079882 :   delete avail_exprs;
    1070      2079882 :   avail_exprs = NULL;
    1071              : 
    1072              :   /* Free asserted bitmaps and stacks.  */
    1073      2079882 :   BITMAP_FREE (need_eh_cleanup);
    1074      2079882 :   need_noreturn_fixup.release ();
    1075      2079882 :   delete avail_exprs_stack;
    1076      2079882 :   delete const_and_copies;
    1077              : 
    1078      2079882 :   return 0;
    1079      2079882 : }
    1080              : 
    1081              : } // anon namespace
    1082              : 
    1083              : gimple_opt_pass *
    1084       298828 : make_pass_dominator (gcc::context *ctxt)
    1085              : {
    1086       298828 :   return new pass_dominator (ctxt);
    1087              : }
    1088              : 
    1089              : /* Valueize hook for gimple_fold_stmt_to_constant_1.  */
    1090              : 
    1091              : static tree
    1092     33567969 : dom_valueize (tree t)
    1093              : {
    1094     33567969 :   if (TREE_CODE (t) == SSA_NAME)
    1095              :     {
    1096     24039440 :       tree tem = SSA_NAME_VALUE (t);
    1097     18984907 :       if (tem)
    1098      2973455 :         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     11846643 : back_propagate_equivalences (tree lhs, edge e,
    1108              :                              class const_and_copies *const_and_copies,
    1109              :                              bitmap domby)
    1110              : {
    1111     11846643 :   use_operand_p use_p;
    1112     11846643 :   imm_use_iterator iter;
    1113     11846643 :   basic_block dest = e->dest;
    1114     11846643 :   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     62376841 :   FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
    1123              :     {
    1124     38683555 :       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     38683555 :       if (dest == gimple_bb (use_stmt))
    1129       469896 :         continue;
    1130              : 
    1131              :       /* Filter out statements that can never produce a useful
    1132              :          equivalence.  */
    1133     38213659 :       tree lhs2 = gimple_get_lhs (use_stmt);
    1134     38213659 :       if (!lhs2 || TREE_CODE (lhs2) != SSA_NAME)
    1135     28305750 :         continue;
    1136              : 
    1137      9907909 :       if (domok)
    1138              :         {
    1139      5758426 :           if (!dominated_by_p (CDI_DOMINATORS, dest, gimple_bb (use_stmt)))
    1140      2894078 :             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      4149483 :           if (!bitmap_bit_p (domby, gimple_bb (use_stmt)->index))
    1150      3083400 :             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      3930431 :       tree res = gimple_fold_stmt_to_constant_1 (use_stmt, dom_valueize,
    1157              :                                                  no_follow_ssa_edges);
    1158      3930431 :       if (res && (TREE_CODE (res) == SSA_NAME || is_gimple_min_invariant (res)))
    1159      2295587 :         record_equality (lhs2, res, const_and_copies);
    1160     11846643 :     }
    1161     11846643 : }
    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     32467570 : 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     32467570 :   int i;
    1174     32467570 :   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     32467570 :   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     89849331 :       for (i = 0; edge_info->cond_equivalences.iterate (i, &eq); ++i)
    1184     66424716 :         avail_exprs_stack->record_cond (eq);
    1185              : 
    1186              :       edge_info::equiv_pair *seq;
    1187     35271258 :       for (i = 0; edge_info->simple_equivalences.iterate (i, &seq); ++i)
    1188              :         {
    1189     11846643 :           tree lhs = seq->first;
    1190     11846643 :           if (!lhs || TREE_CODE (lhs) != SSA_NAME)
    1191            0 :             continue;
    1192              : 
    1193              :           /* Record the simple NAME = VALUE equivalence.  */
    1194     11846643 :           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     11846643 :           if (TREE_CODE (lhs) == SSA_NAME && TREE_CODE (rhs) == SSA_NAME)
    1203              :             {
    1204      1692977 :               gimple *rhs_def = SSA_NAME_DEF_STMT (rhs);
    1205      1692977 :               int rhs_cost = estimate_num_insns (rhs_def, &eni_size_weights);
    1206              : 
    1207      1692977 :               gimple *lhs_def = SSA_NAME_DEF_STMT (lhs);
    1208      1692977 :               int lhs_cost = estimate_num_insns (lhs_def, &eni_size_weights);
    1209              : 
    1210      1692977 :               if (rhs_cost > lhs_cost)
    1211       186542 :                 record_equality (rhs, lhs, const_and_copies);
    1212      1506435 :               else if (rhs_cost < lhs_cost)
    1213       437329 :                 record_equality (lhs, rhs, const_and_copies);
    1214              :             }
    1215              :           else
    1216     10153666 :             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     11846643 :           back_propagate_equivalences (lhs, e, const_and_copies,
    1223              :                                        blocks_on_stack);
    1224              :         }
    1225              :     }
    1226     32467570 : }
    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     23144504 : record_equivalences_from_phis (basic_block bb)
    1236              : {
    1237     23144504 :   gphi_iterator gsi;
    1238              : 
    1239     32145735 :   for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); )
    1240              :     {
    1241      9001231 :       gphi *phi = gsi.phi ();
    1242              : 
    1243              :       /* We might eliminate the PHI, so advance GSI now.  */
    1244      9001231 :       gsi_next (&gsi);
    1245              : 
    1246      9001231 :       tree lhs = gimple_phi_result (phi);
    1247      9001231 :       tree rhs = NULL;
    1248      9001231 :       size_t i;
    1249              : 
    1250     16193908 :       for (i = 0; i < gimple_phi_num_args (phi); i++)
    1251              :         {
    1252     15267193 :           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     15267193 :           if (lhs == t)
    1258        29315 :             continue;
    1259              : 
    1260              :           /* If the associated edge is not marked as executable, then it
    1261              :              can be ignored.  */
    1262     15237878 :           if ((gimple_phi_arg_edge (phi, i)->flags & EDGE_EXECUTABLE) == 0)
    1263       115819 :             continue;
    1264              : 
    1265     15122059 :           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     15122059 :           if (TREE_CODE (t) == SSA_NAME
    1270     15122059 :               && (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     12145406 :           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      5606260 :           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      9001231 :       if (!rhs)
    1287      2462085 :         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      9001231 :       if (i == gimple_phi_num_args (phi))
    1296              :         {
    1297       926715 :           if (may_propagate_copy (lhs, rhs))
    1298       479818 :             set_ssa_name_value (lhs, rhs);
    1299       893794 :           else if (virtual_operand_p (lhs))
    1300              :             {
    1301       446574 :               gimple *use_stmt;
    1302       446574 :               imm_use_iterator iter;
    1303       446574 :               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      1767364 :               FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
    1307      2678830 :                 FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
    1308       902307 :                   SET_USE (use_p, rhs);
    1309       446574 :               if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
    1310           72 :                 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs) = 1;
    1311       446574 :               gimple_stmt_iterator tmp_gsi = gsi_for_stmt (phi);
    1312       446574 :               remove_phi_node (&tmp_gsi, true);
    1313              :             }
    1314              :         }
    1315              :     }
    1316     23144504 : }
    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       383744 : all_uses_feed_or_dominated_by_stmt (tree name, gimple *stmt)
    1323              : {
    1324       383744 :   use_operand_p use_p, use2_p;
    1325       383744 :   imm_use_iterator iter;
    1326       383744 :   basic_block stmt_bb = gimple_bb (stmt);
    1327              : 
    1328      1908140 :   FOR_EACH_IMM_USE_FAST (use_p, iter, name)
    1329              :     {
    1330      1353323 :       gimple *use_stmt = USE_STMT (use_p), *use_stmt2;
    1331      2485849 :       if (use_stmt == stmt
    1332      1228722 :           || is_gimple_debug (use_stmt)
    1333      2033150 :           || (gimple_bb (use_stmt) != stmt_bb
    1334       521706 :               && dominated_by_p (CDI_DOMINATORS,
    1335       521706 :                                  gimple_bb (use_stmt), stmt_bb)))
    1336      1132526 :         continue;
    1337              :       while (use_stmt != stmt
    1338       428071 :              && is_gimple_assign (use_stmt)
    1339       378040 :              && TREE_CODE (gimple_assign_lhs (use_stmt)) == SSA_NAME
    1340       802380 :              && single_imm_use (gimple_assign_lhs (use_stmt),
    1341              :                                 &use2_p, &use_stmt2))
    1342       215400 :         use_stmt = use_stmt2;
    1343       220797 :       if (use_stmt != stmt)
    1344       212671 :         return false;
    1345       212671 :     }
    1346       171073 :   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       153727 : maybe_set_nonzero_bits (edge e, tree var)
    1364              : {
    1365       153727 :   basic_block cond_bb = e->src;
    1366       307454 :   gcond *cond = safe_dyn_cast <gcond *> (*gsi_last_bb (cond_bb));
    1367       153727 :   tree cst;
    1368              : 
    1369       153727 :   if (cond == NULL
    1370       153727 :       || gimple_cond_code (cond) != ((e->flags & EDGE_TRUE_VALUE)
    1371       153727 :                                      ? EQ_EXPR : NE_EXPR)
    1372        46829 :       || TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
    1373         1695 :       || !integer_zerop (gimple_cond_rhs (cond)))
    1374       152188 :     return;
    1375              : 
    1376         1539 :   gimple *stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (cond));
    1377         1539 :   if (!is_gimple_assign (stmt)
    1378         1517 :       || gimple_assign_rhs_code (stmt) != BIT_AND_EXPR
    1379         1556 :       || 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     23144504 : dom_opt_dom_walker::set_global_ranges_from_unreachable_edges (basic_block bb)
    1429              : {
    1430     23144504 :   edge pred_e = single_pred_edge_ignoring_loop_edges (bb, false);
    1431     23144504 :   if (!pred_e)
    1432              :     return;
    1433              : 
    1434     17188986 :   gimple *stmt = *gsi_last_bb (pred_e->src);
    1435     17188986 :   if (!stmt
    1436     14413717 :       || gimple_code (stmt) != GIMPLE_COND
    1437     29128770 :       || !assert_unreachable_fallthru_edge_p (pred_e))
    1438     16979099 :     return;
    1439              : 
    1440              :   // Bail if the condition leading to the unreachable edge has 2 ssa-names.
    1441              :   // See PR 125501.
    1442       209887 :   if ((TREE_CODE (gimple_cond_lhs (stmt)) == SSA_NAME
    1443       209887 :       && TREE_CODE (gimple_cond_rhs (stmt)) == SSA_NAME))
    1444              :     return;
    1445              : 
    1446       207689 :   tree name;
    1447       591433 :   FOR_EACH_GORI_EXPORT_NAME (m_ranger->gori_ssa (), pred_e->src, name)
    1448       383744 :     if (all_uses_feed_or_dominated_by_stmt (name, stmt)
    1449              :         // The condition must post-dominate the definition point.
    1450       554817 :         && (SSA_NAME_IS_DEFAULT_DEF (name)
    1451       170961 :             || (gimple_bb (SSA_NAME_DEF_STMT (name))
    1452       170961 :                 == pred_e->src)))
    1453              :       {
    1454       166321 :         value_range r (TREE_TYPE (name));
    1455              : 
    1456       166321 :         if (m_ranger->range_on_edge (r, pred_e, name)
    1457       166321 :             && !r.varying_p ()
    1458       320117 :             && !r.undefined_p ())
    1459              :           {
    1460       153727 :             set_range_info (name, r);
    1461       153727 :             maybe_set_nonzero_bits (pred_e, name);
    1462              :           }
    1463       166321 :       }
    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     23144504 : 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     23144504 :   edge e;
    1477     23144504 :   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     23144504 :   parent = get_immediate_dominator (CDI_DOMINATORS, bb);
    1483              : 
    1484     23144504 :   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     23144504 :   if (e && e->src == parent)
    1489     17194882 :     record_temporary_equivalences (e, const_and_copies, avail_exprs_stack,
    1490              :                                    blocks_on_stack);
    1491     23144504 : }
    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     13073124 : record_equality (tree x, tree y, class const_and_copies *const_and_copies)
    1528              : {
    1529     13073124 :   tree prev_x = NULL, prev_y = NULL;
    1530              : 
    1531     13073124 :   if (tree_swap_operands_p (x, y))
    1532       597804 :     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     13073124 :   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      1078669 :       if (has_single_use (y) && ! has_single_use (x))
    1546              :         std::swap (x, y);
    1547              :     }
    1548     13073124 :   if (TREE_CODE (x) == SSA_NAME)
    1549     13073124 :     prev_x = SSA_NAME_VALUE (x);
    1550     13073124 :   if (TREE_CODE (y) == SSA_NAME)
    1551      1078669 :     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     13073124 :   if (is_gimple_min_invariant (y))
    1558              :     ;
    1559      1078669 :   else if (is_gimple_min_invariant (x))
    1560              :     prev_x = x, x = y, y = prev_x, prev_x = prev_y;
    1561      1078669 :   else if (prev_x && is_gimple_min_invariant (prev_x))
    1562              :     x = y, y = prev_x, prev_x = prev_y;
    1563       992130 :   else if (prev_y)
    1564     13073124 :     y = prev_y;
    1565              : 
    1566              :   /* After the swapping, we must have one SSA_NAME.  */
    1567     13073124 :   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     13073124 :   if (HONOR_SIGNED_ZEROS (x)
    1575     13073124 :       && (TREE_CODE (y) != REAL_CST
    1576       170713 :           || real_equal (&dconst0, &TREE_REAL_CST (y))))
    1577          502 :     return;
    1578              : 
    1579     13072622 :   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     42213864 : simple_iv_increment_p (gimple *stmt)
    1593              : {
    1594     42213864 :   enum tree_code code;
    1595     42213864 :   tree lhs, preinc;
    1596     42213864 :   gimple *phi;
    1597     42213864 :   size_t i;
    1598              : 
    1599     42213864 :   if (gimple_code (stmt) != GIMPLE_ASSIGN)
    1600              :     return false;
    1601              : 
    1602     32475549 :   lhs = gimple_assign_lhs (stmt);
    1603     32475549 :   if (TREE_CODE (lhs) != SSA_NAME)
    1604              :     return false;
    1605              : 
    1606     32475549 :   code = gimple_assign_rhs_code (stmt);
    1607     32475549 :   if (code != PLUS_EXPR
    1608     32475549 :       && code != MINUS_EXPR
    1609     32475549 :       && code != POINTER_PLUS_EXPR)
    1610              :     return false;
    1611              : 
    1612      7843109 :   preinc = gimple_assign_rhs1 (stmt);
    1613      7843109 :   if (TREE_CODE (preinc) != SSA_NAME)
    1614              :     return false;
    1615              : 
    1616      7568918 :   phi = SSA_NAME_DEF_STMT (preinc);
    1617      7593691 :   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      5148984 :       if (!gimple_assign_ssa_name_copy_p (phi))
    1622              :         return false;
    1623        24773 :       preinc = gimple_assign_rhs1 (phi);
    1624        24773 :       phi = SSA_NAME_DEF_STMT (preinc);
    1625              :     }
    1626              : 
    1627      4803542 :   for (i = 0; i < gimple_phi_num_args (phi); i++)
    1628      3882998 :     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     23144504 : cprop_into_successor_phis (basic_block bb,
    1639              :                            class const_and_copies *const_and_copies)
    1640              : {
    1641     23144504 :   edge e;
    1642     23144504 :   edge_iterator ei;
    1643              : 
    1644     54940718 :   FOR_EACH_EDGE (e, ei, bb->succs)
    1645              :     {
    1646     31796214 :       int indx;
    1647     31796214 :       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     31796214 :       if (e->flags & EDGE_ABNORMAL)
    1652     18759312 :         continue;
    1653              : 
    1654     31782220 :       gsi = gsi_start_phis (e->dest);
    1655     31782220 :       if (gsi_end_p (gsi))
    1656     18745318 :         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     13036902 :       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     13036902 :       class edge_info *edge_info = (class edge_info *) e->aux;
    1671              : 
    1672     13036902 :       if (edge_info)
    1673              :         {
    1674              :           edge_info::equiv_pair *seq;
    1675      8182129 :           for (int i = 0; edge_info->simple_equivalences.iterate (i, &seq); ++i)
    1676              :             {
    1677      3118048 :               tree lhs = seq->first;
    1678      3118048 :               tree rhs = seq->second;
    1679              : 
    1680      3118048 :               if (lhs && TREE_CODE (lhs) == SSA_NAME)
    1681      3118048 :                 const_and_copies->record_const_or_copy (lhs, rhs);
    1682              :             }
    1683              : 
    1684              :         }
    1685              : 
    1686     13036902 :       indx = e->dest_idx;
    1687     35607760 :       for ( ; !gsi_end_p (gsi); gsi_next (&gsi))
    1688              :         {
    1689     22570858 :           tree new_val;
    1690     22570858 :           use_operand_p orig_p;
    1691     22570858 :           tree orig_val;
    1692     22570858 :           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     22570858 :           orig_p = gimple_phi_arg_imm_use_ptr (phi, indx);
    1697     22570858 :           orig_val = get_use_from_ptr (orig_p);
    1698     22570858 :           if (TREE_CODE (orig_val) != SSA_NAME)
    1699      3137360 :             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     19433498 :           new_val = SSA_NAME_VALUE (orig_val);
    1704     19433498 :           if (new_val
    1705     19433498 :               && new_val != orig_val
    1706     19433498 :               && may_propagate_copy (orig_val, new_val))
    1707      1036294 :             propagate_value (orig_p, new_val);
    1708              :         }
    1709              : 
    1710     13036902 :       const_and_copies->pop_to_marker ();
    1711              :     }
    1712     23144504 : }
    1713              : 
    1714              : edge
    1715     23144504 : dom_opt_dom_walker::before_dom_children (basic_block bb)
    1716              : {
    1717     23144504 :   gimple_stmt_iterator gsi;
    1718              : 
    1719     23144504 :   if (dump_file && (dump_flags & TDF_DETAILS))
    1720          742 :     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     23144504 :   m_avail_exprs_stack->push_marker ();
    1725     23144504 :   m_const_and_copies->push_marker ();
    1726     23144504 :   bitmap_set_bit (m_state->get_blocks_on_stack (), bb->index);
    1727              : 
    1728     23144504 :   record_equivalences_from_incoming_edge (bb, m_const_and_copies,
    1729              :                                           m_avail_exprs_stack,
    1730     23144504 :                                           m_state->get_blocks_on_stack ());
    1731     23144504 :   set_global_ranges_from_unreachable_edges (bb);
    1732              : 
    1733              :   /* PHI nodes can create equivalences too.  */
    1734     23144504 :   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     23144504 :   m_avail_exprs_stack->push_marker ();
    1740     31699161 :   for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    1741      8554657 :     eliminate_redundant_computations (&gsi, m_const_and_copies,
    1742              :                                       m_avail_exprs_stack);
    1743     23144504 :   m_avail_exprs_stack->pop_to_marker ();
    1744              : 
    1745     23144504 :   edge taken_edge = NULL;
    1746              :   /* Initialize visited flag ahead of us, it has undefined state on
    1747              :      pass entry.  */
    1748    213973232 :   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    1749    167684224 :     gimple_set_visited (gsi_stmt (gsi), false);
    1750    358390954 :   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    335246450 :       if (gimple_visited_p (gsi_stmt (gsi)))
    1755              :         {
    1756    167562025 :           gsi_next (&gsi);
    1757    167562025 :           continue;
    1758              :         }
    1759              : 
    1760    167684425 :       bool removed_p = false;
    1761    167684425 :       taken_edge = this->optimize_stmt (bb, &gsi, &removed_p);
    1762    167684425 :       if (!removed_p)
    1763    167562025 :         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    167684425 :       if (gsi_end_p (gsi))
    1768              :         {
    1769         2788 :           gcc_checking_assert (removed_p);
    1770         2788 :           gsi = gsi_last_bb (bb);
    1771         5176 :           while (!gsi_end_p (gsi) && !gimple_visited_p (gsi_stmt (gsi)))
    1772         2788 :             gsi_prev (&gsi);
    1773              :         }
    1774              :       else
    1775              :         {
    1776    167681838 :           do
    1777              :             {
    1778    167681838 :               gsi_prev (&gsi);
    1779              :             }
    1780    335363475 :           while (!gsi_end_p (gsi) && !gimple_visited_p (gsi_stmt (gsi)));
    1781              :         }
    1782    167684425 :       if (gsi_end_p (gsi))
    1783     38094900 :         gsi = gsi_start_bb (bb);
    1784              :       else
    1785    148636975 :         gsi_next (&gsi);
    1786              :     }
    1787              : 
    1788              :   /* Now prepare to process dominated blocks.  */
    1789     23144504 :   record_edge_info (bb);
    1790     23144504 :   cprop_into_successor_phis (bb, m_const_and_copies);
    1791     23144504 :   if (taken_edge && !dbg_cnt (dom_unreachable_edges))
    1792              :     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     23144504 : dom_opt_dom_walker::after_dom_children (basic_block bb)
    1803              : {
    1804     23144504 :   m_threader->thread_outgoing_edges (bb);
    1805     23144504 :   bitmap_clear_bit (m_state->get_blocks_on_stack (), bb->index);
    1806     23144504 :   m_avail_exprs_stack->pop_to_marker ();
    1807     23144504 :   m_const_and_copies->pop_to_marker ();
    1808     23144504 : }
    1809              : 
    1810              : /* Search for redundant computations in STMT.  If any are found, then
    1811              :    replace them with the variable holding the result of the computation.
    1812              : 
    1813              :    If safe, record this expression into AVAIL_EXPRS_STACK and
    1814              :    CONST_AND_COPIES.  */
    1815              : 
    1816              : static void
    1817     62568339 : eliminate_redundant_computations (gimple_stmt_iterator* gsi,
    1818              :                                   class const_and_copies *const_and_copies,
    1819              :                                   class avail_exprs_stack *avail_exprs_stack)
    1820              : {
    1821     62568339 :   tree expr_type;
    1822     62568339 :   tree cached_lhs;
    1823     62568339 :   tree def;
    1824     62568339 :   bool insert = true;
    1825     62568339 :   bool assigns_var_p = false;
    1826              : 
    1827     62568339 :   gimple *stmt = gsi_stmt (*gsi);
    1828              : 
    1829     62568339 :   if (gimple_code (stmt) == GIMPLE_PHI)
    1830      8554657 :     def = gimple_phi_result (stmt);
    1831              :   else
    1832     54013682 :     def = gimple_get_lhs (stmt);
    1833              : 
    1834              :   /* Certain expressions on the RHS can be optimized away, but cannot
    1835              :      themselves be entered into the hash tables.  */
    1836     62568339 :   if (! def
    1837     53708146 :       || TREE_CODE (def) != SSA_NAME
    1838     41134032 :       || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def)
    1839     32578092 :       || gimple_vdef (stmt)
    1840              :       /* Do not record equivalences for increments of ivs.  This would create
    1841              :          overlapping live ranges for a very questionable gain.  */
    1842    103691653 :       || simple_iv_increment_p (stmt))
    1843              :     insert = false;
    1844              : 
    1845              :   /* Check if the expression has been computed before.  */
    1846     62568339 :   cached_lhs = avail_exprs_stack->lookup_avail_expr (stmt, insert, true);
    1847              : 
    1848     62568339 :   opt_stats.num_exprs_considered++;
    1849              : 
    1850              :   /* Get the type of the expression we are trying to optimize.  */
    1851     62568339 :   if (is_gimple_assign (stmt))
    1852              :     {
    1853     43911601 :       expr_type = TREE_TYPE (gimple_assign_lhs (stmt));
    1854     43911601 :       assigns_var_p = true;
    1855              :     }
    1856     18656738 :   else if (gimple_code (stmt) == GIMPLE_COND)
    1857      8825745 :     expr_type = boolean_type_node;
    1858      9830993 :   else if (is_gimple_call (stmt))
    1859              :     {
    1860      1241888 :       gcc_assert (gimple_call_lhs (stmt));
    1861      1241888 :       expr_type = TREE_TYPE (gimple_call_lhs (stmt));
    1862      1241888 :       assigns_var_p = true;
    1863              :     }
    1864      8589105 :   else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt))
    1865        34448 :     expr_type = TREE_TYPE (gimple_switch_index (swtch_stmt));
    1866      8554657 :   else if (gimple_code (stmt) == GIMPLE_PHI)
    1867              :     /* We can't propagate into a phi, so the logic below doesn't apply.
    1868              :        Instead record an equivalence between the cached LHS and the
    1869              :        PHI result of this statement, provided they are in the same block.
    1870              :        This should be sufficient to kill the redundant phi.  */
    1871              :     {
    1872      8554657 :       if (def && cached_lhs)
    1873        18842 :         const_and_copies->record_const_or_copy (def, cached_lhs);
    1874      8554657 :       return;
    1875              :     }
    1876              :   else
    1877            0 :     gcc_unreachable ();
    1878              : 
    1879     54013682 :   if (!cached_lhs)
    1880              :     return;
    1881              : 
    1882              :   /* It is safe to ignore types here since we have already done
    1883              :      type checking in the hashing and equality routines.  In fact
    1884              :      type checking here merely gets in the way of constant
    1885              :      propagation.  Also, make sure that it is safe to propagate
    1886              :      CACHED_LHS into the expression in STMT.  */
    1887       426329 :   if ((TREE_CODE (cached_lhs) != SSA_NAME
    1888        41060 :        && (assigns_var_p
    1889         6363 :            || useless_type_conversion_p (expr_type, TREE_TYPE (cached_lhs))))
    1890       426329 :       || may_propagate_copy_into_stmt (stmt, cached_lhs))
    1891              :   {
    1892       412850 :       gcc_checking_assert (TREE_CODE (cached_lhs) == SSA_NAME
    1893              :                            || is_gimple_min_invariant (cached_lhs));
    1894              : 
    1895       412850 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1896              :         {
    1897           16 :           fprintf (dump_file, "  Replaced redundant expr '");
    1898           16 :           print_gimple_expr (dump_file, stmt, 0, dump_flags);
    1899           16 :           fprintf (dump_file, "' with '");
    1900           16 :           print_generic_expr (dump_file, cached_lhs, dump_flags);
    1901           16 :           fprintf (dump_file, "'\n");
    1902              :         }
    1903              : 
    1904       412850 :       opt_stats.num_re++;
    1905              : 
    1906       412850 :       if (assigns_var_p
    1907       412850 :           && !useless_type_conversion_p (expr_type, TREE_TYPE (cached_lhs)))
    1908            0 :         cached_lhs = fold_convert (expr_type, cached_lhs);
    1909              : 
    1910       412850 :       propagate_tree_value_into_stmt (gsi, cached_lhs);
    1911              : 
    1912              :       /* Since it is always necessary to mark the result as modified,
    1913              :          perhaps we should move this into propagate_tree_value_into_stmt
    1914              :          itself.  */
    1915       412850 :       gimple_set_modified (gsi_stmt (*gsi), true);
    1916              :   }
    1917              : }
    1918              : 
    1919              : /* STMT, a GIMPLE_ASSIGN, may create certain equivalences, in either
    1920              :    the available expressions table or the const_and_copies table.
    1921              :    Detect and record those equivalences into AVAIL_EXPRS_STACK.
    1922              : 
    1923              :    We handle only very simple copy equivalences here.  The heavy
    1924              :    lifing is done by eliminate_redundant_computations.  */
    1925              : 
    1926              : static void
    1927     47250123 : record_equivalences_from_stmt (gimple *stmt, int may_optimize_p,
    1928              :                                class avail_exprs_stack *avail_exprs_stack)
    1929              : {
    1930     47250123 :   tree lhs;
    1931     47250123 :   enum tree_code lhs_code;
    1932              : 
    1933     47250123 :   gcc_assert (is_gimple_assign (stmt));
    1934              : 
    1935     47250123 :   lhs = gimple_assign_lhs (stmt);
    1936     47250123 :   lhs_code = TREE_CODE (lhs);
    1937              : 
    1938     47250123 :   if (lhs_code == SSA_NAME
    1939     47250123 :       && gimple_assign_single_p (stmt))
    1940              :     {
    1941     15481580 :       tree rhs = gimple_assign_rhs1 (stmt);
    1942              : 
    1943              :       /* If the RHS of the assignment is a constant or another variable that
    1944              :          may be propagated, register it in the CONST_AND_COPIES table.  We
    1945              :          do not need to record unwind data for this, since this is a true
    1946              :          assignment and not an equivalence inferred from a comparison.  All
    1947              :          uses of this ssa name are dominated by this assignment, so unwinding
    1948              :          just costs time and space.  */
    1949     15481580 :       if (may_optimize_p
    1950     15481580 :           && (TREE_CODE (rhs) == SSA_NAME
    1951     13458534 :               || is_gimple_min_invariant (rhs)))
    1952              :         {
    1953      1980106 :           rhs = dom_valueize (rhs);
    1954              : 
    1955      1980106 :           if (dump_file && (dump_flags & TDF_DETAILS))
    1956              :             {
    1957           74 :               fprintf (dump_file, "==== ASGN ");
    1958           74 :               print_generic_expr (dump_file, lhs);
    1959           74 :               fprintf (dump_file, " = ");
    1960           74 :               print_generic_expr (dump_file, rhs);
    1961           74 :               fprintf (dump_file, "\n");
    1962              :             }
    1963              : 
    1964      1980106 :           set_ssa_name_value (lhs, rhs);
    1965              :         }
    1966              :     }
    1967              : 
    1968              :   /* Make sure we can propagate &x + CST.  */
    1969     47250123 :   if (lhs_code == SSA_NAME
    1970     31972646 :       && gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR
    1971      1610281 :       && TREE_CODE (gimple_assign_rhs1 (stmt)) == ADDR_EXPR
    1972     47438502 :       && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST)
    1973              :     {
    1974         5303 :       tree op0 = gimple_assign_rhs1 (stmt);
    1975         5303 :       tree op1 = gimple_assign_rhs2 (stmt);
    1976         5303 :       tree new_rhs
    1977        10606 :         = build1 (ADDR_EXPR, TREE_TYPE (op0),
    1978         5303 :                   fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (op0)),
    1979              :                                unshare_expr (op0), fold_convert (ptr_type_node,
    1980              :                                                                  op1)));
    1981         5303 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1982              :         {
    1983            0 :           fprintf (dump_file, "==== ASGN ");
    1984            0 :           print_generic_expr (dump_file, lhs);
    1985            0 :           fprintf (dump_file, " = ");
    1986            0 :           print_generic_expr (dump_file, new_rhs);
    1987            0 :           fprintf (dump_file, "\n");
    1988              :         }
    1989              : 
    1990         5303 :       set_ssa_name_value (lhs, new_rhs);
    1991              :     }
    1992              : 
    1993              :   /* A memory store, even an aliased store, creates a useful
    1994              :      equivalence.  By exchanging the LHS and RHS, creating suitable
    1995              :      vops and recording the result in the available expression table,
    1996              :      we may be able to expose more redundant loads.  */
    1997     91044790 :   if (!gimple_has_volatile_ops (stmt)
    1998     71049905 :       && gimple_references_memory_p (stmt)
    1999     23799782 :       && gimple_assign_single_p (stmt)
    2000     23799782 :       && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
    2001     18600450 :           || is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
    2002     58692183 :       && !is_gimple_reg (lhs))
    2003              :     {
    2004     11272159 :       tree rhs = gimple_assign_rhs1 (stmt);
    2005     11272159 :       gassign *new_stmt;
    2006              : 
    2007              :       /* Build a new statement with the RHS and LHS exchanged.  */
    2008     11272159 :       if (TREE_CODE (rhs) == SSA_NAME)
    2009              :         {
    2010              :           /* NOTE tuples.  The call to gimple_build_assign below replaced
    2011              :              a call to build_gimple_modify_stmt, which did not set the
    2012              :              SSA_NAME_DEF_STMT on the LHS of the assignment.  Doing so
    2013              :              may cause an SSA validation failure, as the LHS may be a
    2014              :              default-initialized name and should have no definition.  I'm
    2015              :              a bit dubious of this, as the artificial statement that we
    2016              :              generate here may in fact be ill-formed, but it is simply
    2017              :              used as an internal device in this pass, and never becomes
    2018              :              part of the CFG.  */
    2019      5059549 :           gimple *defstmt = SSA_NAME_DEF_STMT (rhs);
    2020      5059549 :           new_stmt = gimple_build_assign (rhs, lhs);
    2021      5059549 :           SSA_NAME_DEF_STMT (rhs) = defstmt;
    2022              :         }
    2023              :       else
    2024      6212610 :         new_stmt = gimple_build_assign (rhs, lhs);
    2025              : 
    2026     22544318 :       gimple_set_vuse (new_stmt, gimple_vdef (stmt));
    2027              : 
    2028              :       /* Finally enter the statement into the available expression
    2029              :          table.  */
    2030     11272159 :       avail_exprs_stack->lookup_avail_expr (new_stmt, true, true);
    2031              :     }
    2032     47250123 : }
    2033              : 
    2034              : /* Replace *OP_P in STMT with any known equivalent value for *OP_P from
    2035              :    CONST_AND_COPIES.  */
    2036              : 
    2037              : static void
    2038     78697744 : cprop_operand (gimple *stmt, use_operand_p op_p, range_query *query)
    2039              : {
    2040     78697744 :   tree val;
    2041     78697744 :   tree op = USE_FROM_PTR (op_p);
    2042              : 
    2043              :   /* If the operand has a known constant value or it is known to be a
    2044              :      copy of some other variable, use the value or copy stored in
    2045              :      CONST_AND_COPIES.  */
    2046     78697744 :   val = SSA_NAME_VALUE (op);
    2047     52772744 :   if (!val)
    2048              :     {
    2049     74851395 :       value_range r (TREE_TYPE (op));
    2050     74851395 :       tree single;
    2051    147401816 :       if (query->range_of_expr (r, op, stmt) && r.singleton_p (&single))
    2052        23726 :         val = single;
    2053     74851395 :     }
    2054              : 
    2055     78697744 :   if (val && val != op)
    2056              :     {
    2057              :       /* Certain operands are not allowed to be copy propagated due
    2058              :          to their interaction with exception handling and some GCC
    2059              :          extensions.  */
    2060      3868458 :       if (!may_propagate_copy (op, val))
    2061              :         return;
    2062              : 
    2063              :       /* Do not propagate copies into BIVs.
    2064              :          See PR23821 and PR62217 for how this can disturb IV and
    2065              :          number of iteration analysis.  */
    2066      3866895 :       if (TREE_CODE (val) != INTEGER_CST)
    2067              :         {
    2068      3156799 :           gimple *def = SSA_NAME_DEF_STMT (op);
    2069      3156799 :           if (gimple_code (def) == GIMPLE_PHI
    2070      3156799 :               && gimple_bb (def)->loop_father->header == gimple_bb (def))
    2071              :             return;
    2072              :         }
    2073              : 
    2074              :       /* Dump details.  */
    2075      3856224 :       if (dump_file && (dump_flags & TDF_DETAILS))
    2076              :         {
    2077           76 :           fprintf (dump_file, "  Replaced '");
    2078           76 :           print_generic_expr (dump_file, op, dump_flags);
    2079           76 :           fprintf (dump_file, "' with %s '",
    2080           76 :                    (TREE_CODE (val) != SSA_NAME ? "constant" : "variable"));
    2081           76 :           print_generic_expr (dump_file, val, dump_flags);
    2082           76 :           fprintf (dump_file, "'\n");
    2083              :         }
    2084              : 
    2085      3856224 :       if (TREE_CODE (val) != SSA_NAME)
    2086       884537 :         opt_stats.num_const_prop++;
    2087              :       else
    2088      2971687 :         opt_stats.num_copy_prop++;
    2089              : 
    2090      3856224 :       propagate_value (op_p, val);
    2091              : 
    2092              :       /* And note that we modified this statement.  This is now
    2093              :          safe, even if we changed virtual operands since we will
    2094              :          rescan the statement and rewrite its operands again.  */
    2095      3856224 :       gimple_set_modified (stmt, true);
    2096              :     }
    2097              : }
    2098              : 
    2099              : /* CONST_AND_COPIES is a table which maps an SSA_NAME to the current
    2100              :    known value for that SSA_NAME (or NULL if no value is known).
    2101              : 
    2102              :    Propagate values from CONST_AND_COPIES into the uses, vuses and
    2103              :    vdef_ops of STMT.  */
    2104              : 
    2105              : static void
    2106    167684425 : cprop_into_stmt (gimple *stmt, range_query *query)
    2107              : {
    2108    167684425 :   use_operand_p op_p;
    2109    167684425 :   ssa_op_iter iter;
    2110    167684425 :   tree last_copy_propagated_op = NULL;
    2111              : 
    2112    246382767 :   FOR_EACH_SSA_USE_OPERAND (op_p, stmt, iter, SSA_OP_USE)
    2113              :     {
    2114     78698342 :       tree old_op = USE_FROM_PTR (op_p);
    2115              : 
    2116              :       /* If we have A = B and B = A in the copy propagation tables
    2117              :          (due to an equality comparison), avoid substituting B for A
    2118              :          then A for B in the trivially discovered cases.   This allows
    2119              :          optimization of statements were A and B appear as input
    2120              :          operands.  */
    2121     78698342 :       if (old_op != last_copy_propagated_op)
    2122              :         {
    2123     78697744 :           cprop_operand (stmt, op_p, query);
    2124              : 
    2125     78697744 :           tree new_op = USE_FROM_PTR (op_p);
    2126     78697744 :           if (new_op != old_op && TREE_CODE (new_op) == SSA_NAME)
    2127     78698342 :             last_copy_propagated_op = new_op;
    2128              :         }
    2129              :     }
    2130    167684425 : }
    2131              : 
    2132              : /* If STMT contains a relational test, try to convert it into an
    2133              :    equality test if there is only a single value which can ever
    2134              :    make the test true.
    2135              : 
    2136              :    For example, if the expression hash table contains:
    2137              : 
    2138              :     TRUE = (i <= 1)
    2139              : 
    2140              :    And we have a test within statement of i >= 1, then we can safely
    2141              :    rewrite the test as i == 1 since there only a single value where
    2142              :    the test is true.
    2143              : 
    2144              :    This is similar to code in VRP.  */
    2145              : 
    2146              : void
    2147     53891282 : dom_opt_dom_walker::test_for_singularity (gimple *stmt,
    2148              :                                           avail_exprs_stack *avail_exprs_stack)
    2149              : {
    2150              :   /* We want to support gimple conditionals as well as assignments
    2151              :      where the RHS contains a conditional.  */
    2152     53891282 :   if (is_gimple_assign (stmt) || gimple_code (stmt) == GIMPLE_COND)
    2153              :     {
    2154     52620412 :       enum tree_code code = ERROR_MARK;
    2155     52620412 :       tree lhs, rhs;
    2156              : 
    2157              :       /* Extract the condition of interest from both forms we support.  */
    2158     52620412 :       if (is_gimple_assign (stmt))
    2159              :         {
    2160     43794667 :           code = gimple_assign_rhs_code (stmt);
    2161     43794667 :           lhs = gimple_assign_rhs1 (stmt);
    2162     43794667 :           rhs = gimple_assign_rhs2 (stmt);
    2163              :         }
    2164      8825745 :       else if (gimple_code (stmt) == GIMPLE_COND)
    2165              :         {
    2166      8825745 :           code = gimple_cond_code (as_a <gcond *> (stmt));
    2167      8825745 :           lhs = gimple_cond_lhs (as_a <gcond *> (stmt));
    2168      8825745 :           rhs = gimple_cond_rhs (as_a <gcond *> (stmt));
    2169              :         }
    2170              : 
    2171              :       /* We're looking for a relational test using LE/GE.  Also note we can
    2172              :          canonicalize LT/GT tests against constants into LE/GT tests.  */
    2173     52620412 :       if (code == LE_EXPR || code == GE_EXPR
    2174     51961848 :           || ((code == LT_EXPR || code == GT_EXPR)
    2175      1676255 :                && TREE_CODE (rhs) == INTEGER_CST))
    2176              :         {
    2177              :           /* For LT_EXPR and GT_EXPR, canonicalize to LE_EXPR and GE_EXPR.  */
    2178       877996 :           if (code == LT_EXPR)
    2179       132027 :             rhs = fold_build2 (MINUS_EXPR, TREE_TYPE (rhs),
    2180              :                                rhs, build_int_cst (TREE_TYPE (rhs), 1));
    2181              : 
    2182      1536560 :           if (code == GT_EXPR)
    2183       745969 :             rhs = fold_build2 (PLUS_EXPR, TREE_TYPE (rhs),
    2184              :                                rhs, build_int_cst (TREE_TYPE (rhs), 1));
    2185              : 
    2186              :           /* Determine the code we want to check for in the hash table.  */
    2187      1536560 :           enum tree_code test_code;
    2188      1536560 :           if (code == GE_EXPR || code == GT_EXPR)
    2189              :             test_code = LE_EXPR;
    2190              :           else
    2191       532547 :             test_code = GE_EXPR;
    2192              : 
    2193              :           /* Update the dummy statement so we can query the hash tables.  */
    2194      1536560 :           gimple_cond_set_code (m_dummy_cond, test_code);
    2195      1536560 :           gimple_cond_set_lhs (m_dummy_cond, lhs);
    2196      1536560 :           gimple_cond_set_rhs (m_dummy_cond, rhs);
    2197      1536560 :           tree cached_lhs
    2198      1536560 :             = avail_exprs_stack->lookup_avail_expr (m_dummy_cond,
    2199              :                                                     false, false);
    2200              : 
    2201              :           /* If the lookup returned 1 (true), then the expression we
    2202              :              queried was in the hash table.  As a result there is only
    2203              :              one value that makes the original conditional true.  Update
    2204              :              STMT accordingly.  */
    2205      1536560 :           if (cached_lhs && integer_onep (cached_lhs))
    2206              :             {
    2207         1359 :               if (is_gimple_assign (stmt))
    2208              :                 {
    2209           97 :                   gimple_assign_set_rhs_code (stmt, EQ_EXPR);
    2210           97 :                   gimple_assign_set_rhs2 (stmt, rhs);
    2211           97 :                   gimple_set_modified (stmt, true);
    2212              :                 }
    2213              :               else
    2214              :                 {
    2215         1262 :                   gimple_set_modified (stmt, true);
    2216         1262 :                   gimple_cond_set_code (as_a <gcond *> (stmt), EQ_EXPR);
    2217         1262 :                   gimple_cond_set_rhs (as_a <gcond *> (stmt), rhs);
    2218         1262 :                   gimple_set_modified (stmt, true);
    2219              :                 }
    2220              :             }
    2221              :         }
    2222              :     }
    2223     53891282 : }
    2224              : 
    2225              : /* If STMT is a comparison of two uniform vectors reduce it to a comparison
    2226              :    of scalar objects, otherwise leave STMT unchanged.  */
    2227              : 
    2228              : static void
    2229    167684425 : reduce_vector_comparison_to_scalar_comparison (gimple *stmt)
    2230              : {
    2231    167684425 :   if (gimple_code (stmt) == GIMPLE_COND)
    2232              :     {
    2233      8924635 :       tree lhs = gimple_cond_lhs (stmt);
    2234      8924635 :       tree rhs = gimple_cond_rhs (stmt);
    2235              : 
    2236              :       /* We may have a vector comparison where both arms are uniform
    2237              :          vectors.  If so, we can simplify the vector comparison down
    2238              :          to a scalar comparison.  */
    2239      8924635 :       if (VECTOR_TYPE_P (TREE_TYPE (lhs))
    2240      8924635 :           && VECTOR_TYPE_P (TREE_TYPE (rhs)))
    2241              :         {
    2242              :           /* If either operand is an SSA_NAME, then look back to its
    2243              :              defining statement to try and get at a suitable source.  */
    2244         2499 :           if (TREE_CODE (rhs) == SSA_NAME)
    2245              :             {
    2246            0 :               gimple *def_stmt = SSA_NAME_DEF_STMT (rhs);
    2247            0 :               if (gimple_assign_single_p (def_stmt))
    2248            0 :                 rhs = gimple_assign_rhs1 (def_stmt);
    2249              :             }
    2250              : 
    2251         2499 :           if (TREE_CODE (lhs) == SSA_NAME)
    2252              :             {
    2253         2499 :               gimple *def_stmt = SSA_NAME_DEF_STMT (lhs);
    2254         2499 :               if (gimple_assign_single_p (def_stmt))
    2255            6 :                 lhs = gimple_assign_rhs1 (def_stmt);
    2256              :             }
    2257              : 
    2258              :           /* Now see if they are both uniform vectors and if so replace
    2259              :              the vector comparison with a scalar comparison.  */
    2260         2499 :           tree rhs_elem = rhs ? uniform_vector_p (rhs) : NULL_TREE;
    2261         2499 :           tree lhs_elem = lhs ? uniform_vector_p (lhs) : NULL_TREE;
    2262         2499 :           if (rhs_elem && lhs_elem)
    2263              :             {
    2264            3 :               if (dump_file && dump_flags & TDF_DETAILS)
    2265              :                 {
    2266            0 :                   fprintf (dump_file, "Reducing vector comparison: ");
    2267            0 :                   print_gimple_stmt (dump_file, stmt, 0);
    2268              :                 }
    2269              : 
    2270            3 :               gimple_cond_set_rhs (as_a <gcond *>(stmt), rhs_elem);
    2271            3 :               gimple_cond_set_lhs (as_a <gcond *>(stmt), lhs_elem);
    2272            3 :               gimple_set_modified (stmt, true);
    2273              : 
    2274            3 :               if (dump_file && dump_flags & TDF_DETAILS)
    2275              :                 {
    2276            0 :                   fprintf (dump_file, "To scalar equivalent: ");
    2277            0 :                   print_gimple_stmt (dump_file, stmt, 0);
    2278            0 :                   fprintf (dump_file, "\n");
    2279              :                 }
    2280              :             }
    2281              :         }
    2282              :     }
    2283    167684425 : }
    2284              : 
    2285              : /* If possible, rewrite the conditional as TRUE or FALSE, and return
    2286              :    the taken edge.  Otherwise, return NULL.  */
    2287              : 
    2288              : edge
    2289      8863605 : dom_opt_dom_walker::fold_cond (gcond *cond)
    2290              : {
    2291      8863605 :   simplify_using_ranges simplify (m_ranger);
    2292      8863605 :   if (simplify.fold_cond (cond))
    2293              :     {
    2294        98890 :       basic_block bb = gimple_bb (cond);
    2295        98890 :       if (gimple_cond_true_p (cond))
    2296        23625 :         return find_taken_edge (bb, boolean_true_node);
    2297        75265 :       if (gimple_cond_false_p (cond))
    2298        75265 :         return find_taken_edge (bb, boolean_false_node);
    2299              :     }
    2300              :   return NULL;
    2301      8863605 : }
    2302              : 
    2303              : /* Optimize the statement in block BB pointed to by iterator SI.
    2304              : 
    2305              :    We try to perform some simplistic global redundancy elimination and
    2306              :    constant propagation:
    2307              : 
    2308              :    1- To detect global redundancy, we keep track of expressions that have
    2309              :       been computed in this block and its dominators.  If we find that the
    2310              :       same expression is computed more than once, we eliminate repeated
    2311              :       computations by using the target of the first one.
    2312              : 
    2313              :    2- Constant values and copy assignments.  This is used to do very
    2314              :       simplistic constant and copy propagation.  When a constant or copy
    2315              :       assignment is found, we map the value on the RHS of the assignment to
    2316              :       the variable in the LHS in the CONST_AND_COPIES table.
    2317              : 
    2318              :    3- Very simple redundant store elimination is performed.
    2319              : 
    2320              :    4- We can simplify a condition to a constant or from a relational
    2321              :       condition to an equality condition.  */
    2322              : 
    2323              : edge
    2324    167684425 : dom_opt_dom_walker::optimize_stmt (basic_block bb, gimple_stmt_iterator *si,
    2325              :                                    bool *removed_p)
    2326              : {
    2327    167684425 :   gimple *stmt, *old_stmt;
    2328    167684425 :   bool may_optimize_p;
    2329    167684425 :   bool modified_p = false;
    2330    167684425 :   bool was_noreturn;
    2331    167684425 :   edge retval = NULL;
    2332              : 
    2333    167684425 :   old_stmt = stmt = gsi_stmt (*si);
    2334    167684425 :   was_noreturn = is_gimple_call (stmt) && gimple_call_noreturn_p (stmt);
    2335              : 
    2336    167684425 :   if (dump_file && (dump_flags & TDF_DETAILS))
    2337              :     {
    2338         1612 :       fprintf (dump_file, "Optimizing statement ");
    2339         1612 :       print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    2340              :     }
    2341              : 
    2342              :   /* STMT may be a comparison of uniform vectors that we can simplify
    2343              :      down to a comparison of scalars.  Do that transformation first
    2344              :      so that all the scalar optimizations from here onward apply.  */
    2345    167684425 :   reduce_vector_comparison_to_scalar_comparison (stmt);
    2346              : 
    2347    167684425 :   update_stmt_if_modified (stmt);
    2348    167684425 :   opt_stats.num_stmts++;
    2349              : 
    2350              :   /* Const/copy propagate into USES, VUSES and the RHS of VDEFs.  */
    2351    167684425 :   cprop_into_stmt (stmt, m_ranger);
    2352              : 
    2353              :   /* If the statement has been modified with constant replacements,
    2354              :      fold its RHS before checking for redundant computations.  */
    2355    335078715 :   if (gimple_modified_p (stmt))
    2356              :     {
    2357      3694716 :       tree rhs = NULL;
    2358              : 
    2359              :       /* Try to fold the statement making sure that STMT is kept
    2360              :          up to date.  */
    2361      3694716 :       if (fold_stmt (si))
    2362              :         {
    2363       373420 :           stmt = gsi_stmt (*si);
    2364       373420 :           gimple_set_modified (stmt, true);
    2365              : 
    2366       373420 :           if (dump_file && (dump_flags & TDF_DETAILS))
    2367              :             {
    2368           12 :               fprintf (dump_file, "  Folded to: ");
    2369           12 :               print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    2370              :             }
    2371              :         }
    2372              : 
    2373              :       /* We only need to consider cases that can yield a gimple operand.  */
    2374      3694716 :       if (gimple_assign_single_p (stmt))
    2375      1398015 :         rhs = gimple_assign_rhs1 (stmt);
    2376      2296701 :       else if (gimple_code (stmt) == GIMPLE_GOTO)
    2377            1 :         rhs = gimple_goto_dest (stmt);
    2378    169981125 :       else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt))
    2379              :         /* This should never be an ADDR_EXPR.  */
    2380         2112 :         rhs = gimple_switch_index (swtch_stmt);
    2381              : 
    2382      1400128 :       if (rhs && TREE_CODE (rhs) == ADDR_EXPR)
    2383        81763 :         recompute_tree_invariant_for_addr_expr (rhs);
    2384              : 
    2385              :       /* Indicate that maybe_clean_or_replace_eh_stmt needs to be called,
    2386              :          even if fold_stmt updated the stmt already and thus cleared
    2387              :          gimple_modified_p flag on it.  */
    2388              :       modified_p = true;
    2389              :     }
    2390              : 
    2391              :   /* Check for redundant computations.  Do this optimization only
    2392              :      for assignments that have no volatile ops and conditionals.  */
    2393    167684425 :   may_optimize_p = (!gimple_has_side_effects (stmt)
    2394    167684425 :                     && (is_gimple_assign (stmt)
    2395    110822191 :                         || (is_gimple_call (stmt)
    2396      1244125 :                             && gimple_call_lhs (stmt) != NULL_TREE)
    2397    109578395 :                         || gimple_code (stmt) == GIMPLE_COND
    2398    100653760 :                         || gimple_code (stmt) == GIMPLE_SWITCH));
    2399              : 
    2400     54112572 :   if (may_optimize_p)
    2401              :     {
    2402     54112572 :       if (gimple_code (stmt) == GIMPLE_CALL)
    2403              :         {
    2404              :           /* Resolve __builtin_constant_p.  If it hasn't been
    2405              :              folded to integer_one_node by now, it's fairly
    2406              :              certain that the value simply isn't constant.  */
    2407      1243796 :           tree callee = gimple_call_fndecl (stmt);
    2408      1243796 :           if (callee
    2409      1243796 :               && fndecl_built_in_p (callee, BUILT_IN_CONSTANT_P))
    2410              :             {
    2411         1908 :               propagate_tree_value_into_stmt (si, integer_zero_node);
    2412         1908 :               stmt = gsi_stmt (*si);
    2413              :             }
    2414              :         }
    2415              : 
    2416     54112572 :       if (gimple_code (stmt) == GIMPLE_COND)
    2417              :         {
    2418      8924635 :           tree lhs = gimple_cond_lhs (stmt);
    2419      8924635 :           tree rhs = gimple_cond_rhs (stmt);
    2420              : 
    2421              :           /* If the LHS has a range [0..1] and the RHS has a range ~[0..1],
    2422              :              then this conditional is computable at compile time.  We can just
    2423              :              shove either 0 or 1 into the LHS, mark the statement as modified
    2424              :              and all the right things will just happen below.
    2425              : 
    2426              :              Note this would apply to any case where LHS has a range
    2427              :              narrower than its type implies and RHS is outside that
    2428              :              narrower range.  Future work.  */
    2429      8924635 :           if (TREE_CODE (lhs) == SSA_NAME
    2430      8863630 :               && ssa_name_has_boolean_range (lhs)
    2431      1003571 :               && TREE_CODE (rhs) == INTEGER_CST
    2432      9896825 :               && ! (integer_zerop (rhs) || integer_onep (rhs)))
    2433              :             {
    2434           25 :               gimple_cond_set_lhs (as_a <gcond *> (stmt),
    2435           25 :                                    fold_convert (TREE_TYPE (lhs),
    2436              :                                                  integer_zero_node));
    2437           25 :               gimple_set_modified (stmt, true);
    2438              :             }
    2439      8924610 :           else if (TREE_CODE (lhs) == SSA_NAME)
    2440              :             {
    2441              :               /* Exploiting EVRP data is not yet fully integrated into DOM
    2442              :                  but we need to do something for this case to avoid regressing
    2443              :                  udr4.f90 and new1.C which have unexecutable blocks with
    2444              :                  undefined behavior that get diagnosed if they're left in the
    2445              :                  IL because we've attached range information to new
    2446              :                  SSA_NAMES.  */
    2447      8863605 :               update_stmt_if_modified (stmt);
    2448      8863605 :               edge taken_edge = fold_cond (as_a <gcond *> (stmt));
    2449      8863605 :               if (taken_edge)
    2450              :                 {
    2451        98890 :                   gimple_set_modified (stmt, true);
    2452        98890 :                   update_stmt (stmt);
    2453        98890 :                   cfg_altered = true;
    2454        98890 :                   return taken_edge;
    2455              :                 }
    2456              :             }
    2457              :         }
    2458              : 
    2459     54013682 :       update_stmt_if_modified (stmt);
    2460     54013682 :       eliminate_redundant_computations (si, m_const_and_copies,
    2461              :                                         m_avail_exprs_stack);
    2462     54013682 :       stmt = gsi_stmt (*si);
    2463              : 
    2464              :       /* Perform simple redundant store elimination.  */
    2465     54013682 :       if (gimple_assign_single_p (stmt)
    2466     27426001 :           && TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME
    2467     66539049 :           && (TREE_CODE (gimple_assign_lhs (stmt)) != VAR_DECL
    2468      1013819 :               || !DECL_HARD_REGISTER (gimple_assign_lhs (stmt))))
    2469              :         {
    2470     12523349 :           tree lhs = gimple_assign_lhs (stmt);
    2471     12523349 :           tree rhs = gimple_assign_rhs1 (stmt);
    2472     12523349 :           tree cached_lhs;
    2473     12523349 :           gassign *new_stmt;
    2474     12523349 :           rhs = dom_valueize (rhs);
    2475              :           /* Build a new statement with the RHS and LHS exchanged.  */
    2476     12523349 :           if (TREE_CODE (rhs) == SSA_NAME)
    2477              :             {
    2478      5178148 :               gimple *defstmt = SSA_NAME_DEF_STMT (rhs);
    2479      5178148 :               new_stmt = gimple_build_assign (rhs, lhs);
    2480      5178148 :               SSA_NAME_DEF_STMT (rhs) = defstmt;
    2481              :             }
    2482              :           else
    2483      7345201 :             new_stmt = gimple_build_assign (rhs, lhs);
    2484     25046698 :           gimple_set_vuse (new_stmt, gimple_vuse (stmt));
    2485     12523349 :           expr_hash_elt *elt = NULL;
    2486     12523349 :           cached_lhs = m_avail_exprs_stack->lookup_avail_expr (new_stmt, false,
    2487              :                                                                false, &elt);
    2488     12523349 :           if (cached_lhs
    2489       819587 :               && operand_equal_p (rhs, cached_lhs, 0)
    2490     12773701 :               && refs_same_for_tbaa_p (elt->expr ()->kind == EXPR_SINGLE
    2491       125176 :                                        ? elt->expr ()->ops.single.rhs
    2492              :                                        : NULL_TREE, lhs))
    2493              :             {
    2494       122400 :               basic_block bb = gimple_bb (stmt);
    2495       122400 :               unlink_stmt_vdef (stmt);
    2496       122400 :               if (gsi_remove (si, true))
    2497              :                 {
    2498            0 :                   bitmap_set_bit (need_eh_cleanup, bb->index);
    2499            0 :                   if (dump_file && (dump_flags & TDF_DETAILS))
    2500            0 :                     fprintf (dump_file, "  Flagged to clear EH edges.\n");
    2501              :                 }
    2502       122400 :               release_defs (stmt);
    2503       122400 :               *removed_p = true;
    2504       122400 :               return retval;
    2505              :             }
    2506              :         }
    2507              : 
    2508              :       /* If this statement was not redundant, we may still be able to simplify
    2509              :          it, which may in turn allow other part of DOM or other passes to do
    2510              :          a better job.  */
    2511     53891282 :       test_for_singularity (stmt, m_avail_exprs_stack);
    2512              :     }
    2513              : 
    2514              :   /* Record any additional equivalences created by this statement.  */
    2515    167463135 :   if (is_gimple_assign (stmt))
    2516     47250123 :     record_equivalences_from_stmt (stmt, may_optimize_p, m_avail_exprs_stack);
    2517              : 
    2518              :   /* If STMT is a COND_EXPR or SWITCH_EXPR and it was modified, then we may
    2519              :      know where it goes.  */
    2520    334926270 :   if (gimple_modified_p (stmt) || modified_p)
    2521              :     {
    2522      3976185 :       tree val = NULL;
    2523              : 
    2524      3976185 :       if (gimple_code (stmt) == GIMPLE_COND)
    2525       438905 :         val = fold_binary_loc (gimple_location (stmt),
    2526              :                                gimple_cond_code (stmt), boolean_type_node,
    2527              :                                gimple_cond_lhs (stmt),
    2528              :                                gimple_cond_rhs (stmt));
    2529      3537280 :       else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt))
    2530         2112 :         val = gimple_switch_index (swtch_stmt);
    2531              : 
    2532       441017 :       if (val && TREE_CODE (val) == INTEGER_CST)
    2533              :         {
    2534        66164 :           retval = find_taken_edge (bb, val);
    2535        66164 :           if (retval)
    2536              :             {
    2537              :               /* Fix the condition to be either true or false.  */
    2538        66164 :               if (gimple_code (stmt) == GIMPLE_COND)
    2539              :                 {
    2540        66148 :                   if (integer_zerop (val))
    2541        35205 :                     gimple_cond_make_false (as_a <gcond *> (stmt));
    2542        30943 :                   else if (integer_onep (val))
    2543        30943 :                     gimple_cond_make_true (as_a <gcond *> (stmt));
    2544              :                   else
    2545            0 :                     gcc_unreachable ();
    2546              : 
    2547        66148 :                   gimple_set_modified (stmt, true);
    2548              :                 }
    2549              : 
    2550              :               /* Further simplifications may be possible.  */
    2551        66164 :               cfg_altered = true;
    2552              :             }
    2553              :         }
    2554              : 
    2555      3976185 :       update_stmt_if_modified (stmt);
    2556              : 
    2557              :       /* If we simplified a statement in such a way as to be shown that it
    2558              :          cannot trap, update the eh information and the cfg to match.  */
    2559      3976185 :       if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
    2560              :         {
    2561         1506 :           bitmap_set_bit (need_eh_cleanup, bb->index);
    2562         1506 :           if (dump_file && (dump_flags & TDF_DETAILS))
    2563            0 :             fprintf (dump_file, "  Flagged to clear EH edges.\n");
    2564              :         }
    2565              : 
    2566      3976185 :       if (!was_noreturn
    2567      3976185 :           && is_gimple_call (stmt) && gimple_call_noreturn_p (stmt))
    2568            3 :         need_noreturn_fixup.safe_push (stmt);
    2569              :     }
    2570              :   return retval;
    2571              : }
        

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.