LCOV - code coverage report
Current view: top level - gcc - tree-ssa-dom.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 94.1 % 1064 1001
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 43 43
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.4-beta

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