LCOV - code coverage report
Current view: top level - gcc - tree-ssa-dom.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 95.4 % 970 925
Test Date: 2026-10-17 16:30:31 Functions: 100.0 % 41 41
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              : /* Bitmap of SSA names that have no use in an assignment or call that
      98              :    defines an SSA name, so back_propagate_equivalences has nothing to do
      99              :    for them.  A bit is cleared when DOM adds such a use.  */
     100              : static bitmap names_without_foldable_uses;
     101              : 
     102              : /* Statistics for dominator optimizations.  */
     103              : struct opt_stats_d
     104              : {
     105              :   long num_stmts;
     106              :   long num_exprs_considered;
     107              :   long num_re;
     108              :   long num_const_prop;
     109              :   long num_copy_prop;
     110              : };
     111              : 
     112              : static struct opt_stats_d opt_stats;
     113              : 
     114              : /* Local functions.  */
     115              : static void record_equality (tree, tree, class const_and_copies *);
     116              : static void record_equivalences_from_phis (basic_block);
     117              : static void dump_dominator_optimization_stats (FILE *file,
     118              :                                                hash_table<expr_elt_hasher> *);
     119              : static void record_temporary_equivalences (edge, class const_and_copies *,
     120              :                                            class avail_exprs_stack *, bitmap);
     121              : 
     122              : /* Constructor for EDGE_INFO.  An EDGE_INFO instance is always
     123              :    associated with an edge E.  */
     124              : 
     125     37361231 : edge_info::edge_info (edge e)
     126              : {
     127              :   /* Free the old one associated with E, if it exists and
     128              :      associate our new object with E.  */
     129     37361231 :   free_dom_edge_info (e);
     130     37361231 :   e->aux = this;
     131              : 
     132              :   /* And initialize the embedded vectors.  */
     133     37361231 :   simple_equivalences = vNULL;
     134     37361231 :   cond_equivalences = vNULL;
     135     37361231 : }
     136              : 
     137              : /* Destructor just needs to release the vectors.  */
     138              : 
     139     37361231 : edge_info::~edge_info (void)
     140              : {
     141     37361231 :   this->cond_equivalences.release ();
     142     37361231 :   this->simple_equivalences.release ();
     143     37361231 : }
     144              : 
     145              : /* NAME is known to have the value VALUE, which must be a constant.
     146              : 
     147              :    Walk through its use-def chain to see if there are other equivalences
     148              :    we might be able to derive.
     149              : 
     150              :    RECURSION_LIMIT controls how far back we recurse through the use-def
     151              :    chains.  */
     152              : 
     153              : void
     154     13537486 : edge_info::derive_equivalences (tree name, tree value, int recursion_limit)
     155              : {
     156     15682432 :   if (TREE_CODE (name) != SSA_NAME || TREE_CODE (value) != INTEGER_CST)
     157              :     return;
     158              : 
     159              :   /* This records the equivalence for the toplevel object.  Do
     160              :      this before checking the recursion limit.  */
     161     15682140 :   simple_equivalences.safe_push (equiv_pair (name, value));
     162              : 
     163              :   /* Limit how far up the use-def chains we are willing to walk.  */
     164     15682140 :   if (recursion_limit == 0)
     165              :     return;
     166              : 
     167              :   /* We can walk up the use-def chains to potentially find more
     168              :      equivalences.  */
     169     15669304 :   gimple *def_stmt = SSA_NAME_DEF_STMT (name);
     170     15669304 :   if (is_gimple_assign (def_stmt))
     171              :     {
     172     10250761 :       enum tree_code code = gimple_assign_rhs_code (def_stmt);
     173     10250761 :       switch (code)
     174              :         {
     175              :         /* If the result of an OR is zero, then its operands are, too.  */
     176       588838 :         case BIT_IOR_EXPR:
     177       588838 :           if (integer_zerop (value))
     178              :             {
     179       323273 :               tree rhs1 = gimple_assign_rhs1 (def_stmt);
     180       323273 :               tree rhs2 = gimple_assign_rhs2 (def_stmt);
     181              : 
     182       323273 :               value = build_zero_cst (TREE_TYPE (rhs1));
     183       323273 :               derive_equivalences (rhs1, value, recursion_limit - 1);
     184       323273 :               value = build_zero_cst (TREE_TYPE (rhs2));
     185       323273 :               derive_equivalences (rhs2, value, recursion_limit - 1);
     186              :             }
     187              :           break;
     188              : 
     189              :         /* If the result of an AND is nonzero, then its operands are, too.  */
     190      1101883 :         case BIT_AND_EXPR:
     191      1101883 :           if (!integer_zerop (value))
     192              :             {
     193       465179 :               tree rhs1 = gimple_assign_rhs1 (def_stmt);
     194       465179 :               tree rhs2 = gimple_assign_rhs2 (def_stmt);
     195              : 
     196              :               /* If either operand has a boolean range, then we
     197              :                  know its value must be one, otherwise we just know it
     198              :                  is nonzero.  The former is clearly useful, I haven't
     199              :                  seen cases where the latter is helpful yet.  */
     200       465179 :               if (TREE_CODE (rhs1) == SSA_NAME)
     201              :                 {
     202       465179 :                   if (ssa_name_has_boolean_range (rhs1))
     203              :                     {
     204       291749 :                       value = build_one_cst (TREE_TYPE (rhs1));
     205       291749 :                       derive_equivalences (rhs1, value, recursion_limit - 1);
     206              :                     }
     207              :                 }
     208       465179 :               if (TREE_CODE (rhs2) == SSA_NAME)
     209              :                 {
     210       294382 :                   if (ssa_name_has_boolean_range (rhs2))
     211              :                     {
     212       291466 :                       value = build_one_cst (TREE_TYPE (rhs2));
     213       291466 :                       derive_equivalences (rhs2, value, recursion_limit - 1);
     214              :                     }
     215              :                 }
     216              :             }
     217              :           break;
     218              : 
     219              :         /* If LHS is an SSA_NAME and RHS is a constant integer and LHS was
     220              :            set via a widening type conversion, then we may be able to record
     221              :            additional equivalences.  */
     222       450965 :         CASE_CONVERT:
     223       450965 :           {
     224       450965 :             tree rhs = gimple_assign_rhs1 (def_stmt);
     225       450965 :             tree rhs_type = TREE_TYPE (rhs);
     226       450965 :             if (INTEGRAL_TYPE_P (rhs_type)
     227       447980 :                 && (TYPE_PRECISION (TREE_TYPE (name))
     228       447980 :                     >= TYPE_PRECISION (rhs_type))
     229       700957 :                 && int_fits_type_p (value, rhs_type))
     230       238166 :               derive_equivalences (rhs,
     231              :                                    fold_convert (rhs_type, value),
     232              :                                    recursion_limit - 1);
     233              :             break;
     234              :           }
     235              : 
     236              :         /* We can invert the operation of these codes trivially if
     237              :            one of the RHS operands is a constant to produce a known
     238              :            value for the other RHS operand.  */
     239      1058274 :         case POINTER_PLUS_EXPR:
     240      1058274 :         case PLUS_EXPR:
     241      1058274 :           {
     242      1058274 :             tree rhs1 = gimple_assign_rhs1 (def_stmt);
     243      1058274 :             tree rhs2 = gimple_assign_rhs2 (def_stmt);
     244              : 
     245              :             /* If the second argument is a constant, then we can compute
     246              :                a constant value for the first one.  */
     247      1058274 :             if (TREE_CODE (rhs2) == INTEGER_CST
     248      1003968 :                 && TREE_CODE (rhs1) == SSA_NAME)
     249      1003966 :               derive_equivalences (rhs1,
     250      1003966 :                                    fold_binary (MINUS_EXPR, TREE_TYPE (rhs1),
     251              :                                                 value, rhs2),
     252              :                                    recursion_limit - 1);
     253              :             break;
     254              :           }
     255              : 
     256              :         /* If one of the operands is a constant, then we can compute
     257              :            the value of the other operand.  If both operands are
     258              :            SSA_NAMEs, then they must be equal if the result is zero.  */
     259        75962 :         case MINUS_EXPR:
     260        75962 :           {
     261        75962 :             tree rhs1 = gimple_assign_rhs1 (def_stmt);
     262        75962 :             tree rhs2 = gimple_assign_rhs2 (def_stmt);
     263              : 
     264              :             /* If either argument is a constant, then we can compute
     265              :                a constant value for the nonconstant argument.  */
     266        75962 :             if (TREE_CODE (rhs1) == INTEGER_CST
     267          666 :                 && TREE_CODE (rhs2) == SSA_NAME)
     268          666 :               derive_equivalences (rhs2,
     269          666 :                                    fold_binary (MINUS_EXPR, TREE_TYPE (rhs1),
     270              :                                                 rhs1, value),
     271              :                                    recursion_limit - 1);
     272        75296 :             else if (TREE_CODE (rhs2) == INTEGER_CST
     273        30230 :                      && TREE_CODE (rhs1) == SSA_NAME)
     274        30230 :               derive_equivalences (rhs1,
     275        30230 :                                    fold_binary (PLUS_EXPR, TREE_TYPE (rhs1),
     276              :                                                 value, rhs2),
     277              :                                    recursion_limit - 1);
     278        45066 :             else if (integer_zerop (value))
     279              :               {
     280        16351 :                 tree cond = build2 (EQ_EXPR, boolean_type_node,
     281              :                                     gimple_assign_rhs1 (def_stmt),
     282              :                                     gimple_assign_rhs2 (def_stmt));
     283        16351 :                 tree inverted = invert_truthvalue (cond);
     284        16351 :                 record_conditions (&this->cond_equivalences, cond, inverted);
     285              :               }
     286              :             break;
     287              :           }
     288              : 
     289       761138 :         case EQ_EXPR:
     290       761138 :         case NE_EXPR:
     291       761138 :           {
     292       347631 :             if ((code == EQ_EXPR && integer_onep (value))
     293       904939 :                 || (code == NE_EXPR && integer_zerop (value)))
     294              :               {
     295       465690 :                 tree rhs1 = gimple_assign_rhs1 (def_stmt);
     296       465690 :                 tree rhs2 = gimple_assign_rhs2 (def_stmt);
     297              : 
     298              :                 /* If the second argument is a constant, then record the
     299              :                    first argument as being the same as that constant.
     300              : 
     301              :                    If neither operand is a constant, then we have a
     302              :                    conditional name == name equivalence.  */
     303       465690 :                 if (TREE_CODE (rhs2) == INTEGER_CST)
     304       242869 :                   derive_equivalences (rhs1, rhs2, recursion_limit - 1);
     305              :               }
     306              :             else
     307              :               {
     308       295448 :                 tree cond = build2 (code, boolean_type_node,
     309              :                                     gimple_assign_rhs1 (def_stmt),
     310       295448 :                                     gimple_assign_rhs2 (def_stmt));
     311       295448 :                 tree inverted = invert_truthvalue (cond);
     312       295448 :                 if (integer_zerop (value))
     313       143801 :                   std::swap (cond, inverted);
     314       295448 :                 record_conditions (&this->cond_equivalences, cond, inverted);
     315              :               }
     316              :             break;
     317              :           }
     318              : 
     319              :         /* For BIT_NOT and NEGATE, we can just apply the operation to the
     320              :            VALUE to get the new equivalence.  It will always be a constant
     321              :            so we can recurse.  */
     322        14310 :         case BIT_NOT_EXPR:
     323        14310 :         case NEGATE_EXPR:
     324        14310 :           {
     325        14310 :             tree rhs = gimple_assign_rhs1 (def_stmt);
     326        14310 :             tree res;
     327              :             /* If this is a NOT and the operand has a boolean range, then we
     328              :                know its value must be zero or one.  We are not supposed to
     329              :                have a BIT_NOT_EXPR for boolean types with precision > 1 in
     330              :                the general case, see e.g. the handling of TRUTH_NOT_EXPR in
     331              :                the gimplifier, but it can be generated by match.pd out of
     332              :                a BIT_XOR_EXPR wrapped in a BIT_AND_EXPR.  Now the handling
     333              :                of BIT_AND_EXPR above already forces a specific semantics for
     334              :                boolean types with precision > 1 so we must do the same here,
     335              :                otherwise we could change the semantics of TRUTH_NOT_EXPR for
     336              :                boolean types with precision > 1.  */
     337        14310 :             if (code == BIT_NOT_EXPR
     338        14055 :                 && TREE_CODE (rhs) == SSA_NAME
     339        28365 :                 && ssa_name_has_boolean_range (rhs))
     340              :               {
     341        13602 :                 if ((TREE_INT_CST_LOW (value) & 1) == 0)
     342         6188 :                   res = build_one_cst (TREE_TYPE (rhs));
     343              :                 else
     344         7414 :                   res = build_zero_cst (TREE_TYPE (rhs));
     345              :               }
     346              :             else
     347          708 :               res = fold_build1 (code, TREE_TYPE (rhs), value);
     348        14310 :             derive_equivalences (rhs, res, recursion_limit - 1);
     349        14310 :             break;
     350              :           }
     351              : 
     352      6199391 :         default:
     353      6199391 :           {
     354      6199391 :             if (TREE_CODE_CLASS (code) == tcc_comparison)
     355              :               {
     356       531628 :                 tree cond = build2 (code, boolean_type_node,
     357              :                                     gimple_assign_rhs1 (def_stmt),
     358       531628 :                                     gimple_assign_rhs2 (def_stmt));
     359       531628 :                 tree inverted = invert_truthvalue (cond);
     360       531628 :                 if (integer_zerop (value))
     361       225999 :                   std::swap (cond, inverted);
     362       531628 :                 record_conditions (&this->cond_equivalences, cond, inverted);
     363       531628 :                 break;
     364              :               }
     365              :             break;
     366              :           }
     367              :         }
     368              :     }
     369              : }
     370              : 
     371              : void
     372     16291732 : edge_info::record_simple_equiv (tree lhs, tree rhs)
     373              : {
     374              :   /* If the RHS is a constant, then we may be able to derive
     375              :      further equivalences.  Else just record the name = name
     376              :      equivalence.  */
     377     16291732 :   if (TREE_CODE (rhs) == INTEGER_CST)
     378     12922464 :     derive_equivalences (lhs, rhs, 4);
     379              :   else
     380      3369268 :     simple_equivalences.safe_push (equiv_pair (lhs, rhs));
     381     16291732 : }
     382              : 
     383              : /* Free the edge_info data attached to E, if it exists and
     384              :    clear e->aux.  */
     385              : 
     386              : void
     387    135338283 : free_dom_edge_info (edge e)
     388              : {
     389    135338283 :   class edge_info *edge_info = (class edge_info *)e->aux;
     390              : 
     391    135338283 :   if (edge_info)
     392     37361231 :     delete edge_info;
     393    135338283 :   e->aux = NULL;
     394    135338283 : }
     395              : 
     396              : /* Free all EDGE_INFO structures associated with edges in the CFG.
     397              :    If a particular edge can be threaded, copy the redirection
     398              :    target from the EDGE_INFO structure into the edge's AUX field
     399              :    as required by code to update the CFG and SSA graph for
     400              :    jump threading.  */
     401              : 
     402              : static void
     403      2136688 : free_all_edge_infos (void)
     404              : {
     405      2136688 :   basic_block bb;
     406      2136688 :   edge_iterator ei;
     407      2136688 :   edge e;
     408              : 
     409     24366268 :   FOR_EACH_BB_FN (bb, cfun)
     410              :     {
     411     53641136 :       FOR_EACH_EDGE (e, ei, bb->preds)
     412     31411556 :         free_dom_edge_info (e);
     413              :     }
     414      2136688 : }
     415              : 
     416              : /* We have finished optimizing BB, record any information implied by
     417              :    taking a specific outgoing edge from BB.  */
     418              : 
     419              : static void
     420     46511505 : record_edge_info (basic_block bb)
     421              : {
     422     46511505 :   gimple_stmt_iterator gsi = gsi_last_bb (bb);
     423     46511505 :   class edge_info *edge_info;
     424              : 
     425              :   /* Free all the outgoing edge info data associated with
     426              :      BB's outgoing edges.  */
     427     46511505 :   edge e;
     428     46511505 :   edge_iterator ei;
     429    111275394 :   FOR_EACH_EDGE (e, ei, bb->succs)
     430     64763889 :     free_dom_edge_info (e);
     431              : 
     432     46511505 :   if (! gsi_end_p (gsi))
     433              :     {
     434     40185904 :       gimple *stmt = gsi_stmt (gsi);
     435     40185904 :       location_t loc = gimple_location (stmt);
     436              : 
     437     40185904 :       if (gimple_code (stmt) == GIMPLE_SWITCH)
     438              :         {
     439        72103 :           gswitch *switch_stmt = as_a <gswitch *> (stmt);
     440        72103 :           tree index = gimple_switch_index (switch_stmt);
     441              : 
     442        72103 :           if (TREE_CODE (index) == SSA_NAME)
     443              :             {
     444        72088 :               int i;
     445        72088 :               int n_labels = gimple_switch_num_labels (switch_stmt);
     446              :               /* info contains NULL, error_mark_node or a value.
     447              :                  error_mark signifies there are multiple values already.
     448              :                  A NULL signifies there it is uninitialized.
     449              :                  A value signifies that is the only value on that edge
     450              :                  to that bb.  */
     451        72088 :               tree *info = XCNEWVEC (tree, last_basic_block_for_fn (cfun));
     452              : 
     453       679188 :               for (i = 0; i < n_labels; i++)
     454              :                 {
     455       535012 :                   tree label = gimple_switch_label (switch_stmt, i);
     456       535012 :                   basic_block target_bb
     457       535012 :                     = label_to_block (cfun, CASE_LABEL (label));
     458              :                   /* The default case is a case with multiple values.
     459              :                      If the value is already set then it has multiple values.  */
     460       535012 :                   if (CASE_HIGH (label)
     461       510710 :                       || !CASE_LOW (label)
     462       973634 :                       || info[target_bb->index])
     463       145408 :                     info[target_bb->index] = error_mark_node;
     464              :                   else
     465              :                     /* Record the one value that can be on that edge to the
     466              :                        target_bb.  */
     467       389604 :                     info[target_bb->index] = CASE_LOW (label);
     468              :                 }
     469              : 
     470       551040 :               FOR_EACH_EDGE (e, ei, bb->succs)
     471              :                 {
     472       478952 :                   basic_block target_bb = e->dest;
     473       478952 :                   tree value = info[target_bb->index];
     474              : 
     475       478952 :                   if (value != NULL && value != error_mark_node)
     476              :                     {
     477       364433 :                       tree x = fold_convert_loc (loc, TREE_TYPE (index),
     478              :                                                  value);
     479       364433 :                       edge_info = new class edge_info (e);
     480       364433 :                       edge_info->record_simple_equiv (index, x);
     481              :                     }
     482              :                 }
     483        72088 :               free (info);
     484              :             }
     485              :         }
     486              : 
     487              :       /* A COND_EXPR may create equivalences too.  */
     488     40185904 :       if (gimple_code (stmt) == GIMPLE_COND)
     489              :         {
     490     18689764 :           edge true_edge;
     491     18689764 :           edge false_edge;
     492              : 
     493     18689764 :           tree op0 = gimple_cond_lhs (stmt);
     494     18689764 :           tree op1 = gimple_cond_rhs (stmt);
     495     18689764 :           enum tree_code code = gimple_cond_code (stmt);
     496              : 
     497     18689764 :           extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
     498              : 
     499              :           /* Special case comparing booleans against a constant as we
     500              :              know the value of OP0 on both arms of the branch.  i.e., we
     501              :              can record an equivalence for OP0 rather than COND.
     502              : 
     503              :              However, don't do this if the constant isn't zero or one.
     504              :              Such conditionals will get optimized more thoroughly during
     505              :              the domwalk.  */
     506     18689764 :           if ((code == EQ_EXPR || code == NE_EXPR)
     507     14318654 :               && TREE_CODE (op0) == SSA_NAME
     508     14127819 :               && ssa_name_has_boolean_range (op0)
     509      2073880 :               && is_gimple_min_invariant (op1)
     510     20698584 :               && (integer_zerop (op1) || integer_onep (op1)))
     511              :             {
     512      2008820 :               tree true_val = constant_boolean_node (true, TREE_TYPE (op0));
     513      2008820 :               tree false_val = constant_boolean_node (false, TREE_TYPE (op0));
     514              : 
     515      2008820 :               if (code == EQ_EXPR)
     516              :                 {
     517        77925 :                   edge_info = new class edge_info (true_edge);
     518       116174 :                   edge_info->record_simple_equiv (op0,
     519        77925 :                                                   (integer_zerop (op1)
     520              :                                                    ? false_val : true_val));
     521        77925 :                   edge_info = new class edge_info (false_edge);
     522       116174 :                   edge_info->record_simple_equiv (op0,
     523        77925 :                                                   (integer_zerop (op1)
     524              :                                                    ? true_val : false_val));
     525              :                 }
     526              :               else
     527              :                 {
     528      1930895 :                   edge_info = new class edge_info (true_edge);
     529      1934248 :                   edge_info->record_simple_equiv (op0,
     530      1930895 :                                                   (integer_zerop (op1)
     531              :                                                    ? true_val : false_val));
     532      1930895 :                   edge_info = new class edge_info (false_edge);
     533      1934248 :                   edge_info->record_simple_equiv (op0,
     534      1930895 :                                                   (integer_zerop (op1)
     535              :                                                    ? false_val : true_val));
     536              :                 }
     537              :             }
     538     16680944 :           else if (TREE_CODE (op0) == SSA_NAME
     539     16680944 :                    && (TREE_CODE (op1) == SSA_NAME
     540     12288749 :                        || is_gimple_min_invariant (op1)))
     541              :             {
     542     16489579 :               tree cond = build2 (code, boolean_type_node, op0, op1);
     543     16489579 :               tree inverted = invert_truthvalue_loc (loc, cond);
     544     16489579 :               bool can_infer_simple_equiv
     545     17201863 :                 = !(HONOR_SIGNED_ZEROS (op1) && real_maybe_zerop (op1))
     546     16896458 :                   && !DECIMAL_FLOAT_MODE_P (element_mode (TREE_TYPE (op1)));
     547     16489579 :               class edge_info *edge_info;
     548              : 
     549     16489579 :               edge_info = new class edge_info (true_edge);
     550     16489579 :               record_conditions (&edge_info->cond_equivalences, cond, inverted);
     551              : 
     552     16489579 :               if (can_infer_simple_equiv && code == EQ_EXPR)
     553      5585093 :                 edge_info->record_simple_equiv (op0, op1);
     554              : 
     555     16489579 :               edge_info = new class edge_info (false_edge);
     556     16489579 :               record_conditions (&edge_info->cond_equivalences, inverted, cond);
     557              : 
     558     16489579 :               if (can_infer_simple_equiv && TREE_CODE (inverted) == EQ_EXPR)
     559      6324566 :                 edge_info->record_simple_equiv (op0, op1);
     560              :             }
     561              :         }
     562              :     }
     563     46511505 : }
     564              : 
     565              : class dom_jt_state : public jt_state
     566              : {
     567              : public:
     568      2136688 :   dom_jt_state (const_and_copies *copies, avail_exprs_stack *avails)
     569      2136688 :     : m_copies (copies), m_avails (avails)
     570              :   {
     571      2136688 :     bitmap_tree_view (m_blocks_on_stack);
     572      2136688 :   }
     573     17279832 :   void push (edge e) override
     574              :   {
     575     17279832 :     m_copies->push_marker ();
     576     17279832 :     m_avails->push_marker ();
     577     17279832 :     jt_state::push (e);
     578     17279832 :   }
     579     17279832 :   void pop () override
     580              :   {
     581     17279832 :     m_copies->pop_to_marker ();
     582     17279832 :     m_avails->pop_to_marker ();
     583     17279832 :     jt_state::pop ();
     584     17279832 :   }
     585     16012996 :   void register_equivs_edge (edge e) override
     586              :   {
     587     16012996 :     record_temporary_equivalences (e, m_copies, m_avails, m_blocks_on_stack);
     588     16012996 :   }
     589              :   void register_equiv (tree dest, tree src, bool update) override;
     590     66646228 :   bitmap get_blocks_on_stack () { return m_blocks_on_stack; }
     591              : private:
     592              :   const_and_copies *m_copies;
     593              :   avail_exprs_stack *m_avails;
     594              :   /* Set of blocks on the stack, to be used for medium-fast
     595              :      dominance queries in back_propagate_equivalences.  */
     596              :   auto_bitmap m_blocks_on_stack;
     597              : };
     598              : 
     599              : void
     600     21715237 : dom_jt_state::register_equiv (tree dest, tree src, bool)
     601              : {
     602     21715237 :   m_copies->record_const_or_copy (dest, src);
     603     21715237 : }
     604              : 
     605      2136688 : class dom_jt_simplifier : public hybrid_jt_simplifier
     606              : {
     607              : public:
     608      2136688 :   dom_jt_simplifier (avail_exprs_stack *avails, gimple_ranger *ranger,
     609              :                      path_range_query *query)
     610      4273376 :     : hybrid_jt_simplifier (ranger, query), m_avails (avails) { }
     611              : 
     612              : private:
     613              :   tree simplify (gimple *, gimple *, basic_block, jt_state *) override;
     614              :   avail_exprs_stack *m_avails;
     615              : };
     616              : 
     617              : tree
     618     32207204 : dom_jt_simplifier::simplify (gimple *stmt, gimple *within_stmt,
     619              :                              basic_block bb, jt_state *state)
     620              : {
     621              :   /* First see if the conditional is in the hash table.  */
     622     32207204 :   tree cached_lhs =  m_avails->lookup_avail_expr (stmt, false, true);
     623     32207204 :   if (cached_lhs)
     624              :     return cached_lhs;
     625              : 
     626              :   /* Otherwise call the ranger if possible.  */
     627     31364705 :   if (state)
     628      8895092 :     return hybrid_jt_simplifier::simplify (stmt, within_stmt, bb, state);
     629              : 
     630              :   return NULL;
     631              : }
     632              : 
     633      4273376 : class dom_opt_dom_walker : public dom_walker
     634              : {
     635              : public:
     636      2136688 :   dom_opt_dom_walker (cdi_direction direction,
     637              :                       jump_threader *threader,
     638              :                       dom_jt_state *state,
     639              :                       gimple_ranger *ranger,
     640              :                       const_and_copies *const_and_copies,
     641              :                       avail_exprs_stack *avail_exprs_stack)
     642      4273376 :     : dom_walker (direction, REACHABLE_BLOCKS)
     643              :     {
     644      2136688 :       m_ranger = ranger;
     645      2136688 :       m_state = state;
     646      2136688 :       m_const_and_copies = const_and_copies;
     647      2136688 :       m_avail_exprs_stack = avail_exprs_stack;
     648      2136688 :       m_threader = threader;
     649              :     }
     650              : 
     651              :   edge before_dom_children (basic_block) final override;
     652              :   void after_dom_children (basic_block) final override;
     653              : 
     654              : private:
     655              : 
     656              :   /* Unwindable equivalences, both const/copy and expression varieties.  */
     657              :   class const_and_copies *m_const_and_copies;
     658              :   class avail_exprs_stack *m_avail_exprs_stack;
     659              : 
     660              :   /* Optimize a single statement within a basic block using the
     661              :      various tables maintained by DOM.  Returns the taken edge if
     662              :      the statement is a conditional with a statically determined
     663              :      value.  */
     664              :   edge optimize_stmt (basic_block, gimple_stmt_iterator *, bool *);
     665              : 
     666              :   void set_global_ranges_from_unreachable_edges (basic_block);
     667              : 
     668              :   void fold_cond (gimple *);
     669              :   void record_equivalences_from_incoming_edge (basic_block);
     670              :   void eliminate_redundant_computations (gimple_stmt_iterator *);
     671              :   void record_equivalences_from_stmt (gimple *, int);
     672              :   tree const_or_copy_of_stmt (gimple *);
     673              : 
     674              :   jump_threader *m_threader;
     675              :   gimple_ranger *m_ranger;
     676              :   dom_jt_state *m_state;
     677              : };
     678              : 
     679              : /* Jump threading, redundancy elimination and const/copy propagation.
     680              : 
     681              :    This pass may expose new symbols that need to be renamed into SSA.  For
     682              :    every new symbol exposed, its corresponding bit will be set in
     683              :    VARS_TO_RENAME.  */
     684              : 
     685              : namespace {
     686              : 
     687              : const pass_data pass_data_dominator =
     688              : {
     689              :   GIMPLE_PASS, /* type */
     690              :   "dom", /* name */
     691              :   OPTGROUP_NONE, /* optinfo_flags */
     692              :   TV_TREE_SSA_DOMINATOR_OPTS, /* tv_id */
     693              :   ( PROP_cfg | PROP_ssa ), /* properties_required */
     694              :   0, /* properties_provided */
     695              :   0, /* properties_destroyed */
     696              :   0, /* todo_flags_start */
     697              :   ( TODO_cleanup_cfg | TODO_update_ssa ), /* todo_flags_finish */
     698              : };
     699              : 
     700              : class pass_dominator : public gimple_opt_pass
     701              : {
     702              : public:
     703       883608 :   pass_dominator (gcc::context *ctxt)
     704              :     : gimple_opt_pass (pass_data_dominator, ctxt),
     705      1767216 :       may_peel_loop_headers_p (false)
     706              :   {}
     707              : 
     708              :   /* opt_pass methods: */
     709       589072 :   opt_pass * clone () final override { return new pass_dominator (m_ctxt); }
     710       883608 :   void set_pass_param (unsigned int n, bool param) final override
     711              :     {
     712       883608 :       gcc_assert (n == 0);
     713       883608 :       may_peel_loop_headers_p = param;
     714       883608 :     }
     715      2137479 :   bool gate (function *) final override { return flag_tree_dom != 0; }
     716              :   unsigned int execute (function *) final override;
     717              : 
     718              :  private:
     719              :   /* This flag is used to prevent loops from being peeled repeatedly in jump
     720              :      threading; it will be removed once we preserve loop structures throughout
     721              :      the compilation -- we will be able to mark the affected loops directly in
     722              :      jump threading, and avoid peeling them next time.  */
     723              :   bool may_peel_loop_headers_p;
     724              : }; // class pass_dominator
     725              : 
     726              : unsigned int
     727      2136688 : pass_dominator::execute (function *fun)
     728              : {
     729      2136688 :   memset (&opt_stats, 0, sizeof (opt_stats));
     730              : 
     731              :   /* Create our hash tables.  */
     732      2136688 :   hash_table<expr_elt_hasher> *avail_exprs
     733      2136688 :     = new hash_table<expr_elt_hasher> (1024);
     734      2136688 :   class avail_exprs_stack *avail_exprs_stack
     735      2136688 :     = new class avail_exprs_stack (avail_exprs);
     736      2136688 :   class const_and_copies *const_and_copies = new class const_and_copies ();
     737      2136688 :   need_eh_cleanup = BITMAP_ALLOC (NULL);
     738      2136688 :   need_noreturn_fixup.create (0);
     739      2136688 :   names_without_foldable_uses = BITMAP_ALLOC (NULL);
     740      2136688 :   bitmap_tree_view (names_without_foldable_uses);
     741              : 
     742      2136688 :   calculate_dominance_info (CDI_DOMINATORS);
     743      2136688 :   cfg_altered = false;
     744              : 
     745              :   /* We need to know loop structures in order to avoid destroying them
     746              :      in jump threading.  Note that we still can e.g. thread through loop
     747              :      headers to an exit edge, or through loop header to the loop body, assuming
     748              :      that we update the loop info.
     749              : 
     750              :      TODO: We don't need to set LOOPS_HAVE_PREHEADERS generally, but due
     751              :      to several overly conservative bail-outs in jump threading, case
     752              :      gcc.dg/tree-ssa/pr21417.c can't be threaded if loop preheader is
     753              :      missing.  We should improve jump threading in future then
     754              :      LOOPS_HAVE_PREHEADERS won't be needed here.  */
     755      2136688 :   loop_optimizer_init (LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES
     756              :                        | LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS);
     757              : 
     758              :   /* We need accurate information regarding back edges in the CFG
     759              :      for jump threading; this may include back edges that are not part of
     760              :      a single loop.  */
     761      2136688 :   mark_dfs_back_edges ();
     762              : 
     763              :   /* We want to create the edge info structures before the dominator walk
     764              :      so that they'll be in place for the jump threader, particularly when
     765              :      threading through a join block.
     766              : 
     767              :      The conditions will be lazily updated with global equivalences as
     768              :      we reach them during the dominator walk.  */
     769      2136688 :   basic_block bb;
     770     24366268 :   FOR_EACH_BB_FN (bb, fun)
     771     22229580 :     record_edge_info (bb);
     772              : 
     773              :   /* Recursively walk the dominator tree optimizing statements.  */
     774      2136688 :   gimple_ranger *ranger = enable_ranger (fun);
     775      2136688 :   path_range_query path_query (*ranger);
     776      2136688 :   dom_jt_simplifier simplifier (avail_exprs_stack, ranger, &path_query);
     777      2136688 :   dom_jt_state state (const_and_copies, avail_exprs_stack);
     778      2136688 :   jump_threader threader (&simplifier, &state);
     779      2136688 :   dom_opt_dom_walker walker (CDI_DOMINATORS,
     780              :                              &threader,
     781              :                              &state,
     782              :                              ranger,
     783              :                              const_and_copies,
     784      2136688 :                              avail_exprs_stack);
     785      2136688 :   walker.walk (fun->cfg->x_entry_block_ptr);
     786              : 
     787      2136688 :   ranger->export_global_ranges ();
     788      2136688 :   disable_ranger (fun);
     789              : 
     790              :   /* Look for blocks where we cleared EDGE_EXECUTABLE on an outgoing
     791              :      edge.  When found, remove jump threads which contain any outgoing
     792              :      edge from the affected block.  */
     793      2136688 :   if (cfg_altered)
     794              :     {
     795      5121677 :       FOR_EACH_BB_FN (bb, fun)
     796              :         {
     797      5056657 :           edge_iterator ei;
     798      5056657 :           edge e;
     799              : 
     800              :           /* First see if there are any edges without EDGE_EXECUTABLE
     801              :              set.  */
     802      5056657 :           bool found = false;
     803     12134383 :           FOR_EACH_EDGE (e, ei, bb->succs)
     804              :             {
     805      7321056 :               if ((e->flags & EDGE_EXECUTABLE) == 0)
     806              :                 {
     807              :                   found = true;
     808              :                   break;
     809              :                 }
     810              :             }
     811              : 
     812              :           /* If there were any such edges found, then remove jump threads
     813              :              containing any edge leaving BB.  */
     814      5056657 :           if (found)
     815       710755 :             FOR_EACH_EDGE (e, ei, bb->succs)
     816       467425 :               threader.remove_jump_threads_including (e);
     817              :         }
     818              :     }
     819              : 
     820      2136688 :   {
     821      2136688 :     gimple_stmt_iterator gsi;
     822      2136688 :     basic_block bb;
     823     24366268 :     FOR_EACH_BB_FN (bb, fun)
     824              :       {
     825    231836769 :         for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
     826    187377609 :           update_stmt_if_modified (gsi_stmt (gsi));
     827              :       }
     828              :   }
     829              : 
     830              :   /* If we exposed any new variables, go ahead and put them into
     831              :      SSA form now, before we handle jump threading.  This simplifies
     832              :      interactions between rewriting of _DECL nodes into SSA form
     833              :      and rewriting SSA_NAME nodes into SSA form after block
     834              :      duplication and CFG manipulation.  */
     835      2136688 :   update_ssa (TODO_update_ssa);
     836              : 
     837      2136688 :   free_all_edge_infos ();
     838              : 
     839              :   /* Thread jumps, creating duplicate blocks as needed.  */
     840      2136688 :   cfg_altered |= threader.thread_through_all_blocks (may_peel_loop_headers_p);
     841              : 
     842      2136688 :   if (cfg_altered)
     843       125639 :     free_dominance_info (CDI_DOMINATORS);
     844              : 
     845              :   /* Removal of statements may make some EH edges dead.  Purge
     846              :      such edges from the CFG as needed.  */
     847      2136688 :   if (!bitmap_empty_p (need_eh_cleanup))
     848              :     {
     849          558 :       unsigned i;
     850          558 :       bitmap_iterator bi;
     851              : 
     852              :       /* Jump threading may have created forwarder blocks from blocks
     853              :          needing EH cleanup; the new successor of these blocks, which
     854              :          has inherited from the original block, needs the cleanup.
     855              :          Don't clear bits in the bitmap, as that can break the bitmap
     856              :          iterator.  */
     857         1801 :       EXECUTE_IF_SET_IN_BITMAP (need_eh_cleanup, 0, i, bi)
     858              :         {
     859         1243 :           basic_block bb = BASIC_BLOCK_FOR_FN (fun, i);
     860         1243 :           if (bb == NULL)
     861            0 :             continue;
     862         2565 :           while (single_succ_p (bb)
     863         1377 :                  && (single_succ_edge (bb)->flags
     864          151 :                      & (EDGE_EH|EDGE_DFS_BACK)) == 0)
     865          134 :             bb = single_succ (bb);
     866         1243 :           if (bb == EXIT_BLOCK_PTR_FOR_FN (fun))
     867           55 :             continue;
     868         1188 :           if ((unsigned) bb->index != i)
     869           59 :             bitmap_set_bit (need_eh_cleanup, bb->index);
     870              :         }
     871              : 
     872          558 :       gimple_purge_all_dead_eh_edges (need_eh_cleanup);
     873          558 :       bitmap_clear (need_eh_cleanup);
     874              :     }
     875              : 
     876              :   /* Fixup stmts that became noreturn calls.  This may require splitting
     877              :      blocks and thus isn't possible during the dominator walk or before
     878              :      jump threading finished.  Do this in reverse order so we don't
     879              :      inadvertently remove a stmt we want to fixup by visiting a dominating
     880              :      now noreturn call first.  */
     881      2136691 :   while (!need_noreturn_fixup.is_empty ())
     882              :     {
     883            3 :       gimple *stmt = need_noreturn_fixup.pop ();
     884            3 :       if (dump_file && dump_flags & TDF_DETAILS)
     885              :         {
     886            0 :           fprintf (dump_file, "Fixing up noreturn call ");
     887            0 :           print_gimple_stmt (dump_file, stmt, 0);
     888            0 :           fprintf (dump_file, "\n");
     889              :         }
     890            3 :       fixup_noreturn_call (stmt);
     891              :     }
     892              : 
     893      2136688 :   statistics_counter_event (fun, "Redundant expressions eliminated",
     894      2136688 :                             opt_stats.num_re);
     895      2136688 :   statistics_counter_event (fun, "Constants propagated",
     896      2136688 :                             opt_stats.num_const_prop);
     897      2136688 :   statistics_counter_event (fun, "Copies propagated",
     898      2136688 :                             opt_stats.num_copy_prop);
     899              : 
     900              :   /* Debugging dumps.  */
     901      2136688 :   if (dump_file && (dump_flags & TDF_STATS))
     902           36 :     dump_dominator_optimization_stats (dump_file, avail_exprs);
     903              : 
     904      2136688 :   loop_optimizer_finalize ();
     905              : 
     906              :   /* Delete our main hashtable.  */
     907      2136688 :   delete avail_exprs;
     908      2136688 :   avail_exprs = NULL;
     909              : 
     910              :   /* Free asserted bitmaps and stacks.  */
     911      2136688 :   BITMAP_FREE (need_eh_cleanup);
     912      2136688 :   need_noreturn_fixup.release ();
     913      2136688 :   BITMAP_FREE (names_without_foldable_uses);
     914      2136688 :   delete avail_exprs_stack;
     915      2136688 :   delete const_and_copies;
     916              : 
     917      2136688 :   return 0;
     918      2136688 : }
     919              : 
     920              : } // anon namespace
     921              : 
     922              : gimple_opt_pass *
     923       294536 : make_pass_dominator (gcc::context *ctxt)
     924              : {
     925       294536 :   return new pass_dominator (ctxt);
     926              : }
     927              : 
     928              : /* Valueize hook for gimple_fold_stmt_to_constant_1.  */
     929              : 
     930              : static tree
     931     35332731 : dom_valueize (tree t)
     932              : {
     933     35332731 :   if (TREE_CODE (t) == SSA_NAME)
     934              :     {
     935     25382475 :       tree tem = SSA_NAME_VALUE (t);
     936     20171843 :       if (tem)
     937      3183733 :         return tem;
     938              :     }
     939              :   return t;
     940              : }
     941              : 
     942              : /* We have just found an equivalence for LHS on an edge E.
     943              :    Look backwards to other uses of LHS and see if we can derive
     944              :    additional equivalences that are valid on edge E.  */
     945              : static void
     946     12387014 : back_propagate_equivalences (tree lhs, edge e,
     947              :                              class const_and_copies *const_and_copies,
     948              :                              bitmap domby)
     949              : {
     950     12387014 :   use_operand_p use_p;
     951     12387014 :   imm_use_iterator iter;
     952     12387014 :   basic_block dest = e->dest;
     953     12387014 :   bool domok = (dom_info_state (CDI_DOMINATORS) == DOM_OK);
     954     12387014 :   unsigned version = SSA_NAME_VERSION (lhs);
     955              : 
     956              :   /* If an earlier walk found no use of LHS that can produce an
     957              :      equivalence, there is nothing to do.  With checking enabled, walk
     958              :      the uses anyway to verify that no such use has been added.  */
     959     12387014 :   bool cached_p = bitmap_bit_p (names_without_foldable_uses, version);
     960     12387014 :   if (cached_p && !flag_checking)
     961           49 :     return;
     962              : 
     963              :   /* Iterate over the uses of LHS to see if any dominate E->dest.
     964              :      If so, they may create useful equivalences too.
     965              : 
     966              :      ???  If the code gets re-organized to a worklist to catch more
     967              :      indirect opportunities and it is made to handle PHIs then this
     968              :      should only consider use_stmts in basic-blocks we have already visited.  */
     969     12386965 :   bool foldable_use_p = false;
     970     53422662 :   FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
     971              :     {
     972     41035697 :       gimple *use_stmt = USE_STMT (use_p);
     973              : 
     974              :       /* Filter out statements that can never produce a useful
     975              :          equivalence.  gimple_fold_stmt_to_constant_1 does not fold
     976              :          PHI nodes.  */
     977     41035697 :       if (gimple_code (use_stmt) == GIMPLE_PHI)
     978      3498073 :         continue;
     979     37537624 :       tree lhs2 = gimple_get_lhs (use_stmt);
     980     37537624 :       if (!lhs2 || TREE_CODE (lhs2) != SSA_NAME)
     981     29930665 :         continue;
     982              : 
     983      7606959 :       gcc_checking_assert (!cached_p);
     984      7606959 :       foldable_use_p = true;
     985              : 
     986              :       /* Often the use is in DEST, which we trivially know we can't use.
     987              :          This is cheaper than the dominator set tests below.  */
     988      7606959 :       if (dest == gimple_bb (use_stmt))
     989       114906 :         continue;
     990              : 
     991      7492053 :       if (domok)
     992              :         {
     993      4358163 :           if (!dominated_by_p (CDI_DOMINATORS, dest, gimple_bb (use_stmt)))
     994      2205554 :             continue;
     995              :         }
     996              :       else
     997              :         {
     998              :           /* We can use the set of BBs on the stack from a domwalk
     999              :              for a medium fast way to query dominance.  Profiling
    1000              :              has shown non-fast query dominance tests here can be fairly
    1001              :              expensive.  */
    1002              :           /* This tests if USE_STMT does not dominate DEST.  */
    1003      3133890 :           if (!bitmap_bit_p (domby, gimple_bb (use_stmt)->index))
    1004      2158867 :             continue;
    1005              :         }
    1006              : 
    1007              :       /* At this point USE_STMT dominates DEST and may result in a
    1008              :          useful equivalence.  Try to simplify its RHS to a constant
    1009              :          or SSA_NAME.  */
    1010      3127632 :       tree res = gimple_fold_stmt_to_constant_1 (use_stmt, dom_valueize,
    1011              :                                                  no_follow_ssa_edges);
    1012      3127632 :       if (res && (TREE_CODE (res) == SSA_NAME || is_gimple_min_invariant (res)))
    1013      2464965 :         record_equality (lhs2, res, const_and_copies);
    1014     12386965 :     }
    1015              : 
    1016     12386965 :   if (!foldable_use_p)
    1017      8809339 :     bitmap_set_bit (names_without_foldable_uses, version);
    1018              : }
    1019              : 
    1020              : /* Record into CONST_AND_COPIES and AVAIL_EXPRS_STACK any equivalences implied
    1021              :    by traversing edge E (which are cached in E->aux).
    1022              : 
    1023              :    Callers are responsible for managing the unwinding markers.  */
    1024              : static void
    1025     34095374 : record_temporary_equivalences (edge e,
    1026              :                                class const_and_copies *const_and_copies,
    1027              :                                class avail_exprs_stack *avail_exprs_stack,
    1028              :                                bitmap blocks_on_stack)
    1029              : {
    1030     34095374 :   int i;
    1031     34095374 :   class edge_info *edge_info = (class edge_info *) e->aux;
    1032              : 
    1033              :   /* If we have info associated with this edge, record it into
    1034              :      our equivalence tables.  */
    1035     34095374 :   if (edge_info)
    1036              :     {
    1037              :       cond_equivalence *eq;
    1038              :       /* If we have 0 = COND or 1 = COND equivalences, record them
    1039              :          into our expression hash tables.  */
    1040     68797527 :       for (i = 0; edge_info->cond_equivalences.iterate (i, &eq); ++i)
    1041     44270072 :         avail_exprs_stack->record_cond (eq);
    1042              : 
    1043              :       edge_info::equiv_pair *seq;
    1044     36914469 :       for (i = 0; edge_info->simple_equivalences.iterate (i, &seq); ++i)
    1045              :         {
    1046     12387014 :           tree lhs = seq->first;
    1047     12387014 :           if (!lhs || TREE_CODE (lhs) != SSA_NAME)
    1048            0 :             continue;
    1049              : 
    1050              :           /* Record the simple NAME = VALUE equivalence.  */
    1051     12387014 :           tree rhs = seq->second;
    1052              : 
    1053              :           /* If this is a SSA_NAME = SSA_NAME equivalence and one operand is
    1054              :              cheaper to compute than the other, then set up the equivalence
    1055              :              such that we replace the expensive one with the cheap one.
    1056              : 
    1057              :              If they are the same cost to compute, then do not record
    1058              :              anything.  */
    1059     12387014 :           if (TREE_CODE (lhs) == SSA_NAME && TREE_CODE (rhs) == SSA_NAME)
    1060              :             {
    1061      1788489 :               gimple *rhs_def = SSA_NAME_DEF_STMT (rhs);
    1062      1788489 :               int rhs_cost = estimate_num_insns (rhs_def, &eni_size_weights);
    1063              : 
    1064      1788489 :               gimple *lhs_def = SSA_NAME_DEF_STMT (lhs);
    1065      1788489 :               int lhs_cost = estimate_num_insns (lhs_def, &eni_size_weights);
    1066              : 
    1067      1788489 :               if (rhs_cost > lhs_cost)
    1068       198034 :                 record_equality (rhs, lhs, const_and_copies);
    1069      1590455 :               else if (rhs_cost < lhs_cost)
    1070       482348 :                 record_equality (lhs, rhs, const_and_copies);
    1071              :             }
    1072              :           else
    1073     10598525 :             record_equality (lhs, rhs, const_and_copies);
    1074              : 
    1075              : 
    1076              :           /* Any equivalence found for LHS may result in additional
    1077              :              equivalences for other uses of LHS that we have already
    1078              :              processed.  */
    1079     12387014 :           back_propagate_equivalences (lhs, e, const_and_copies,
    1080              :                                        blocks_on_stack);
    1081              :         }
    1082              :     }
    1083     34095374 : }
    1084              : 
    1085              : /* PHI nodes can create equivalences too.
    1086              : 
    1087              :    Ignoring any alternatives which are the same as the result, if
    1088              :    all the alternatives are equal, then the PHI node creates an
    1089              :    equivalence.  */
    1090              : 
    1091              : static void
    1092     24281925 : record_equivalences_from_phis (basic_block bb)
    1093              : {
    1094     24281925 :   gphi_iterator gsi;
    1095              : 
    1096     33843609 :   for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); )
    1097              :     {
    1098      9561684 :       gphi *phi = gsi.phi ();
    1099              : 
    1100              :       /* We might eliminate the PHI, so advance GSI now.  */
    1101      9561684 :       gsi_next (&gsi);
    1102              : 
    1103      9561684 :       tree lhs = gimple_phi_result (phi);
    1104      9561684 :       tree rhs = NULL;
    1105      9561684 :       size_t i;
    1106              : 
    1107     17265526 :       for (i = 0; i < gimple_phi_num_args (phi); i++)
    1108              :         {
    1109     16166284 :           tree t = gimple_phi_arg_def (phi, i);
    1110              : 
    1111              :           /* Ignore alternatives which are the same as our LHS.  Since
    1112              :              LHS is a PHI_RESULT, it is known to be a SSA_NAME, so we
    1113              :              can simply compare pointers.  */
    1114     16166284 :           if (lhs == t)
    1115        31657 :             continue;
    1116              : 
    1117              :           /* If the associated edge is not marked as executable, then it
    1118              :              can be ignored.  */
    1119     16134627 :           if ((gimple_phi_arg_edge (phi, i)->flags & EDGE_EXECUTABLE) == 0)
    1120       135677 :             continue;
    1121              : 
    1122     15998950 :           t = dom_valueize (t);
    1123              : 
    1124              :           /* If T is an SSA_NAME and its associated edge is a backedge,
    1125              :              then quit as we cannot utilize this equivalence.  */
    1126     15998950 :           if (TREE_CODE (t) == SSA_NAME
    1127     15998950 :               && (gimple_phi_arg_edge (phi, i)->flags & EDGE_DFS_BACK))
    1128              :             break;
    1129              : 
    1130              :           /* If we have not processed an alternative yet, then set
    1131              :              RHS to this alternative.  */
    1132     12892253 :           if (rhs == NULL)
    1133              :             rhs = t;
    1134              :           /* If we have processed an alternative (stored in RHS), then
    1135              :              see if it is equal to this one.  If it isn't, then stop
    1136              :              the search.  */
    1137      5927438 :           else if (! operand_equal_for_phi_arg_p (rhs, t))
    1138              :             break;
    1139              :         }
    1140              : 
    1141              :       /* If we had no interesting alternatives, then all the RHS alternatives
    1142              :          must have been the same as LHS.  */
    1143      9561684 :       if (!rhs)
    1144      2596869 :         rhs = lhs;
    1145              : 
    1146              :       /* If we managed to iterate through each PHI alternative without
    1147              :          breaking out of the loop, then we have a PHI which may create
    1148              :          a useful equivalence.  We do not need to record unwind data for
    1149              :          this, since this is a true assignment and not an equivalence
    1150              :          inferred from a comparison.  All uses of this ssa name are dominated
    1151              :          by this assignment, so unwinding just costs time and space.  */
    1152      9561684 :       if (i == gimple_phi_num_args (phi))
    1153              :         {
    1154      1099242 :           if (may_propagate_copy (lhs, rhs))
    1155       608480 :             set_ssa_name_value (lhs, rhs);
    1156       981524 :           else if (virtual_operand_p (lhs))
    1157              :             {
    1158       490318 :               gimple *use_stmt;
    1159       490318 :               imm_use_iterator iter;
    1160       490318 :               use_operand_p use_p;
    1161              :               /* For virtual operands we have to propagate into all uses as
    1162              :                  otherwise we will create overlapping life-ranges.  */
    1163      1477805 :               FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
    1164      2042538 :                 FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
    1165      1021269 :                   SET_USE (use_p, rhs);
    1166       490318 :               if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
    1167           70 :                 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs) = 1;
    1168       490318 :               gimple_stmt_iterator tmp_gsi = gsi_for_stmt (phi);
    1169       490318 :               remove_phi_node (&tmp_gsi, true);
    1170              :             }
    1171              :         }
    1172              :     }
    1173     24281925 : }
    1174              : 
    1175              : /* Return true if all uses of NAME are dominated by STMT or feed STMT
    1176              :    via a chain of single immediate uses.  */
    1177              : 
    1178              : static bool
    1179       430351 : all_uses_feed_or_dominated_by_stmt (tree name, gimple *stmt)
    1180              : {
    1181       430351 :   use_operand_p use_p, use2_p;
    1182       430351 :   imm_use_iterator iter;
    1183       430351 :   basic_block stmt_bb = gimple_bb (stmt);
    1184              : 
    1185      1786234 :   FOR_EACH_IMM_USE_FAST (use_p, iter, name)
    1186              :     {
    1187      1585599 :       gimple *use_stmt = USE_STMT (use_p), *use_stmt2;
    1188      2932797 :       if (use_stmt == stmt
    1189      1439463 :           || is_gimple_debug (use_stmt)
    1190      2364628 :           || (gimple_bb (use_stmt) != stmt_bb
    1191       612089 :               && dominated_by_p (CDI_DOMINATORS,
    1192       612089 :                                  gimple_bb (use_stmt), stmt_bb)))
    1193      1347198 :         continue;
    1194              :       while (use_stmt != stmt
    1195       446378 :              && is_gimple_assign (use_stmt)
    1196       389879 :              && TREE_CODE (gimple_assign_lhs (use_stmt)) == SSA_NAME
    1197       829952 :              && single_imm_use (gimple_assign_lhs (use_stmt),
    1198              :                                 &use2_p, &use_stmt2))
    1199       216662 :         use_stmt = use_stmt2;
    1200       238401 :       if (use_stmt != stmt)
    1201       229716 :         return false;
    1202       229716 :     }
    1203       200635 :   return true;
    1204              : }
    1205              : 
    1206              : /* Handle
    1207              :    _4 = x_3 & 31;
    1208              :    if (_4 != 0)
    1209              :      goto <bb 6>;
    1210              :    else
    1211              :      goto <bb 7>;
    1212              :    <bb 6>:
    1213              :    __builtin_unreachable ();
    1214              :    <bb 7>:
    1215              : 
    1216              :    If x_3 has no other immediate uses (checked by caller), var is the
    1217              :    x_3 var, we can clear low 5 bits from the non-zero bitmask.  */
    1218              : 
    1219              : static void
    1220       179445 : maybe_set_nonzero_bits (edge e, tree var)
    1221              : {
    1222       179445 :   basic_block cond_bb = e->src;
    1223       358890 :   gcond *cond = safe_dyn_cast <gcond *> (*gsi_last_bb (cond_bb));
    1224       179445 :   tree cst;
    1225              : 
    1226       179445 :   if (cond == NULL
    1227       179445 :       || gimple_cond_code (cond) != ((e->flags & EDGE_TRUE_VALUE)
    1228       179445 :                                      ? EQ_EXPR : NE_EXPR)
    1229        53256 :       || TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
    1230         2062 :       || !integer_zerop (gimple_cond_rhs (cond)))
    1231              :     return;
    1232              : 
    1233         1987 :   gimple *stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (cond));
    1234         1987 :   if (!is_gimple_assign (stmt)
    1235         1965 :       || gimple_assign_rhs_code (stmt) != BIT_AND_EXPR
    1236         2014 :       || TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST)
    1237              :     return;
    1238            1 :   if (gimple_assign_rhs1 (stmt) != var)
    1239              :     {
    1240            1 :       gimple *stmt2;
    1241              : 
    1242            1 :       if (TREE_CODE (gimple_assign_rhs1 (stmt)) != SSA_NAME)
    1243              :         return;
    1244            1 :       stmt2 = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
    1245            1 :       if (!gimple_assign_cast_p (stmt2)
    1246            0 :           || gimple_assign_rhs1 (stmt2) != var
    1247            0 :           || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt2))
    1248            1 :           || (TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (stmt)))
    1249            0 :                               != TYPE_PRECISION (TREE_TYPE (var))))
    1250              :         return;
    1251              :     }
    1252            0 :   cst = gimple_assign_rhs2 (stmt);
    1253            0 :   if (POINTER_TYPE_P (TREE_TYPE (var)))
    1254              :     {
    1255            0 :       struct ptr_info_def *pi = SSA_NAME_PTR_INFO (var);
    1256            0 :       if (pi && pi->misalign)
    1257            0 :         return;
    1258            0 :       wide_int w = wi::bit_not (wi::to_wide (cst));
    1259            0 :       unsigned int bits = wi::ctz (w);
    1260            0 :       if (bits == 0 || bits >= HOST_BITS_PER_INT)
    1261            0 :         return;
    1262            0 :       unsigned int align = 1U << bits;
    1263            0 :       if (pi == NULL || pi->align < align)
    1264            0 :         set_ptr_info_alignment (get_ptr_info (var), align, 0);
    1265            0 :     }
    1266              :   else
    1267            0 :     set_nonzero_bits (var, wi::bit_and_not (get_nonzero_bits (var),
    1268            0 :                                             wi::to_wide (cst)));
    1269              : }
    1270              : 
    1271              : /* Set global ranges that can be determined from the C->M edge:
    1272              : 
    1273              :    <bb C>:
    1274              :    ...
    1275              :    if (something)
    1276              :      goto <bb N>;
    1277              :    else
    1278              :      goto <bb M>;
    1279              :    <bb N>:
    1280              :    __builtin_unreachable ();
    1281              :    <bb M>:
    1282              : */
    1283              : 
    1284              : void
    1285     24281925 : dom_opt_dom_walker::set_global_ranges_from_unreachable_edges (basic_block bb)
    1286              : {
    1287     24281925 :   edge pred_e = single_pred_edge_ignoring_loop_edges (bb, false);
    1288     24281925 :   if (!pred_e)
    1289              :     return;
    1290              : 
    1291     18076765 :   gimple *stmt = *gsi_last_bb (pred_e->src);
    1292     18076765 :   if (!stmt
    1293     15227836 :       || gimple_code (stmt) != GIMPLE_COND
    1294     30571316 :       || !assert_unreachable_fallthru_edge_p (pred_e))
    1295              :     return;
    1296              : 
    1297              :   // Bail if the condition leading to the unreachable edge has 2 ssa-names.
    1298              :   // See PR 125501.
    1299       243760 :   if ((TREE_CODE (gimple_cond_lhs (stmt)) == SSA_NAME
    1300       243760 :       && TREE_CODE (gimple_cond_rhs (stmt)) == SSA_NAME))
    1301              :     return;
    1302              : 
    1303       240933 :   tree name;
    1304       671284 :   FOR_EACH_GORI_EXPORT_NAME (m_ranger->gori_ssa (), pred_e->src, name)
    1305       430351 :     if (all_uses_feed_or_dominated_by_stmt (name, stmt)
    1306              :         // The condition must post-dominate the definition point.
    1307       630986 :         && (SSA_NAME_IS_DEFAULT_DEF (name)
    1308       200511 :             || (gimple_bb (SSA_NAME_DEF_STMT (name))
    1309       200511 :                 == pred_e->src)))
    1310              :       {
    1311       194109 :         value_range r (TREE_TYPE (name));
    1312              : 
    1313       194109 :         if (m_ranger->range_on_edge (r, pred_e, name)
    1314       194109 :             && !r.varying_p ()
    1315       373623 :             && !r.undefined_p ())
    1316              :           {
    1317       179445 :             set_range_info (name, r);
    1318       179445 :             maybe_set_nonzero_bits (pred_e, name);
    1319              :           }
    1320       194109 :       }
    1321              : }
    1322              : 
    1323              : /* Record any equivalences created by the incoming edge to BB.  If BB
    1324              :    has more than one incoming edge, then no equivalence is created.  */
    1325              : 
    1326              : void
    1327     24281925 : dom_opt_dom_walker::record_equivalences_from_incoming_edge (basic_block bb)
    1328              : {
    1329     24281925 :   edge e;
    1330     24281925 :   basic_block parent;
    1331              : 
    1332              :   /* If our parent block ended with a control statement, then we may be
    1333              :      able to record some equivalences based on which outgoing edge from
    1334              :      the parent was followed.  */
    1335     24281925 :   parent = get_immediate_dominator (CDI_DOMINATORS, bb);
    1336              : 
    1337     24281925 :   e = single_pred_edge_ignoring_loop_edges (bb, true);
    1338              : 
    1339              :   /* If we had a single incoming edge from our parent block, then enter
    1340              :      any data associated with the edge into our tables.  */
    1341     24281925 :   if (e && e->src == parent)
    1342     18082378 :     record_temporary_equivalences (e, m_const_and_copies, m_avail_exprs_stack,
    1343     18082378 :                                    m_state->get_blocks_on_stack ());
    1344     24281925 : }
    1345              : 
    1346              : /* Dump statistics for the hash table HTAB.  */
    1347              : 
    1348              : static void
    1349           36 : htab_statistics (FILE *file, const hash_table<expr_elt_hasher> &htab)
    1350              : {
    1351           68 :   fprintf (file, "size " HOST_SIZE_T_PRINT_DEC ", " HOST_SIZE_T_PRINT_DEC
    1352              :            " elements, %f collision/search ratio\n",
    1353           36 :            (fmt_size_t) htab.size (),
    1354           36 :            (fmt_size_t) htab.elements (),
    1355              :            htab.collisions ());
    1356           36 : }
    1357              : 
    1358              : /* Dump SSA statistics on FILE.  */
    1359              : 
    1360              : static void
    1361           36 : dump_dominator_optimization_stats (FILE *file,
    1362              :                                    hash_table<expr_elt_hasher> *avail_exprs)
    1363              : {
    1364           36 :   fprintf (file, "Total number of statements:                   %6ld\n\n",
    1365              :            opt_stats.num_stmts);
    1366           36 :   fprintf (file, "Exprs considered for dominator optimizations: %6ld\n",
    1367              :            opt_stats.num_exprs_considered);
    1368              : 
    1369           36 :   fprintf (file, "\nHash table statistics:\n");
    1370              : 
    1371           36 :   fprintf (file, "    avail_exprs: ");
    1372           36 :   htab_statistics (file, *avail_exprs);
    1373           36 : }
    1374              : 
    1375              : 
    1376              : /* Similarly, but assume that X and Y are the two operands of an EQ_EXPR.
    1377              :    This constrains the cases in which we may treat this as assignment.  */
    1378              : 
    1379              : static void
    1380     13743872 : record_equality (tree x, tree y, class const_and_copies *const_and_copies)
    1381              : {
    1382     13743872 :   tree prev_x = NULL, prev_y = NULL;
    1383              : 
    1384     13743872 :   if (tree_swap_operands_p (x, y))
    1385       622442 :     std::swap (x, y);
    1386              : 
    1387              :   /* Most of the time tree_swap_operands_p does what we want.  But there
    1388              :      are cases where we know one operand is better for copy propagation than
    1389              :      the other.  Given no other code cares about ordering of equality
    1390              :      comparison operators for that purpose, we just handle the special cases
    1391              :      here.  */
    1392     13743872 :   if (TREE_CODE (x) == SSA_NAME && TREE_CODE (y) == SSA_NAME)
    1393              :     {
    1394              :       /* If one operand is a single use operand, then make it
    1395              :          X.  This will preserve its single use properly and if this
    1396              :          conditional is eliminated, the computation of X can be
    1397              :          eliminated as well.  */
    1398      1153557 :       if (has_single_use (y) && ! has_single_use (x))
    1399              :         std::swap (x, y);
    1400              :     }
    1401     13743872 :   if (TREE_CODE (x) == SSA_NAME)
    1402     13743872 :     prev_x = SSA_NAME_VALUE (x);
    1403     13743872 :   if (TREE_CODE (y) == SSA_NAME)
    1404      1153557 :     prev_y = SSA_NAME_VALUE (y);
    1405              : 
    1406              :   /* If one of the previous values is invariant, or invariant in more loops
    1407              :      (by depth), then use that.
    1408              :      Otherwise it doesn't matter which value we choose, just so
    1409              :      long as we canonicalize on one value.  */
    1410     13743872 :   if (is_gimple_min_invariant (y))
    1411              :     ;
    1412      1153557 :   else if (is_gimple_min_invariant (x))
    1413              :     prev_x = x, x = y, y = prev_x, prev_x = prev_y;
    1414      1153557 :   else if (prev_x && is_gimple_min_invariant (prev_x))
    1415              :     x = y, y = prev_x, prev_x = prev_y;
    1416      1062491 :   else if (prev_y)
    1417     13743872 :     y = prev_y;
    1418              : 
    1419              :   /* After the swapping, we must have one SSA_NAME.  */
    1420     13743872 :   if (TREE_CODE (x) != SSA_NAME)
    1421              :     return;
    1422              : 
    1423              :   /* For IEEE, -0.0 == 0.0, so we don't necessarily know the sign of a
    1424              :      variable compared against zero.  If we're honoring signed zeros,
    1425              :      then we cannot record this value unless we know that the value is
    1426              :      nonzero.  */
    1427     13743872 :   if (HONOR_SIGNED_ZEROS (x)
    1428     13743872 :       && (TREE_CODE (y) != REAL_CST
    1429       172132 :           || real_equal (&dconst0, &TREE_REAL_CST (y))))
    1430              :     return;
    1431              : 
    1432     13743534 :   const_and_copies->record_const_or_copy (x, y, prev_x);
    1433              : }
    1434              : 
    1435              : /* Returns true when STMT is a simple iv increment.  It detects the
    1436              :    following situation:
    1437              : 
    1438              :    i_1 = phi (..., i_k)
    1439              :    [...]
    1440              :    i_j = i_{j-1}  for each j : 2 <= j <= k-1
    1441              :    [...]
    1442              :    i_k = i_{k-1} +/- ...  */
    1443              : 
    1444              : bool
    1445     44211461 : simple_iv_increment_p (gimple *stmt)
    1446              : {
    1447     44211461 :   enum tree_code code;
    1448     44211461 :   tree lhs, preinc;
    1449     44211461 :   gimple *phi;
    1450     44211461 :   size_t i;
    1451              : 
    1452     44211461 :   if (gimple_code (stmt) != GIMPLE_ASSIGN)
    1453              :     return false;
    1454              : 
    1455     33932857 :   lhs = gimple_assign_lhs (stmt);
    1456     33932857 :   if (TREE_CODE (lhs) != SSA_NAME)
    1457              :     return false;
    1458              : 
    1459     33932857 :   code = gimple_assign_rhs_code (stmt);
    1460     33932857 :   if (code != PLUS_EXPR
    1461     33932857 :       && code != MINUS_EXPR
    1462     33932857 :       && code != POINTER_PLUS_EXPR)
    1463              :     return false;
    1464              : 
    1465      8131974 :   preinc = gimple_assign_rhs1 (stmt);
    1466      8131974 :   if (TREE_CODE (preinc) != SSA_NAME)
    1467              :     return false;
    1468              : 
    1469      7850214 :   phi = SSA_NAME_DEF_STMT (preinc);
    1470      7876131 :   while (gimple_code (phi) != GIMPLE_PHI)
    1471              :     {
    1472              :       /* Follow trivial copies, but not the DEF used in a back edge,
    1473              :          so that we don't prevent coalescing.  */
    1474      5326308 :       if (!gimple_assign_ssa_name_copy_p (phi))
    1475              :         return false;
    1476        25917 :       preinc = gimple_assign_rhs1 (phi);
    1477        25917 :       phi = SSA_NAME_DEF_STMT (preinc);
    1478              :     }
    1479              : 
    1480      5004195 :   for (i = 0; i < gimple_phi_num_args (phi); i++)
    1481      4056125 :     if (gimple_phi_arg_def (phi, i) == lhs)
    1482              :       return true;
    1483              : 
    1484              :   return false;
    1485              : }
    1486              : 
    1487              : /* Propagate know values from SSA_NAME_VALUE into the PHI nodes of the
    1488              :    successors of BB.  */
    1489              : 
    1490              : static void
    1491     24281925 : cprop_into_successor_phis (basic_block bb,
    1492              :                            class const_and_copies *const_and_copies)
    1493              : {
    1494     24281925 :   edge e;
    1495     24281925 :   edge_iterator ei;
    1496              : 
    1497     57687473 :   FOR_EACH_EDGE (e, ei, bb->succs)
    1498              :     {
    1499     33405548 :       int indx;
    1500     33405548 :       gphi_iterator gsi;
    1501              : 
    1502              :       /* If this is an abnormal edge, then we do not want to copy propagate
    1503              :          into the PHI alternative associated with this edge.  */
    1504     33405548 :       if (e->flags & EDGE_ABNORMAL)
    1505     19669194 :         continue;
    1506              : 
    1507     33391505 :       gsi = gsi_start_phis (e->dest);
    1508     33391505 :       if (gsi_end_p (gsi))
    1509     19655151 :         continue;
    1510              : 
    1511              :       /* We may have an equivalence associated with this edge.  While
    1512              :          we cannot propagate it into non-dominated blocks, we can
    1513              :          propagate them into PHIs in non-dominated blocks.  */
    1514              : 
    1515              :       /* Push the unwind marker so we can reset the const and copies
    1516              :          table back to its original state after processing this edge.  */
    1517     13736354 :       const_and_copies->push_marker ();
    1518              : 
    1519              :       /* Extract and record any simple NAME = VALUE equivalences.
    1520              : 
    1521              :          Don't bother with [01] = COND equivalences, they're not useful
    1522              :          here.  */
    1523     13736354 :       class edge_info *edge_info = (class edge_info *) e->aux;
    1524              : 
    1525     13736354 :       if (edge_info)
    1526              :         {
    1527              :           edge_info::equiv_pair *seq;
    1528      8624772 :           for (int i = 0; edge_info->simple_equivalences.iterate (i, &seq); ++i)
    1529              :             {
    1530      3314913 :               tree lhs = seq->first;
    1531      3314913 :               tree rhs = seq->second;
    1532              : 
    1533      3314913 :               if (lhs && TREE_CODE (lhs) == SSA_NAME)
    1534      3314913 :                 const_and_copies->record_const_or_copy (lhs, rhs);
    1535              :             }
    1536              : 
    1537              :         }
    1538              : 
    1539     13736354 :       indx = e->dest_idx;
    1540     37862691 :       for ( ; !gsi_end_p (gsi); gsi_next (&gsi))
    1541              :         {
    1542     24126337 :           tree new_val;
    1543     24126337 :           use_operand_p orig_p;
    1544     24126337 :           tree orig_val;
    1545     24126337 :           gphi *phi = gsi.phi ();
    1546              : 
    1547              :           /* The alternative may be associated with a constant, so verify
    1548              :              it is an SSA_NAME before doing anything with it.  */
    1549     24126337 :           orig_p = gimple_phi_arg_imm_use_ptr (phi, indx);
    1550     24126337 :           orig_val = get_use_from_ptr (orig_p);
    1551     24126337 :           if (TREE_CODE (orig_val) != SSA_NAME)
    1552      3258767 :             continue;
    1553              : 
    1554              :           /* If we have *ORIG_P in our constant/copy table, then replace
    1555              :              ORIG_P with its value in our constant/copy table.  */
    1556     20867570 :           new_val = SSA_NAME_VALUE (orig_val);
    1557     20867570 :           if (new_val
    1558     20867570 :               && new_val != orig_val
    1559     20867570 :               && may_propagate_copy (orig_val, new_val))
    1560      1215685 :             propagate_value (orig_p, new_val);
    1561              :         }
    1562              : 
    1563     13736354 :       const_and_copies->pop_to_marker ();
    1564              :     }
    1565     24281925 : }
    1566              : 
    1567              : edge
    1568     24281925 : dom_opt_dom_walker::before_dom_children (basic_block bb)
    1569              : {
    1570     24281925 :   gimple_stmt_iterator gsi;
    1571              : 
    1572     24281925 :   if (dump_file && (dump_flags & TDF_DETAILS))
    1573          764 :     fprintf (dump_file, "\n\nOptimizing block #%d\n\n", bb->index);
    1574              : 
    1575              :   /* Push a marker on the stacks of local information so that we know how
    1576              :      far to unwind when we finalize this block.  */
    1577     24281925 :   m_avail_exprs_stack->push_marker ();
    1578     24281925 :   m_const_and_copies->push_marker ();
    1579     24281925 :   bitmap_set_bit (m_state->get_blocks_on_stack (), bb->index);
    1580              : 
    1581     24281925 :   record_equivalences_from_incoming_edge (bb);
    1582     24281925 :   set_global_ranges_from_unreachable_edges (bb);
    1583              : 
    1584              :   /* PHI nodes can create equivalences too.  */
    1585     24281925 :   record_equivalences_from_phis (bb);
    1586              : 
    1587              :   /* Create equivalences from redundant PHIs.  PHIs are only truly
    1588              :      redundant when they exist in the same block, so push another
    1589              :      marker and unwind right afterwards.  */
    1590     24281925 :   m_avail_exprs_stack->push_marker ();
    1591     33353291 :   for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    1592      9071366 :     eliminate_redundant_computations (&gsi);
    1593     24281925 :   m_avail_exprs_stack->pop_to_marker ();
    1594              : 
    1595     24281925 :   edge taken_edge = NULL;
    1596              :   /* Initialize visited flag ahead of us, it has undefined state on
    1597              :      pass entry.  */
    1598    234858804 :   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    1599    186294954 :     gimple_set_visited (gsi_stmt (gsi), false);
    1600    396747670 :   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
    1601              :     {
    1602              :       /* Do not optimize a stmt twice, substitution might end up with
    1603              :          _3 = _3 which is not valid.  */
    1604    372465745 :       if (gimple_visited_p (gsi_stmt (gsi)))
    1605              :         {
    1606    186170632 :           gsi_next (&gsi);
    1607    186170632 :           continue;
    1608              :         }
    1609              : 
    1610    186295113 :       bool removed_p = false;
    1611    186295113 :       taken_edge = this->optimize_stmt (bb, &gsi, &removed_p);
    1612    186295113 :       if (!removed_p)
    1613              :         {
    1614    186170632 :           gimple *stmt = gsi_stmt (gsi);
    1615    186170632 :           gimple_set_visited (stmt, true);
    1616              : 
    1617              :           /* Propagation and folding may have added uses to STMT, which
    1618              :              back_propagate_equivalences has to consider.  */
    1619    186170632 :           tree lhs = gimple_get_lhs (stmt);
    1620    186170632 :           if (lhs && TREE_CODE (lhs) == SSA_NAME)
    1621              :             {
    1622     36880523 :               ssa_op_iter iter;
    1623     36880523 :               tree use;
    1624     72736313 :               FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
    1625     35855790 :                 bitmap_clear_bit (names_without_foldable_uses,
    1626     35855790 :                                   SSA_NAME_VERSION (use));
    1627              :             }
    1628              :         }
    1629              : 
    1630              :       /* Go back and visit stmts inserted by folding after substituting
    1631              :          into the stmt at gsi.  */
    1632    186295113 :       if (gsi_end_p (gsi))
    1633              :         {
    1634         2819 :           gcc_checking_assert (removed_p);
    1635         2819 :           gsi = gsi_last_bb (bb);
    1636         2819 :           while (!gsi_end_p (gsi) && !gimple_visited_p (gsi_stmt (gsi)))
    1637            0 :             gsi_prev (&gsi);
    1638              :         }
    1639              :       else
    1640              :         {
    1641    186292453 :           do
    1642              :             {
    1643    186292453 :               gsi_prev (&gsi);
    1644              :             }
    1645    372584747 :           while (!gsi_end_p (gsi) && !gimple_visited_p (gsi_stmt (gsi)));
    1646              :         }
    1647    186295113 :       if (gsi_end_p (gsi))
    1648     40136954 :         gsi = gsi_start_bb (bb);
    1649              :       else
    1650    166226636 :         gsi_next (&gsi);
    1651              :     }
    1652              : 
    1653              :   /* Now prepare to process dominated blocks.  */
    1654     24281925 :   record_edge_info (bb);
    1655     24281925 :   cprop_into_successor_phis (bb, m_const_and_copies);
    1656     24281925 :   if (taken_edge && !dbg_cnt (dom_unreachable_edges))
    1657            0 :     return NULL;
    1658              : 
    1659              :   return taken_edge;
    1660              : }
    1661              : 
    1662              : /* We have finished processing the dominator children of BB, perform
    1663              :    any finalization actions in preparation for leaving this node in
    1664              :    the dominator tree.  */
    1665              : 
    1666              : void
    1667     24281925 : dom_opt_dom_walker::after_dom_children (basic_block bb)
    1668              : {
    1669     24281925 :   if (param_dom_jump_threading)
    1670     24281176 :     m_threader->thread_outgoing_edges (bb);
    1671     24281925 :   bitmap_clear_bit (m_state->get_blocks_on_stack (), bb->index);
    1672     24281925 :   m_avail_exprs_stack->pop_to_marker ();
    1673     24281925 :   m_const_and_copies->pop_to_marker ();
    1674     24281925 : }
    1675              : 
    1676              : /* Return the constant STMT computes, and barring that, an operand its
    1677              :    result is equivalent to.  NULL if neither.  */
    1678              : 
    1679              : tree
    1680     65023174 : dom_opt_dom_walker::const_or_copy_of_stmt (gimple *stmt)
    1681              : {
    1682     65023174 :   if (tree val = m_ranger->value_of_stmt (stmt))
    1683              :     return val;
    1684              : 
    1685              :   /* We could remove this gate, but we'd end up with tons of useless
    1686              :      replacements (casts, copies, etc).  Best to keep it to binops, which is
    1687              :      what the original code did.  */
    1688     64301023 :   if (!is_gimple_assign (stmt)
    1689    109209253 :       || gimple_assign_rhs_class (stmt) != GIMPLE_BINARY_RHS)
    1690              :     return NULL_TREE;
    1691              : 
    1692     11925266 :   tree lhs = gimple_assign_lhs (stmt);
    1693     11925266 :   tree rhs1 = gimple_assign_rhs1 (stmt);
    1694     11925266 :   tree rhs2 = gimple_assign_rhs2 (stmt);
    1695     11925266 :   if (m_ranger->relation ().query (stmt, lhs, rhs1) == VREL_EQ)
    1696              :     return rhs1;
    1697     11921836 :   if (m_ranger->relation ().query (stmt, lhs, rhs2) == VREL_EQ)
    1698           43 :     return rhs2;
    1699              : 
    1700              :   return NULL_TREE;
    1701              : }
    1702              : 
    1703              : /* Search for redundant computations in STMT.  If any are found, then
    1704              :    replace them with the variable holding the result of the computation.
    1705              : 
    1706              :    If safe, record this expression into the tables.  */
    1707              : 
    1708              : void
    1709     65509960 : dom_opt_dom_walker::eliminate_redundant_computations (gimple_stmt_iterator *gsi)
    1710              : {
    1711     65509960 :   tree expr_type;
    1712     65509960 :   tree cached_lhs;
    1713     65509960 :   tree def;
    1714     65509960 :   bool insert = true;
    1715     65509960 :   bool assigns_var_p = false;
    1716              : 
    1717     65509960 :   gimple *stmt = gsi_stmt (*gsi);
    1718              : 
    1719     65509960 :   if (gimple_code (stmt) == GIMPLE_PHI)
    1720      9071366 :     def = gimple_phi_result (stmt);
    1721              :   else
    1722     56438594 :     def = gimple_get_lhs (stmt);
    1723              : 
    1724              :   /* Certain expressions on the RHS can be optimized away, but cannot
    1725              :      themselves be entered into the hash tables.  */
    1726     65509960 :   if (! def
    1727     56146118 :       || TREE_CODE (def) != SSA_NAME
    1728     43072559 :       || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def)
    1729     33999913 :       || gimple_vdef (stmt)
    1730              :       /* Do not record equivalences for increments of ivs.  This would create
    1731              :          overlapping live ranges for a very questionable gain.  */
    1732    108571833 :       || simple_iv_increment_p (stmt))
    1733              :     insert = false;
    1734              : 
    1735              :   /* Check if the expression has been computed before.  */
    1736     65509960 :   cached_lhs = m_avail_exprs_stack->lookup_avail_expr (stmt, insert, true);
    1737              : 
    1738              :   /* Otherwise, ask the ranger.  */
    1739     65509960 :   if (!cached_lhs)
    1740     65023174 :     cached_lhs = const_or_copy_of_stmt (stmt);
    1741              : 
    1742     65509960 :   opt_stats.num_exprs_considered++;
    1743              : 
    1744              :   /* Get the type of the expression we are trying to optimize.  */
    1745     65509960 :   if (is_gimple_assign (stmt))
    1746              :     {
    1747     45795821 :       expr_type = TREE_TYPE (gimple_assign_lhs (stmt));
    1748     45795821 :       assigns_var_p = true;
    1749              :     }
    1750     19714139 :   else if (gimple_code (stmt) == GIMPLE_COND)
    1751      9327798 :     expr_type = boolean_type_node;
    1752     10386341 :   else if (is_gimple_call (stmt))
    1753              :     {
    1754      1278931 :       gcc_assert (gimple_call_lhs (stmt));
    1755      1278931 :       expr_type = TREE_TYPE (gimple_call_lhs (stmt));
    1756      1278931 :       assigns_var_p = true;
    1757              :     }
    1758      9107410 :   else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt))
    1759        36044 :     expr_type = TREE_TYPE (gimple_switch_index (swtch_stmt));
    1760      9071366 :   else if (gimple_code (stmt) == GIMPLE_PHI)
    1761              :     /* We can't propagate into a phi, so the logic below doesn't apply.
    1762              :        Instead record an equivalence between the cached LHS and the
    1763              :        PHI result of this statement, provided they are in the same block.
    1764              :        This should be sufficient to kill the redundant phi.  */
    1765              :     {
    1766      9071366 :       if (def && cached_lhs)
    1767       257653 :         m_const_and_copies->record_const_or_copy (def, cached_lhs);
    1768              :       return;
    1769              :     }
    1770              :   else
    1771            0 :     gcc_unreachable ();
    1772              : 
    1773     56438594 :   if (!cached_lhs)
    1774              :     return;
    1775              : 
    1776              :   /* It is safe to ignore types here since we have already done
    1777              :      type checking in the hashing and equality routines.  In fact
    1778              :      type checking here merely gets in the way of constant
    1779              :      propagation.  Also, make sure that it is safe to propagate
    1780              :      CACHED_LHS into the expression in STMT.  */
    1781       954757 :   if ((TREE_CODE (cached_lhs) != SSA_NAME
    1782       559154 :        && (assigns_var_p
    1783        33704 :            || useless_type_conversion_p (expr_type, TREE_TYPE (cached_lhs))))
    1784       954757 :       || may_propagate_copy_into_stmt (stmt, cached_lhs))
    1785              :   {
    1786       940007 :       gcc_checking_assert (TREE_CODE (cached_lhs) == SSA_NAME
    1787              :                            || is_gimple_min_invariant (cached_lhs));
    1788              : 
    1789       940007 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1790              :         {
    1791           19 :           fprintf (dump_file, "  Replaced redundant expr '");
    1792           19 :           print_gimple_expr (dump_file, stmt, 0, dump_flags);
    1793           19 :           fprintf (dump_file, "' with '");
    1794           19 :           print_generic_expr (dump_file, cached_lhs, dump_flags);
    1795           19 :           fprintf (dump_file, "'\n");
    1796              :         }
    1797              : 
    1798       940007 :       opt_stats.num_re++;
    1799              : 
    1800       940007 :       if (assigns_var_p
    1801       940007 :           && !useless_type_conversion_p (expr_type, TREE_TYPE (cached_lhs)))
    1802            0 :         cached_lhs = fold_convert (expr_type, cached_lhs);
    1803              : 
    1804       940007 :       propagate_tree_value_into_stmt (gsi, cached_lhs);
    1805              : 
    1806              :       /* Since it is always necessary to mark the result as modified,
    1807              :          perhaps we should move this into propagate_tree_value_into_stmt
    1808              :          itself.  */
    1809       940007 :       gimple_set_modified (gsi_stmt (*gsi), true);
    1810              :   }
    1811              : }
    1812              : 
    1813              : /* STMT, a GIMPLE_ASSIGN, may create certain equivalences, in either
    1814              :    the available expressions table or the const_and_copies table.
    1815              :    Detect and record those equivalences.
    1816              : 
    1817              :    We handle only very simple copy equivalences here.  The heavy
    1818              :    lifing is done by eliminate_redundant_computations.  */
    1819              : 
    1820              : void
    1821     49423572 : dom_opt_dom_walker::record_equivalences_from_stmt (gimple *stmt,
    1822              :                                                    int may_optimize_p)
    1823              : {
    1824     49423572 :   tree lhs;
    1825     49423572 :   enum tree_code lhs_code;
    1826              : 
    1827     49423572 :   gcc_assert (is_gimple_assign (stmt));
    1828              : 
    1829     49423572 :   lhs = gimple_assign_lhs (stmt);
    1830     49423572 :   lhs_code = TREE_CODE (lhs);
    1831              : 
    1832     49423572 :   if (lhs_code == SSA_NAME
    1833     49423572 :       && gimple_assign_single_p (stmt))
    1834              :     {
    1835     16273541 :       tree rhs = gimple_assign_rhs1 (stmt);
    1836              : 
    1837              :       /* If the RHS of the assignment is a constant or another variable that
    1838              :          may be propagated, register it in the CONST_AND_COPIES table.  We
    1839              :          do not need to record unwind data for this, since this is a true
    1840              :          assignment and not an equivalence inferred from a comparison.  All
    1841              :          uses of this ssa name are dominated by this assignment, so unwinding
    1842              :          just costs time and space.  */
    1843     16273541 :       if (may_optimize_p
    1844     16273541 :           && (TREE_CODE (rhs) == SSA_NAME
    1845     14178433 :               || is_gimple_min_invariant (rhs)))
    1846              :         {
    1847      2113002 :           rhs = dom_valueize (rhs);
    1848              : 
    1849      2113002 :           if (dump_file && (dump_flags & TDF_DETAILS))
    1850              :             {
    1851           73 :               fprintf (dump_file, "==== ASGN ");
    1852           73 :               print_generic_expr (dump_file, lhs);
    1853           73 :               fprintf (dump_file, " = ");
    1854           73 :               print_generic_expr (dump_file, rhs);
    1855           73 :               fprintf (dump_file, "\n");
    1856              :             }
    1857              : 
    1858      2113002 :           set_ssa_name_value (lhs, rhs);
    1859              :         }
    1860              :     }
    1861              : 
    1862              :   /* Make sure we can propagate &x + CST.  */
    1863     49423572 :   if (lhs_code == SSA_NAME
    1864     33377209 :       && gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR
    1865      1685705 :       && TREE_CODE (gimple_assign_rhs1 (stmt)) == ADDR_EXPR
    1866     49625285 :       && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST)
    1867              :     {
    1868         7310 :       tree op0 = gimple_assign_rhs1 (stmt);
    1869         7310 :       tree op1 = gimple_assign_rhs2 (stmt);
    1870         7310 :       tree new_rhs
    1871        14620 :         = build1 (ADDR_EXPR, TREE_TYPE (op0),
    1872         7310 :                   fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (op0)),
    1873              :                                unshare_expr (op0), fold_convert (ptr_type_node,
    1874              :                                                                  op1)));
    1875         7310 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1876              :         {
    1877            0 :           fprintf (dump_file, "==== ASGN ");
    1878            0 :           print_generic_expr (dump_file, lhs);
    1879            0 :           fprintf (dump_file, " = ");
    1880            0 :           print_generic_expr (dump_file, new_rhs);
    1881            0 :           fprintf (dump_file, "\n");
    1882              :         }
    1883              : 
    1884         7310 :       set_ssa_name_value (lhs, new_rhs);
    1885              :     }
    1886              : 
    1887              :   /* A memory store, even an aliased store, creates a useful
    1888              :      equivalence.  By exchanging the LHS and RHS, creating suitable
    1889              :      vops and recording the result in the available expression table,
    1890              :      we may be able to expose more redundant loads.  */
    1891     95103379 :   if (!gimple_has_volatile_ops (stmt)
    1892     74258016 :       && gimple_references_memory_p (stmt)
    1893     24834444 :       && gimple_assign_single_p (stmt)
    1894     24834444 :       && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
    1895     19419016 :           || is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
    1896     61324080 :       && !is_gimple_reg (lhs))
    1897              :     {
    1898     11731707 :       tree rhs = gimple_assign_rhs1 (stmt);
    1899     11731707 :       gassign *new_stmt;
    1900              : 
    1901              :       /* Build a new statement with the RHS and LHS exchanged.  */
    1902     11731707 :       if (TREE_CODE (rhs) == SSA_NAME)
    1903              :         {
    1904              :           /* NOTE tuples.  The call to gimple_build_assign below replaced
    1905              :              a call to build_gimple_modify_stmt, which did not set the
    1906              :              SSA_NAME_DEF_STMT on the LHS of the assignment.  Doing so
    1907              :              may cause an SSA validation failure, as the LHS may be a
    1908              :              default-initialized name and should have no definition.  I'm
    1909              :              a bit dubious of this, as the artificial statement that we
    1910              :              generate here may in fact be ill-formed, but it is simply
    1911              :              used as an internal device in this pass, and never becomes
    1912              :              part of the CFG.  */
    1913      5279300 :           gimple *defstmt = SSA_NAME_DEF_STMT (rhs);
    1914      5279300 :           new_stmt = gimple_build_assign (rhs, lhs);
    1915      5279300 :           SSA_NAME_DEF_STMT (rhs) = defstmt;
    1916              :         }
    1917              :       else
    1918      6452407 :         new_stmt = gimple_build_assign (rhs, lhs);
    1919              : 
    1920     23463414 :       gimple_set_vuse (new_stmt, gimple_vdef (stmt));
    1921              : 
    1922              :       /* Finally enter the statement into the available expression
    1923              :          table.  */
    1924     11731707 :       m_avail_exprs_stack->lookup_avail_expr (new_stmt, true, true);
    1925              :     }
    1926     49423572 : }
    1927              : 
    1928              : /* Replace *OP_P in STMT with any known equivalent value for *OP_P from
    1929              :    CONST_AND_COPIES.  */
    1930              : 
    1931              : static void
    1932     83245231 : cprop_operand (gimple *stmt, use_operand_p op_p, range_query *query)
    1933              : {
    1934     83245231 :   tree val;
    1935     83245231 :   tree op = USE_FROM_PTR (op_p);
    1936              : 
    1937              :   /* If the operand has a known constant value or it is known to be a
    1938              :      copy of some other variable, use the value or copy stored in
    1939              :      CONST_AND_COPIES.  */
    1940     83245231 :   val = SSA_NAME_VALUE (op);
    1941     56568832 :   if (!val)
    1942              :     {
    1943     79111570 :       value_range r (TREE_TYPE (op));
    1944     79111570 :       tree single;
    1945    155778763 :       if (query->range_of_expr (r, op, stmt) && r.singleton_p (&single))
    1946        10584 :         val = single;
    1947     79111570 :     }
    1948              : 
    1949     83245231 :   if (val && val != op)
    1950              :     {
    1951              :       /* Certain operands are not allowed to be copy propagated due
    1952              :          to their interaction with exception handling and some GCC
    1953              :          extensions.  */
    1954      4142410 :       if (!may_propagate_copy (op, val))
    1955              :         return;
    1956              : 
    1957              :       /* Do not propagate copies into BIVs.
    1958              :          See PR23821 and PR62217 for how this can disturb IV and
    1959              :          number of iteration analysis.  */
    1960      4140864 :       if (TREE_CODE (val) != INTEGER_CST)
    1961              :         {
    1962      3347317 :           gimple *def = SSA_NAME_DEF_STMT (op);
    1963      3347317 :           if (gimple_code (def) == GIMPLE_PHI
    1964      3347317 :               && gimple_bb (def)->loop_father->header == gimple_bb (def))
    1965              :             return;
    1966              :         }
    1967              : 
    1968              :       /* Dump details.  */
    1969      4129453 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1970              :         {
    1971           76 :           fprintf (dump_file, "  Replaced '");
    1972           76 :           print_generic_expr (dump_file, op, dump_flags);
    1973           76 :           fprintf (dump_file, "' with %s '",
    1974           76 :                    (TREE_CODE (val) != SSA_NAME ? "constant" : "variable"));
    1975           76 :           print_generic_expr (dump_file, val, dump_flags);
    1976           76 :           fprintf (dump_file, "'\n");
    1977              :         }
    1978              : 
    1979      4129453 :       if (TREE_CODE (val) != SSA_NAME)
    1980       977050 :         opt_stats.num_const_prop++;
    1981              :       else
    1982      3152403 :         opt_stats.num_copy_prop++;
    1983              : 
    1984      4129453 :       propagate_value (op_p, val);
    1985              : 
    1986              :       /* And note that we modified this statement.  This is now
    1987              :          safe, even if we changed virtual operands since we will
    1988              :          rescan the statement and rewrite its operands again.  */
    1989      4129453 :       gimple_set_modified (stmt, true);
    1990              :     }
    1991              : }
    1992              : 
    1993              : /* Fold the conditional STMT with range info.  */
    1994              : 
    1995              : void
    1996     55374106 : dom_opt_dom_walker::fold_cond (gimple *stmt)
    1997              : {
    1998     55374106 :   gcond *cond = dyn_cast <gcond *> (stmt);
    1999     55374106 :   if (!cond)
    2000     46101534 :     return;
    2001              : 
    2002      9272572 :   simplify_using_ranges simplify (m_ranger);
    2003      9272572 :   if (simplify.fold_cond (cond))
    2004        86902 :     gimple_set_modified (cond, true);
    2005      9272572 : }
    2006              : 
    2007              : /* CONST_AND_COPIES is a table which maps an SSA_NAME to the current
    2008              :    known value for that SSA_NAME (or NULL if no value is known).
    2009              : 
    2010              :    Propagate values from CONST_AND_COPIES into the uses, vuses and
    2011              :    vdef_ops of STMT.  */
    2012              : 
    2013              : static void
    2014    186295113 : cprop_into_stmt (gimple *stmt, range_query *query)
    2015              : {
    2016    186295113 :   use_operand_p op_p;
    2017    186295113 :   ssa_op_iter iter;
    2018    186295113 :   tree last_copy_propagated_op = NULL;
    2019              : 
    2020    269541025 :   FOR_EACH_SSA_USE_OPERAND (op_p, stmt, iter, SSA_OP_USE)
    2021              :     {
    2022     83245912 :       tree old_op = USE_FROM_PTR (op_p);
    2023              : 
    2024              :       /* If we have A = B and B = A in the copy propagation tables
    2025              :          (due to an equality comparison), avoid substituting B for A
    2026              :          then A for B in the trivially discovered cases.   This allows
    2027              :          optimization of statements were A and B appear as input
    2028              :          operands.  */
    2029     83245912 :       if (old_op != last_copy_propagated_op)
    2030              :         {
    2031     83245231 :           cprop_operand (stmt, op_p, query);
    2032              : 
    2033     83245231 :           tree new_op = USE_FROM_PTR (op_p);
    2034     83245231 :           if (new_op != old_op && TREE_CODE (new_op) == SSA_NAME)
    2035     83245912 :             last_copy_propagated_op = new_op;
    2036              :         }
    2037              :     }
    2038    186295113 : }
    2039              : 
    2040              : /* If STMT is a comparison of two uniform vectors reduce it to a comparison
    2041              :    of scalar objects, otherwise leave STMT unchanged.  */
    2042              : 
    2043              : static void
    2044    186295113 : reduce_vector_comparison_to_scalar_comparison (gimple *stmt)
    2045              : {
    2046    186295113 :   if (gimple_code (stmt) == GIMPLE_COND)
    2047              :     {
    2048      9327798 :       tree lhs = gimple_cond_lhs (stmt);
    2049      9327798 :       tree rhs = gimple_cond_rhs (stmt);
    2050              : 
    2051              :       /* We may have a vector comparison where both arms are uniform
    2052              :          vectors.  If so, we can simplify the vector comparison down
    2053              :          to a scalar comparison.  */
    2054      9327798 :       if (VECTOR_TYPE_P (TREE_TYPE (lhs))
    2055      9327798 :           && VECTOR_TYPE_P (TREE_TYPE (rhs)))
    2056              :         {
    2057              :           /* If either operand is an SSA_NAME, then look back to its
    2058              :              defining statement to try and get at a suitable source.  */
    2059         2490 :           if (TREE_CODE (rhs) == SSA_NAME)
    2060              :             {
    2061            0 :               gimple *def_stmt = SSA_NAME_DEF_STMT (rhs);
    2062            0 :               if (gimple_assign_single_p (def_stmt))
    2063            0 :                 rhs = gimple_assign_rhs1 (def_stmt);
    2064              :             }
    2065              : 
    2066         2490 :           if (TREE_CODE (lhs) == SSA_NAME)
    2067              :             {
    2068         2490 :               gimple *def_stmt = SSA_NAME_DEF_STMT (lhs);
    2069         2490 :               if (gimple_assign_single_p (def_stmt))
    2070            4 :                 lhs = gimple_assign_rhs1 (def_stmt);
    2071              :             }
    2072              : 
    2073              :           /* Now see if they are both uniform vectors and if so replace
    2074              :              the vector comparison with a scalar comparison.  */
    2075         2490 :           tree rhs_elem = rhs ? uniform_vector_p (rhs) : NULL_TREE;
    2076         2490 :           tree lhs_elem = lhs ? uniform_vector_p (lhs) : NULL_TREE;
    2077         2490 :           if (rhs_elem && lhs_elem)
    2078              :             {
    2079            3 :               if (dump_file && dump_flags & TDF_DETAILS)
    2080              :                 {
    2081            0 :                   fprintf (dump_file, "Reducing vector comparison: ");
    2082            0 :                   print_gimple_stmt (dump_file, stmt, 0);
    2083              :                 }
    2084              : 
    2085            3 :               gimple_cond_set_rhs (as_a <gcond *>(stmt), rhs_elem);
    2086            3 :               gimple_cond_set_lhs (as_a <gcond *>(stmt), lhs_elem);
    2087            3 :               gimple_set_modified (stmt, true);
    2088              : 
    2089            3 :               if (dump_file && dump_flags & TDF_DETAILS)
    2090              :                 {
    2091            0 :                   fprintf (dump_file, "To scalar equivalent: ");
    2092            0 :                   print_gimple_stmt (dump_file, stmt, 0);
    2093            0 :                   fprintf (dump_file, "\n");
    2094              :                 }
    2095              :             }
    2096              :         }
    2097              :     }
    2098    186295113 : }
    2099              : 
    2100              : /* Optimize the statement in block BB pointed to by iterator SI.
    2101              : 
    2102              :    We try to perform some simplistic global redundancy elimination and
    2103              :    constant propagation:
    2104              : 
    2105              :    1- To detect global redundancy, we keep track of expressions that have
    2106              :       been computed in this block and its dominators.  If we find that the
    2107              :       same expression is computed more than once, we eliminate repeated
    2108              :       computations by using the target of the first one.
    2109              : 
    2110              :    2- Constant values and copy assignments.  This is used to do very
    2111              :       simplistic constant and copy propagation.  When a constant or copy
    2112              :       assignment is found, we map the value on the RHS of the assignment to
    2113              :       the variable in the LHS in the CONST_AND_COPIES table.
    2114              : 
    2115              :    3- Very simple redundant store elimination is performed.
    2116              : 
    2117              :    4- We can simplify a condition to a constant or from a relational
    2118              :       condition to an equality condition.  */
    2119              : 
    2120              : edge
    2121    186295113 : dom_opt_dom_walker::optimize_stmt (basic_block bb, gimple_stmt_iterator *si,
    2122              :                                    bool *removed_p)
    2123              : {
    2124    186295113 :   gimple *stmt, *old_stmt;
    2125    186295113 :   bool may_optimize_p;
    2126    186295113 :   bool modified_p = false;
    2127    186295113 :   bool was_noreturn;
    2128    186295113 :   edge retval = NULL;
    2129              : 
    2130    186295113 :   old_stmt = stmt = gsi_stmt (*si);
    2131    186295113 :   was_noreturn = is_gimple_call (stmt) && gimple_call_noreturn_p (stmt);
    2132              : 
    2133    186295113 :   if (dump_file && (dump_flags & TDF_DETAILS))
    2134              :     {
    2135         1623 :       fprintf (dump_file, "Optimizing statement ");
    2136         1623 :       print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    2137              :     }
    2138              : 
    2139              :   /* STMT may be a comparison of uniform vectors that we can simplify
    2140              :      down to a comparison of scalars.  Do that transformation first
    2141              :      so that all the scalar optimizations from here onward apply.  */
    2142    186295113 :   reduce_vector_comparison_to_scalar_comparison (stmt);
    2143              : 
    2144    186295113 :   update_stmt_if_modified (stmt);
    2145    186295113 :   opt_stats.num_stmts++;
    2146              : 
    2147              :   /* Const/copy propagate into USES, VUSES and the RHS of VDEFs.  */
    2148    186295113 :   cprop_into_stmt (stmt, m_ranger);
    2149              : 
    2150              :   /* If the statement has been modified with constant replacements,
    2151              :      fold its RHS before checking for redundant computations.  */
    2152    372247664 :   if (gimple_modified_p (stmt))
    2153              :     {
    2154      3959265 :       tree rhs = NULL;
    2155              : 
    2156              :       /* Try to fold the statement making sure that STMT is kept
    2157              :          up to date.  */
    2158      3959265 :       if (fold_stmt (si))
    2159              :         {
    2160       409958 :           stmt = gsi_stmt (*si);
    2161       409958 :           gimple_set_modified (stmt, true);
    2162              : 
    2163       409958 :           if (dump_file && (dump_flags & TDF_DETAILS))
    2164              :             {
    2165           10 :               fprintf (dump_file, "  Folded to: ");
    2166           10 :               print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    2167              :             }
    2168              :         }
    2169              : 
    2170              :       /* We only need to consider cases that can yield a gimple operand.  */
    2171      3959265 :       if (gimple_assign_single_p (stmt))
    2172      1463890 :         rhs = gimple_assign_rhs1 (stmt);
    2173      2495375 :       else if (gimple_code (stmt) == GIMPLE_GOTO)
    2174            2 :         rhs = gimple_goto_dest (stmt);
    2175    186297056 :       else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt))
    2176              :         /* This should never be an ADDR_EXPR.  */
    2177         1943 :         rhs = gimple_switch_index (swtch_stmt);
    2178              : 
    2179      1465835 :       if (rhs && TREE_CODE (rhs) == ADDR_EXPR)
    2180        83019 :         recompute_tree_invariant_for_addr_expr (rhs);
    2181              : 
    2182              :       /* Indicate that maybe_clean_or_replace_eh_stmt needs to be called,
    2183              :          even if fold_stmt updated the stmt already and thus cleared
    2184              :          gimple_modified_p flag on it.  */
    2185              :       modified_p = true;
    2186              :     }
    2187              : 
    2188              :   /* Check for redundant computations.  Do this optimization only
    2189              :      for assignments that have no volatile ops and conditionals.  */
    2190    186295113 :   may_optimize_p = (!gimple_has_side_effects (stmt)
    2191    186295113 :                     && (is_gimple_assign (stmt)
    2192    126761478 :                         || (is_gimple_call (stmt)
    2193      1283289 :                             && gimple_call_lhs (stmt) != NULL_TREE)
    2194    125478553 :                         || gimple_code (stmt) == GIMPLE_COND
    2195    116150755 :                         || gimple_code (stmt) == GIMPLE_SWITCH));
    2196              : 
    2197              :   if (may_optimize_p)
    2198              :     {
    2199     56438594 :       if (gimple_code (stmt) == GIMPLE_CALL)
    2200              :         {
    2201              :           /* Resolve __builtin_constant_p.  If it hasn't been
    2202              :              folded to integer_one_node by now, it's fairly
    2203              :              certain that the value simply isn't constant.  */
    2204      1282925 :           tree callee = gimple_call_fndecl (stmt);
    2205      1282925 :           if (callee
    2206      1282925 :               && fndecl_built_in_p (callee, BUILT_IN_CONSTANT_P))
    2207              :             {
    2208         3994 :               propagate_tree_value_into_stmt (si, integer_zero_node);
    2209         3994 :               stmt = gsi_stmt (*si);
    2210              :             }
    2211              :         }
    2212              : 
    2213     56438594 :       update_stmt_if_modified (stmt);
    2214     56438594 :       eliminate_redundant_computations (si);
    2215     56438594 :       stmt = gsi_stmt (*si);
    2216              : 
    2217              :       /* Perform simple redundant store elimination.  */
    2218     56438594 :       if (gimple_assign_single_p (stmt)
    2219     28700620 :           && TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME
    2220     69449914 :           && (TREE_CODE (gimple_assign_lhs (stmt)) != VAR_DECL
    2221      1052499 :               || !DECL_HARD_REGISTER (gimple_assign_lhs (stmt))))
    2222              :         {
    2223     13009300 :           tree lhs = gimple_assign_lhs (stmt);
    2224     13009300 :           tree rhs = gimple_assign_rhs1 (stmt);
    2225     13009300 :           tree cached_lhs;
    2226     13009300 :           gassign *new_stmt;
    2227     13009300 :           rhs = dom_valueize (rhs);
    2228              :           /* Build a new statement with the RHS and LHS exchanged.  */
    2229     13009300 :           if (TREE_CODE (rhs) == SSA_NAME)
    2230              :             {
    2231      5399901 :               gimple *defstmt = SSA_NAME_DEF_STMT (rhs);
    2232      5399901 :               new_stmt = gimple_build_assign (rhs, lhs);
    2233      5399901 :               SSA_NAME_DEF_STMT (rhs) = defstmt;
    2234              :             }
    2235              :           else
    2236      7609399 :             new_stmt = gimple_build_assign (rhs, lhs);
    2237     26018600 :           gimple_set_vuse (new_stmt, gimple_vuse (stmt));
    2238     13009300 :           expr_hash_elt *elt = NULL;
    2239     13009300 :           cached_lhs = m_avail_exprs_stack->lookup_avail_expr (new_stmt, false,
    2240              :                                                                false, &elt);
    2241     13009300 :           if (cached_lhs
    2242       855564 :               && operand_equal_p (rhs, cached_lhs, 0)
    2243     13267382 :               && refs_same_for_tbaa_p (elt->expr ()->kind == EXPR_SINGLE
    2244       129041 :                                        ? elt->expr ()->ops.single.rhs
    2245              :                                        : NULL_TREE, lhs))
    2246              :             {
    2247       124481 :               basic_block bb = gimple_bb (stmt);
    2248       124481 :               unlink_stmt_vdef (stmt);
    2249       124481 :               if (gsi_remove (si, true))
    2250              :                 {
    2251            0 :                   bitmap_set_bit (need_eh_cleanup, bb->index);
    2252            0 :                   if (dump_file && (dump_flags & TDF_DETAILS))
    2253            0 :                     fprintf (dump_file, "  Flagged to clear EH edges.\n");
    2254              :                 }
    2255       124481 :               release_defs (stmt);
    2256       124481 :               *removed_p = true;
    2257       124481 :               return retval;
    2258              :             }
    2259              :         }
    2260              : 
    2261              :       /* If this statement was not redundant, we may still be able to simplify
    2262              :          it, which may in turn allow other part of DOM or other passes to do
    2263              :          a better job.  */
    2264    112628226 :       if (!gimple_modified_p (stmt))
    2265     55374106 :         fold_cond (stmt);
    2266              :     }
    2267              : 
    2268              :   /* Record any additional equivalences created by this statement.  */
    2269    186170632 :   if (is_gimple_assign (stmt))
    2270     49423572 :     record_equivalences_from_stmt (stmt, may_optimize_p);
    2271              : 
    2272              :   /* If STMT is a COND_EXPR or SWITCH_EXPR and it was modified, then we may
    2273              :      know where it goes.  */
    2274    372341264 :   if (gimple_modified_p (stmt) || modified_p)
    2275              :     {
    2276      4582290 :       tree val = NULL;
    2277              : 
    2278      4582290 :       if (gimple_code (stmt) == GIMPLE_COND)
    2279       582926 :         val = fold_binary_loc (gimple_location (stmt),
    2280              :                                gimple_cond_code (stmt), boolean_type_node,
    2281              :                                gimple_cond_lhs (stmt),
    2282              :                                gimple_cond_rhs (stmt));
    2283      3999364 :       else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt))
    2284         1943 :         val = gimple_switch_index (swtch_stmt);
    2285              : 
    2286       584869 :       if (val && TREE_CODE (val) == INTEGER_CST)
    2287              :         {
    2288       188941 :           retval = find_taken_edge (bb, val);
    2289       188941 :           if (retval)
    2290              :             {
    2291              :               /* Fix the condition to be either true or false.  */
    2292       188941 :               if (gimple_code (stmt) == GIMPLE_COND)
    2293              :                 {
    2294       188926 :                   if (integer_zerop (val))
    2295       126782 :                     gimple_cond_make_false (as_a <gcond *> (stmt));
    2296        62144 :                   else if (integer_onep (val))
    2297        62144 :                     gimple_cond_make_true (as_a <gcond *> (stmt));
    2298              :                   else
    2299            0 :                     gcc_unreachable ();
    2300              : 
    2301       188926 :                   gimple_set_modified (stmt, true);
    2302              :                 }
    2303              : 
    2304              :               /* Further simplifications may be possible.  */
    2305       188941 :               cfg_altered = true;
    2306              :             }
    2307              :         }
    2308              : 
    2309      4582290 :       update_stmt_if_modified (stmt);
    2310              : 
    2311              :       /* If we simplified a statement in such a way as to be shown that it
    2312              :          cannot trap, update the eh information and the cfg to match.  */
    2313      4582290 :       if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
    2314              :         {
    2315         1410 :           bitmap_set_bit (need_eh_cleanup, bb->index);
    2316         1410 :           if (dump_file && (dump_flags & TDF_DETAILS))
    2317            0 :             fprintf (dump_file, "  Flagged to clear EH edges.\n");
    2318              :         }
    2319              : 
    2320      4582290 :       if (!was_noreturn
    2321      4582290 :           && is_gimple_call (stmt) && gimple_call_noreturn_p (stmt))
    2322            3 :         need_noreturn_fixup.safe_push (stmt);
    2323              :     }
    2324              :   return retval;
    2325              : }
        

Generated by: LCOV version 2.5.0-beta

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