LCOV - code coverage report
Current view: top level - gcc - cfghooks.c (source / functions) Hit Total Coverage
Test: gcc.info Lines: 536 661 81.1 %
Date: 2020-04-04 11:58:09 Functions: 51 63 81.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* Hooks for cfg representation specific functions.
       2                 :            :    Copyright (C) 2003-2020 Free Software Foundation, Inc.
       3                 :            :    Contributed by Sebastian Pop <s.pop@laposte.net>
       4                 :            : 
       5                 :            : This file is part of GCC.
       6                 :            : 
       7                 :            : GCC is free software; you can redistribute it and/or modify
       8                 :            : it under the terms of the GNU General Public License as published by
       9                 :            : the Free Software Foundation; either version 3, or (at your option)
      10                 :            : any later version.
      11                 :            : 
      12                 :            : GCC is distributed in the hope that it will be useful,
      13                 :            : but WITHOUT ANY WARRANTY; without even the implied warranty of
      14                 :            : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15                 :            : GNU General Public License for more details.
      16                 :            : 
      17                 :            : You should have received a copy of the GNU General Public License
      18                 :            : along with GCC; see the file COPYING3.  If not see
      19                 :            : <http://www.gnu.org/licenses/>.  */
      20                 :            : 
      21                 :            : #include "config.h"
      22                 :            : #include "system.h"
      23                 :            : #include "coretypes.h"
      24                 :            : #include "backend.h"
      25                 :            : #include "rtl.h"
      26                 :            : #include "cfghooks.h"
      27                 :            : #include "timevar.h"
      28                 :            : #include "pretty-print.h"
      29                 :            : #include "diagnostic-core.h"
      30                 :            : #include "dumpfile.h"
      31                 :            : #include "cfganal.h"
      32                 :            : #include "tree-ssa.h"
      33                 :            : #include "cfgloop.h"
      34                 :            : 
      35                 :            : /* Disable warnings about missing quoting in GCC diagnostics.  */
      36                 :            : #if __GNUC__ >= 10
      37                 :            : #  pragma GCC diagnostic push
      38                 :            : #  pragma GCC diagnostic ignored "-Wformat-diag"
      39                 :            : #endif
      40                 :            : 
      41                 :            : /* A pointer to one of the hooks containers.  */
      42                 :            : static struct cfg_hooks *cfg_hooks;
      43                 :            : 
      44                 :            : /* Initialization of functions specific to the rtl IR.  */
      45                 :            : void
      46                 :    2577380 : rtl_register_cfg_hooks (void)
      47                 :            : {
      48                 :    2577380 :   cfg_hooks = &rtl_cfg_hooks;
      49                 :    2577380 : }
      50                 :            : 
      51                 :            : /* Initialization of functions specific to the rtl IR.  */
      52                 :            : void
      53                 :    1632810 : cfg_layout_rtl_register_cfg_hooks (void)
      54                 :            : {
      55                 :    1632810 :   cfg_hooks = &cfg_layout_rtl_cfg_hooks;
      56                 :    1632810 : }
      57                 :            : 
      58                 :            : /* Initialization of functions specific to the tree IR.  */
      59                 :            : 
      60                 :            : void
      61                 :    8834760 : gimple_register_cfg_hooks (void)
      62                 :            : {
      63                 :    8834760 :   cfg_hooks = &gimple_cfg_hooks;
      64                 :    8834760 : }
      65                 :            : 
      66                 :            : struct cfg_hooks
      67                 :        730 : get_cfg_hooks (void)
      68                 :            : {
      69                 :        730 :   return *cfg_hooks;
      70                 :            : }
      71                 :            : 
      72                 :            : void
      73                 :       1460 : set_cfg_hooks (struct cfg_hooks new_cfg_hooks)
      74                 :            : {
      75                 :       1460 :   *cfg_hooks = new_cfg_hooks;
      76                 :       1460 : }
      77                 :            : 
      78                 :            : /* Returns current ir type.  */
      79                 :            : 
      80                 :            : enum ir_type
      81                 :  166940000 : current_ir_type (void)
      82                 :            : {
      83                 :  166940000 :   if (cfg_hooks == &gimple_cfg_hooks)
      84                 :            :     return IR_GIMPLE;
      85                 :   77708500 :   else if (cfg_hooks == &rtl_cfg_hooks)
      86                 :            :     return IR_RTL_CFGRTL;
      87                 :   26106900 :   else if (cfg_hooks == &cfg_layout_rtl_cfg_hooks)
      88                 :            :     return IR_RTL_CFGLAYOUT;
      89                 :            :   else
      90                 :          0 :     gcc_unreachable ();
      91                 :            : }
      92                 :            : 
      93                 :            : /* Verify the CFG consistency.
      94                 :            : 
      95                 :            :    Currently it does following: checks edge and basic block list correctness
      96                 :            :    and calls into IL dependent checking then.  */
      97                 :            : 
      98                 :            : DEBUG_FUNCTION void
      99                 :  188053000 : verify_flow_info (void)
     100                 :            : {
     101                 :  188053000 :   size_t *edge_checksum;
     102                 :  188053000 :   int err = 0;
     103                 :  188053000 :   basic_block bb, last_bb_seen;
     104                 :  188053000 :   basic_block *last_visited;
     105                 :            : 
     106                 :  188053000 :   timevar_push (TV_CFG_VERIFY);
     107                 :  188053000 :   last_visited = XCNEWVEC (basic_block, last_basic_block_for_fn (cfun));
     108                 :  188053000 :   edge_checksum = XCNEWVEC (size_t, last_basic_block_for_fn (cfun));
     109                 :            : 
     110                 :            :   /* Check bb chain & numbers.  */
     111                 :  188053000 :   last_bb_seen = ENTRY_BLOCK_PTR_FOR_FN (cfun);
     112                 : 2058070000 :   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb, NULL, next_bb)
     113                 :            :     {
     114                 : 1870020000 :       if (bb != EXIT_BLOCK_PTR_FOR_FN (cfun)
     115                 : 1870020000 :           && bb != BASIC_BLOCK_FOR_FN (cfun, bb->index))
     116                 :            :         {
     117                 :          0 :           error ("bb %d on wrong place", bb->index);
     118                 :          0 :           err = 1;
     119                 :            :         }
     120                 :            : 
     121                 : 1870020000 :       if (bb->prev_bb != last_bb_seen)
     122                 :            :         {
     123                 :          0 :           error ("prev_bb of %d should be %d, not %d",
     124                 :            :                  bb->index, last_bb_seen->index, bb->prev_bb->index);
     125                 :          0 :           err = 1;
     126                 :            :         }
     127                 :            : 
     128                 : 1870020000 :       last_bb_seen = bb;
     129                 :            :     }
     130                 :            : 
     131                 :            :   /* Now check the basic blocks (boundaries etc.) */
     132                 : 1870020000 :   FOR_EACH_BB_REVERSE_FN (bb, cfun)
     133                 :            :     {
     134                 : 1681960000 :       int n_fallthru = 0;
     135                 : 1681960000 :       edge e;
     136                 : 1681960000 :       edge_iterator ei;
     137                 :            : 
     138                 : 1681960000 :       if (bb->loop_father != NULL && current_loops == NULL)
     139                 :            :         {
     140                 :          0 :           error ("verify_flow_info: Block %i has loop_father, but there are no loops",
     141                 :            :                  bb->index);
     142                 :          0 :           err = 1;
     143                 :            :         }
     144                 : 1681960000 :       if (bb->loop_father == NULL && current_loops != NULL)
     145                 :            :         {
     146                 :          0 :           error ("verify_flow_info: Block %i lacks loop_father", bb->index);
     147                 :          0 :           err = 1;
     148                 :            :         }
     149                 :            : 
     150                 : 1681960000 :       if (!bb->count.verify ())
     151                 :            :         {
     152                 :          0 :           error ("verify_flow_info: Wrong count of block %i", bb->index);
     153                 :          0 :           err = 1;
     154                 :            :         }
     155                 :            :       /* FIXME: Graphite and SLJL and target code still tends to produce
     156                 :            :          edges with no probability.  */
     157                 : 1681960000 :       if (profile_status_for_fn (cfun) >= PROFILE_GUESSED
     158                 :            :           && !bb->count.initialized_p () && !flag_graphite && 0)
     159                 :            :         {
     160                 :            :           error ("verify_flow_info: Missing count of block %i", bb->index);
     161                 :            :           err = 1;
     162                 :            :         }
     163                 :            : 
     164                 : 4069550000 :       FOR_EACH_EDGE (e, ei, bb->succs)
     165                 :            :         {
     166                 : 2387590000 :           if (last_visited [e->dest->index] == bb)
     167                 :            :             {
     168                 :          0 :               error ("verify_flow_info: Duplicate edge %i->%i",
     169                 :          0 :                      e->src->index, e->dest->index);
     170                 :          0 :               err = 1;
     171                 :            :             }
     172                 :            :           /* FIXME: Graphite and SLJL and target code still tends to produce
     173                 :            :              edges with no probability.  */
     174                 : 2387590000 :           if (profile_status_for_fn (cfun) >= PROFILE_GUESSED
     175                 :            :               && !e->probability.initialized_p () && !flag_graphite && 0)
     176                 :            :             {
     177                 :            :               error ("Uninitialized probability of edge %i->%i", e->src->index,
     178                 :            :                      e->dest->index);
     179                 :            :               err = 1;
     180                 :            :             }
     181                 : 2387590000 :           if (!e->probability.verify ())
     182                 :            :             {
     183                 :          0 :               error ("verify_flow_info: Wrong probability of edge %i->%i",
     184                 :          0 :                      e->src->index, e->dest->index);
     185                 :          0 :               err = 1;
     186                 :            :             }
     187                 :            : 
     188                 : 2387590000 :           last_visited [e->dest->index] = bb;
     189                 :            : 
     190                 : 2387590000 :           if (e->flags & EDGE_FALLTHRU)
     191                 :  933455000 :             n_fallthru++;
     192                 :            : 
     193                 : 2387590000 :           if (e->src != bb)
     194                 :            :             {
     195                 :          0 :               error ("verify_flow_info: Basic block %d succ edge is corrupted",
     196                 :            :                      bb->index);
     197                 :          0 :               fprintf (stderr, "Predecessor: ");
     198                 :          0 :               dump_edge_info (stderr, e, TDF_DETAILS, 0);
     199                 :          0 :               fprintf (stderr, "\nSuccessor: ");
     200                 :          0 :               dump_edge_info (stderr, e, TDF_DETAILS, 1);
     201                 :          0 :               fprintf (stderr, "\n");
     202                 :          0 :               err = 1;
     203                 :            :             }
     204                 :            : 
     205                 : 2387590000 :           edge_checksum[e->dest->index] += (size_t) e;
     206                 :            :         }
     207                 : 1681960000 :       if (n_fallthru > 1)
     208                 :            :         {
     209                 :          0 :           error ("wrong amount of branch edges after unconditional jump %i", bb->index);
     210                 :          0 :           err = 1;
     211                 :            :         }
     212                 :            : 
     213                 : 4068260000 :       FOR_EACH_EDGE (e, ei, bb->preds)
     214                 :            :         {
     215                 : 2386300000 :           if (e->dest != bb)
     216                 :            :             {
     217                 :          0 :               error ("basic block %d pred edge is corrupted", bb->index);
     218                 :          0 :               fputs ("Predecessor: ", stderr);
     219                 :          0 :               dump_edge_info (stderr, e, TDF_DETAILS, 0);
     220                 :          0 :               fputs ("\nSuccessor: ", stderr);
     221                 :          0 :               dump_edge_info (stderr, e, TDF_DETAILS, 1);
     222                 :          0 :               fputc ('\n', stderr);
     223                 :          0 :               err = 1;
     224                 :            :             }
     225                 :            : 
     226                 : 2386300000 :           if (ei.index != e->dest_idx)
     227                 :            :             {
     228                 :          0 :               error ("basic block %d pred edge is corrupted", bb->index);
     229                 :          0 :               error ("its dest_idx should be %d, not %d",
     230                 :            :                      ei.index, e->dest_idx);
     231                 :          0 :               fputs ("Predecessor: ", stderr);
     232                 :          0 :               dump_edge_info (stderr, e, TDF_DETAILS, 0);
     233                 :          0 :               fputs ("\nSuccessor: ", stderr);
     234                 :          0 :               dump_edge_info (stderr, e, TDF_DETAILS, 1);
     235                 :          0 :               fputc ('\n', stderr);
     236                 :          0 :               err = 1;
     237                 :            :             }
     238                 :            : 
     239                 : 2386300000 :           edge_checksum[e->dest->index] -= (size_t) e;
     240                 :            :         }
     241                 :            :     }
     242                 :            : 
     243                 :            :   /* Complete edge checksumming for ENTRY and EXIT.  */
     244                 :  188053000 :   {
     245                 :  188053000 :     edge e;
     246                 :  188053000 :     edge_iterator ei;
     247                 :            : 
     248                 :  376106000 :     FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs)
     249                 :  188053000 :       edge_checksum[e->dest->index] += (size_t) e;
     250                 :            : 
     251                 :  377398000 :     FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
     252                 :  189345000 :       edge_checksum[e->dest->index] -= (size_t) e;
     253                 :            :   }
     254                 :            : 
     255                 : 2246120000 :   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
     256                 : 2058070000 :     if (edge_checksum[bb->index])
     257                 :            :       {
     258                 :          0 :         error ("basic block %i edge lists are corrupted", bb->index);
     259                 :          0 :         err = 1;
     260                 :            :       }
     261                 :            : 
     262                 :            :   /* Clean up.  */
     263                 :  188053000 :   free (last_visited);
     264                 :  188053000 :   free (edge_checksum);
     265                 :            : 
     266                 :  188053000 :   if (cfg_hooks->verify_flow_info)
     267                 :  188053000 :     err |= cfg_hooks->verify_flow_info ();
     268                 :  188053000 :   if (err)
     269                 :          0 :     internal_error ("verify_flow_info failed");
     270                 :  188053000 :   timevar_pop (TV_CFG_VERIFY);
     271                 :  188053000 : }
     272                 :            : 
     273                 :            : /* Print out one basic block BB to file OUTF.  INDENT is printed at the
     274                 :            :    start of each new line.  FLAGS are the TDF_* flags in dumpfile.h.
     275                 :            : 
     276                 :            :    This function takes care of the purely graph related information.
     277                 :            :    The cfg hook for the active representation should dump
     278                 :            :    representation-specific information.  */
     279                 :            : 
     280                 :            : void
     281                 :     190390 : dump_bb (FILE *outf, basic_block bb, int indent, dump_flags_t flags)
     282                 :            : {
     283                 :     190390 :   if (flags & TDF_BLOCKS)
     284                 :      24688 :     dump_bb_info (outf, bb, indent, flags, true, false);
     285                 :     190390 :   if (cfg_hooks->dump_bb)
     286                 :     190390 :     cfg_hooks->dump_bb (outf, bb, indent, flags);
     287                 :     190390 :   if (flags & TDF_BLOCKS)
     288                 :      24688 :     dump_bb_info (outf, bb, indent, flags, false, true);
     289                 :     190390 :   fputc ('\n', outf);
     290                 :     190390 : }
     291                 :            : 
     292                 :            : DEBUG_FUNCTION void
     293                 :          0 : debug (basic_block_def &ref)
     294                 :            : {
     295                 :          0 :   dump_bb (stderr, &ref, 0, TDF_NONE);
     296                 :          0 : }
     297                 :            : 
     298                 :            : DEBUG_FUNCTION void
     299                 :          0 : debug (basic_block_def *ptr)
     300                 :            : {
     301                 :          0 :   if (ptr)
     302                 :          0 :     debug (*ptr);
     303                 :            :   else
     304                 :          0 :     fprintf (stderr, "<nil>\n");
     305                 :          0 : }
     306                 :            : 
     307                 :            : static void
     308                 :          0 : debug_slim (basic_block ptr)
     309                 :            : {
     310                 :          0 :   fprintf (stderr, "<basic_block %p (%d)>", (void *) ptr, ptr->index);
     311                 :          0 : }
     312                 :            : 
     313                 :          0 : DEFINE_DEBUG_VEC (basic_block_def *)
     314                 :          0 : DEFINE_DEBUG_HASH_SET (basic_block_def *)
     315                 :            : 
     316                 :            : /* Dumps basic block BB to pretty-printer PP, for use as a label of
     317                 :            :    a DOT graph record-node.  The implementation of this hook is
     318                 :            :    expected to write the label to the stream that is attached to PP.
     319                 :            :    Field separators between instructions are pipe characters printed
     320                 :            :    verbatim.  Instructions should be written with some characters
     321                 :            :    escaped, using pp_write_text_as_dot_label_to_stream().  */
     322                 :            : 
     323                 :            : void
     324                 :        408 : dump_bb_for_graph (pretty_printer *pp, basic_block bb)
     325                 :            : {
     326                 :        408 :   if (!cfg_hooks->dump_bb_for_graph)
     327                 :          0 :     internal_error ("%s does not support dump_bb_for_graph",
     328                 :            :                     cfg_hooks->name);
     329                 :            :   /* TODO: Add pretty printer for counter.  */
     330                 :        408 :   if (bb->count.initialized_p ())
     331                 :        326 :     pp_printf (pp, "COUNT:" "%" PRId64, bb->count.to_gcov_type ());
     332                 :        408 :   pp_write_text_to_stream (pp);
     333                 :        408 :   if (!(dump_flags & TDF_SLIM))
     334                 :        408 :     cfg_hooks->dump_bb_for_graph (pp, bb);
     335                 :        408 : }
     336                 :            : 
     337                 :            : /* Dump the complete CFG to FILE.  FLAGS are the TDF_* flags in dumpfile.h.  */
     338                 :            : void
     339                 :        295 : dump_flow_info (FILE *file, dump_flags_t flags)
     340                 :            : {
     341                 :        295 :   basic_block bb;
     342                 :            : 
     343                 :        295 :   fprintf (file, "\n%d basic blocks, %d edges.\n", n_basic_blocks_for_fn (cfun),
     344                 :        295 :            n_edges_for_fn (cfun));
     345                 :       2588 :   FOR_ALL_BB_FN (bb, cfun)
     346                 :       2293 :     dump_bb (file, bb, 0, flags);
     347                 :            : 
     348                 :        295 :   putc ('\n', file);
     349                 :        295 : }
     350                 :            : 
     351                 :            : /* Like above, but dump to stderr.  To be called from debuggers.  */
     352                 :            : void debug_flow_info (void);
     353                 :            : DEBUG_FUNCTION void
     354                 :          0 : debug_flow_info (void)
     355                 :            : {
     356                 :          0 :   dump_flow_info (stderr, TDF_DETAILS);
     357                 :          0 : }
     358                 :            : 
     359                 :            : /* Redirect edge E to the given basic block DEST and update underlying program
     360                 :            :    representation.  Returns edge representing redirected branch (that may not
     361                 :            :    be equivalent to E in the case of duplicate edges being removed) or NULL
     362                 :            :    if edge is not easily redirectable for whatever reason.  */
     363                 :            : 
     364                 :            : edge
     365                 :   39664800 : redirect_edge_and_branch (edge e, basic_block dest)
     366                 :            : {
     367                 :   39664800 :   edge ret;
     368                 :            : 
     369                 :   39664800 :   if (!cfg_hooks->redirect_edge_and_branch)
     370                 :          0 :     internal_error ("%s does not support redirect_edge_and_branch",
     371                 :            :                     cfg_hooks->name);
     372                 :            : 
     373                 :   39664800 :   ret = cfg_hooks->redirect_edge_and_branch (e, dest);
     374                 :            : 
     375                 :            :   /* If RET != E, then either the redirection failed, or the edge E
     376                 :            :      was removed since RET already lead to the same destination.  */
     377                 :   39664800 :   if (current_loops != NULL && ret == e)
     378                 :   32058600 :     rescan_loop_exit (e, false, false);
     379                 :            : 
     380                 :   39664800 :   return ret;
     381                 :            : }
     382                 :            : 
     383                 :            : /* Returns true if it is possible to remove the edge E by redirecting it
     384                 :            :    to the destination of the other edge going from its source.  */
     385                 :            : 
     386                 :            : bool
     387                 :     238876 : can_remove_branch_p (const_edge e)
     388                 :            : {
     389                 :     238876 :   if (!cfg_hooks->can_remove_branch_p)
     390                 :          0 :     internal_error ("%s does not support can_remove_branch_p",
     391                 :            :                     cfg_hooks->name);
     392                 :            : 
     393                 :     238876 :   if (EDGE_COUNT (e->src->succs) != 2)
     394                 :            :     return false;
     395                 :            : 
     396                 :     238876 :   return cfg_hooks->can_remove_branch_p (e);
     397                 :            : }
     398                 :            : 
     399                 :            : /* Removes E, by redirecting it to the destination of the other edge going
     400                 :            :    from its source.  Can_remove_branch_p must be true for E, hence this
     401                 :            :    operation cannot fail.  */
     402                 :            : 
     403                 :            : void
     404                 :     238941 : remove_branch (edge e)
     405                 :            : {
     406                 :     238941 :   edge other;
     407                 :     238941 :   basic_block src = e->src;
     408                 :     238941 :   int irr;
     409                 :            : 
     410                 :     238941 :   gcc_assert (EDGE_COUNT (e->src->succs) == 2);
     411                 :            : 
     412                 :     238941 :   other = EDGE_SUCC (src, EDGE_SUCC (src, 0) == e);
     413                 :     238941 :   irr = other->flags & EDGE_IRREDUCIBLE_LOOP;
     414                 :            : 
     415                 :     238941 :   e = redirect_edge_and_branch (e, other->dest);
     416                 :     238941 :   gcc_assert (e != NULL);
     417                 :            : 
     418                 :     238941 :   e->flags &= ~EDGE_IRREDUCIBLE_LOOP;
     419                 :     238941 :   e->flags |= irr;
     420                 :     238941 : }
     421                 :            : 
     422                 :            : /* Removes edge E from cfg.  Unlike remove_branch, it does not update IL.  */
     423                 :            : 
     424                 :            : void
     425                 :   45293900 : remove_edge (edge e)
     426                 :            : {
     427                 :   45293900 :   if (current_loops != NULL)
     428                 :            :     {
     429                 :   39588100 :       rescan_loop_exit (e, false, true);
     430                 :            : 
     431                 :            :       /* Removal of an edge inside an irreducible region or which leads
     432                 :            :          to an irreducible region can turn the region into a natural loop.
     433                 :            :          In that case, ask for the loop structure fixups.
     434                 :            : 
     435                 :            :          FIXME: Note that LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS is not always
     436                 :            :          set, so always ask for fixups when removing an edge in that case.  */
     437                 :   39588100 :       if (!loops_state_satisfies_p (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
     438                 :    3946850 :           || (e->flags & EDGE_IRREDUCIBLE_LOOP)
     439                 :   43532200 :           || (e->dest->flags & BB_IRREDUCIBLE_LOOP))
     440                 :   35644400 :         loops_state_set (LOOPS_NEED_FIXUP);
     441                 :            :     }
     442                 :            : 
     443                 :            :   /* This is probably not needed, but it doesn't hurt.  */
     444                 :            :   /* FIXME: This should be called via a remove_edge hook.  */
     445                 :   45293900 :   if (current_ir_type () == IR_GIMPLE)
     446                 :   35559300 :     redirect_edge_var_map_clear (e);
     447                 :            : 
     448                 :   45293900 :   remove_edge_raw (e);
     449                 :   45293900 : }
     450                 :            : 
     451                 :            : /* Like redirect_edge_succ but avoid possible duplicate edge.  */
     452                 :            : 
     453                 :            : edge
     454                 :   41840700 : redirect_edge_succ_nodup (edge e, basic_block new_succ)
     455                 :            : {
     456                 :   41840700 :   edge s;
     457                 :            : 
     458                 :   41840700 :   s = find_edge (e->src, new_succ);
     459                 :   41840700 :   if (s && s != e)
     460                 :            :     {
     461                 :     215946 :       s->flags |= e->flags;
     462                 :     215946 :       s->probability += e->probability;
     463                 :            :       /* FIXME: This should be called via a hook and only for IR_GIMPLE.  */
     464                 :     215946 :       redirect_edge_var_map_dup (s, e);
     465                 :     215946 :       remove_edge (e);
     466                 :     215946 :       e = s;
     467                 :            :     }
     468                 :            :   else
     469                 :   41624800 :     redirect_edge_succ (e, new_succ);
     470                 :            : 
     471                 :   41840700 :   return e;
     472                 :            : }
     473                 :            : 
     474                 :            : /* Redirect the edge E to basic block DEST even if it requires creating
     475                 :            :    of a new basic block; then it returns the newly created basic block.
     476                 :            :    Aborts when redirection is impossible.  */
     477                 :            : 
     478                 :            : basic_block
     479                 :    4383070 : redirect_edge_and_branch_force (edge e, basic_block dest)
     480                 :            : {
     481                 :    4383070 :   basic_block ret, src = e->src;
     482                 :            : 
     483                 :    4383070 :   if (!cfg_hooks->redirect_edge_and_branch_force)
     484                 :          0 :     internal_error ("%s does not support redirect_edge_and_branch_force",
     485                 :            :                     cfg_hooks->name);
     486                 :            : 
     487                 :    4383070 :   if (current_loops != NULL)
     488                 :    3453130 :     rescan_loop_exit (e, false, true);
     489                 :            : 
     490                 :    4383070 :   ret = cfg_hooks->redirect_edge_and_branch_force (e, dest);
     491                 :            : 
     492                 :    4383070 :   if (ret != NULL && dom_info_available_p (CDI_DOMINATORS))
     493                 :      27930 :     set_immediate_dominator (CDI_DOMINATORS, ret, src);
     494                 :            : 
     495                 :    4383070 :   if (current_loops != NULL)
     496                 :            :     {
     497                 :    3453130 :       if (ret != NULL)
     498                 :            :         {
     499                 :          7 :           class loop *loop
     500                 :          7 :             = find_common_loop (single_pred (ret)->loop_father,
     501                 :          7 :                                 single_succ (ret)->loop_father);
     502                 :          7 :           add_bb_to_loop (ret, loop);
     503                 :            :         }
     504                 :    3453120 :       else if (find_edge (src, dest) == e)
     505                 :    3453120 :         rescan_loop_exit (e, true, false);
     506                 :            :     }
     507                 :            : 
     508                 :    4383070 :   return ret;
     509                 :            : }
     510                 :            : 
     511                 :            : /* Splits basic block BB after the specified instruction I (but at least after
     512                 :            :    the labels).  If I is NULL, splits just after labels.  The newly created edge
     513                 :            :    is returned.  The new basic block is created just after the old one.  */
     514                 :            : 
     515                 :            : static edge
     516                 :    4922940 : split_block_1 (basic_block bb, void *i)
     517                 :            : {
     518                 :    4922940 :   basic_block new_bb;
     519                 :    4922940 :   edge res;
     520                 :            : 
     521                 :    4922940 :   if (!cfg_hooks->split_block)
     522                 :          0 :     internal_error ("%s does not support split_block", cfg_hooks->name);
     523                 :            : 
     524                 :    4922940 :   new_bb = cfg_hooks->split_block (bb, i);
     525                 :    4922940 :   if (!new_bb)
     526                 :            :     return NULL;
     527                 :            : 
     528                 :    4922940 :   new_bb->count = bb->count;
     529                 :    4922940 :   new_bb->discriminator = bb->discriminator;
     530                 :            : 
     531                 :    4922940 :   if (dom_info_available_p (CDI_DOMINATORS))
     532                 :            :     {
     533                 :     387843 :       redirect_immediate_dominators (CDI_DOMINATORS, bb, new_bb);
     534                 :     387843 :       set_immediate_dominator (CDI_DOMINATORS, new_bb, bb);
     535                 :            :     }
     536                 :            : 
     537                 :    4922940 :   if (current_loops != NULL)
     538                 :            :     {
     539                 :    4342890 :       edge_iterator ei;
     540                 :    4342890 :       edge e;
     541                 :    4342890 :       add_bb_to_loop (new_bb, bb->loop_father);
     542                 :            :       /* Identify all loops bb may have been the latch of and adjust them.  */
     543                 :   10869500 :       FOR_EACH_EDGE (e, ei, new_bb->succs)
     544                 :    6526630 :         if (e->dest->loop_father->latch == bb)
     545                 :      70785 :           e->dest->loop_father->latch = new_bb;
     546                 :            :     }
     547                 :            : 
     548                 :    4922940 :   res = make_single_succ_edge (bb, new_bb, EDGE_FALLTHRU);
     549                 :            : 
     550                 :    4922940 :   if (bb->flags & BB_IRREDUCIBLE_LOOP)
     551                 :            :     {
     552                 :       1064 :       new_bb->flags |= BB_IRREDUCIBLE_LOOP;
     553                 :       1064 :       res->flags |= EDGE_IRREDUCIBLE_LOOP;
     554                 :            :     }
     555                 :            : 
     556                 :            :   return res;
     557                 :            : }
     558                 :            : 
     559                 :            : edge
     560                 :    2870040 : split_block (basic_block bb, gimple *i)
     561                 :            : {
     562                 :    2870040 :   return split_block_1 (bb, i);
     563                 :            : }
     564                 :            : 
     565                 :            : edge
     566                 :    1760740 : split_block (basic_block bb, rtx i)
     567                 :            : {
     568                 :    1760740 :   return split_block_1 (bb, i);
     569                 :            : }
     570                 :            : 
     571                 :            : /* Splits block BB just after labels.  The newly created edge is returned.  */
     572                 :            : 
     573                 :            : edge
     574                 :     292148 : split_block_after_labels (basic_block bb)
     575                 :            : {
     576                 :     292148 :   return split_block_1 (bb, NULL);
     577                 :            : }
     578                 :            : 
     579                 :            : /* Moves block BB immediately after block AFTER.  Returns false if the
     580                 :            :    movement was impossible.  */
     581                 :            : 
     582                 :            : bool
     583                 :   11676500 : move_block_after (basic_block bb, basic_block after)
     584                 :            : {
     585                 :   11676500 :   bool ret;
     586                 :            : 
     587                 :   11676500 :   if (!cfg_hooks->move_block_after)
     588                 :          0 :     internal_error ("%s does not support move_block_after", cfg_hooks->name);
     589                 :            : 
     590                 :   11676500 :   ret = cfg_hooks->move_block_after (bb, after);
     591                 :            : 
     592                 :   11676500 :   return ret;
     593                 :            : }
     594                 :            : 
     595                 :            : /* Deletes the basic block BB.  */
     596                 :            : 
     597                 :            : void
     598                 :   22400000 : delete_basic_block (basic_block bb)
     599                 :            : {
     600                 :   22400000 :   if (!cfg_hooks->delete_basic_block)
     601                 :          0 :     internal_error ("%s does not support delete_basic_block", cfg_hooks->name);
     602                 :            : 
     603                 :   22400000 :   cfg_hooks->delete_basic_block (bb);
     604                 :            : 
     605                 :   22400000 :   if (current_loops != NULL)
     606                 :            :     {
     607                 :   19316400 :       class loop *loop = bb->loop_father;
     608                 :            : 
     609                 :            :       /* If we remove the header or the latch of a loop, mark the loop for
     610                 :            :          removal.  */
     611                 :   19316400 :       if (loop->latch == bb
     612                 :   19292500 :           || loop->header == bb)
     613                 :      37463 :         mark_loop_for_removal (loop);
     614                 :            : 
     615                 :   19316400 :       remove_bb_from_loops (bb);
     616                 :            :     }
     617                 :            : 
     618                 :            :   /* Remove the edges into and out of this block.  Note that there may
     619                 :            :      indeed be edges in, if we are removing an unreachable loop.  */
     620                 :   22609900 :   while (EDGE_COUNT (bb->preds) != 0)
     621                 :     209871 :     remove_edge (EDGE_PRED (bb, 0));
     622                 :   26408500 :   while (EDGE_COUNT (bb->succs) != 0)
     623                 :    4008420 :     remove_edge (EDGE_SUCC (bb, 0));
     624                 :            : 
     625                 :   22400000 :   if (dom_info_available_p (CDI_DOMINATORS))
     626                 :   15453500 :     delete_from_dominance_info (CDI_DOMINATORS, bb);
     627                 :   22400000 :   if (dom_info_available_p (CDI_POST_DOMINATORS))
     628                 :     276251 :     delete_from_dominance_info (CDI_POST_DOMINATORS, bb);
     629                 :            : 
     630                 :            :   /* Remove the basic block from the array.  */
     631                 :   22400000 :   expunge_block (bb);
     632                 :   22400000 : }
     633                 :            : 
     634                 :            : /* Splits edge E and returns the newly created basic block.  */
     635                 :            : 
     636                 :            : basic_block
     637                 :   15727600 : split_edge (edge e)
     638                 :            : {
     639                 :   15727600 :   basic_block ret;
     640                 :   15727600 :   profile_count count = e->count ();
     641                 :   15727600 :   edge f;
     642                 :   15727600 :   bool irr = (e->flags & EDGE_IRREDUCIBLE_LOOP) != 0;
     643                 :   15727600 :   class loop *loop;
     644                 :   15727600 :   basic_block src = e->src, dest = e->dest;
     645                 :            : 
     646                 :   15727600 :   if (!cfg_hooks->split_edge)
     647                 :          0 :     internal_error ("%s does not support split_edge", cfg_hooks->name);
     648                 :            : 
     649                 :   15727600 :   if (current_loops != NULL)
     650                 :   14827600 :     rescan_loop_exit (e, false, true);
     651                 :            : 
     652                 :   15727600 :   ret = cfg_hooks->split_edge (e);
     653                 :   15727600 :   ret->count = count;
     654                 :   15727600 :   single_succ_edge (ret)->probability = profile_probability::always ();
     655                 :            : 
     656                 :   15727600 :   if (irr)
     657                 :            :     {
     658                 :      27309 :       ret->flags |= BB_IRREDUCIBLE_LOOP;
     659                 :      27309 :       single_pred_edge (ret)->flags |= EDGE_IRREDUCIBLE_LOOP;
     660                 :      27309 :       single_succ_edge (ret)->flags |= EDGE_IRREDUCIBLE_LOOP;
     661                 :            :     }
     662                 :            : 
     663                 :   15727600 :   if (dom_info_available_p (CDI_DOMINATORS))
     664                 :   13426300 :     set_immediate_dominator (CDI_DOMINATORS, ret, single_pred (ret));
     665                 :            : 
     666                 :   15727600 :   if (dom_info_state (CDI_DOMINATORS) >= DOM_NO_FAST_QUERY)
     667                 :            :     {
     668                 :            :       /* There are two cases:
     669                 :            : 
     670                 :            :          If the immediate dominator of e->dest is not e->src, it
     671                 :            :          remains unchanged.
     672                 :            : 
     673                 :            :          If immediate dominator of e->dest is e->src, it may become
     674                 :            :          ret, provided that all other predecessors of e->dest are
     675                 :            :          dominated by e->dest.  */
     676                 :            : 
     677                 :   13426300 :       if (get_immediate_dominator (CDI_DOMINATORS, single_succ (ret))
     678                 :   13426300 :           == single_pred (ret))
     679                 :            :         {
     680                 :    5253680 :           edge_iterator ei;
     681                 :    9417260 :           FOR_EACH_EDGE (f, ei, single_succ (ret)->preds)
     682                 :            :             {
     683                 :    7215660 :               if (f == single_succ_edge (ret))
     684                 :    2203880 :                 continue;
     685                 :            : 
     686                 :    5011780 :               if (!dominated_by_p (CDI_DOMINATORS, f->src,
     687                 :    5011780 :                                    single_succ (ret)))
     688                 :            :                 break;
     689                 :            :             }
     690                 :            : 
     691                 :    5253680 :           if (!f)
     692                 :    2201600 :             set_immediate_dominator (CDI_DOMINATORS, single_succ (ret), ret);
     693                 :            :         }
     694                 :            :     }
     695                 :            : 
     696                 :   15727600 :   if (current_loops != NULL)
     697                 :            :     {
     698                 :   14827600 :       loop = find_common_loop (src->loop_father, dest->loop_father);
     699                 :   14827600 :       add_bb_to_loop (ret, loop);
     700                 :            : 
     701                 :            :       /* If we split the latch edge of loop adjust the latch block.  */
     702                 :   14827600 :       if (loop->latch == src
     703                 :    3044930 :           && loop->header == dest)
     704                 :    3044900 :         loop->latch = ret;
     705                 :            :     }
     706                 :            : 
     707                 :   15727600 :   return ret;
     708                 :            : }
     709                 :            : 
     710                 :            : /* Creates a new basic block just after the basic block AFTER.
     711                 :            :    HEAD and END are the first and the last statement belonging
     712                 :            :    to the block.  If both are NULL, an empty block is created.  */
     713                 :            : 
     714                 :            : static basic_block
     715                 :   46020000 : create_basic_block_1 (void *head, void *end, basic_block after)
     716                 :            : {
     717                 :   46020000 :   basic_block ret;
     718                 :            : 
     719                 :   46020000 :   if (!cfg_hooks->create_basic_block)
     720                 :          0 :     internal_error ("%s does not support create_basic_block", cfg_hooks->name);
     721                 :            : 
     722                 :   46020000 :   ret = cfg_hooks->create_basic_block (head, end, after);
     723                 :            : 
     724                 :   46020000 :   if (dom_info_available_p (CDI_DOMINATORS))
     725                 :   15806800 :     add_to_dominance_info (CDI_DOMINATORS, ret);
     726                 :   46020000 :   if (dom_info_available_p (CDI_POST_DOMINATORS))
     727                 :      73042 :     add_to_dominance_info (CDI_POST_DOMINATORS, ret);
     728                 :            : 
     729                 :   46020000 :   return ret;
     730                 :            : }
     731                 :            : 
     732                 :            : basic_block
     733                 :   20186800 : create_basic_block (gimple_seq seq, basic_block after)
     734                 :            : {
     735                 :   20186800 :   return create_basic_block_1 (seq, NULL, after);
     736                 :            : }
     737                 :            : 
     738                 :            : basic_block
     739                 :    7892950 : create_basic_block (rtx head, rtx end, basic_block after)
     740                 :            : {
     741                 :    7892950 :   return create_basic_block_1 (head, end, after);
     742                 :            : }
     743                 :            : 
     744                 :            : 
     745                 :            : /* Creates an empty basic block just after basic block AFTER.  */
     746                 :            : 
     747                 :            : basic_block
     748                 :   17940200 : create_empty_bb (basic_block after)
     749                 :            : {
     750                 :   17940200 :   return create_basic_block_1 (NULL, NULL, after);
     751                 :            : }
     752                 :            : 
     753                 :            : /* Checks whether we may merge blocks BB1 and BB2.  */
     754                 :            : 
     755                 :            : bool
     756                 :  230227000 : can_merge_blocks_p (basic_block bb1, basic_block bb2)
     757                 :            : {
     758                 :  230227000 :   bool ret;
     759                 :            : 
     760                 :  230227000 :   if (!cfg_hooks->can_merge_blocks_p)
     761                 :          0 :     internal_error ("%s does not support can_merge_blocks_p", cfg_hooks->name);
     762                 :            : 
     763                 :  230227000 :   ret = cfg_hooks->can_merge_blocks_p (bb1, bb2);
     764                 :            : 
     765                 :  230227000 :   return ret;
     766                 :            : }
     767                 :            : 
     768                 :            : void
     769                 :    4147460 : predict_edge (edge e, enum br_predictor predictor, int probability)
     770                 :            : {
     771                 :    4147460 :   if (!cfg_hooks->predict_edge)
     772                 :          0 :     internal_error ("%s does not support predict_edge", cfg_hooks->name);
     773                 :            : 
     774                 :    4147460 :   cfg_hooks->predict_edge (e, predictor, probability);
     775                 :    4147460 : }
     776                 :            : 
     777                 :            : bool
     778                 :    2183230 : predicted_by_p (const_basic_block bb, enum br_predictor predictor)
     779                 :            : {
     780                 :    2183230 :   if (!cfg_hooks->predict_edge)
     781                 :          0 :     internal_error ("%s does not support predicted_by_p", cfg_hooks->name);
     782                 :            : 
     783                 :    2183230 :   return cfg_hooks->predicted_by_p (bb, predictor);
     784                 :            : }
     785                 :            : 
     786                 :            : /* Merges basic block B into basic block A.  */
     787                 :            : 
     788                 :            : void
     789                 :   11932000 : merge_blocks (basic_block a, basic_block b)
     790                 :            : {
     791                 :   11932000 :   edge e;
     792                 :   11932000 :   edge_iterator ei;
     793                 :            : 
     794                 :   11932000 :   if (!cfg_hooks->merge_blocks)
     795                 :          0 :     internal_error ("%s does not support merge_blocks", cfg_hooks->name);
     796                 :            : 
     797                 :   11932000 :   cfg_hooks->merge_blocks (a, b);
     798                 :            : 
     799                 :   11932000 :   if (current_loops != NULL)
     800                 :            :     {
     801                 :            :       /* If the block we merge into is a loop header do nothing unless ... */
     802                 :    9971740 :       if (a->loop_father->header == a)
     803                 :            :         {
     804                 :            :           /* ... we merge two loop headers, in which case we kill
     805                 :            :              the inner loop.  */
     806                 :     305955 :           if (b->loop_father->header == b)
     807                 :       1170 :             mark_loop_for_removal (b->loop_father);
     808                 :            :         }
     809                 :            :       /* If we merge a loop header into its predecessor, update the loop
     810                 :            :          structure.  */
     811                 :    9665780 :       else if (b->loop_father->header == b)
     812                 :            :         {
     813                 :       5281 :           remove_bb_from_loops (a);
     814                 :       5281 :           add_bb_to_loop  (a, b->loop_father);
     815                 :       5281 :           a->loop_father->header = a;
     816                 :            :         }
     817                 :            :       /* If we merge a loop latch into its predecessor, update the loop
     818                 :            :          structure.  */
     819                 :    9971740 :       if (b->loop_father->latch
     820                 :    9907780 :           && b->loop_father->latch == b)
     821                 :     246426 :         b->loop_father->latch = a;
     822                 :    9971740 :       remove_bb_from_loops (b);
     823                 :            :     }
     824                 :            : 
     825                 :            :   /* Normally there should only be one successor of A and that is B, but
     826                 :            :      partway though the merge of blocks for conditional_execution we'll
     827                 :            :      be merging a TEST block with THEN and ELSE successors.  Free the
     828                 :            :      whole lot of them and hope the caller knows what they're doing.  */
     829                 :            : 
     830                 :   23864100 :   while (EDGE_COUNT (a->succs) != 0)
     831                 :   11932000 :     remove_edge (EDGE_SUCC (a, 0));
     832                 :            : 
     833                 :            :   /* Adjust the edges out of B for the new owner.  */
     834                 :   27144300 :   FOR_EACH_EDGE (e, ei, b->succs)
     835                 :            :     {
     836                 :   15212300 :       e->src = a;
     837                 :   15212300 :       if (current_loops != NULL)
     838                 :            :         {
     839                 :            :           /* If b was a latch, a now is.  */
     840                 :   13055300 :           if (e->dest->loop_father->latch == b)
     841                 :        485 :             e->dest->loop_father->latch = a;
     842                 :   13055300 :           rescan_loop_exit (e, true, false);
     843                 :            :         }
     844                 :            :     }
     845                 :   11932000 :   a->succs = b->succs;
     846                 :   11932000 :   a->flags |= b->flags;
     847                 :            : 
     848                 :            :   /* B hasn't quite yet ceased to exist.  Attempt to prevent mishap.  */
     849                 :   11932000 :   b->preds = b->succs = NULL;
     850                 :            : 
     851                 :   11932000 :   if (dom_info_available_p (CDI_DOMINATORS))
     852                 :    9103710 :     redirect_immediate_dominators (CDI_DOMINATORS, b, a);
     853                 :            : 
     854                 :   11932000 :   if (dom_info_available_p (CDI_DOMINATORS))
     855                 :    9103710 :     delete_from_dominance_info (CDI_DOMINATORS, b);
     856                 :   11932000 :   if (dom_info_available_p (CDI_POST_DOMINATORS))
     857                 :      59784 :     delete_from_dominance_info (CDI_POST_DOMINATORS, b);
     858                 :            : 
     859                 :   11932000 :   expunge_block (b);
     860                 :   11932000 : }
     861                 :            : 
     862                 :            : /* Split BB into entry part and the rest (the rest is the newly created block).
     863                 :            :    Redirect those edges for that REDIRECT_EDGE_P returns true to the entry
     864                 :            :    part.  Returns the edge connecting the entry part to the rest.  */
     865                 :            : 
     866                 :            : edge
     867                 :     278015 : make_forwarder_block (basic_block bb, bool (*redirect_edge_p) (edge),
     868                 :            :                       void (*new_bb_cbk) (basic_block))
     869                 :            : {
     870                 :     278015 :   edge e, fallthru;
     871                 :     278015 :   edge_iterator ei;
     872                 :     278015 :   basic_block dummy, jump;
     873                 :     278015 :   class loop *loop, *ploop, *cloop;
     874                 :            : 
     875                 :     278015 :   if (!cfg_hooks->make_forwarder_block)
     876                 :          0 :     internal_error ("%s does not support make_forwarder_block",
     877                 :            :                     cfg_hooks->name);
     878                 :            : 
     879                 :     278015 :   fallthru = split_block_after_labels (bb);
     880                 :     278015 :   dummy = fallthru->src;
     881                 :     278015 :   dummy->count = profile_count::zero ();
     882                 :     278015 :   bb = fallthru->dest;
     883                 :            : 
     884                 :            :   /* Redirect back edges we want to keep.  */
     885                 :    1061500 :   for (ei = ei_start (dummy->preds); (e = ei_safe_edge (ei)); )
     886                 :            :     {
     887                 :     783487 :       basic_block e_src;
     888                 :            : 
     889                 :     783487 :       if (redirect_edge_p (e))
     890                 :            :         {
     891                 :     500353 :           dummy->count += e->count ();
     892                 :     500353 :           ei_next (&ei);
     893                 :     500353 :           continue;
     894                 :            :         }
     895                 :            : 
     896                 :     283134 :       e_src = e->src;
     897                 :     283134 :       jump = redirect_edge_and_branch_force (e, bb);
     898                 :     283134 :       if (jump != NULL)
     899                 :            :         {
     900                 :            :           /* If we redirected the loop latch edge, the JUMP block now acts like
     901                 :            :              the new latch of the loop.  */
     902                 :          5 :           if (current_loops != NULL
     903                 :          5 :               && dummy->loop_father != NULL
     904                 :          5 :               && dummy->loop_father->header == dummy
     905                 :          5 :               && dummy->loop_father->latch == e_src)
     906                 :          0 :             dummy->loop_father->latch = jump;
     907                 :            : 
     908                 :          5 :           if (new_bb_cbk != NULL)
     909                 :          0 :             new_bb_cbk (jump);
     910                 :            :         }
     911                 :            :     }
     912                 :            : 
     913                 :     278015 :   if (dom_info_available_p (CDI_DOMINATORS))
     914                 :            :     {
     915                 :     126838 :       vec<basic_block> doms_to_fix;
     916                 :     126838 :       doms_to_fix.create (2);
     917                 :     126838 :       doms_to_fix.quick_push (dummy);
     918                 :     126838 :       doms_to_fix.quick_push (bb);
     919                 :     126838 :       iterate_fix_dominators (CDI_DOMINATORS, doms_to_fix, false);
     920                 :     253676 :       doms_to_fix.release ();
     921                 :            :     }
     922                 :            : 
     923                 :     278015 :   if (current_loops != NULL)
     924                 :            :     {
     925                 :            :       /* If we do not split a loop header, then both blocks belong to the
     926                 :            :          same loop.  In case we split loop header and do not redirect the
     927                 :            :          latch edge to DUMMY, then DUMMY belongs to the outer loop, and
     928                 :            :          BB becomes the new header.  If latch is not recorded for the loop,
     929                 :            :          we leave this updating on the caller (this may only happen during
     930                 :            :          loop analysis).  */
     931                 :     278015 :       loop = dummy->loop_father;
     932                 :     278015 :       if (loop->header == dummy
     933                 :     277636 :           && loop->latch != NULL
     934                 :     367847 :           && find_edge (loop->latch, dummy) == NULL)
     935                 :            :         {
     936                 :      89808 :           remove_bb_from_loops (dummy);
     937                 :      89808 :           loop->header = bb;
     938                 :            : 
     939                 :      89808 :           cloop = loop;
     940                 :     303874 :           FOR_EACH_EDGE (e, ei, dummy->preds)
     941                 :            :             {
     942                 :     214066 :               cloop = find_common_loop (cloop, e->src->loop_father);
     943                 :            :             }
     944                 :      89808 :           add_bb_to_loop (dummy, cloop);
     945                 :            :         }
     946                 :            : 
     947                 :            :       /* In case we split loop latch, update it.  */
     948                 :    1249780 :       for (ploop = loop; ploop; ploop = loop_outer (ploop))
     949                 :     624889 :         if (ploop->latch == dummy)
     950                 :          0 :           ploop->latch = bb;
     951                 :            :     }
     952                 :            : 
     953                 :     278015 :   cfg_hooks->make_forwarder_block (fallthru);
     954                 :            : 
     955                 :     278015 :   return fallthru;
     956                 :            : }
     957                 :            : 
     958                 :            : /* Try to make the edge fallthru.  */
     959                 :            : 
     960                 :            : void
     961                 :     311933 : tidy_fallthru_edge (edge e)
     962                 :            : {
     963                 :     311933 :   if (cfg_hooks->tidy_fallthru_edge)
     964                 :     311933 :     cfg_hooks->tidy_fallthru_edge (e);
     965                 :     311933 : }
     966                 :            : 
     967                 :            : /* Fix up edges that now fall through, or rather should now fall through
     968                 :            :    but previously required a jump around now deleted blocks.  Simplify
     969                 :            :    the search by only examining blocks numerically adjacent, since this
     970                 :            :    is how they were created.
     971                 :            : 
     972                 :            :    ??? This routine is currently RTL specific.  */
     973                 :            : 
     974                 :            : void
     975                 :     308813 : tidy_fallthru_edges (void)
     976                 :            : {
     977                 :     308813 :   basic_block b, c;
     978                 :            : 
     979                 :     308813 :   if (!cfg_hooks->tidy_fallthru_edge)
     980                 :            :     return;
     981                 :            : 
     982                 :      82972 :   if (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
     983                 :            :     return;
     984                 :            : 
     985                 :    1627960 :   FOR_BB_BETWEEN (b, ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb,
     986                 :            :                   EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb, next_bb)
     987                 :            :     {
     988                 :    1544990 :       edge s;
     989                 :            : 
     990                 :    1544990 :       c = b->next_bb;
     991                 :            : 
     992                 :            :       /* We care about simple conditional or unconditional jumps with
     993                 :            :          a single successor.
     994                 :            : 
     995                 :            :          If we had a conditional branch to the next instruction when
     996                 :            :          CFG was built, then there will only be one out edge for the
     997                 :            :          block which ended with the conditional branch (since we do
     998                 :            :          not create duplicate edges).
     999                 :            : 
    1000                 :            :          Furthermore, the edge will be marked as a fallthru because we
    1001                 :            :          merge the flags for the duplicate edges.  So we do not want to
    1002                 :            :          check that the edge is not a FALLTHRU edge.  */
    1003                 :            : 
    1004                 :    1544990 :       if (single_succ_p (b))
    1005                 :            :         {
    1006                 :     668691 :           s = single_succ_edge (b);
    1007                 :     668691 :           if (! (s->flags & EDGE_COMPLEX)
    1008                 :     636821 :               && s->dest == c
    1009                 :     982744 :               && !(JUMP_P (BB_END (b)) && CROSSING_JUMP_P (BB_END (b))))
    1010                 :     305978 :             tidy_fallthru_edge (s);
    1011                 :            :         }
    1012                 :            :     }
    1013                 :            : }
    1014                 :            : 
    1015                 :            : /* Edge E is assumed to be fallthru edge.  Emit needed jump instruction
    1016                 :            :    (and possibly create new basic block) to make edge non-fallthru.
    1017                 :            :    Return newly created BB or NULL if none.  */
    1018                 :            : 
    1019                 :            : basic_block
    1020                 :     513678 : force_nonfallthru (edge e)
    1021                 :            : {
    1022                 :     513678 :   basic_block ret, src = e->src;
    1023                 :            : 
    1024                 :     513678 :   if (!cfg_hooks->force_nonfallthru)
    1025                 :          0 :     internal_error ("%s does not support force_nonfallthru",
    1026                 :            :                     cfg_hooks->name);
    1027                 :            : 
    1028                 :     513678 :   ret = cfg_hooks->force_nonfallthru (e);
    1029                 :     513678 :   if (ret != NULL)
    1030                 :            :     {
    1031                 :     103549 :       if (dom_info_available_p (CDI_DOMINATORS))
    1032                 :       2661 :         set_immediate_dominator (CDI_DOMINATORS, ret, src);
    1033                 :            : 
    1034                 :     103549 :       if (current_loops != NULL)
    1035                 :            :         {
    1036                 :      36720 :           basic_block pred = single_pred (ret);
    1037                 :      36720 :           basic_block succ = single_succ (ret);
    1038                 :      36720 :           class loop *loop
    1039                 :      36720 :             = find_common_loop (pred->loop_father, succ->loop_father);
    1040                 :      36720 :           rescan_loop_exit (e, false, true);
    1041                 :      36720 :           add_bb_to_loop (ret, loop);
    1042                 :            : 
    1043                 :            :           /* If we split the latch edge of loop adjust the latch block.  */
    1044                 :      36720 :           if (loop->latch == pred
    1045                 :       2157 :               && loop->header == succ)
    1046                 :       2157 :             loop->latch = ret;
    1047                 :            :         }
    1048                 :            :     }
    1049                 :            : 
    1050                 :     513678 :   return ret;
    1051                 :            : }
    1052                 :            : 
    1053                 :            : /* Returns true if we can duplicate basic block BB.  */
    1054                 :            : 
    1055                 :            : bool
    1056                 :    5645590 : can_duplicate_block_p (const_basic_block bb)
    1057                 :            : {
    1058                 :    5645590 :   if (!cfg_hooks->can_duplicate_block_p)
    1059                 :          0 :     internal_error ("%s does not support can_duplicate_block_p",
    1060                 :            :                     cfg_hooks->name);
    1061                 :            : 
    1062                 :    5645590 :   if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun) || bb == ENTRY_BLOCK_PTR_FOR_FN (cfun))
    1063                 :            :     return false;
    1064                 :            : 
    1065                 :    5645590 :   return cfg_hooks->can_duplicate_block_p (bb);
    1066                 :            : }
    1067                 :            : 
    1068                 :            : /* Duplicates basic block BB and redirects edge E to it.  Returns the
    1069                 :            :    new basic block.  The new basic block is placed after the basic block
    1070                 :            :    AFTER.  */
    1071                 :            : 
    1072                 :            : basic_block
    1073                 :    2038880 : duplicate_block (basic_block bb, edge e, basic_block after, copy_bb_data *id)
    1074                 :            : {
    1075                 :    2038880 :   edge s, n;
    1076                 :    2038880 :   basic_block new_bb;
    1077                 :    2038880 :   profile_count new_count = e ? e->count (): profile_count::uninitialized ();
    1078                 :    2038880 :   edge_iterator ei;
    1079                 :            : 
    1080                 :    2038880 :   if (!cfg_hooks->duplicate_block)
    1081                 :          0 :     internal_error ("%s does not support duplicate_block",
    1082                 :            :                     cfg_hooks->name);
    1083                 :            : 
    1084                 :    2038880 :   if (bb->count < new_count)
    1085                 :       1364 :     new_count = bb->count;
    1086                 :            : 
    1087                 :    2038880 :   gcc_checking_assert (can_duplicate_block_p (bb));
    1088                 :            : 
    1089                 :    2038880 :   new_bb = cfg_hooks->duplicate_block (bb, id);
    1090                 :    2038880 :   if (after)
    1091                 :    1493330 :     move_block_after (new_bb, after);
    1092                 :            : 
    1093                 :    2038880 :   new_bb->flags = (bb->flags & ~BB_DUPLICATED);
    1094                 :    5605860 :   FOR_EACH_EDGE (s, ei, bb->succs)
    1095                 :            :     {
    1096                 :            :       /* Since we are creating edges from a new block to successors
    1097                 :            :          of another block (which therefore are known to be disjoint), there
    1098                 :            :          is no need to actually check for duplicated edges.  */
    1099                 :    3566980 :       n = unchecked_make_edge (new_bb, s->dest, s->flags);
    1100                 :    3566980 :       n->probability = s->probability;
    1101                 :    3566980 :       n->aux = s->aux;
    1102                 :            :     }
    1103                 :            : 
    1104                 :    2038880 :   if (e)
    1105                 :            :     {
    1106                 :     164081 :       new_bb->count = new_count;
    1107                 :     164081 :       bb->count -= new_count;
    1108                 :            : 
    1109                 :     164081 :       redirect_edge_and_branch_force (e, new_bb);
    1110                 :            :     }
    1111                 :            :   else
    1112                 :    1874800 :     new_bb->count = bb->count;
    1113                 :            : 
    1114                 :    2038880 :   set_bb_original (new_bb, bb);
    1115                 :    2038880 :   set_bb_copy (bb, new_bb);
    1116                 :            : 
    1117                 :            :   /* Add the new block to the copy of the loop of BB, or directly to the loop
    1118                 :            :      of BB if the loop is not being copied.  */
    1119                 :    2038880 :   if (current_loops != NULL)
    1120                 :            :     {
    1121                 :    1872840 :       class loop *cloop = bb->loop_father;
    1122                 :    1872840 :       class loop *copy = get_loop_copy (cloop);
    1123                 :            :       /* If we copied the loop header block but not the loop
    1124                 :            :          we have created a loop with multiple entries.  Ditch the loop,
    1125                 :            :          add the new block to the outer loop and arrange for a fixup.  */
    1126                 :    1872840 :       if (!copy
    1127                 :     429994 :           && cloop->header == bb)
    1128                 :            :         {
    1129                 :       3218 :           add_bb_to_loop (new_bb, loop_outer (cloop));
    1130                 :       1609 :           mark_loop_for_removal (cloop);
    1131                 :            :         }
    1132                 :            :       else
    1133                 :            :         {
    1134                 :    2299620 :           add_bb_to_loop (new_bb, copy ? copy : cloop);
    1135                 :            :           /* If we copied the loop latch block but not the loop, adjust
    1136                 :            :              loop state.  */
    1137                 :    1871230 :           if (!copy
    1138                 :     428385 :               && cloop->latch == bb)
    1139                 :            :             {
    1140                 :       1393 :               cloop->latch = NULL;
    1141                 :       1393 :               loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
    1142                 :            :             }
    1143                 :            :         }
    1144                 :            :     }
    1145                 :            : 
    1146                 :    2038880 :   return new_bb;
    1147                 :            : }
    1148                 :            : 
    1149                 :            : /* Return 1 if BB ends with a call, possibly followed by some
    1150                 :            :    instructions that must stay with the call, 0 otherwise.  */
    1151                 :            : 
    1152                 :            : bool
    1153                 :    6240780 : block_ends_with_call_p (basic_block bb)
    1154                 :            : {
    1155                 :    6240780 :   if (!cfg_hooks->block_ends_with_call_p)
    1156                 :          0 :     internal_error ("%s does not support block_ends_with_call_p", cfg_hooks->name);
    1157                 :            : 
    1158                 :    6240780 :   return (cfg_hooks->block_ends_with_call_p) (bb);
    1159                 :            : }
    1160                 :            : 
    1161                 :            : /* Return 1 if BB ends with a conditional branch, 0 otherwise.  */
    1162                 :            : 
    1163                 :            : bool
    1164                 :       1636 : block_ends_with_condjump_p (const_basic_block bb)
    1165                 :            : {
    1166                 :       1636 :   if (!cfg_hooks->block_ends_with_condjump_p)
    1167                 :          0 :     internal_error ("%s does not support block_ends_with_condjump_p",
    1168                 :            :                     cfg_hooks->name);
    1169                 :            : 
    1170                 :       1636 :   return (cfg_hooks->block_ends_with_condjump_p) (bb);
    1171                 :            : }
    1172                 :            : 
    1173                 :            : /* Add fake edges to the function exit for any non constant and non noreturn
    1174                 :            :    calls, volatile inline assembly in the bitmap of blocks specified by
    1175                 :            :    BLOCKS or to the whole CFG if BLOCKS is zero.  Return the number of blocks
    1176                 :            :    that were split.
    1177                 :            : 
    1178                 :            :    The goal is to expose cases in which entering a basic block does not imply
    1179                 :            :    that all subsequent instructions must be executed.  */
    1180                 :            : 
    1181                 :            : int
    1182                 :       2054 : flow_call_edges_add (sbitmap blocks)
    1183                 :            : {
    1184                 :       2054 :   if (!cfg_hooks->flow_call_edges_add)
    1185                 :          0 :     internal_error ("%s does not support flow_call_edges_add",
    1186                 :            :                     cfg_hooks->name);
    1187                 :            : 
    1188                 :       2054 :   return (cfg_hooks->flow_call_edges_add) (blocks);
    1189                 :            : }
    1190                 :            : 
    1191                 :            : /* This function is called immediately after edge E is added to the
    1192                 :            :    edge vector E->dest->preds.  */
    1193                 :            : 
    1194                 :            : void
    1195                 :  109955000 : execute_on_growing_pred (edge e)
    1196                 :            : {
    1197                 :  109955000 :   if (! (e->dest->flags & BB_DUPLICATED)
    1198                 :  109090000 :       && cfg_hooks->execute_on_growing_pred)
    1199                 :   84253600 :     cfg_hooks->execute_on_growing_pred (e);
    1200                 :  109955000 : }
    1201                 :            : 
    1202                 :            : /* This function is called immediately before edge E is removed from
    1203                 :            :    the edge vector E->dest->preds.  */
    1204                 :            : 
    1205                 :            : void
    1206                 :   91013100 : execute_on_shrinking_pred (edge e)
    1207                 :            : {
    1208                 :   91013100 :   if (! (e->dest->flags & BB_DUPLICATED)
    1209                 :   90147700 :       && cfg_hooks->execute_on_shrinking_pred)
    1210                 :   66934100 :     cfg_hooks->execute_on_shrinking_pred (e);
    1211                 :   91013100 : }
    1212                 :            : 
    1213                 :            : /* This is used inside loop versioning when we want to insert
    1214                 :            :    stmts/insns on the edges, which have a different behavior
    1215                 :            :    in tree's and in RTL, so we made a CFG hook.  */
    1216                 :            : void
    1217                 :      18090 : lv_flush_pending_stmts (edge e)
    1218                 :            : {
    1219                 :      18090 :   if (cfg_hooks->flush_pending_stmts)
    1220                 :      18090 :     cfg_hooks->flush_pending_stmts (e);
    1221                 :      18090 : }
    1222                 :            : 
    1223                 :            : /* Loop versioning uses the duplicate_loop_to_header_edge to create
    1224                 :            :    a new version of the loop basic-blocks, the parameters here are
    1225                 :            :    exactly the same as in duplicate_loop_to_header_edge or
    1226                 :            :    tree_duplicate_loop_to_header_edge; while in tree-ssa there is
    1227                 :            :    additional work to maintain ssa information that's why there is
    1228                 :            :    a need to call the tree_duplicate_loop_to_header_edge rather
    1229                 :            :    than duplicate_loop_to_header_edge when we are in tree mode.  */
    1230                 :            : bool
    1231                 :       9054 : cfg_hook_duplicate_loop_to_header_edge (class loop *loop, edge e,
    1232                 :            :                                         unsigned int ndupl,
    1233                 :            :                                         sbitmap wont_exit, edge orig,
    1234                 :            :                                         vec<edge> *to_remove,
    1235                 :            :                                         int flags)
    1236                 :            : {
    1237                 :       9054 :   gcc_assert (cfg_hooks->cfg_hook_duplicate_loop_to_header_edge);
    1238                 :       9054 :   return cfg_hooks->cfg_hook_duplicate_loop_to_header_edge (loop, e,
    1239                 :            :                                                             ndupl, wont_exit,
    1240                 :            :                                                             orig, to_remove,
    1241                 :       9054 :                                                             flags);
    1242                 :            : }
    1243                 :            : 
    1244                 :            : /* Conditional jumps are represented differently in trees and RTL,
    1245                 :            :    this hook takes a basic block that is known to have a cond jump
    1246                 :            :    at its end and extracts the taken and not taken edges out of it
    1247                 :            :    and store it in E1 and E2 respectively.  */
    1248                 :            : void
    1249                 :      18090 : extract_cond_bb_edges (basic_block b, edge *e1, edge *e2)
    1250                 :            : {
    1251                 :      18090 :   gcc_assert (cfg_hooks->extract_cond_bb_edges);
    1252                 :      18090 :   cfg_hooks->extract_cond_bb_edges (b, e1, e2);
    1253                 :      18090 : }
    1254                 :            : 
    1255                 :            : /* Responsible for updating the ssa info (PHI nodes) on the
    1256                 :            :    new condition basic block that guards the versioned loop.  */
    1257                 :            : void
    1258                 :       9045 : lv_adjust_loop_header_phi (basic_block first, basic_block second,
    1259                 :            :                            basic_block new_block, edge e)
    1260                 :            : {
    1261                 :       9045 :   if (cfg_hooks->lv_adjust_loop_header_phi)
    1262                 :       9045 :     cfg_hooks->lv_adjust_loop_header_phi (first, second, new_block, e);
    1263                 :       9045 : }
    1264                 :            : 
    1265                 :            : /* Conditions in trees and RTL are different so we need
    1266                 :            :    a different handling when we add the condition to the
    1267                 :            :    versioning code.  */
    1268                 :            : void
    1269                 :       9045 : lv_add_condition_to_bb (basic_block first, basic_block second,
    1270                 :            :                         basic_block new_block, void *cond)
    1271                 :            : {
    1272                 :       9045 :   gcc_assert (cfg_hooks->lv_add_condition_to_bb);
    1273                 :       9045 :   cfg_hooks->lv_add_condition_to_bb (first, second, new_block, cond);
    1274                 :       9045 : }
    1275                 :            : 
    1276                 :            : /* Checks whether all N blocks in BBS array can be copied.  */
    1277                 :            : bool
    1278                 :     636615 : can_copy_bbs_p (basic_block *bbs, unsigned n)
    1279                 :            : {
    1280                 :     636615 :   unsigned i;
    1281                 :     636615 :   edge e;
    1282                 :     636615 :   int ret = true;
    1283                 :            : 
    1284                 :    1799340 :   for (i = 0; i < n; i++)
    1285                 :    1162720 :     bbs[i]->flags |= BB_DUPLICATED;
    1286                 :            : 
    1287                 :    1799010 :   for (i = 0; i < n; i++)
    1288                 :            :     {
    1289                 :            :       /* In case we should redirect abnormal edge during duplication, fail.  */
    1290                 :    1162430 :       edge_iterator ei;
    1291                 :    3180670 :       FOR_EACH_EDGE (e, ei, bbs[i]->succs)
    1292                 :    2018270 :         if ((e->flags & EDGE_ABNORMAL)
    1293                 :        146 :             && (e->dest->flags & BB_DUPLICATED))
    1294                 :            :           {
    1295                 :         28 :             ret = false;
    1296                 :         28 :             goto end;
    1297                 :            :           }
    1298                 :            : 
    1299                 :    1162400 :       if (!can_duplicate_block_p (bbs[i]))
    1300                 :            :         {
    1301                 :         10 :           ret = false;
    1302                 :         10 :           break;
    1303                 :            :         }
    1304                 :            :     }
    1305                 :            : 
    1306                 :     636577 : end:
    1307                 :    1799340 :   for (i = 0; i < n; i++)
    1308                 :    1162720 :     bbs[i]->flags &= ~BB_DUPLICATED;
    1309                 :            : 
    1310                 :     636615 :   return ret;
    1311                 :            : }
    1312                 :            : 
    1313                 :            : /* Duplicates N basic blocks stored in array BBS.  Newly created basic blocks
    1314                 :            :    are placed into array NEW_BBS in the same order.  Edges from basic blocks
    1315                 :            :    in BBS are also duplicated and copies of those that lead into BBS are
    1316                 :            :    redirected to appropriate newly created block.  The function assigns bbs
    1317                 :            :    into loops (copy of basic block bb is assigned to bb->loop_father->copy
    1318                 :            :    loop, so this must be set up correctly in advance)
    1319                 :            : 
    1320                 :            :    If UPDATE_DOMINANCE is true then this function updates dominators locally
    1321                 :            :    (LOOPS structure that contains the information about dominators is passed
    1322                 :            :    to enable this), otherwise it does not update the dominator information
    1323                 :            :    and it assumed that the caller will do this, perhaps by destroying and
    1324                 :            :    recreating it instead of trying to do an incremental update like this
    1325                 :            :    function does when update_dominance is true.
    1326                 :            : 
    1327                 :            :    BASE is the superloop to that basic block belongs; if its header or latch
    1328                 :            :    is copied, we do not set the new blocks as header or latch.
    1329                 :            : 
    1330                 :            :    Created copies of N_EDGES edges in array EDGES are stored in array NEW_EDGES,
    1331                 :            :    also in the same order.
    1332                 :            : 
    1333                 :            :    Newly created basic blocks are put after the basic block AFTER in the
    1334                 :            :    instruction stream, and the order of the blocks in BBS array is preserved.  */
    1335                 :            : 
    1336                 :            : void
    1337                 :     772177 : copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs,
    1338                 :            :           edge *edges, unsigned num_edges, edge *new_edges,
    1339                 :            :           class loop *base, basic_block after, bool update_dominance)
    1340                 :            : {
    1341                 :     772177 :   unsigned i, j;
    1342                 :     772177 :   basic_block bb, new_bb, dom_bb;
    1343                 :     772177 :   edge e;
    1344                 :    1544350 :   copy_bb_data id;
    1345                 :            : 
    1346                 :            :   /* Mark the blocks to be copied.  This is used by edge creation hooks
    1347                 :            :      to decide whether to reallocate PHI nodes capacity to avoid reallocating
    1348                 :            :      PHIs in the set of source BBs.  */
    1349                 :    2101520 :   for (i = 0; i < n; i++)
    1350                 :    1329340 :     bbs[i]->flags |= BB_DUPLICATED;
    1351                 :            : 
    1352                 :            :   /* Duplicate bbs, update dominators, assign bbs to loops.  */
    1353                 :    2101520 :   for (i = 0; i < n; i++)
    1354                 :            :     {
    1355                 :            :       /* Duplicate.  */
    1356                 :    1329340 :       bb = bbs[i];
    1357                 :    1329340 :       new_bb = new_bbs[i] = duplicate_block (bb, NULL, after, &id);
    1358                 :    1329340 :       after = new_bb;
    1359                 :    1329340 :       if (bb->loop_father)
    1360                 :            :         {
    1361                 :            :           /* Possibly set loop header.  */
    1362                 :    1329340 :           if (bb->loop_father->header == bb && bb->loop_father != base)
    1363                 :      14972 :             new_bb->loop_father->header = new_bb;
    1364                 :            :           /* Or latch.  */
    1365                 :    1329340 :           if (bb->loop_father->latch == bb && bb->loop_father != base)
    1366                 :      14972 :             new_bb->loop_father->latch = new_bb;
    1367                 :            :         }
    1368                 :            :     }
    1369                 :            : 
    1370                 :            :   /* Set dominators.  */
    1371                 :     772177 :   if (update_dominance)
    1372                 :            :     {
    1373                 :    1453660 :       for (i = 0; i < n; i++)
    1374                 :            :         {
    1375                 :     975775 :           bb = bbs[i];
    1376                 :     975775 :           new_bb = new_bbs[i];
    1377                 :            : 
    1378                 :     975775 :           dom_bb = get_immediate_dominator (CDI_DOMINATORS, bb);
    1379                 :     975775 :           if (dom_bb->flags & BB_DUPLICATED)
    1380                 :            :             {
    1381                 :     497891 :               dom_bb = get_bb_copy (dom_bb);
    1382                 :     497891 :               set_immediate_dominator (CDI_DOMINATORS, new_bb, dom_bb);
    1383                 :            :             }
    1384                 :            :         }
    1385                 :            :     }
    1386                 :            : 
    1387                 :            :   /* Redirect edges.  */
    1388                 :    1828510 :   for (j = 0; j < num_edges; j++)
    1389                 :    1056340 :     new_edges[j] = NULL;
    1390                 :    2101520 :   for (i = 0; i < n; i++)
    1391                 :            :     {
    1392                 :    1329340 :       edge_iterator ei;
    1393                 :    1329340 :       new_bb = new_bbs[i];
    1394                 :    1329340 :       bb = bbs[i];
    1395                 :            : 
    1396                 :    3606330 :       FOR_EACH_EDGE (e, ei, new_bb->succs)
    1397                 :            :         {
    1398                 :    5707520 :           for (j = 0; j < num_edges; j++)
    1399                 :    3430530 :             if (edges[j] && edges[j]->src == bb && edges[j]->dest == e->dest)
    1400                 :    1018840 :               new_edges[j] = e;
    1401                 :            : 
    1402                 :    2276990 :           if (!(e->dest->flags & BB_DUPLICATED))
    1403                 :    1411570 :             continue;
    1404                 :     865418 :           redirect_edge_and_branch_force (e, get_bb_copy (e->dest));
    1405                 :            :         }
    1406                 :            :     }
    1407                 :            : 
    1408                 :            :   /* Clear information about duplicates.  */
    1409                 :    2101520 :   for (i = 0; i < n; i++)
    1410                 :    1329340 :     bbs[i]->flags &= ~BB_DUPLICATED;
    1411                 :     772177 : }
    1412                 :            : 
    1413                 :            : /* Return true if BB contains only labels or non-executable
    1414                 :            :    instructions */
    1415                 :            : bool
    1416                 :    6425790 : empty_block_p (basic_block bb)
    1417                 :            : {
    1418                 :    6425790 :   gcc_assert (cfg_hooks->empty_block_p);
    1419                 :    6425790 :   return cfg_hooks->empty_block_p (bb);
    1420                 :            : }
    1421                 :            : 
    1422                 :            : /* Split a basic block if it ends with a conditional branch and if
    1423                 :            :    the other part of the block is not empty.  */
    1424                 :            : basic_block
    1425                 :        540 : split_block_before_cond_jump (basic_block bb)
    1426                 :            : {
    1427                 :        540 :   gcc_assert (cfg_hooks->split_block_before_cond_jump);
    1428                 :        540 :   return cfg_hooks->split_block_before_cond_jump (bb);
    1429                 :            : }
    1430                 :            : 
    1431                 :            : /* Work-horse for passes.c:check_profile_consistency.
    1432                 :            :    Do book-keeping of the CFG for the profile consistency checker.
    1433                 :            :    Store the counting in RECORD.  */
    1434                 :            : 
    1435                 :            : void
    1436                 :          0 : profile_record_check_consistency (profile_record *record)
    1437                 :            : {
    1438                 :          0 :   basic_block bb;
    1439                 :          0 :   edge_iterator ei;
    1440                 :          0 :   edge e;
    1441                 :            : 
    1442                 :          0 :   FOR_ALL_BB_FN (bb, cfun)
    1443                 :            :    {
    1444                 :          0 :       if (bb != EXIT_BLOCK_PTR_FOR_FN (cfun)
    1445                 :          0 :           && profile_status_for_fn (cfun) != PROFILE_ABSENT)
    1446                 :            :         {
    1447                 :          0 :           profile_probability sum = profile_probability::never ();
    1448                 :          0 :           FOR_EACH_EDGE (e, ei, bb->succs)
    1449                 :          0 :             sum += e->probability;
    1450                 :          0 :           if (EDGE_COUNT (bb->succs)
    1451                 :          0 :               && sum.differs_from_p (profile_probability::always ()))
    1452                 :          0 :             record->num_mismatched_freq_out++;
    1453                 :          0 :           profile_count lsum = profile_count::zero ();
    1454                 :          0 :           FOR_EACH_EDGE (e, ei, bb->succs)
    1455                 :          0 :             lsum += e->count ();
    1456                 :          0 :           if (EDGE_COUNT (bb->succs) && (lsum.differs_from_p (bb->count)))
    1457                 :          0 :             record->num_mismatched_count_out++;
    1458                 :            :         }
    1459                 :          0 :       if (bb != ENTRY_BLOCK_PTR_FOR_FN (cfun)
    1460                 :          0 :           && profile_status_for_fn (cfun) != PROFILE_ABSENT)
    1461                 :            :         {
    1462                 :          0 :           profile_probability sum = profile_probability::never ();
    1463                 :          0 :           profile_count lsum = profile_count::zero ();
    1464                 :          0 :           FOR_EACH_EDGE (e, ei, bb->preds)
    1465                 :            :             {
    1466                 :          0 :               sum += e->probability;
    1467                 :          0 :               lsum += e->count ();
    1468                 :            :             }
    1469                 :          0 :           if (EDGE_COUNT (bb->preds)
    1470                 :          0 :               && sum.differs_from_p (profile_probability::always ()))
    1471                 :          0 :             record->num_mismatched_freq_in++;
    1472                 :          0 :           if (lsum.differs_from_p (bb->count))
    1473                 :          0 :             record->num_mismatched_count_in++;
    1474                 :            :         }
    1475                 :          0 :       if (bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)
    1476                 :          0 :           || bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
    1477                 :          0 :         continue;
    1478                 :          0 :       gcc_assert (cfg_hooks->account_profile_record);
    1479                 :          0 :       cfg_hooks->account_profile_record (bb, record);
    1480                 :            :    }
    1481                 :          0 : }
    1482                 :            : 
    1483                 :            : /* Work-horse for passes.c:acount_profile.
    1484                 :            :    Do book-keeping of the CFG for the profile accounting.
    1485                 :            :    Store the counting in RECORD.  */
    1486                 :            : 
    1487                 :            : void
    1488                 :          0 : profile_record_account_profile (profile_record *record)
    1489                 :            : {
    1490                 :          0 :   basic_block bb;
    1491                 :            : 
    1492                 :          0 :   FOR_ALL_BB_FN (bb, cfun)
    1493                 :            :    {
    1494                 :          0 :       gcc_assert (cfg_hooks->account_profile_record);
    1495                 :          0 :       cfg_hooks->account_profile_record (bb, record);
    1496                 :            :    }
    1497                 :          0 : }
    1498                 :            : 
    1499                 :            : #if __GNUC__ >= 10
    1500                 :            : #  pragma GCC diagnostic pop
    1501                 :            : #endif

Generated by: LCOV version 1.0

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 --enable-host-shared. GCC test suite is run with the built compiler.