LCOV - code coverage report
Current view: top level - gcc - gimple-iterator.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 96.0 % 447 429
Test Date: 2024-04-13 14:00:49 Functions: 97.4 % 39 38
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Iterator routines for GIMPLE statements.
       2                 :             :    Copyright (C) 2007-2024 Free Software Foundation, Inc.
       3                 :             :    Contributed by Aldy Hernandez  <aldy@quesejoda.com>
       4                 :             : 
       5                 :             : This file is part of GCC.
       6                 :             : 
       7                 :             : GCC is free software; you can redistribute it and/or modify it under
       8                 :             : the terms of the GNU General Public License as published by the Free
       9                 :             : Software Foundation; either version 3, or (at your option) any later
      10                 :             : version.
      11                 :             : 
      12                 :             : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      13                 :             : 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 "cfghooks.h"
      28                 :             : #include "ssa.h"
      29                 :             : #include "cgraph.h"
      30                 :             : #include "tree-eh.h"
      31                 :             : #include "gimple-iterator.h"
      32                 :             : #include "tree-cfg.h"
      33                 :             : #include "tree-ssa.h"
      34                 :             : #include "value-prof.h"
      35                 :             : #include "gimplify.h"
      36                 :             : 
      37                 :             : 
      38                 :             : /* Mark the statement STMT as modified, and update it.  */
      39                 :             : 
      40                 :             : static inline void
      41                 :   166853422 : update_modified_stmt (gimple *stmt)
      42                 :             : {
      43                 :   166853422 :   if (!ssa_operands_active (cfun))
      44                 :             :     return;
      45                 :   145514879 :   update_stmt_if_modified (stmt);
      46                 :             : }
      47                 :             : 
      48                 :             : 
      49                 :             : /* Mark the statements in SEQ as modified, and update them.  */
      50                 :             : 
      51                 :             : void
      52                 :    44325980 : update_modified_stmts (gimple_seq seq)
      53                 :             : {
      54                 :    44325980 :   gimple_stmt_iterator gsi;
      55                 :             : 
      56                 :    44325980 :   if (!ssa_operands_active (cfun))
      57                 :    44325980 :     return;
      58                 :    96906341 :   for (gsi = gsi_start (seq); !gsi_end_p (gsi); gsi_next (&gsi))
      59                 :    74623862 :     update_stmt_if_modified (gsi_stmt (gsi));
      60                 :             : }
      61                 :             : 
      62                 :             : 
      63                 :             : /* Set BB to be the basic block for all the statements in the list
      64                 :             :    starting at FIRST and LAST.  */
      65                 :             : 
      66                 :             : static void
      67                 :   145058743 : update_bb_for_stmts (gimple_seq_node first, gimple_seq_node last,
      68                 :             :                      basic_block bb)
      69                 :             : {
      70                 :   145058743 :   gimple_seq_node n;
      71                 :             : 
      72                 :   208812713 :   for (n = first; n; n = n->next)
      73                 :             :     {
      74                 :   208812713 :       gimple_set_bb (n, bb);
      75                 :   208812713 :       if (n == last)
      76                 :             :         break;
      77                 :             :     }
      78                 :   145058743 : }
      79                 :             : 
      80                 :             : /* Set the frequencies for the cgraph_edges for each of the calls
      81                 :             :    starting at FIRST for their new position within BB.  */
      82                 :             : 
      83                 :             : static void
      84                 :     1366769 : update_call_edge_frequencies (gimple_seq_node first, basic_block bb)
      85                 :             : {
      86                 :     1366769 :   struct cgraph_node *cfun_node = NULL;
      87                 :     1366769 :   gimple_seq_node n;
      88                 :             : 
      89                 :     4116121 :   for (n = first; n ; n = n->next)
      90                 :     2749352 :     if (is_gimple_call (n))
      91                 :             :       {
      92                 :        7610 :         struct cgraph_edge *e;
      93                 :             : 
      94                 :             :         /* These function calls are expensive enough that we want
      95                 :             :            to avoid calling them if we never see any calls.  */
      96                 :        7610 :         if (cfun_node == NULL)
      97                 :        5951 :           cfun_node = cgraph_node::get (current_function_decl);
      98                 :             : 
      99                 :        7610 :         e = cfun_node->get_edge (n);
     100                 :        7610 :         if (e != NULL)
     101                 :         933 :           e->count = bb->count;
     102                 :             :       }
     103                 :     1366769 : }
     104                 :             : 
     105                 :             : /* Insert the sequence delimited by nodes FIRST and LAST before
     106                 :             :    iterator I.  M specifies how to update iterator I after insertion
     107                 :             :    (see enum gsi_iterator_update).
     108                 :             : 
     109                 :             :    This routine assumes that there is a forward and backward path
     110                 :             :    between FIRST and LAST (i.e., they are linked in a doubly-linked
     111                 :             :    list).  Additionally, if FIRST == LAST, this routine will properly
     112                 :             :    insert a single node.  */
     113                 :             : 
     114                 :             : static void
     115                 :    42832874 : gsi_insert_seq_nodes_before (gimple_stmt_iterator *i,
     116                 :             :                              gimple_seq_node first,
     117                 :             :                              gimple_seq_node last,
     118                 :             :                              enum gsi_iterator_update mode)
     119                 :             : {
     120                 :    42832874 :   basic_block bb;
     121                 :    42832874 :   gimple_seq_node cur = i->ptr;
     122                 :             : 
     123                 :    42832874 :   gcc_assert (!cur || cur->prev);
     124                 :             : 
     125                 :    42832874 :   if ((bb = gsi_bb (*i)) != NULL)
     126                 :    31223783 :     update_bb_for_stmts (first, last, bb);
     127                 :             : 
     128                 :             :   /* Link SEQ before CUR in the sequence.  */
     129                 :    42832874 :   if (cur)
     130                 :             :     {
     131                 :    39133693 :       first->prev = cur->prev;
     132                 :    39133693 :       if (first->prev->next)
     133                 :    26004918 :         first->prev->next = first;
     134                 :             :       else
     135                 :    13128775 :         gimple_seq_set_first (i->seq, first);
     136                 :    39133693 :       last->next = cur;
     137                 :    39133693 :       cur->prev = last;
     138                 :             :     }
     139                 :             :   else
     140                 :             :     {
     141                 :     3699181 :       gimple_seq_node itlast = gimple_seq_last (*i->seq);
     142                 :             : 
     143                 :             :       /* If CUR is NULL, we link at the end of the sequence (this case happens
     144                 :             :          when gsi_after_labels is called for a basic block that contains only
     145                 :             :          labels, so it returns an iterator after the end of the block, and
     146                 :             :          we need to insert before it; it might be cleaner to add a flag to the
     147                 :             :          iterator saying whether we are at the start or end of the list).  */
     148                 :     3699181 :       last->next = NULL;
     149                 :     3699181 :       if (itlast)
     150                 :             :         {
     151                 :     1279554 :           first->prev = itlast;
     152                 :     1279554 :           itlast->next = first;
     153                 :             :         }
     154                 :             :       else
     155                 :     2419627 :         gimple_seq_set_first (i->seq, first);
     156                 :     3699181 :       gimple_seq_set_last (i->seq, last);
     157                 :             :     }
     158                 :             : 
     159                 :             :   /* Update the iterator, if requested.  */
     160                 :    42832874 :   switch (mode)
     161                 :             :     {
     162                 :     3878842 :     case GSI_NEW_STMT:
     163                 :     3878842 :     case GSI_CONTINUE_LINKING:
     164                 :     3878842 :       i->ptr = first;
     165                 :     3878842 :       break;
     166                 :           0 :     case GSI_LAST_NEW_STMT:
     167                 :           0 :       i->ptr = last;
     168                 :           0 :       break;
     169                 :             :     case GSI_SAME_STMT:
     170                 :             :       break;
     171                 :           0 :     default:
     172                 :           0 :       gcc_unreachable ();
     173                 :             :     }
     174                 :    42832874 : }
     175                 :             : 
     176                 :             : 
     177                 :             : /* Inserts the sequence of statements SEQ before the statement pointed
     178                 :             :    by iterator I.  MODE indicates what to do with the iterator after
     179                 :             :    insertion (see enum gsi_iterator_update).
     180                 :             : 
     181                 :             :    This function does not scan for new operands.  It is provided for
     182                 :             :    the use of the gimplifier, which manipulates statements for which
     183                 :             :    def/use information has not yet been constructed.  Most callers
     184                 :             :    should use gsi_insert_seq_before.  */
     185                 :             : 
     186                 :             : void
     187                 :    22869785 : gsi_insert_seq_before_without_update (gimple_stmt_iterator *i, gimple_seq seq,
     188                 :             :                                       enum gsi_iterator_update mode)
     189                 :             : {
     190                 :    22869785 :   gimple_seq_node first, last;
     191                 :             : 
     192                 :    22869785 :   if (seq == NULL)
     193                 :             :     return;
     194                 :             : 
     195                 :             :   /* Don't allow inserting a sequence into itself.  */
     196                 :    14681626 :   gcc_assert (seq != *i->seq);
     197                 :             : 
     198                 :    14681626 :   first = gimple_seq_first (seq);
     199                 :    14681626 :   last = gimple_seq_last (seq);
     200                 :             : 
     201                 :             :   /* Empty sequences need no work.  */
     202                 :    14681626 :   if (!first || !last)
     203                 :             :     {
     204                 :           0 :       gcc_assert (first == last);
     205                 :             :       return;
     206                 :             :     }
     207                 :             : 
     208                 :    14681626 :   gsi_insert_seq_nodes_before (i, first, last, mode);
     209                 :             : }
     210                 :             : 
     211                 :             : 
     212                 :             : /* Inserts the sequence of statements SEQ before the statement pointed
     213                 :             :    by iterator I.  MODE indicates what to do with the iterator after
     214                 :             :    insertion (see enum gsi_iterator_update). Scan the statements in SEQ
     215                 :             :    for new operands.  */
     216                 :             : 
     217                 :             : void
     218                 :    19845139 : gsi_insert_seq_before (gimple_stmt_iterator *i, gimple_seq seq,
     219                 :             :                        enum gsi_iterator_update mode)
     220                 :             : {
     221                 :    19845139 :   update_modified_stmts (seq);
     222                 :    19845139 :   gsi_insert_seq_before_without_update (i, seq, mode);
     223                 :    19845139 : }
     224                 :             : 
     225                 :             : 
     226                 :             : /* Insert the sequence delimited by nodes FIRST and LAST after
     227                 :             :    iterator I.  M specifies how to update iterator I after insertion
     228                 :             :    (see enum gsi_iterator_update).
     229                 :             : 
     230                 :             :    This routine assumes that there is a forward and backward path
     231                 :             :    between FIRST and LAST (i.e., they are linked in a doubly-linked
     232                 :             :    list).  Additionally, if FIRST == LAST, this routine will properly
     233                 :             :    insert a single node.  */
     234                 :             : 
     235                 :             : static void
     236                 :   313728030 : gsi_insert_seq_nodes_after (gimple_stmt_iterator *i,
     237                 :             :                             gimple_seq_node first,
     238                 :             :                             gimple_seq_node last,
     239                 :             :                             enum gsi_iterator_update m)
     240                 :             : {
     241                 :   313728030 :   basic_block bb;
     242                 :   313728030 :   gimple_seq_node cur = i->ptr;
     243                 :             : 
     244                 :   313728030 :   gcc_assert (!cur || cur->prev);
     245                 :             : 
     246                 :             :   /* If the iterator is inside a basic block, we need to update the
     247                 :             :      basic block information for all the nodes between FIRST and LAST.  */
     248                 :   313728030 :   if ((bb = gsi_bb (*i)) != NULL)
     249                 :   113834960 :     update_bb_for_stmts (first, last, bb);
     250                 :             : 
     251                 :             :   /* Link SEQ after CUR.  */
     252                 :   313728030 :   if (cur)
     253                 :             :     {
     254                 :   186950996 :       last->next = cur->next;
     255                 :   186950996 :       if (last->next)
     256                 :             :         {
     257                 :     9030776 :           last->next->prev = last;
     258                 :             :         }
     259                 :             :       else
     260                 :   177920220 :         gimple_seq_set_last (i->seq, last);
     261                 :   186950996 :       first->prev = cur;
     262                 :   186950996 :       cur->next = first;
     263                 :             :     }
     264                 :             :   else
     265                 :             :     {
     266                 :   126777034 :       gcc_assert (!gimple_seq_last (*i->seq));
     267                 :   126777034 :       last->next = NULL;
     268                 :   126777034 :       gimple_seq_set_first (i->seq, first);
     269                 :   126777034 :       gimple_seq_set_last (i->seq, last);
     270                 :             :     }
     271                 :             : 
     272                 :             :   /* Update the iterator, if requested.  */
     273                 :   313728030 :   switch (m)
     274                 :             :     {
     275                 :   297606636 :     case GSI_NEW_STMT:
     276                 :   297606636 :       i->ptr = first;
     277                 :   297606636 :       break;
     278                 :     5667458 :     case GSI_LAST_NEW_STMT:
     279                 :     5667458 :     case GSI_CONTINUE_LINKING:
     280                 :     5667458 :       i->ptr = last;
     281                 :     5667458 :       break;
     282                 :    10453936 :     case GSI_SAME_STMT:
     283                 :    10453936 :       gcc_assert (cur);
     284                 :             :       break;
     285                 :           0 :     default:
     286                 :           0 :       gcc_unreachable ();
     287                 :             :     }
     288                 :   313728030 : }
     289                 :             : 
     290                 :             : 
     291                 :             : /* Links sequence SEQ after the statement pointed-to by iterator I.
     292                 :             :    MODE is as in gsi_insert_after.
     293                 :             : 
     294                 :             :    This function does not scan for new operands.  It is provided for
     295                 :             :    the use of the gimplifier, which manipulates statements for which
     296                 :             :    def/use information has not yet been constructed.  Most callers
     297                 :             :    should use gsi_insert_seq_after.  */
     298                 :             : 
     299                 :             : void
     300                 :    30605101 : gsi_insert_seq_after_without_update (gimple_stmt_iterator *i, gimple_seq seq,
     301                 :             :                                      enum gsi_iterator_update mode)
     302                 :             : {
     303                 :    30605101 :   gimple_seq_node first, last;
     304                 :             : 
     305                 :    30605101 :   if (seq == NULL)
     306                 :             :     return;
     307                 :             : 
     308                 :             :   /* Don't allow inserting a sequence into itself.  */
     309                 :    29407826 :   gcc_assert (seq != *i->seq);
     310                 :             : 
     311                 :    29407826 :   first = gimple_seq_first (seq);
     312                 :    29407826 :   last = gimple_seq_last (seq);
     313                 :             : 
     314                 :             :   /* Empty sequences need no work.  */
     315                 :    29407826 :   if (!first || !last)
     316                 :             :     {
     317                 :           0 :       gcc_assert (first == last);
     318                 :             :       return;
     319                 :             :     }
     320                 :             : 
     321                 :    29407826 :   gsi_insert_seq_nodes_after (i, first, last, mode);
     322                 :             : }
     323                 :             : 
     324                 :             : 
     325                 :             : /* Links sequence SEQ after the statement pointed-to by iterator I.
     326                 :             :    MODE is as in gsi_insert_after.  Scan the statements in SEQ
     327                 :             :    for new operands.  */
     328                 :             : 
     329                 :             : void
     330                 :    24428144 : gsi_insert_seq_after (gimple_stmt_iterator *i, gimple_seq seq,
     331                 :             :                       enum gsi_iterator_update mode)
     332                 :             : {
     333                 :    24428144 :   update_modified_stmts (seq);
     334                 :    24428144 :   gsi_insert_seq_after_without_update (i, seq, mode);
     335                 :    24428144 : }
     336                 :             : 
     337                 :             : 
     338                 :             : /* Move all statements in the sequence after I to a new sequence.
     339                 :             :    Return this new sequence.  */
     340                 :             : 
     341                 :             : gimple_seq
     342                 :      446748 : gsi_split_seq_after (gimple_stmt_iterator i)
     343                 :             : {
     344                 :      446748 :   gimple_seq_node cur, next;
     345                 :      446748 :   gimple_seq *pold_seq, new_seq;
     346                 :             : 
     347                 :      446748 :   cur = i.ptr;
     348                 :             : 
     349                 :             :   /* How can we possibly split after the end, or before the beginning?  */
     350                 :      446748 :   gcc_assert (cur && cur->next);
     351                 :      446748 :   next = cur->next;
     352                 :             : 
     353                 :      446748 :   pold_seq = i.seq;
     354                 :             : 
     355                 :      446748 :   gimple_seq_set_first (&new_seq, next);
     356                 :      446748 :   gimple_seq_set_last (&new_seq, gimple_seq_last (*pold_seq));
     357                 :      446748 :   gimple_seq_set_last (pold_seq, cur);
     358                 :      446748 :   cur->next = NULL;
     359                 :             : 
     360                 :      446748 :   return new_seq;
     361                 :             : }
     362                 :             : 
     363                 :             : 
     364                 :             : /* Set the statement to which GSI points to STMT.  This only updates
     365                 :             :    the iterator and the gimple sequence, it doesn't do the bookkeeping
     366                 :             :    of gsi_replace.  */
     367                 :             : 
     368                 :             : void
     369                 :     4017350 : gsi_set_stmt (gimple_stmt_iterator *gsi, gimple *stmt)
     370                 :             : {
     371                 :     4017350 :   gimple *orig_stmt = gsi_stmt (*gsi);
     372                 :     4017350 :   gimple *prev, *next;
     373                 :             : 
     374                 :     4017350 :   stmt->next = next = orig_stmt->next;
     375                 :     4017350 :   stmt->prev = prev = orig_stmt->prev;
     376                 :             :   /* Note how we don't clear next/prev of orig_stmt.  This is so that
     377                 :             :      copies of *GSI our callers might still hold (to orig_stmt)
     378                 :             :      can be advanced as if they too were replaced.  */
     379                 :     4017350 :   if (prev->next)
     380                 :     2849501 :     prev->next = stmt;
     381                 :             :   else
     382                 :     1167849 :     gimple_seq_set_first (gsi->seq, stmt);
     383                 :     4017350 :   if (next)
     384                 :     2624405 :     next->prev = stmt;
     385                 :             :   else
     386                 :     1392945 :     gimple_seq_set_last (gsi->seq, stmt);
     387                 :             : 
     388                 :     4017350 :   gsi->ptr = stmt;
     389                 :     4017350 : }
     390                 :             : 
     391                 :             : 
     392                 :             : /* Move all statements in the sequence before I to a new sequence.
     393                 :             :    Return this new sequence.  I is set to the head of the new list.  */
     394                 :             : 
     395                 :             : void
     396                 :    21061679 : gsi_split_seq_before (gimple_stmt_iterator *i, gimple_seq *pnew_seq)
     397                 :             : {
     398                 :    21061679 :   gimple_seq_node cur, prev;
     399                 :    21061679 :   gimple_seq old_seq;
     400                 :             : 
     401                 :    21061679 :   cur = i->ptr;
     402                 :             : 
     403                 :             :   /* How can we possibly split after the end?  */
     404                 :    21061679 :   gcc_assert (cur);
     405                 :    21061679 :   prev = cur->prev;
     406                 :             : 
     407                 :    21061679 :   old_seq = *i->seq;
     408                 :    21061679 :   if (!prev->next)
     409                 :     1171826 :     *i->seq = NULL;
     410                 :    21061679 :   i->seq = pnew_seq;
     411                 :             : 
     412                 :             :   /* Set the limits on NEW_SEQ.  */
     413                 :    21061679 :   gimple_seq_set_first (pnew_seq, cur);
     414                 :    42123358 :   gimple_seq_set_last (pnew_seq, gimple_seq_last (old_seq));
     415                 :             : 
     416                 :             :   /* Cut OLD_SEQ before I.  */
     417                 :    21061679 :   gimple_seq_set_last (&old_seq, prev);
     418                 :    21061679 :   if (prev->next)
     419                 :    19889853 :     prev->next = NULL;
     420                 :    21061679 : }
     421                 :             : 
     422                 :             : 
     423                 :             : /* Replace the statement pointed-to by GSI to STMT.  If UPDATE_EH_INFO
     424                 :             :    is true, the exception handling information of the original
     425                 :             :    statement is moved to the new statement.  Assignments must only be
     426                 :             :    replaced with assignments to the same LHS.  Returns whether EH edge
     427                 :             :    cleanup is required.  */
     428                 :             : 
     429                 :             : bool
     430                 :     2951928 : gsi_replace (gimple_stmt_iterator *gsi, gimple *stmt, bool update_eh_info)
     431                 :             : {
     432                 :     2951928 :   gimple *orig_stmt = gsi_stmt (*gsi);
     433                 :     2951928 :   bool require_eh_edge_purge = false;
     434                 :             : 
     435                 :     2951928 :   if (stmt == orig_stmt)
     436                 :             :     return false;
     437                 :             : 
     438                 :     5562319 :   gcc_assert (!gimple_has_lhs (orig_stmt) || !gimple_has_lhs (stmt)
     439                 :             :               || gimple_get_lhs (orig_stmt) == gimple_get_lhs (stmt));
     440                 :             : 
     441                 :     2948888 :   gimple_set_location (stmt, gimple_location (orig_stmt));
     442                 :     2948888 :   gimple_set_bb (stmt, gsi_bb (*gsi));
     443                 :             : 
     444                 :             :   /* Preserve EH region information from the original statement, if
     445                 :             :      requested by the caller.  */
     446                 :     2948888 :   if (update_eh_info)
     447                 :      816498 :     require_eh_edge_purge = maybe_clean_or_replace_eh_stmt (orig_stmt, stmt);
     448                 :             : 
     449                 :     2948888 :   gimple_duplicate_stmt_histograms (cfun, stmt, cfun, orig_stmt);
     450                 :             : 
     451                 :             :   /* Free all the data flow information for ORIG_STMT.  */
     452                 :     2948888 :   gimple_set_bb (orig_stmt, NULL);
     453                 :     2948888 :   gimple_remove_stmt_histograms (cfun, orig_stmt);
     454                 :     2948888 :   delink_stmt_imm_use (orig_stmt);
     455                 :             : 
     456                 :     2948888 :   gsi_set_stmt (gsi, stmt);
     457                 :     2948888 :   gimple_set_modified (stmt, true);
     458                 :     2948888 :   update_modified_stmt (stmt);
     459                 :     2948888 :   return require_eh_edge_purge;
     460                 :             : }
     461                 :             : 
     462                 :             : 
     463                 :             : /* Replace the statement pointed-to by GSI with the sequence SEQ.
     464                 :             :    If UPDATE_EH_INFO is true, the exception handling information of
     465                 :             :    the original statement is moved to the last statement of the new
     466                 :             :    sequence.  If the old statement is an assignment, then so must
     467                 :             :    be the last statement of the new sequence, and they must have the
     468                 :             :    same LHS.  */
     469                 :             : 
     470                 :             : void
     471                 :      179244 : gsi_replace_with_seq (gimple_stmt_iterator *gsi, gimple_seq seq,
     472                 :             :                       bool update_eh_info)
     473                 :             : {
     474                 :      179244 :   gimple_stmt_iterator seqi;
     475                 :      179244 :   gimple *last;
     476                 :      179244 :   if (gimple_seq_empty_p (seq))
     477                 :             :     {
     478                 :          53 :       gsi_remove (gsi, true);
     479                 :          53 :       return;
     480                 :             :     }
     481                 :      179191 :   seqi = gsi_last (seq);
     482                 :      179191 :   last = gsi_stmt (seqi);
     483                 :      179191 :   gsi_remove (&seqi, false);
     484                 :      179191 :   gsi_insert_seq_before (gsi, seq, GSI_SAME_STMT);
     485                 :      179191 :   gsi_replace (gsi, last, update_eh_info);
     486                 :             : }
     487                 :             : 
     488                 :             : 
     489                 :             : /* Insert statement STMT before the statement pointed-to by iterator I.
     490                 :             :    M specifies how to update iterator I after insertion (see enum
     491                 :             :    gsi_iterator_update).
     492                 :             : 
     493                 :             :    This function does not scan for new operands.  It is provided for
     494                 :             :    the use of the gimplifier, which manipulates statements for which
     495                 :             :    def/use information has not yet been constructed.  Most callers
     496                 :             :    should use gsi_insert_before.  */
     497                 :             : 
     498                 :             : void
     499                 :    28151248 : gsi_insert_before_without_update (gimple_stmt_iterator *i, gimple *stmt,
     500                 :             :                                   enum gsi_iterator_update m)
     501                 :             : {
     502                 :    28151248 :   gsi_insert_seq_nodes_before (i, stmt, stmt, m);
     503                 :    28151248 : }
     504                 :             : 
     505                 :             : /* Insert statement STMT before the statement pointed-to by iterator I.
     506                 :             :    Update STMT's basic block and scan it for new operands.  M
     507                 :             :    specifies how to update iterator I after insertion (see enum
     508                 :             :    gsi_iterator_update).  */
     509                 :             : 
     510                 :             : void
     511                 :    28059905 : gsi_insert_before (gimple_stmt_iterator *i, gimple *stmt,
     512                 :             :                    enum gsi_iterator_update m)
     513                 :             : {
     514                 :    28059905 :   update_modified_stmt (stmt);
     515                 :    28059905 :   gsi_insert_before_without_update (i, stmt, m);
     516                 :    28059905 : }
     517                 :             : 
     518                 :             : 
     519                 :             : /* Insert statement STMT after the statement pointed-to by iterator I.
     520                 :             :    M specifies how to update iterator I after insertion (see enum
     521                 :             :    gsi_iterator_update).
     522                 :             : 
     523                 :             :    This function does not scan for new operands.  It is provided for
     524                 :             :    the use of the gimplifier, which manipulates statements for which
     525                 :             :    def/use information has not yet been constructed.  Most callers
     526                 :             :    should use gsi_insert_after.  */
     527                 :             : 
     528                 :             : void
     529                 :   284320204 : gsi_insert_after_without_update (gimple_stmt_iterator *i, gimple *stmt,
     530                 :             :                                  enum gsi_iterator_update m)
     531                 :             : {
     532                 :   284320204 :   gsi_insert_seq_nodes_after (i, stmt, stmt, m);
     533                 :   284320204 : }
     534                 :             : 
     535                 :             : 
     536                 :             : /* Insert statement STMT after the statement pointed-to by iterator I.
     537                 :             :    Update STMT's basic block and scan it for new operands.  M
     538                 :             :    specifies how to update iterator I after insertion (see enum
     539                 :             :    gsi_iterator_update).  */
     540                 :             : 
     541                 :             : void
     542                 :   135844629 : gsi_insert_after (gimple_stmt_iterator *i, gimple *stmt,
     543                 :             :                   enum gsi_iterator_update m)
     544                 :             : {
     545                 :   135844629 :   update_modified_stmt (stmt);
     546                 :   135844629 :   gsi_insert_after_without_update (i, stmt, m);
     547                 :   135844629 : }
     548                 :             : 
     549                 :             : 
     550                 :             : /* Remove the current stmt from the sequence.  The iterator is updated
     551                 :             :    to point to the next statement.
     552                 :             : 
     553                 :             :    REMOVE_PERMANENTLY is true when the statement is going to be removed
     554                 :             :    from the IL and not reinserted elsewhere.  In that case we remove the
     555                 :             :    statement pointed to by iterator I from the EH tables, and free its
     556                 :             :    operand caches.  Otherwise we do not modify this information.  Returns
     557                 :             :    true whether EH edge cleanup is required.  */
     558                 :             : 
     559                 :             : bool
     560                 :   133991488 : gsi_remove (gimple_stmt_iterator *i, bool remove_permanently)
     561                 :             : {
     562                 :   133991488 :   gimple_seq_node cur, next, prev;
     563                 :   133991488 :   gimple *stmt = gsi_stmt (*i);
     564                 :   133991488 :   bool require_eh_edge_purge = false;
     565                 :             : 
     566                 :             :   /* ???  Do we want to do this for non-permanent operation?  */
     567                 :   133991488 :   if (gimple_code (stmt) != GIMPLE_PHI)
     568                 :   118119243 :     insert_debug_temps_for_defs (i);
     569                 :             : 
     570                 :   133991488 :   gimple_set_bb (stmt, NULL);
     571                 :             : 
     572                 :   133991488 :   if (remove_permanently)
     573                 :             :     {
     574                 :             :       /* Free all the data flow information for STMT.  */
     575                 :    93075445 :       delink_stmt_imm_use (stmt);
     576                 :    93075445 :       gimple_set_modified (stmt, true);
     577                 :             : 
     578                 :    93075445 :       if (gimple_debug_nonbind_marker_p (stmt))
     579                 :             :         /* We don't need this to be exact, but try to keep it at least
     580                 :             :            close.  */
     581                 :     3056244 :         cfun->debug_marker_count--;
     582                 :    93075445 :       require_eh_edge_purge = remove_stmt_from_eh_lp (stmt);
     583                 :    93075445 :       gimple_remove_stmt_histograms (cfun, stmt);
     584                 :             :     }
     585                 :             : 
     586                 :             :   /* Update the iterator and re-wire the links in I->SEQ.  */
     587                 :   133991488 :   cur = i->ptr;
     588                 :   133991488 :   next = cur->next;
     589                 :   133991488 :   prev = cur->prev;
     590                 :             :   /* See gsi_set_stmt for why we don't reset prev/next of STMT.  */
     591                 :             : 
     592                 :   133991488 :   if (next)
     593                 :             :     /* Cur is not last.  */
     594                 :    84772482 :     next->prev = prev;
     595                 :    49219006 :   else if (prev->next)
     596                 :             :     /* Cur is last but not first.  */
     597                 :    28133502 :     gimple_seq_set_last (i->seq, prev);
     598                 :             : 
     599                 :   133991488 :   if (prev->next)
     600                 :             :     /* Cur is not first.  */
     601                 :    78020101 :     prev->next = next;
     602                 :             :   else
     603                 :             :     /* Cur is first.  */
     604                 :    55971387 :     *i->seq = next;
     605                 :             : 
     606                 :   133991488 :   i->ptr = next;
     607                 :             : 
     608                 :   133991488 :   return require_eh_edge_purge;
     609                 :             : }
     610                 :             : 
     611                 :             : 
     612                 :             : /* Finds iterator for STMT.  */
     613                 :             : 
     614                 :             : gimple_stmt_iterator
     615                 :    59029340 : gsi_for_stmt (gimple *stmt)
     616                 :             : {
     617                 :    59029340 :   gimple_stmt_iterator i;
     618                 :    59029340 :   basic_block bb = gimple_bb (stmt);
     619                 :             : 
     620                 :    59029340 :   if (gimple_code (stmt) == GIMPLE_PHI)
     621                 :     4840438 :     i = gsi_start_phis (bb);
     622                 :             :   else
     623                 :   108377804 :     i = gsi_start_bb (bb);
     624                 :             : 
     625                 :    59029340 :   i.ptr = stmt;
     626                 :    59029340 :   return i;
     627                 :             : }
     628                 :             : 
     629                 :             : /* Get an iterator for STMT, which is known to belong to SEQ.  This is
     630                 :             :    equivalent to starting at the beginning of SEQ and searching forward
     631                 :             :    until STMT is found.  */
     632                 :             : 
     633                 :             : gimple_stmt_iterator
     634                 :        7681 : gsi_for_stmt (gimple *stmt, gimple_seq *seq)
     635                 :             : {
     636                 :        7681 :   gimple_stmt_iterator i = gsi_start (*seq);
     637                 :        7681 :   i.ptr = stmt;
     638                 :        7681 :   return i;
     639                 :             : }
     640                 :             : 
     641                 :             : /* Finds iterator for PHI.  */
     642                 :             : 
     643                 :             : gphi_iterator
     644                 :           0 : gsi_for_phi (gphi *phi)
     645                 :             : {
     646                 :           0 :   gphi_iterator i;
     647                 :           0 :   basic_block bb = gimple_bb (phi);
     648                 :             : 
     649                 :           0 :   i = gsi_start_phis (bb);
     650                 :           0 :   i.ptr = phi;
     651                 :             : 
     652                 :           0 :   return i;
     653                 :             : }
     654                 :             : 
     655                 :             : /* Move the statement at FROM so it comes right after the statement at TO.  */
     656                 :             : 
     657                 :             : void
     658                 :      959644 : gsi_move_after (gimple_stmt_iterator *from, gimple_stmt_iterator *to)
     659                 :             : {
     660                 :      959644 :   gimple *stmt = gsi_stmt (*from);
     661                 :      959644 :   gsi_remove (from, false);
     662                 :             : 
     663                 :             :   /* We must have GSI_NEW_STMT here, as gsi_move_after is sometimes used to
     664                 :             :      move statements to an empty block.  */
     665                 :      959644 :   gsi_insert_after (to, stmt, GSI_NEW_STMT);
     666                 :      959644 : }
     667                 :             : 
     668                 :             : 
     669                 :             : /* Move the statement at FROM so it comes right before the statement
     670                 :             :    at TO using method M.  M defaults to GSI_SAME_STMT.  */
     671                 :             : 
     672                 :             : void
     673                 :    13192529 : gsi_move_before (gimple_stmt_iterator *from, gimple_stmt_iterator *to,
     674                 :             :                  gsi_iterator_update m)
     675                 :             : {
     676                 :    13192529 :   gimple *stmt = gsi_stmt (*from);
     677                 :    13192529 :   gsi_remove (from, false);
     678                 :             : 
     679                 :             :   /* For consistency with gsi_move_after, it might be better to have
     680                 :             :      GSI_NEW_STMT here; however, that breaks several places that expect
     681                 :             :      that TO does not change.  */
     682                 :    13192529 :   gsi_insert_before (to, stmt, m);
     683                 :    13192529 : }
     684                 :             : 
     685                 :             : 
     686                 :             : /* Move the statement at FROM to the end of basic block BB.  */
     687                 :             : 
     688                 :             : void
     689                 :       61707 : gsi_move_to_bb_end (gimple_stmt_iterator *from, basic_block bb)
     690                 :             : {
     691                 :       61707 :   gimple_stmt_iterator last = gsi_last_bb (bb);
     692                 :       61707 :   gcc_checking_assert (gsi_bb (last) == bb);
     693                 :             : 
     694                 :             :   /* Have to check gsi_end_p because it could be an empty block.  */
     695                 :       61707 :   if (!gsi_end_p (last) && is_ctrl_stmt (gsi_stmt (last)))
     696                 :       11230 :     gsi_move_before (from, &last);
     697                 :             :   else
     698                 :       50477 :     gsi_move_after (from, &last);
     699                 :       61707 : }
     700                 :             : 
     701                 :             : 
     702                 :             : /* Add STMT to the pending list of edge E.  No actual insertion is
     703                 :             :    made until a call to gsi_commit_edge_inserts () is made.  */
     704                 :             : 
     705                 :             : void
     706                 :      450178 : gsi_insert_on_edge (edge e, gimple *stmt)
     707                 :             : {
     708                 :      450178 :   gimple_seq_add_stmt (&PENDING_STMT (e), stmt);
     709                 :      450178 : }
     710                 :             : 
     711                 :             : /* Add the sequence of statements SEQ to the pending list of edge E.
     712                 :             :    No actual insertion is made until a call to gsi_commit_edge_inserts
     713                 :             :    is made.  */
     714                 :             : 
     715                 :             : void
     716                 :       22951 : gsi_insert_seq_on_edge (edge e, gimple_seq seq)
     717                 :             : {
     718                 :       22951 :   gimple_seq_add_seq (&PENDING_STMT (e), seq);
     719                 :       22951 : }
     720                 :             : 
     721                 :             : /* Return a new iterator pointing to the first statement in sequence of
     722                 :             :    statements on edge E.  Such statements need to be subsequently moved into a
     723                 :             :    basic block by calling gsi_commit_edge_inserts.  */
     724                 :             : 
     725                 :             : gimple_stmt_iterator
     726                 :      125155 : gsi_start_edge (edge e)
     727                 :             : {
     728                 :      125155 :   return gsi_start (PENDING_STMT (e));
     729                 :             : }
     730                 :             : 
     731                 :             : /* Insert the statement pointed-to by GSI into edge E.  Every attempt
     732                 :             :    is made to place the statement in an existing basic block, but
     733                 :             :    sometimes that isn't possible.  When it isn't possible, the edge is
     734                 :             :    split and the statement is added to the new block.
     735                 :             : 
     736                 :             :    In all cases, the returned *GSI points to the correct location.  The
     737                 :             :    return value is true if insertion should be done after the location,
     738                 :             :    or false if it should be done before the location.  If a new basic block
     739                 :             :    has to be created, it is stored in *NEW_BB.  */
     740                 :             : 
     741                 :             : static bool
     742                 :     1366769 : gimple_find_edge_insert_loc (edge e, gimple_stmt_iterator *gsi,
     743                 :             :                              basic_block *new_bb)
     744                 :             : {
     745                 :     1366769 :   basic_block dest, src;
     746                 :     1366769 :   gimple *tmp;
     747                 :             : 
     748                 :     1366769 :   dest = e->dest;
     749                 :             : 
     750                 :             :   /* If the destination has one predecessor which has no PHI nodes,
     751                 :             :      insert there.  Except for the exit block.
     752                 :             : 
     753                 :             :      The requirement for no PHI nodes could be relaxed.  Basically we
     754                 :             :      would have to examine the PHIs to prove that none of them used
     755                 :             :      the value set by the statement we want to insert on E.  That
     756                 :             :      hardly seems worth the effort.  */
     757                 :     1400279 :  restart:
     758                 :     1400279 :   if (single_pred_p (dest)
     759                 :      221401 :       && gimple_seq_empty_p (phi_nodes (dest))
     760                 :     1617659 :       && dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
     761                 :             :     {
     762                 :      216635 :       *gsi = gsi_start_bb (dest);
     763                 :      216635 :       if (gsi_end_p (*gsi))
     764                 :             :         return true;
     765                 :             : 
     766                 :             :       /* Make sure we insert after any leading labels.  */
     767                 :      181853 :       tmp = gsi_stmt (*gsi);
     768                 :      181853 :       while (gimple_code (tmp) == GIMPLE_LABEL)
     769                 :             :         {
     770                 :        5037 :           gsi_next (gsi);
     771                 :        5037 :           if (gsi_end_p (*gsi))
     772                 :             :             break;
     773                 :      181853 :           tmp = gsi_stmt (*gsi);
     774                 :             :         }
     775                 :             : 
     776                 :      180371 :       if (gsi_end_p (*gsi))
     777                 :             :         {
     778                 :        3555 :           *gsi = gsi_last_bb (dest);
     779                 :        3555 :           return true;
     780                 :             :         }
     781                 :             :       else
     782                 :             :         return false;
     783                 :             :     }
     784                 :             : 
     785                 :             :   /* If the source has one successor, the edge is not abnormal and
     786                 :             :      the last statement does not end a basic block, insert there.
     787                 :             :      Except for the entry block.  */
     788                 :     1183644 :   src = e->src;
     789                 :     1183644 :   if ((e->flags & EDGE_ABNORMAL) == 0
     790                 :     1183644 :       && (single_succ_p (src)
     791                 :             :           /* Do not count a fake edge as successor as added to infinite
     792                 :             :              loops by connect_infinite_loops_to_exit.  */
     793                 :       33261 :           || (EDGE_COUNT (src->succs) == 2
     794                 :       33239 :               && (EDGE_SUCC (src, 0)->flags & EDGE_FAKE
     795                 :       33239 :                   || EDGE_SUCC (src, 1)->flags & EDGE_FAKE)))
     796                 :     2334063 :       && src != ENTRY_BLOCK_PTR_FOR_FN (cfun))
     797                 :             :     {
     798                 :     1150143 :       *gsi = gsi_last_bb (src);
     799                 :     1150143 :       if (gsi_end_p (*gsi))
     800                 :             :         return true;
     801                 :             : 
     802                 :      736462 :       tmp = gsi_stmt (*gsi);
     803                 :      736462 :       if (is_gimple_debug (tmp))
     804                 :             :         {
     805                 :       60154 :           gimple_stmt_iterator si = *gsi;
     806                 :       60154 :           gsi_prev_nondebug (&si);
     807                 :       60154 :           if (!gsi_end_p (si))
     808                 :       53206 :             tmp = gsi_stmt (si);
     809                 :             :           /* If we don't have a BB-ending nondebug stmt, we want to
     810                 :             :              insert after the trailing debug stmts.  Otherwise, we may
     811                 :             :              insert before the BB-ending nondebug stmt, or split the
     812                 :             :              edge.  */
     813                 :       60154 :           if (!stmt_ends_bb_p (tmp))
     814                 :       60154 :             return true;
     815                 :           0 :           *gsi = si;
     816                 :             :         }
     817                 :      676308 :       else if (!stmt_ends_bb_p (tmp))
     818                 :             :         return true;
     819                 :             : 
     820                 :         908 :       switch (gimple_code (tmp))
     821                 :             :         {
     822                 :             :         case GIMPLE_RETURN:
     823                 :             :         case GIMPLE_RESX:
     824                 :             :           return false;
     825                 :             :         default:
     826                 :             :           break;
     827                 :             :         }
     828                 :             :     }
     829                 :             : 
     830                 :             :   /* Otherwise, create a new basic block, and split this edge.  */
     831                 :       33510 :   dest = split_edge (e);
     832                 :       33510 :   if (new_bb)
     833                 :         363 :     *new_bb = dest;
     834                 :       33510 :   e = single_pred_edge (dest);
     835                 :       33510 :   goto restart;
     836                 :             : }
     837                 :             : 
     838                 :             : 
     839                 :             : /* Similar to gsi_insert_on_edge+gsi_commit_edge_inserts.  If a new
     840                 :             :    block has to be created, it is returned.  */
     841                 :             : 
     842                 :             : basic_block
     843                 :        4631 : gsi_insert_on_edge_immediate (edge e, gimple *stmt)
     844                 :             : {
     845                 :        4631 :   gimple_stmt_iterator gsi;
     846                 :        4631 :   basic_block new_bb = NULL;
     847                 :        4631 :   bool ins_after;
     848                 :             : 
     849                 :        4631 :   gcc_assert (!PENDING_STMT (e));
     850                 :             : 
     851                 :        4631 :   ins_after = gimple_find_edge_insert_loc (e, &gsi, &new_bb);
     852                 :             : 
     853                 :        4631 :   update_call_edge_frequencies (stmt, gsi.bb);
     854                 :             : 
     855                 :        4631 :   if (ins_after)
     856                 :        1865 :     gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
     857                 :             :   else
     858                 :        2766 :     gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
     859                 :             : 
     860                 :        4631 :   return new_bb;
     861                 :             : }
     862                 :             : 
     863                 :             : /* Insert STMTS on edge E.  If a new block has to be created, it
     864                 :             :    is returned.  */
     865                 :             : 
     866                 :             : basic_block
     867                 :     1098991 : gsi_insert_seq_on_edge_immediate (edge e, gimple_seq stmts)
     868                 :             : {
     869                 :     1098991 :   gimple_stmt_iterator gsi;
     870                 :     1098991 :   basic_block new_bb = NULL;
     871                 :     1098991 :   bool ins_after;
     872                 :             : 
     873                 :     1098991 :   gcc_assert (!PENDING_STMT (e));
     874                 :             : 
     875                 :     1098991 :   ins_after = gimple_find_edge_insert_loc (e, &gsi, &new_bb);
     876                 :     1098991 :   update_call_edge_frequencies (gimple_seq_first (stmts), gsi.bb);
     877                 :             : 
     878                 :     1098991 :   if (ins_after)
     879                 :     1051863 :     gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
     880                 :             :   else
     881                 :       47128 :     gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
     882                 :             : 
     883                 :     1098991 :   return new_bb;
     884                 :             : }
     885                 :             : 
     886                 :             : /* This routine will commit all pending edge insertions, creating any new
     887                 :             :    basic blocks which are necessary.  */
     888                 :             : 
     889                 :             : void
     890                 :     2729572 : gsi_commit_edge_inserts (void)
     891                 :             : {
     892                 :     2729572 :   basic_block bb;
     893                 :     2729572 :   edge e;
     894                 :     2729572 :   edge_iterator ei;
     895                 :             : 
     896                 :     2729572 :   gsi_commit_one_edge_insert (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)),
     897                 :             :                               NULL);
     898                 :             : 
     899                 :    45536703 :   FOR_EACH_BB_FN (bb, cfun)
     900                 :   103347387 :     FOR_EACH_EDGE (e, ei, bb->succs)
     901                 :    60540256 :       gsi_commit_one_edge_insert (e, NULL);
     902                 :     2729572 : }
     903                 :             : 
     904                 :             : 
     905                 :             : /* Commit insertions pending at edge E. If a new block is created, set NEW_BB
     906                 :             :    to this block, otherwise set it to NULL.  */
     907                 :             : 
     908                 :             : void
     909                 :    63295455 : gsi_commit_one_edge_insert (edge e, basic_block *new_bb)
     910                 :             : {
     911                 :    63295455 :   if (new_bb)
     912                 :           0 :     *new_bb = NULL;
     913                 :             : 
     914                 :    63295455 :   if (PENDING_STMT (e))
     915                 :             :     {
     916                 :      263147 :       gimple_stmt_iterator gsi;
     917                 :      263147 :       gimple_seq seq = PENDING_STMT (e);
     918                 :      263147 :       bool ins_after;
     919                 :             : 
     920                 :      263147 :       PENDING_STMT (e) = NULL;
     921                 :             : 
     922                 :      263147 :       ins_after = gimple_find_edge_insert_loc (e, &gsi, new_bb);
     923                 :      263147 :       update_call_edge_frequencies (gimple_seq_first (seq), gsi.bb);
     924                 :             : 
     925                 :      263147 :       if (ins_after)
     926                 :      135326 :         gsi_insert_seq_after (&gsi, seq, GSI_NEW_STMT);
     927                 :             :       else
     928                 :      127821 :         gsi_insert_seq_before (&gsi, seq, GSI_NEW_STMT);
     929                 :             :     }
     930                 :    63295455 : }
     931                 :             : 
     932                 :             : /* Returns iterator at the start of the list of phi nodes of BB.  */
     933                 :             : 
     934                 :             : gphi_iterator
     935                 : 10342180481 : gsi_start_phis (basic_block bb)
     936                 :             : {
     937                 : 10342180481 :   gimple_seq *pseq = phi_nodes_ptr (bb);
     938                 :             : 
     939                 :             :   /* Adapted from gsi_start. */
     940                 : 10342180481 :   gphi_iterator i;
     941                 :             : 
     942                 : 10342180481 :   i.ptr = gimple_seq_first (*pseq);
     943                 : 10342180481 :   i.seq = pseq;
     944                 : 10342180481 :   i.bb = i.ptr ? gimple_bb (i.ptr) : NULL;
     945                 :             : 
     946                 : 10342180481 :   return i;
     947                 :             : }
     948                 :             : 
     949                 :             : /* Helper function for gsi_safe_insert_before and gsi_safe_insert_seq_before.
     950                 :             :    Find edge to insert statements before returns_twice call at the start of BB,
     951                 :             :    if there isn't just one, split the bb and adjust PHIs to ensure that.  */
     952                 :             : 
     953                 :             : static edge
     954                 :         251 : edge_before_returns_twice_call (basic_block bb)
     955                 :             : {
     956                 :         251 :   gimple_stmt_iterator gsi = gsi_start_nondebug_bb (bb);
     957                 :         251 :   gcc_checking_assert (is_gimple_call (gsi_stmt (gsi))
     958                 :             :                        && (gimple_call_flags (gsi_stmt (gsi))
     959                 :             :                            & ECF_RETURNS_TWICE) != 0);
     960                 :         251 :   edge_iterator ei;
     961                 :         251 :   edge e, ad_edge = NULL, other_edge = NULL;
     962                 :         251 :   bool split = false;
     963                 :         803 :   FOR_EACH_EDGE (e, ei, bb->preds)
     964                 :             :     {
     965                 :         552 :       if ((e->flags & (EDGE_ABNORMAL | EDGE_EH)) == EDGE_ABNORMAL)
     966                 :             :         {
     967                 :         251 :           gimple_stmt_iterator gsi
     968                 :         251 :             = gsi_start_nondebug_after_labels_bb (e->src);
     969                 :         251 :           gimple *ad = gsi_stmt (gsi);
     970                 :         251 :           if (ad && gimple_call_internal_p (ad, IFN_ABNORMAL_DISPATCHER))
     971                 :             :             {
     972                 :         251 :               gcc_checking_assert (ad_edge == NULL);
     973                 :         251 :               ad_edge = e;
     974                 :         251 :               continue;
     975                 :             :             }
     976                 :             :         }
     977                 :         301 :       if (other_edge || e->flags & (EDGE_ABNORMAL | EDGE_EH))
     978                 :          50 :         split = true;
     979                 :             :       other_edge = e;
     980                 :             :     }
     981                 :         251 :   gcc_checking_assert (ad_edge);
     982                 :         251 :   if (other_edge == NULL)
     983                 :             :     split = true;
     984                 :         251 :   if (split)
     985                 :             :     {
     986                 :          25 :       other_edge = split_block_after_labels (bb);
     987                 :          25 :       e = make_edge (ad_edge->src, other_edge->dest, EDGE_ABNORMAL);
     988                 :          25 :       for (gphi_iterator gsi = gsi_start_phis (other_edge->src);
     989                 :          87 :            !gsi_end_p (gsi); gsi_next (&gsi))
     990                 :             :         {
     991                 :          62 :           gphi *phi = gsi.phi ();
     992                 :          62 :           tree lhs = gimple_phi_result (phi);
     993                 :          62 :           tree new_lhs = copy_ssa_name (lhs);
     994                 :          62 :           gimple_phi_set_result (phi, new_lhs);
     995                 :          62 :           gphi *new_phi = create_phi_node (lhs, other_edge->dest);
     996                 :          62 :           add_phi_arg (new_phi, new_lhs, other_edge, UNKNOWN_LOCATION);
     997                 :          62 :           add_phi_arg (new_phi, gimple_phi_arg_def_from_edge (phi, ad_edge),
     998                 :             :                        e, gimple_phi_arg_location_from_edge (phi, ad_edge));
     999                 :             :         }
    1000                 :          25 :       e->flags = ad_edge->flags;
    1001                 :          25 :       e->probability = ad_edge->probability;
    1002                 :          25 :       remove_edge (ad_edge);
    1003                 :          25 :       if (dom_info_available_p (CDI_DOMINATORS))
    1004                 :             :         {
    1005                 :           4 :           set_immediate_dominator (CDI_DOMINATORS, other_edge->src,
    1006                 :             :                                    recompute_dominator (CDI_DOMINATORS,
    1007                 :             :                                                         other_edge->src));
    1008                 :           4 :           set_immediate_dominator (CDI_DOMINATORS, other_edge->dest,
    1009                 :             :                                    recompute_dominator (CDI_DOMINATORS,
    1010                 :             :                                                         other_edge->dest));
    1011                 :             :         }
    1012                 :             :     }
    1013                 :         251 :   return other_edge;
    1014                 :             : }
    1015                 :             : 
    1016                 :             : /* Helper function for gsi_safe_insert_before and gsi_safe_insert_seq_before.
    1017                 :             :    Replace SSA_NAME uses in G if they are PHI results of PHIs on E->dest
    1018                 :             :    bb with the corresponding PHI argument from E edge.  */
    1019                 :             : 
    1020                 :             : static void
    1021                 :         251 : adjust_before_returns_twice_call (edge e, gimple *g)
    1022                 :             : {
    1023                 :         251 :   use_operand_p use_p;
    1024                 :         251 :   ssa_op_iter iter;
    1025                 :         251 :   bool m = false;
    1026                 :         549 :   FOR_EACH_SSA_USE_OPERAND (use_p, g, iter, SSA_OP_USE)
    1027                 :             :     {
    1028                 :         298 :       tree s = USE_FROM_PTR (use_p);
    1029                 :         298 :       if (SSA_NAME_DEF_STMT (s)
    1030                 :         298 :           && gimple_code (SSA_NAME_DEF_STMT (s)) == GIMPLE_PHI
    1031                 :         463 :           && gimple_bb (SSA_NAME_DEF_STMT (s)) == e->dest)
    1032                 :             :         {
    1033                 :         165 :           tree r = gimple_phi_arg_def_from_edge (SSA_NAME_DEF_STMT (s), e);
    1034                 :         165 :           SET_USE (use_p, unshare_expr (r));
    1035                 :         165 :           m = true;
    1036                 :             :         }
    1037                 :             :     }
    1038                 :         251 :   if (m)
    1039                 :         165 :     update_stmt (g);
    1040                 :         251 : }
    1041                 :             : 
    1042                 :             : /* Insert G stmt before ITER and keep ITER pointing to the same statement
    1043                 :             :    as before.  If ITER is a returns_twice call, insert it on an appropriate
    1044                 :             :    edge instead.  */
    1045                 :             : 
    1046                 :             : void
    1047                 :       28106 : gsi_safe_insert_before (gimple_stmt_iterator *iter, gimple *g)
    1048                 :             : {
    1049                 :       28106 :   gimple *stmt = gsi_stmt (*iter);
    1050                 :       28106 :   if (stmt
    1051                 :       27387 :       && is_gimple_call (stmt)
    1052                 :         874 :       && (gimple_call_flags (stmt) & ECF_RETURNS_TWICE) != 0
    1053                 :       28288 :       && bb_has_abnormal_pred (gsi_bb (*iter)))
    1054                 :             :     {
    1055                 :         181 :       edge e = edge_before_returns_twice_call (gsi_bb (*iter));
    1056                 :         181 :       basic_block new_bb = gsi_insert_on_edge_immediate (e, g);
    1057                 :         181 :       if (new_bb)
    1058                 :          27 :         e = single_succ_edge (new_bb);
    1059                 :         181 :       adjust_before_returns_twice_call (e, g);
    1060                 :         181 :       *iter = gsi_for_stmt (stmt);
    1061                 :             :     }
    1062                 :             :   else
    1063                 :       27925 :     gsi_insert_before (iter, g, GSI_SAME_STMT);
    1064                 :       28106 : }
    1065                 :             : 
    1066                 :             : /* Similarly for sequence SEQ.  */
    1067                 :             : 
    1068                 :             : void
    1069                 :        4157 : gsi_safe_insert_seq_before (gimple_stmt_iterator *iter, gimple_seq seq)
    1070                 :             : {
    1071                 :        4157 :   if (gimple_seq_empty_p (seq))
    1072                 :             :     return;
    1073                 :        3033 :   gimple *stmt = gsi_stmt (*iter);
    1074                 :        3033 :   if (stmt
    1075                 :        3033 :       && is_gimple_call (stmt)
    1076                 :          82 :       && (gimple_call_flags (stmt) & ECF_RETURNS_TWICE) != 0
    1077                 :        3103 :       && bb_has_abnormal_pred (gsi_bb (*iter)))
    1078                 :             :     {
    1079                 :          70 :       edge e = edge_before_returns_twice_call (gsi_bb (*iter));
    1080                 :          70 :       gimple *f = gimple_seq_first_stmt (seq);
    1081                 :          70 :       gimple *l = gimple_seq_last_stmt (seq);
    1082                 :          70 :       basic_block new_bb = gsi_insert_seq_on_edge_immediate (e, seq);
    1083                 :          70 :       if (new_bb)
    1084                 :           0 :         e = single_succ_edge (new_bb);
    1085                 :          70 :       for (gimple_stmt_iterator gsi = gsi_for_stmt (f); ; gsi_next (&gsi))
    1086                 :             :         {
    1087                 :          70 :           gimple *g = gsi_stmt (gsi);
    1088                 :          70 :           adjust_before_returns_twice_call (e, g);
    1089                 :          70 :           if (g == l)
    1090                 :             :             break;
    1091                 :             :         }
    1092                 :          70 :       *iter = gsi_for_stmt (stmt);
    1093                 :             :     }
    1094                 :             :   else
    1095                 :        2963 :     gsi_insert_seq_before (iter, seq, GSI_SAME_STMT);
    1096                 :             : }
        

Generated by: LCOV version 2.1-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.