LCOV - code coverage report
Current view: top level - gcc - tree-ssa-propagate.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 95.8 % 544 521
Test Date: 2026-02-28 14:20:25 Functions: 96.3 % 27 26
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Generic SSA value propagation engine.
       2              :    Copyright (C) 2004-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 it
       8              :    under the terms of the GNU General Public License as published by the
       9              :    Free Software Foundation; either version 3, or (at your option) any
      10              :    later version.
      11              : 
      12              :    GCC is distributed in the hope that it will be useful, but WITHOUT
      13              :    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14              :    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15              :    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 "ssa.h"
      28              : #include "gimple-pretty-print.h"
      29              : #include "dumpfile.h"
      30              : #include "gimple-iterator.h"
      31              : #include "gimple-fold.h"
      32              : #include "tree-eh.h"
      33              : #include "gimplify.h"
      34              : #include "tree-cfg.h"
      35              : #include "tree-ssa.h"
      36              : #include "tree-ssa-propagate.h"
      37              : #include "domwalk.h"
      38              : #include "cfgloop.h"
      39              : #include "tree-cfgcleanup.h"
      40              : #include "cfganal.h"
      41              : #include "tree-ssa-dce.h"
      42              : 
      43              : /* This file implements a generic value propagation engine based on
      44              :    the same propagation used by the SSA-CCP algorithm [1].
      45              : 
      46              :    Propagation is performed by simulating the execution of every
      47              :    statement that produces the value being propagated.  Simulation
      48              :    proceeds as follows:
      49              : 
      50              :    1- Initially, all edges of the CFG are marked not executable and
      51              :       the CFG worklist is seeded with all the statements in the entry
      52              :       basic block (block 0).
      53              : 
      54              :    2- Every statement S is simulated with a call to the call-back
      55              :       function SSA_PROP_VISIT_STMT.  This evaluation may produce 3
      56              :       results:
      57              : 
      58              :         SSA_PROP_NOT_INTERESTING: Statement S produces nothing of
      59              :             interest and does not affect any of the work lists.
      60              :             The statement may be simulated again if any of its input
      61              :             operands change in future iterations of the simulator.
      62              : 
      63              :         SSA_PROP_VARYING: The value produced by S cannot be determined
      64              :             at compile time.  Further simulation of S is not required.
      65              :             If S is a conditional jump, all the outgoing edges for the
      66              :             block are considered executable and added to the work
      67              :             list.
      68              : 
      69              :         SSA_PROP_INTERESTING: S produces a value that can be computed
      70              :             at compile time.  Its result can be propagated into the
      71              :             statements that feed from S.  Furthermore, if S is a
      72              :             conditional jump, only the edge known to be taken is added
      73              :             to the work list.  Edges that are known not to execute are
      74              :             never simulated.
      75              : 
      76              :    3- PHI nodes are simulated with a call to SSA_PROP_VISIT_PHI.  The
      77              :       return value from SSA_PROP_VISIT_PHI has the same semantics as
      78              :       described in #2.
      79              : 
      80              :    4- Three work lists are kept.  Statements are only added to these
      81              :       lists if they produce one of SSA_PROP_INTERESTING or
      82              :       SSA_PROP_VARYING.
      83              : 
      84              :         CFG_BLOCKS contains the list of blocks to be simulated.
      85              :             Blocks are added to this list if their incoming edges are
      86              :             found executable.
      87              : 
      88              :         SSA_EDGE_WORKLIST contains the list of statements that we
      89              :             need to revisit.
      90              : 
      91              :    5- Simulation terminates when all three work lists are drained.
      92              : 
      93              :    Before calling ssa_propagate, it is important to clear
      94              :    prop_simulate_again_p for all the statements in the program that
      95              :    should be simulated.  This initialization allows an implementation
      96              :    to specify which statements should never be simulated.
      97              : 
      98              :    It is also important to compute def-use information before calling
      99              :    ssa_propagate.
     100              : 
     101              :    References:
     102              : 
     103              :      [1] Constant propagation with conditional branches,
     104              :          Wegman and Zadeck, ACM TOPLAS 13(2):181-210.
     105              : 
     106              :      [2] Building an Optimizing Compiler,
     107              :          Robert Morgan, Butterworth-Heinemann, 1998, Section 8.9.
     108              : 
     109              :      [3] Advanced Compiler Design and Implementation,
     110              :          Steven Muchnick, Morgan Kaufmann, 1997, Section 12.6  */
     111              : 
     112              : /* Worklists of control flow edge destinations.  This contains
     113              :    the CFG order number of the blocks so we can iterate in CFG
     114              :    order by visiting in bit-order.  We use two worklists to
     115              :    first make forward progress before iterating.  */
     116              : static bitmap cfg_blocks;
     117              : static int *bb_to_cfg_order;
     118              : static int *cfg_order_to_bb;
     119              : 
     120              : /* Worklists of SSA edges which will need reexamination as their
     121              :    definition has changed.  SSA edges are def-use edges in the SSA
     122              :    web.  For each D-U edge, we store the target statement or PHI node
     123              :    UID in a bitmap.  UIDs order stmts in execution order.  We use
     124              :    two worklists to first make forward progress before iterating.  */
     125              : static bitmap ssa_edge_worklist;
     126              : static vec<gimple *> uid_to_stmt;
     127              : 
     128              : /* Current RPO index in the iteration.  */
     129              : static int curr_order;
     130              : 
     131              : 
     132              : /* We have just defined a new value for VAR.  If IS_VARYING is true,
     133              :    add all immediate uses of VAR to VARYING_SSA_EDGES, otherwise add
     134              :    them to INTERESTING_SSA_EDGES.  */
     135              : 
     136              : static void
     137    282293792 : add_ssa_edge (tree var)
     138              : {
     139    282293792 :   imm_use_iterator iter;
     140    282293792 :   use_operand_p use_p;
     141              : 
     142   1149107118 :   FOR_EACH_IMM_USE_FAST (use_p, iter, var)
     143              :     {
     144    584519534 :       gimple *use_stmt = USE_STMT (use_p);
     145    584519534 :       if (!prop_simulate_again_p (use_stmt))
     146    247182721 :         continue;
     147              : 
     148              :       /* If we did not yet simulate the block wait for this to happen
     149              :          and do not add the stmt to the SSA edge worklist.  */
     150    337336813 :       basic_block use_bb = gimple_bb (use_stmt);
     151    337336813 :       if (! (use_bb->flags & BB_VISITED))
     152    137652148 :         continue;
     153              : 
     154              :       /* If this is a use on a not yet executable edge do not bother to
     155              :          queue it.  */
     156    199684665 :       if (gimple_code (use_stmt) == GIMPLE_PHI
     157    199684665 :           && !(EDGE_PRED (use_bb, PHI_ARG_INDEX_FROM_USE (use_p))->flags
     158     64896626 :                & EDGE_EXECUTABLE))
     159      5870341 :         continue;
     160              : 
     161    193814324 :       if (bitmap_set_bit (ssa_edge_worklist, gimple_uid (use_stmt)))
     162              :         {
     163    179333460 :           uid_to_stmt[gimple_uid (use_stmt)] = use_stmt;
     164    179333460 :           if (dump_file && (dump_flags & TDF_DETAILS))
     165              :             {
     166            0 :               fprintf (dump_file, "ssa_edge_worklist: adding SSA use in ");
     167            0 :               print_gimple_stmt (dump_file, use_stmt, 0, TDF_SLIM);
     168              :             }
     169              :         }
     170    282293792 :     }
     171    282293792 : }
     172              : 
     173              : 
     174              : /* Add edge E to the control flow worklist.  */
     175              : 
     176              : static void
     177    135387063 : add_control_edge (edge e)
     178              : {
     179    135387063 :   basic_block bb = e->dest;
     180    135387063 :   if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
     181              :     return;
     182              : 
     183              :   /* If the edge had already been executed, skip it.  */
     184    119981027 :   if (e->flags & EDGE_EXECUTABLE)
     185              :     return;
     186              : 
     187    103893678 :   e->flags |= EDGE_EXECUTABLE;
     188              : 
     189    103893678 :   int bb_order = bb_to_cfg_order[bb->index];
     190    103893678 :   bitmap_set_bit (cfg_blocks, bb_order);
     191              : 
     192    103893678 :   if (dump_file && (dump_flags & TDF_DETAILS))
     193           61 :     fprintf (dump_file, "Adding destination of edge (%d -> %d) to worklist\n",
     194           61 :         e->src->index, e->dest->index);
     195              : }
     196              : 
     197              : 
     198              : /* Simulate the execution of STMT and update the work lists accordingly.  */
     199              : 
     200              : void
     201    789508483 : ssa_propagation_engine::simulate_stmt (gimple *stmt)
     202              : {
     203    789508483 :   enum ssa_prop_result val = SSA_PROP_NOT_INTERESTING;
     204    789508483 :   edge taken_edge = NULL;
     205    789508483 :   tree output_name = NULL_TREE;
     206              : 
     207              :   /* Pull the stmt off the SSA edge worklist.  */
     208    789508483 :   bitmap_clear_bit (ssa_edge_worklist, gimple_uid (stmt));
     209              : 
     210              :   /* Don't bother visiting statements that are already
     211              :      considered varying by the propagator.  */
     212    789508483 :   if (!prop_simulate_again_p (stmt))
     213    555641052 :     return;
     214              : 
     215    354258869 :   if (gimple_code (stmt) == GIMPLE_PHI)
     216              :     {
     217     79287802 :       val = visit_phi (as_a <gphi *> (stmt));
     218     79287802 :       output_name = gimple_phi_result (stmt);
     219              :     }
     220              :   else
     221    274971067 :     val = visit_stmt (stmt, &taken_edge, &output_name);
     222              : 
     223    354258869 :   if (val == SSA_PROP_VARYING)
     224              :     {
     225    120391438 :       prop_set_simulate_again (stmt, false);
     226              : 
     227              :       /* If the statement produced a new varying value, add the SSA
     228              :          edges coming out of OUTPUT_NAME.  */
     229    120391438 :       if (output_name)
     230     71985515 :         add_ssa_edge (output_name);
     231              : 
     232              :       /* If STMT transfers control out of its basic block, add
     233              :          all outgoing edges to the work list.  */
     234    120391438 :       if (stmt_ends_bb_p (stmt))
     235              :         {
     236     49816780 :           edge e;
     237     49816780 :           edge_iterator ei;
     238     49816780 :           basic_block bb = gimple_bb (stmt);
     239    128427099 :           FOR_EACH_EDGE (e, ei, bb->succs)
     240     78610319 :             add_control_edge (e);
     241              :         }
     242    120391438 :       return;
     243              :     }
     244    233867431 :   else if (val == SSA_PROP_INTERESTING)
     245              :     {
     246              :       /* If the statement produced new value, add the SSA edges coming
     247              :          out of OUTPUT_NAME.  */
     248    216841493 :       if (output_name)
     249    210308277 :         add_ssa_edge (output_name);
     250              : 
     251              :       /* If we know which edge is going to be taken out of this block,
     252              :          add it to the CFG work list.  */
     253    216841493 :       if (taken_edge)
     254      6533216 :         add_control_edge (taken_edge);
     255              :     }
     256              : 
     257              :   /* If there are no SSA uses on the stmt whose defs are simulated
     258              :      again then this stmt will be never visited again.  */
     259    233867431 :   bool has_simulate_again_uses = false;
     260    233867431 :   use_operand_p use_p;
     261    233867431 :   ssa_op_iter iter;
     262    233867431 :   if (gimple_code  (stmt) == GIMPLE_PHI)
     263              :     {
     264     66019181 :       edge_iterator ei;
     265     66019181 :       edge e;
     266     66019181 :       tree arg;
     267    102725010 :       FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->preds)
     268    100834605 :         if (!(e->flags & EDGE_EXECUTABLE)
     269    100834605 :             || ((arg = PHI_ARG_DEF_FROM_EDGE (stmt, e))
     270     92717668 :                 && TREE_CODE (arg) == SSA_NAME
     271     76115218 :                 && !SSA_NAME_IS_DEFAULT_DEF (arg)
     272     75907913 :                 && prop_simulate_again_p (SSA_NAME_DEF_STMT (arg))))
     273              :           {
     274              :             has_simulate_again_uses = true;
     275              :             break;
     276              :           }
     277              :     }
     278              :   else
     279    205660737 :     FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
     280              :       {
     281    166585985 :         gimple *def_stmt = SSA_NAME_DEF_STMT (USE_FROM_PTR (use_p));
     282    166585985 :         if (!gimple_nop_p (def_stmt)
     283    166585985 :             && prop_simulate_again_p (def_stmt))
     284              :           {
     285              :             has_simulate_again_uses = true;
     286              :             break;
     287              :           }
     288              :       }
     289    233867431 :   if (!has_simulate_again_uses)
     290              :     {
     291     40965157 :       if (dump_file && (dump_flags & TDF_DETAILS))
     292           40 :         fprintf (dump_file, "marking stmt to be not simulated again\n");
     293     40965157 :       prop_set_simulate_again (stmt, false);
     294              :     }
     295              : }
     296              : 
     297              : 
     298              : /* Simulate the execution of BLOCK.  Evaluate the statement associated
     299              :    with each variable reference inside the block.  */
     300              : 
     301              : void
     302     79151449 : ssa_propagation_engine::simulate_block (basic_block block)
     303              : {
     304     79151449 :   gimple_stmt_iterator gsi;
     305              : 
     306              :   /* There is nothing to do for the exit block.  */
     307     79151449 :   if (block == EXIT_BLOCK_PTR_FOR_FN (cfun))
     308     79151449 :     return;
     309              : 
     310     79151449 :   if (dump_file && (dump_flags & TDF_DETAILS))
     311           57 :     fprintf (dump_file, "\nSimulating block %d\n", block->index);
     312              : 
     313              :   /* Always simulate PHI nodes, even if we have simulated this block
     314              :      before.  */
     315    120844893 :   for (gsi = gsi_start_phis (block); !gsi_end_p (gsi); gsi_next (&gsi))
     316     41693444 :     simulate_stmt (gsi_stmt (gsi));
     317              : 
     318              :   /* If this is the first time we've simulated this block, then we
     319              :      must simulate each of its statements.  */
     320     79151449 :   if (! (block->flags & BB_VISITED))
     321              :     {
     322     73963671 :       gimple_stmt_iterator j;
     323     73963671 :       unsigned int normal_edge_count;
     324     73963671 :       edge e, normal_edge;
     325     73963671 :       edge_iterator ei;
     326              : 
     327    716515795 :       for (j = gsi_start_bb (block); !gsi_end_p (j); gsi_next (&j))
     328    568588453 :         simulate_stmt (gsi_stmt (j));
     329              : 
     330              :       /* Note that we have simulated this block.  */
     331     73963671 :       block->flags |= BB_VISITED;
     332              : 
     333              :       /* We cannot predict when abnormal and EH edges will be executed, so
     334              :          once a block is considered executable, we consider any
     335              :          outgoing abnormal edges as executable.
     336              : 
     337              :          TODO: This is not exactly true.  Simplifying statement might
     338              :          prove it non-throwing and also computed goto can be handled
     339              :          when destination is known.
     340              : 
     341              :          At the same time, if this block has only one successor that is
     342              :          reached by non-abnormal edges, then add that successor to the
     343              :          worklist.  */
     344     73963671 :       normal_edge_count = 0;
     345     73963671 :       normal_edge = NULL;
     346    178123196 :       FOR_EACH_EDGE (e, ei, block->succs)
     347              :         {
     348    104159525 :           if (e->flags & (EDGE_ABNORMAL | EDGE_EH))
     349      6604017 :             add_control_edge (e);
     350              :           else
     351              :             {
     352     97555508 :               normal_edge_count++;
     353     97555508 :               normal_edge = e;
     354              :             }
     355              :         }
     356              : 
     357     73963671 :       if (normal_edge_count == 1)
     358     35769471 :         add_control_edge (normal_edge);
     359              :     }
     360              : }
     361              : 
     362              : 
     363              : /* Initialize local data structures and work lists.  */
     364              : 
     365              : static void
     366      7870040 : ssa_prop_init (void)
     367              : {
     368      7870040 :   edge e;
     369      7870040 :   edge_iterator ei;
     370      7870040 :   basic_block bb;
     371              : 
     372              :   /* Worklists of SSA edges.  */
     373      7870040 :   ssa_edge_worklist = BITMAP_ALLOC (NULL);
     374      7870040 :   bitmap_tree_view (ssa_edge_worklist);
     375              : 
     376              :   /* Worklist of basic-blocks.  */
     377      7870040 :   bb_to_cfg_order = XNEWVEC (int, last_basic_block_for_fn (cfun) + 1);
     378      7870040 :   cfg_order_to_bb = XNEWVEC (int, n_basic_blocks_for_fn (cfun));
     379      7870040 :   int n = pre_and_rev_post_order_compute_fn (cfun, NULL,
     380              :                                              cfg_order_to_bb, false);
     381     82394833 :   for (int i = 0; i < n; ++i)
     382     74524793 :     bb_to_cfg_order[cfg_order_to_bb[i]] = i;
     383      7870040 :   cfg_blocks = BITMAP_ALLOC (NULL);
     384              : 
     385              :   /* Initially assume that every edge in the CFG is not executable.
     386              :      (including the edges coming out of the entry block).  Mark blocks
     387              :      as not visited, blocks not yet visited will have all their statements
     388              :      simulated once an incoming edge gets executable.  */
     389      7870040 :   set_gimple_stmt_max_uid (cfun, 0);
     390     82394833 :   for (int i = 0; i < n; ++i)
     391              :     {
     392     74524793 :       gimple_stmt_iterator si;
     393     74524793 :       bb = BASIC_BLOCK_FOR_FN (cfun, cfg_order_to_bb[i]);
     394              : 
     395    105003839 :       for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
     396              :         {
     397     30479046 :           gimple *stmt = gsi_stmt (si);
     398     30479046 :           gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
     399              :         }
     400              : 
     401    719785803 :       for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
     402              :         {
     403    570736217 :           gimple *stmt = gsi_stmt (si);
     404    570736217 :           gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
     405              :         }
     406              : 
     407     74524793 :       bb->flags &= ~BB_VISITED;
     408    179251595 :       FOR_EACH_EDGE (e, ei, bb->succs)
     409    104726802 :         e->flags &= ~EDGE_EXECUTABLE;
     410              :     }
     411      7870040 :   uid_to_stmt.safe_grow (gimple_stmt_max_uid (cfun), true);
     412      7870040 : }
     413              : 
     414              : 
     415              : /* Free allocated storage.  */
     416              : 
     417              : static void
     418      7870040 : ssa_prop_fini (void)
     419              : {
     420      7870040 :   BITMAP_FREE (cfg_blocks);
     421      7870040 :   free (bb_to_cfg_order);
     422      7870040 :   free (cfg_order_to_bb);
     423      7870040 :   BITMAP_FREE (ssa_edge_worklist);
     424      7870040 :   uid_to_stmt.release ();
     425      7870040 : }
     426              : 
     427              : 
     428              : /* Entry point to the propagation engine.
     429              : 
     430              :    The VISIT_STMT virtual function is called for every statement
     431              :    visited and the VISIT_PHI virtual function is called for every PHI
     432              :    node visited.  */
     433              : 
     434              : void
     435      7870040 : ssa_propagation_engine::ssa_propagate (void)
     436              : {
     437      7870040 :   ssa_prop_init ();
     438              : 
     439      7870040 :   curr_order = 0;
     440              : 
     441              :   /* Iterate until the worklists are empty.  We iterate both blocks
     442              :      and stmts in RPO order, prioritizing backedge processing.
     443              :      Seed the algorithm by adding the successors of the entry block to the
     444              :      edge worklist.  */
     445      7870040 :   edge e;
     446      7870040 :   edge_iterator ei;
     447     15740080 :   FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs)
     448              :     {
     449      7870040 :       e->flags &= ~EDGE_EXECUTABLE;
     450      7870040 :       add_control_edge (e);
     451              :     }
     452    266248075 :   while (1)
     453              :     {
     454    266248075 :       int next_block_order = (bitmap_empty_p (cfg_blocks)
     455    266248075 :                               ? -1 : bitmap_first_set_bit (cfg_blocks));
     456    266248075 :       int next_stmt_uid = (bitmap_empty_p (ssa_edge_worklist)
     457    266248075 :                            ? -1 : bitmap_first_set_bit (ssa_edge_worklist));
     458    266248075 :       if (next_block_order == -1 && next_stmt_uid == -1)
     459              :         break;
     460              : 
     461    258378035 :       int next_stmt_bb_order = -1;
     462    258378035 :       gimple *next_stmt = NULL;
     463    258378035 :       if (next_stmt_uid != -1)
     464              :         {
     465    182800367 :           next_stmt = uid_to_stmt[next_stmt_uid];
     466    182800367 :           next_stmt_bb_order = bb_to_cfg_order[gimple_bb (next_stmt)->index];
     467              :         }
     468              : 
     469              :       /* Pull the next block to simulate off the worklist if it comes first.  */
     470    258378035 :       if (next_block_order != -1
     471    228087326 :           && (next_stmt_bb_order == -1
     472    228087326 :               || next_block_order <= next_stmt_bb_order))
     473              :         {
     474     79151449 :           curr_order = next_block_order;
     475     79151449 :           bitmap_clear_bit (cfg_blocks, next_block_order);
     476     79151449 :           basic_block bb
     477     79151449 :             = BASIC_BLOCK_FOR_FN (cfun, cfg_order_to_bb [next_block_order]);
     478     79151449 :           simulate_block (bb);
     479     79151449 :         }
     480              :       /* Else simulate from the SSA edge worklist.  */
     481              :       else
     482              :         {
     483    179226586 :           curr_order = next_stmt_bb_order;
     484    179226586 :           if (dump_file && (dump_flags & TDF_DETAILS))
     485              :             {
     486            0 :               fprintf (dump_file, "\nSimulating statement: ");
     487            0 :               print_gimple_stmt (dump_file, next_stmt, 0, dump_flags);
     488              :             }
     489    179226586 :           simulate_stmt (next_stmt);
     490              :         }
     491              :     }
     492              : 
     493      7870040 :   ssa_prop_fini ();
     494      7870040 : }
     495              : 
     496              : /* Return true if STMT is of the form 'mem_ref = RHS', where 'mem_ref'
     497              :    is a non-volatile pointer dereference, a structure reference or a
     498              :    reference to a single _DECL.  Ignore volatile memory references
     499              :    because they are not interesting for the optimizers.  */
     500              : 
     501              : bool
     502     30092839 : stmt_makes_single_store (gimple *stmt)
     503              : {
     504     30092839 :   tree lhs;
     505              : 
     506     30092839 :   if (gimple_code (stmt) != GIMPLE_ASSIGN
     507     30092839 :       && gimple_code (stmt) != GIMPLE_CALL)
     508              :     return false;
     509              : 
     510     30107455 :   if (!gimple_vdef (stmt))
     511              :     return false;
     512              : 
     513      2476174 :   lhs = gimple_get_lhs (stmt);
     514              : 
     515              :   /* A call statement may have a null LHS.  */
     516      2476174 :   if (!lhs)
     517              :     return false;
     518              : 
     519      2476174 :   return (!TREE_THIS_VOLATILE (lhs)
     520      2476174 :           && (DECL_P (lhs)
     521      2461558 :               || REFERENCE_CLASS_P (lhs)));
     522              : }
     523              : 
     524              : 
     525              : /* Propagation statistics.  */
     526              : struct prop_stats_d
     527              : {
     528              :   long num_const_prop;
     529              :   long num_copy_prop;
     530              :   long num_stmts_folded;
     531              : };
     532              : 
     533              : static struct prop_stats_d prop_stats;
     534              : 
     535              : // range_query default methods to drive from a value_of_expr() ranther than
     536              : // range_of_expr.
     537              : 
     538              : tree
     539     56582667 : substitute_and_fold_engine::value_on_edge (edge, tree expr)
     540              : {
     541     56582667 :   return value_of_expr (expr);
     542              : }
     543              : 
     544              : tree
     545    130855337 : substitute_and_fold_engine::value_of_stmt (gimple *stmt, tree name)
     546              : {
     547    130855337 :   if (!name)
     548            0 :     name = gimple_get_lhs (stmt);
     549              : 
     550    130855337 :   gcc_checking_assert (!name || name == gimple_get_lhs (stmt));
     551              : 
     552    130855337 :   if (name)
     553    130855337 :     return value_of_expr (name);
     554              :   return NULL_TREE;
     555              : }
     556              : 
     557              : bool
     558            0 : substitute_and_fold_engine::range_of_expr (vrange &, tree, gimple *)
     559              : {
     560            0 :   return false;
     561              : }
     562              : 
     563              : /* Replace USE references in statement STMT with the values stored in
     564              :    PROP_VALUE. Return true if at least one reference was replaced.  */
     565              : 
     566              : bool
     567    793140052 : substitute_and_fold_engine::replace_uses_in (gimple *stmt)
     568              : {
     569    793140052 :   bool replaced = false;
     570    793140052 :   use_operand_p use;
     571    793140052 :   ssa_op_iter iter;
     572              : 
     573   1170397072 :   FOR_EACH_SSA_USE_OPERAND (use, stmt, iter, SSA_OP_USE)
     574              :     {
     575    377257020 :       tree tuse = USE_FROM_PTR (use);
     576    377257020 :       tree val = value_of_expr (tuse, stmt);
     577              : 
     578    377257020 :       if (val == tuse || val == NULL_TREE)
     579    363124532 :         continue;
     580              : 
     581     14132488 :       if (!may_propagate_copy (tuse, val))
     582          512 :         continue;
     583              : 
     584     14131976 :       if (TREE_CODE (val) != SSA_NAME)
     585      5402929 :         prop_stats.num_const_prop++;
     586              :       else
     587      8729047 :         prop_stats.num_copy_prop++;
     588              : 
     589     14131976 :       propagate_value (use, val);
     590              : 
     591     14131976 :       replaced = true;
     592              :     }
     593              : 
     594    793140052 :   return replaced;
     595              : }
     596              : 
     597              : 
     598              : /* Replace propagated values into all the arguments for PHI using the
     599              :    values from PROP_VALUE.  */
     600              : 
     601              : bool
     602     23138921 : substitute_and_fold_engine::replace_phi_args_in (gphi *phi)
     603              : {
     604     23138921 :   size_t i;
     605     23138921 :   bool replaced = false;
     606              : 
     607     78210711 :   for (i = 0; i < gimple_phi_num_args (phi); i++)
     608              :     {
     609     55071790 :       tree arg = gimple_phi_arg_def (phi, i);
     610              : 
     611     55071790 :       if (TREE_CODE (arg) == SSA_NAME)
     612              :         {
     613     38965567 :           edge e = gimple_phi_arg_edge (phi, i);
     614     38965567 :           tree val = value_on_edge (e, arg);
     615              : 
     616     38965567 :           if (val && val != arg && may_propagate_copy (arg, val))
     617              :             {
     618      1150424 :               if (TREE_CODE (val) != SSA_NAME)
     619        30652 :                 prop_stats.num_const_prop++;
     620              :               else
     621      1119772 :                 prop_stats.num_copy_prop++;
     622              : 
     623      1150424 :               propagate_value (PHI_ARG_DEF_PTR (phi, i), val);
     624      1150424 :               replaced = true;
     625              : 
     626              :               /* If we propagated a copy and this argument flows
     627              :                  through an abnormal edge, update the replacement
     628              :                  accordingly.  */
     629      1150424 :               if (TREE_CODE (val) == SSA_NAME
     630      1119772 :                   && e->flags & EDGE_ABNORMAL
     631      1150424 :                   && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val))
     632              :                 {
     633              :                   /* This can only occur for virtual operands, since
     634              :                      for the real ones SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val))
     635              :                      would prevent replacement.  */
     636            0 :                   gcc_checking_assert (virtual_operand_p (val));
     637            0 :                   SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val) = 1;
     638              :                 }
     639              :             }
     640              :         }
     641              :     }
     642              : 
     643     23138921 :   if (dump_file && (dump_flags & TDF_DETAILS))
     644              :     {
     645          147 :       if (!replaced)
     646          147 :         fprintf (dump_file, "No folding possible\n");
     647              :       else
     648              :         {
     649            0 :           fprintf (dump_file, "Folded into: ");
     650            0 :           print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
     651            0 :           fprintf (dump_file, "\n");
     652              :         }
     653              :     }
     654              : 
     655     23138921 :   return replaced;
     656              : }
     657              : 
     658              : 
     659              : class substitute_and_fold_dom_walker : public dom_walker
     660              : {
     661              : public:
     662     12097048 :     substitute_and_fold_dom_walker (cdi_direction direction,
     663              :                                     class substitute_and_fold_engine *engine)
     664     12097048 :         : dom_walker (direction),
     665     12097048 :           something_changed (false),
     666     12097048 :           substitute_and_fold_engine (engine)
     667              :     {
     668     12097048 :       dceworklist = BITMAP_ALLOC (NULL);
     669     12097048 :       stmts_to_fixup.create (0);
     670     12097048 :       need_eh_cleanup = BITMAP_ALLOC (NULL);
     671     12097048 :       need_ab_cleanup = BITMAP_ALLOC (NULL);
     672     12097048 :     }
     673     12097048 :     ~substitute_and_fold_dom_walker ()
     674     12097048 :     {
     675     12097048 :       BITMAP_FREE (dceworklist);
     676     12097048 :       stmts_to_fixup.release ();
     677     12097048 :       BITMAP_FREE (need_eh_cleanup);
     678     12097048 :       BITMAP_FREE (need_ab_cleanup);
     679     12097048 :     }
     680              : 
     681              :     edge before_dom_children (basic_block) final override;
     682    119073506 :     void after_dom_children (basic_block bb) final override
     683              :     {
     684    119073506 :       substitute_and_fold_engine->post_fold_bb (bb);
     685    119073506 :     }
     686              : 
     687              :     bool something_changed;
     688              :     bitmap dceworklist;
     689              :     vec<gimple *> stmts_to_fixup;
     690              :     bitmap need_eh_cleanup;
     691              :     bitmap need_ab_cleanup;
     692              : 
     693              :     class substitute_and_fold_engine *substitute_and_fold_engine;
     694              : 
     695              : private:
     696              :     void foreach_new_stmt_in_bb (gimple_stmt_iterator old_gsi,
     697              :                                  gimple_stmt_iterator new_gsi);
     698              : };
     699              : 
     700              : /* Call post_new_stmt for each new statement that has been added
     701              :    to the current BB.  OLD_GSI is the statement iterator before the BB
     702              :    changes ocurred.  NEW_GSI is the iterator which may contain new
     703              :    statements.  */
     704              : 
     705              : void
     706     14662469 : substitute_and_fold_dom_walker::foreach_new_stmt_in_bb
     707              :                                 (gimple_stmt_iterator old_gsi,
     708              :                                  gimple_stmt_iterator new_gsi)
     709              : {
     710     14662469 :   basic_block bb = gsi_bb (new_gsi);
     711     14662469 :   if (gsi_end_p (old_gsi))
     712      3279960 :     old_gsi = gsi_start_bb (bb);
     713              :   else
     714     13022489 :     gsi_next (&old_gsi);
     715     14730053 :   while (gsi_stmt (old_gsi) != gsi_stmt (new_gsi))
     716              :     {
     717        67584 :       gimple *stmt = gsi_stmt (old_gsi);
     718        67584 :       substitute_and_fold_engine->post_new_stmt (stmt);
     719        67584 :       gsi_next (&old_gsi);
     720              :     }
     721     14662469 : }
     722              : 
     723              : bool
     724    119073506 : substitute_and_fold_engine::propagate_into_phi_args (basic_block bb)
     725              : {
     726    119073506 :   edge e;
     727    119073506 :   edge_iterator ei;
     728    119073506 :   bool propagated = false;
     729              : 
     730              :   /* Visit BB successor PHI nodes and replace PHI args.  */
     731    281263307 :   FOR_EACH_EDGE (e, ei, bb->succs)
     732              :     {
     733    162189801 :       for (gphi_iterator gpi = gsi_start_phis (e->dest);
     734    271045555 :            !gsi_end_p (gpi); gsi_next (&gpi))
     735              :         {
     736    108855754 :           gphi *phi = gpi.phi ();
     737    108855754 :           use_operand_p use_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e);
     738    108855754 :           tree arg = USE_FROM_PTR (use_p);
     739    175368423 :           if (TREE_CODE (arg) != SSA_NAME
     740    108855754 :               || virtual_operand_p (arg))
     741     66512669 :             continue;
     742     42343085 :           tree val = value_on_edge (e, arg);
     743     42343085 :           if (val
     744      3139643 :               && is_gimple_min_invariant (val)
     745     44274900 :               && may_propagate_copy (arg, val))
     746              :             {
     747      1929899 :               propagate_value (use_p, val);
     748      1929899 :               propagated = true;
     749              :             }
     750              :         }
     751              :     }
     752    119073506 :   return propagated;
     753              : }
     754              : 
     755              : edge
     756    119073506 : substitute_and_fold_dom_walker::before_dom_children (basic_block bb)
     757              : {
     758    119073506 :   substitute_and_fold_engine->pre_fold_bb (bb);
     759              : 
     760              :   /* Propagate known values into PHI nodes.  */
     761    119073506 :   for (gphi_iterator i = gsi_start_phis (bb);
     762    164130844 :        !gsi_end_p (i);
     763     45057338 :        gsi_next (&i))
     764              :     {
     765     45057338 :       gphi *phi = i.phi ();
     766     45057338 :       tree res = gimple_phi_result (phi);
     767     90114676 :       if (virtual_operand_p (res))
     768     20042809 :         continue;
     769     25014529 :       if (dump_file && (dump_flags & TDF_DETAILS))
     770              :         {
     771          151 :           fprintf (dump_file, "Folding PHI node: ");
     772          151 :           print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
     773              :         }
     774     25014529 :       if (res && TREE_CODE (res) == SSA_NAME)
     775              :         {
     776     25014529 :           tree sprime = substitute_and_fold_engine->value_of_expr (res, phi);
     777     26890137 :           if (sprime
     778     25014529 :               && sprime != res
     779     25014529 :               && may_propagate_copy (res, sprime))
     780              :             {
     781      1875608 :               if (dump_file && (dump_flags & TDF_DETAILS))
     782              :                 {
     783            4 :                   fprintf (dump_file, "Queued PHI for removal.  Folds to: ");
     784            4 :                   print_generic_expr (dump_file, sprime);
     785            4 :                   fprintf (dump_file, "\n");
     786              :                 }
     787      1875608 :               bitmap_set_bit (dceworklist, SSA_NAME_VERSION (res));
     788              :               /* As this now constitutes a copy duplicate points-to
     789              :                  and range info appropriately.  */
     790      1875608 :               if (TREE_CODE (sprime) == SSA_NAME)
     791      1184164 :                 maybe_duplicate_ssa_info_at_copy (res, sprime);
     792      1875608 :               continue;
     793              :             }
     794              :         }
     795     23138921 :       something_changed |= substitute_and_fold_engine->replace_phi_args_in (phi);
     796              :     }
     797              : 
     798              :   /* Propagate known values into stmts.  In some case it exposes
     799              :      more trivially deletable stmts to walk backward.  */
     800    238147012 :   for (gimple_stmt_iterator i = gsi_start_bb (bb);
     801    926957232 :        !gsi_end_p (i);
     802    807883726 :        gsi_next (&i))
     803              :     {
     804    807883726 :       bool did_replace;
     805    807883726 :       gimple *stmt = gsi_stmt (i);
     806              : 
     807    807883726 :       substitute_and_fold_engine->pre_fold_stmt (stmt);
     808              : 
     809    807883726 :       if (dump_file && (dump_flags & TDF_DETAILS))
     810              :         {
     811         1779 :           fprintf (dump_file, "Folding statement: ");
     812         1779 :           print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
     813              :         }
     814              : 
     815              :       /* No point propagating into a stmt we have a value for we
     816              :          can propagate into all uses.  Mark it for removal instead.  */
     817    807883726 :       tree lhs = gimple_get_lhs (stmt);
     818    807883726 :       if (lhs && TREE_CODE (lhs) == SSA_NAME)
     819              :         {
     820    178016066 :           tree sprime = substitute_and_fold_engine->value_of_stmt (stmt, lhs);
     821    192759740 :           if (sprime
     822    178016066 :               && sprime != lhs
     823     14762727 :               && may_propagate_copy (lhs, sprime)
     824     14761370 :               && !stmt_could_throw_p (cfun, stmt)
     825    192763985 :               && !gimple_has_side_effects (stmt))
     826              :             {
     827     14743674 :               if (dump_file && (dump_flags & TDF_DETAILS))
     828              :                 {
     829           54 :                   fprintf (dump_file, "Queued stmt for removal.  Folds to: ");
     830           54 :                   print_generic_expr (dump_file, sprime);
     831           54 :                   fprintf (dump_file, "\n");
     832              :                 }
     833     14743674 :               bitmap_set_bit (dceworklist, SSA_NAME_VERSION (lhs));
     834              :               /* As this now constitutes a copy duplicate points-to
     835              :                  and range info appropriately.  */
     836     14743674 :               if (TREE_CODE (sprime) == SSA_NAME)
     837      8758280 :                 maybe_duplicate_ssa_info_at_copy (lhs, sprime);
     838     14743674 :               continue;
     839              :             }
     840              :         }
     841              : 
     842              :       /* Replace the statement with its folded version and mark it
     843              :          folded.  */
     844    793140052 :       did_replace = false;
     845    793140052 :       gimple *old_stmt = stmt;
     846    793140052 :       bool was_noreturn = false;
     847    793140052 :       bool can_make_abnormal_goto = false;
     848    793140052 :       if (is_gimple_call (stmt))
     849              :         {
     850     52705565 :           was_noreturn = gimple_call_noreturn_p (stmt);
     851     52705565 :           can_make_abnormal_goto = stmt_can_make_abnormal_goto (stmt);
     852              :         }
     853              : 
     854              :       /* Replace real uses in the statement.  */
     855    793140052 :       did_replace |= substitute_and_fold_engine->replace_uses_in (stmt);
     856              : 
     857    793140052 :       gimple_stmt_iterator prev_gsi = i;
     858    793140052 :       gsi_prev (&prev_gsi);
     859              : 
     860              :       /* If we made a replacement, fold the statement.  */
     861    793140052 :       if (did_replace)
     862              :         {
     863     13298176 :           fold_stmt (&i, follow_single_use_edges);
     864     13298176 :           stmt = gsi_stmt (i);
     865     13298176 :           gimple_set_modified (stmt, true);
     866              :         }
     867              :       /* Also fold if we want to fold all statements.  */
     868    779841876 :       else if (substitute_and_fold_engine->fold_all_stmts
     869    779841876 :                && fold_stmt (&i, follow_single_use_edges))
     870              :         {
     871            0 :           did_replace = true;
     872            0 :           stmt = gsi_stmt (i);
     873            0 :           gimple_set_modified (stmt, true);
     874              :         }
     875              : 
     876              :       /* Some statements may be simplified using propagator
     877              :          specific information.  Do this before propagating
     878              :          into the stmt to not disturb pass specific information.  */
     879    793140052 :       update_stmt_if_modified (stmt);
     880    793140052 :       if (substitute_and_fold_engine->fold_stmt (&i))
     881              :         {
     882      1766296 :           did_replace = true;
     883      1766296 :           prop_stats.num_stmts_folded++;
     884      1766296 :           stmt = gsi_stmt (i);
     885      1766296 :           gimple_set_modified (stmt, true);
     886              :         }
     887              : 
     888              :       /* If this is a control statement the propagator left edges
     889              :          unexecuted on force the condition in a way consistent with
     890              :          that.  See PR66945 for cases where the propagator can end
     891              :          up with a different idea of a taken edge than folding
     892              :          (once undefined behavior is involved).  */
     893    793140052 :       if (gimple_code (stmt) == GIMPLE_COND)
     894              :         {
     895     42616004 :           if ((EDGE_SUCC (bb, 0)->flags & EDGE_EXECUTABLE)
     896     42616004 :               ^ (EDGE_SUCC (bb, 1)->flags & EDGE_EXECUTABLE))
     897              :             {
     898       431538 :               if (((EDGE_SUCC (bb, 0)->flags & EDGE_TRUE_VALUE) != 0)
     899       431538 :                   == ((EDGE_SUCC (bb, 0)->flags & EDGE_EXECUTABLE) != 0))
     900       101236 :                 gimple_cond_make_true (as_a <gcond *> (stmt));
     901              :               else
     902       330302 :                 gimple_cond_make_false (as_a <gcond *> (stmt));
     903       431538 :               gimple_set_modified (stmt, true);
     904       431538 :               did_replace = true;
     905              :             }
     906              :         }
     907              : 
     908              :       /* Now cleanup.  */
     909    793140052 :       if (did_replace)
     910              :         {
     911     14662469 :           foreach_new_stmt_in_bb (prev_gsi, i);
     912              : 
     913              :           /* If we cleaned up EH information from the statement,
     914              :              remove EH edges.  */
     915     14662469 :           if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
     916       155795 :             bitmap_set_bit (need_eh_cleanup, bb->index);
     917              : 
     918              :           /* If we turned a call with possible abnormal control transfer
     919              :              into one that doesn't, remove abnormal edges.  */
     920     14662469 :           if (can_make_abnormal_goto
     921     14662469 :               && !stmt_can_make_abnormal_goto (stmt))
     922            3 :             bitmap_set_bit (need_ab_cleanup, bb->index);
     923              : 
     924              :           /* If we turned a not noreturn call into a noreturn one
     925              :              schedule it for fixup.  */
     926     14662469 :           if (!was_noreturn
     927     14532747 :               && is_gimple_call (stmt)
     928     16077699 :               && gimple_call_noreturn_p (stmt))
     929           70 :             stmts_to_fixup.safe_push (stmt);
     930              : 
     931     14662469 :           if (gimple_assign_single_p (stmt))
     932              :             {
     933      3482511 :               tree rhs = gimple_assign_rhs1 (stmt);
     934              : 
     935      3482511 :               if (TREE_CODE (rhs) == ADDR_EXPR)
     936       377854 :                 recompute_tree_invariant_for_addr_expr (rhs);
     937              :             }
     938              : 
     939              :           /* Determine what needs to be done to update the SSA form.  */
     940     14662469 :           update_stmt_if_modified (stmt);
     941     14662469 :           if (!is_gimple_debug (stmt))
     942     10603765 :             something_changed = true;
     943              :         }
     944              : 
     945    793140052 :       if (dump_file && (dump_flags & TDF_DETAILS))
     946              :         {
     947         1725 :           if (did_replace)
     948              :             {
     949          141 :               fprintf (dump_file, "Folded into: ");
     950          141 :               print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
     951          141 :               fprintf (dump_file, "\n");
     952              :             }
     953              :           else
     954         1584 :             fprintf (dump_file, "Not folded\n");
     955              :         }
     956              :     }
     957              : 
     958    119073506 :   something_changed |= substitute_and_fold_engine->propagate_into_phi_args (bb);
     959              : 
     960    119073506 :   return NULL;
     961              : }
     962              : 
     963              : 
     964              : 
     965              : /* Perform final substitution and folding of propagated values.
     966              :    Process the whole function if BLOCK is null, otherwise only
     967              :    process the blocks that BLOCK dominates.  In the latter case,
     968              :    it is the caller's responsibility to ensure that dominator
     969              :    information is available and up-to-date.
     970              : 
     971              :    PROP_VALUE[I] contains the single value that should be substituted
     972              :    at every use of SSA name N_I.  If PROP_VALUE is NULL, no values are
     973              :    substituted.
     974              : 
     975              :    If FOLD_FN is non-NULL the function will be invoked on all statements
     976              :    before propagating values for pass specific simplification.
     977              : 
     978              :    DO_DCE is true if trivially dead stmts can be removed.
     979              : 
     980              :    If DO_DCE is true, the statements within a BB are walked from
     981              :    last to first element.  Otherwise we scan from first to last element.
     982              : 
     983              :    Return TRUE when something changed.  */
     984              : 
     985              : bool
     986     12097048 : substitute_and_fold_engine::substitute_and_fold (basic_block block)
     987              : {
     988     12097048 :   if (dump_file && (dump_flags & TDF_DETAILS))
     989          158 :     fprintf (dump_file, "\nSubstituting values and folding statements\n\n");
     990              : 
     991     12097048 :   memset (&prop_stats, 0, sizeof (prop_stats));
     992              : 
     993              :   /* Don't call calculate_dominance_info when iterating over a subgraph.
     994              :      Callers that are using the interface this way are likely to want to
     995              :      iterate over several disjoint subgraphs, and it would be expensive
     996              :      in enable-checking builds to revalidate the whole dominance tree
     997              :      each time.  */
     998     12097048 :   if (block)
     999         1192 :     gcc_assert (dom_info_state (CDI_DOMINATORS));
    1000              :   else
    1001     12095856 :     calculate_dominance_info (CDI_DOMINATORS);
    1002     12097048 :   substitute_and_fold_dom_walker walker (CDI_DOMINATORS, this);
    1003     12097048 :   walker.walk (block ? block : ENTRY_BLOCK_PTR_FOR_FN (cfun));
    1004              : 
    1005     12097048 :   simple_dce_from_worklist (walker.dceworklist, walker.need_eh_cleanup);
    1006     12097048 :   if (!bitmap_empty_p (walker.need_eh_cleanup))
    1007        36760 :     gimple_purge_all_dead_eh_edges (walker.need_eh_cleanup);
    1008     12097048 :   if (!bitmap_empty_p (walker.need_ab_cleanup))
    1009            3 :     gimple_purge_all_dead_abnormal_call_edges (walker.need_ab_cleanup);
    1010              : 
    1011              :   /* Fixup stmts that became noreturn calls.  This may require splitting
    1012              :      blocks and thus isn't possible during the dominator walk.  Do this
    1013              :      in reverse order so we don't inadvertedly remove a stmt we want to
    1014              :      fixup by visiting a dominating now noreturn call first.  */
    1015     12097118 :   while (!walker.stmts_to_fixup.is_empty ())
    1016              :     {
    1017           70 :       gimple *stmt = walker.stmts_to_fixup.pop ();
    1018           76 :       if (!gimple_bb (stmt))
    1019            6 :         continue;
    1020           64 :       if (dump_file && dump_flags & TDF_DETAILS)
    1021              :         {
    1022            0 :           fprintf (dump_file, "Fixing up noreturn call ");
    1023            0 :           print_gimple_stmt (dump_file, stmt, 0);
    1024            0 :           fprintf (dump_file, "\n");
    1025              :         }
    1026           64 :       fixup_noreturn_call (stmt);
    1027              :     }
    1028              : 
    1029     12097048 :   statistics_counter_event (cfun, "Constants propagated",
    1030     12097048 :                             prop_stats.num_const_prop);
    1031     12097048 :   statistics_counter_event (cfun, "Copies propagated",
    1032     12097048 :                             prop_stats.num_copy_prop);
    1033     12097048 :   statistics_counter_event (cfun, "Statements folded",
    1034     12097048 :                             prop_stats.num_stmts_folded);
    1035              : 
    1036     12097048 :   return walker.something_changed;
    1037     12097048 : }
    1038              : 
    1039              : 
    1040              : /* Return true if we may propagate ORIG into DEST, false otherwise.
    1041              :    If DEST_NOT_ABNORMAL_PHI_EDGE_P is true then assume the propagation does
    1042              :    not happen into a PHI argument which flows in from an abnormal edge
    1043              :    which relaxes some constraints.  */
    1044              : 
    1045              : bool
    1046    150330607 : may_propagate_copy (tree dest, tree orig, bool dest_not_abnormal_phi_edge_p)
    1047              : {
    1048    150330607 :   tree type_d = TREE_TYPE (dest);
    1049    150330607 :   tree type_o = TREE_TYPE (orig);
    1050              : 
    1051              :   /* If ORIG is a default definition which flows in from an abnormal edge
    1052              :      then the copy can be propagated.  It is important that we do so to avoid
    1053              :      uninitialized copies.  */
    1054    150330607 :   if (TREE_CODE (orig) == SSA_NAME
    1055    104428824 :       && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig)
    1056        28977 :       && SSA_NAME_IS_DEFAULT_DEF (orig)
    1057    150333847 :       && (SSA_NAME_VAR (orig) == NULL_TREE
    1058         3240 :           || VAR_P (SSA_NAME_VAR (orig))))
    1059              :     ;
    1060              :   /* Otherwise if ORIG just flows in from an abnormal edge then the copy cannot
    1061              :      be propagated.  */
    1062    150327770 :   else if (TREE_CODE (orig) == SSA_NAME
    1063    150327770 :            && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig))
    1064              :     return false;
    1065              :   /* Similarly if DEST flows in from an abnormal edge then the copy cannot be
    1066              :      propagated.  If we know we do not propagate into such a PHI argument this
    1067              :      does not apply.  */
    1068    150301630 :   else if (!dest_not_abnormal_phi_edge_p
    1069     77622197 :            && TREE_CODE (dest) == SSA_NAME
    1070    227923827 :            && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (dest))
    1071              :     return false;
    1072              : 
    1073              :   /* Do not copy between types for which we *do* need a conversion.  */
    1074    150289228 :   if (!useless_type_conversion_p (type_d, type_o))
    1075              :     return false;
    1076              : 
    1077              :   /* Generally propagating virtual operands is not ok as that may
    1078              :      create overlapping life-ranges.  */
    1079    150275158 :   if (TREE_CODE (dest) == SSA_NAME && virtual_operand_p (dest))
    1080              :     return false;
    1081              : 
    1082              :   /* Keep lhs of [[gnu::musttail]] calls as is, those need to be still
    1083              :      tail callable.  */
    1084    149835237 :   if (TREE_CODE (dest) == SSA_NAME
    1085    149666815 :       && is_gimple_call (SSA_NAME_DEF_STMT (dest))
    1086    151169123 :       && gimple_call_must_tail_p (as_a <gcall *> (SSA_NAME_DEF_STMT (dest))))
    1087              :     return false;
    1088              : 
    1089              :   /* Anything else is OK.  */
    1090              :   return true;
    1091              : }
    1092              : 
    1093              : /* Like may_propagate_copy, but use as the destination expression
    1094              :    the principal expression (typically, the RHS) contained in
    1095              :    statement DEST.  This is more efficient when working with the
    1096              :    gimple tuples representation.  */
    1097              : 
    1098              : bool
    1099       374641 : may_propagate_copy_into_stmt (gimple *dest, tree orig)
    1100              : {
    1101       374641 :   tree type_d;
    1102       374641 :   tree type_o;
    1103              : 
    1104              :   /* If the statement is a switch or a single-rhs assignment,
    1105              :      then the expression to be replaced by the propagation may
    1106              :      be an SSA_NAME.  Fortunately, there is an explicit tree
    1107              :      for the expression, so we delegate to may_propagate_copy.  */
    1108              : 
    1109       374641 :   if (gimple_assign_single_p (dest))
    1110       181070 :     return may_propagate_copy (gimple_assign_rhs1 (dest), orig, true);
    1111       193571 :   else if (gswitch *dest_swtch = dyn_cast <gswitch *> (dest))
    1112            0 :     return may_propagate_copy (gimple_switch_index (dest_swtch), orig, true);
    1113              : 
    1114              :   /* In other cases, the expression is not materialized, so there
    1115              :      is no destination to pass to may_propagate_copy.  On the other
    1116              :      hand, the expression cannot be an SSA_NAME, so the analysis
    1117              :      is much simpler.  */
    1118              : 
    1119       193571 :   if (TREE_CODE (orig) == SSA_NAME
    1120       193571 :       && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig))
    1121              :     return false;
    1122              : 
    1123       193571 :   if (is_gimple_assign (dest))
    1124       163114 :     type_d = TREE_TYPE (gimple_assign_lhs (dest));
    1125        30457 :   else if (gimple_code (dest) == GIMPLE_COND)
    1126        25759 :     type_d = boolean_type_node;
    1127         4698 :   else if (is_gimple_call (dest)
    1128         4698 :            && gimple_call_lhs (dest) != NULL_TREE)
    1129         4698 :     type_d = TREE_TYPE (gimple_call_lhs (dest));
    1130              :   else
    1131            0 :     gcc_unreachable ();
    1132              : 
    1133       193571 :   type_o = TREE_TYPE (orig);
    1134              : 
    1135       193571 :   if (!useless_type_conversion_p (type_d, type_o))
    1136              :     return false;
    1137              : 
    1138              :   return true;
    1139              : }
    1140              : 
    1141              : /* Replace *OP_P with value VAL (assumed to be a constant or another SSA_NAME).
    1142              : 
    1143              :    Use this version when not const/copy propagating values.  For example,
    1144              :    PRE uses this version when building expressions as they would appear
    1145              :    in specific blocks taking into account actions of PHI nodes.
    1146              : 
    1147              :    The statement in which an expression has been replaced should be
    1148              :    folded using fold_stmt_inplace.  */
    1149              : 
    1150              : void
    1151     54387041 : replace_exp (use_operand_p op_p, tree val)
    1152              : {
    1153     54387041 :   if (TREE_CODE (val) == SSA_NAME || CONSTANT_CLASS_P (val))
    1154     50611896 :     SET_USE (op_p, val);
    1155              :   else
    1156      3775145 :     SET_USE (op_p, unshare_expr (val));
    1157     54387041 : }
    1158              : 
    1159              : 
    1160              : /* Propagate the value VAL (assumed to be a constant or another SSA_NAME)
    1161              :    into the operand pointed to by OP_P.
    1162              : 
    1163              :    Use this version for const/copy propagation as it will perform additional
    1164              :    checks to ensure validity of the const/copy propagation.  */
    1165              : 
    1166              : void
    1167     48137464 : propagate_value (use_operand_p op_p, tree val)
    1168              : {
    1169     48137464 :   if (flag_checking)
    1170              :     {
    1171     48136994 :       bool ab = (is_a <gphi *> (USE_STMT (op_p))
    1172     64331785 :                  && (gimple_phi_arg_edge (as_a <gphi *> (USE_STMT (op_p)),
    1173     16194791 :                                           PHI_ARG_INDEX_FROM_USE (op_p))
    1174     16194791 :                      ->flags & EDGE_ABNORMAL));
    1175     48136994 :       gcc_assert (may_propagate_copy (USE_FROM_PTR (op_p), val, !ab));
    1176              :     }
    1177     48137464 :   replace_exp (op_p, val);
    1178     48137464 : }
    1179              : 
    1180              : 
    1181              : /* Propagate the value VAL (assumed to be a constant or another SSA_NAME)
    1182              :    into the tree pointed to by OP_P.
    1183              : 
    1184              :    Use this version for const/copy propagation when SSA operands are not
    1185              :    available.  It will perform the additional checks to ensure validity of
    1186              :    the const/copy propagation, but will not update any operand information.
    1187              :    Be sure to mark the stmt as modified.  */
    1188              : 
    1189              : void
    1190       401516 : propagate_tree_value (tree *op_p, tree val)
    1191              : {
    1192       401516 :   if (TREE_CODE (val) == SSA_NAME)
    1193       361994 :     *op_p = val;
    1194              :   else
    1195        39522 :     *op_p = unshare_expr (val);
    1196       401516 : }
    1197              : 
    1198              : 
    1199              : /* Like propagate_tree_value, but use as the operand to replace
    1200              :    the principal expression (typically, the RHS) contained in the
    1201              :    statement referenced by iterator GSI.  Note that it is not
    1202              :    always possible to update the statement in-place, so a new
    1203              :    statement may be created to replace the original.  */
    1204              : 
    1205              : void
    1206       401516 : propagate_tree_value_into_stmt (gimple_stmt_iterator *gsi, tree val)
    1207              : {
    1208       401516 :   gimple *stmt = gsi_stmt (*gsi);
    1209              : 
    1210       401516 :   if (is_gimple_assign (stmt))
    1211              :     {
    1212       367659 :       tree expr = NULL_TREE;
    1213       367659 :       if (gimple_assign_single_p (stmt))
    1214       200795 :         expr = gimple_assign_rhs1 (stmt);
    1215       367659 :       propagate_tree_value (&expr, val);
    1216       367659 :       gimple_assign_set_rhs_from_tree (gsi, expr);
    1217              :     }
    1218        33857 :   else if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
    1219              :     {
    1220        28904 :       tree lhs = NULL_TREE;
    1221        28904 :       tree rhs = build_zero_cst (TREE_TYPE (val));
    1222        28904 :       propagate_tree_value (&lhs, val);
    1223        28904 :       gimple_cond_set_code (cond_stmt, NE_EXPR);
    1224        28904 :       gimple_cond_set_lhs (cond_stmt, lhs);
    1225        28904 :       gimple_cond_set_rhs (cond_stmt, rhs);
    1226              :     }
    1227         4953 :   else if (is_gimple_call (stmt)
    1228         4953 :            && gimple_call_lhs (stmt) != NULL_TREE)
    1229              :     {
    1230         4953 :       tree expr = NULL_TREE;
    1231         4953 :       propagate_tree_value (&expr, val);
    1232         4953 :       replace_call_with_value (gsi, expr);
    1233              :     }
    1234            0 :   else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt))
    1235            0 :     propagate_tree_value (gimple_switch_index_ptr (swtch_stmt), val);
    1236              :   else
    1237            0 :     gcc_unreachable ();
    1238       401516 : }
    1239              : 
    1240              : /* Check exits of each loop in FUN, walk over loop closed PHIs in
    1241              :    each exit basic block and propagate degenerate PHIs.  */
    1242              : 
    1243              : unsigned
    1244       241452 : clean_up_loop_closed_phi (function *fun)
    1245              : {
    1246       241452 :   gphi *phi;
    1247       241452 :   tree rhs;
    1248       241452 :   tree lhs;
    1249       241452 :   gphi_iterator gsi;
    1250              : 
    1251              :   /* Avoid possibly quadratic work when scanning for loop exits across
    1252              :    all loops of a nest.  */
    1253       241452 :   if (!loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS))
    1254              :     return 0;
    1255              : 
    1256              :   /* replace_uses_by might purge dead EH edges and we want it to also
    1257              :      remove dominated blocks.  */
    1258       241452 :   calculate_dominance_info  (CDI_DOMINATORS);
    1259              : 
    1260              :   /* Walk over loop in function.  */
    1261      1355592 :   for (auto loop : loops_list (fun, 0))
    1262              :     {
    1263              :       /* Check each exit edege of loop.  */
    1264       631236 :       auto_vec<edge> exits = get_loop_exit_edges (loop);
    1265      3030283 :       for (edge e : exits)
    1266      1919191 :         if (single_pred_p (e->dest))
    1267              :           /* Walk over loop-closed PHIs.  */
    1268      1677216 :           for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi);)
    1269              :             {
    1270       907236 :               phi = gsi.phi ();
    1271       907236 :               rhs = gimple_phi_arg_def (phi, 0);
    1272       907236 :               lhs = gimple_phi_result (phi);
    1273              : 
    1274      1813582 :               if (virtual_operand_p (rhs))
    1275              :                 {
    1276       479043 :                   imm_use_iterator iter;
    1277       479043 :                   use_operand_p use_p;
    1278       479043 :                   gimple *stmt;
    1279              : 
    1280      1643064 :                   FOR_EACH_IMM_USE_STMT (stmt, iter, lhs)
    1281      2068628 :                     FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
    1282       691825 :                       SET_USE (use_p, rhs);
    1283              : 
    1284       479043 :                   if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
    1285           48 :                     SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs) = 1;
    1286       479043 :                   remove_phi_node (&gsi, true);
    1287              :                 }
    1288       428193 :               else if (may_propagate_copy (lhs, rhs))
    1289              :                 {
    1290              :                   /* Dump details.  */
    1291       428152 :                   if (dump_file && (dump_flags & TDF_DETAILS))
    1292              :                     {
    1293            3 :                       fprintf (dump_file, "  Replacing '");
    1294            3 :                       print_generic_expr (dump_file, lhs, dump_flags);
    1295            3 :                       fprintf (dump_file, "' with '");
    1296            3 :                       print_generic_expr (dump_file, rhs, dump_flags);
    1297            3 :                       fprintf (dump_file, "'\n");
    1298              :                     }
    1299              : 
    1300       428152 :                   replace_uses_by (lhs, rhs);
    1301       428152 :                   remove_phi_node (&gsi, true);
    1302              :                 }
    1303              :               else
    1304           41 :                 gsi_next (&gsi);
    1305              :             }
    1306       631236 :     }
    1307              : 
    1308       241452 :   return 0;
    1309              : }
        

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.