LCOV - code coverage report
Current view: top level - gcc - cfghooks.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 76.6 % 727 557
Test Date: 2026-05-11 19:44:49 Functions: 78.5 % 65 51
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Hooks for cfg representation specific functions.
       2              :    Copyright (C) 2003-2026 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              : #define INCLUDE_VECTOR
      22              : #include "config.h"
      23              : #include "system.h"
      24              : #include "coretypes.h"
      25              : #include "backend.h"
      26              : #include "rtl.h"
      27              : #include "cfghooks.h"
      28              : #include "timevar.h"
      29              : #include "pretty-print.h"
      30              : #include "diagnostic-core.h"
      31              : #include "dumpfile.h"
      32              : #include "cfganal.h"
      33              : #include "tree.h"
      34              : #include "tree-ssa.h"
      35              : #include "cfgloop.h"
      36              : #include "sreal.h"
      37              : #include "profile.h"
      38              : #include "diagnostics/sarif-sink.h"
      39              : #include "custom-sarif-properties/cfg.h"
      40              : 
      41              : /* Disable warnings about missing quoting in GCC diagnostics.  */
      42              : #if __GNUC__ >= 10
      43              : #  pragma GCC diagnostic push
      44              : #  pragma GCC diagnostic ignored "-Wformat-diag"
      45              : #endif
      46              : 
      47              : /* A pointer to one of the hooks containers.  */
      48              : static const struct cfg_hooks *cfg_hooks;
      49              : 
      50              : /* Initialization of functions specific to the rtl IR.  */
      51              : void
      52      3991514 : rtl_register_cfg_hooks (void)
      53              : {
      54      3991514 :   cfg_hooks = &rtl_cfg_hooks;
      55      3991514 : }
      56              : 
      57              : /* Initialization of functions specific to the rtl IR.  */
      58              : void
      59      2516221 : cfg_layout_rtl_register_cfg_hooks (void)
      60              : {
      61      2516221 :   cfg_hooks = &cfg_layout_rtl_cfg_hooks;
      62      2516221 : }
      63              : 
      64              : /* Initialization of functions specific to the tree IR.  */
      65              : 
      66              : void
      67     14336459 : gimple_register_cfg_hooks (void)
      68              : {
      69     14336459 :   cfg_hooks = &gimple_cfg_hooks;
      70     14336459 : }
      71              : 
      72              : const struct cfg_hooks *
      73          742 : get_cfg_hooks (void)
      74              : {
      75          742 :   return cfg_hooks;
      76              : }
      77              : 
      78              : void
      79         1484 : set_cfg_hooks (const struct cfg_hooks *new_cfg_hooks)
      80              : {
      81         1484 :   cfg_hooks = new_cfg_hooks;
      82         1484 : }
      83              : 
      84              : /* Returns current ir type.  */
      85              : 
      86              : enum ir_type
      87    272976347 : current_ir_type (void)
      88              : {
      89    272976347 :   return cfg_hooks->ir;
      90              : }
      91              : 
      92              : static const char *
      93            0 : current_ir_name (void)
      94              : {
      95            0 :   enum ir_type ir = cfg_hooks->ir;
      96            0 :   switch (ir)
      97              :     {
      98              :     case IR_GIMPLE:
      99              :       return "gimple";
     100            0 :     case IR_RTL_CFGRTL:
     101            0 :       return "rtl";
     102            0 :     case IR_RTL_CFGLAYOUT:
     103            0 :       return "cfglayout mode";
     104            0 :     default:
     105            0 :       gcc_unreachable();
     106              :     }
     107              : }
     108              : 
     109              : /* Verify the CFG consistency.
     110              : 
     111              :    Currently it does following: checks edge and basic block list correctness
     112              :    and calls into IL dependent checking then.  */
     113              : 
     114              : DEBUG_FUNCTION void
     115    326560146 : verify_flow_info (void)
     116              : {
     117    326560146 :   size_t *edge_checksum;
     118    326560146 :   bool err = false;
     119    326560146 :   basic_block bb, last_bb_seen;
     120    326560146 :   basic_block *last_visited;
     121              : 
     122    326560146 :   timevar_push (TV_CFG_VERIFY);
     123    326560146 :   last_visited = XCNEWVEC (basic_block, last_basic_block_for_fn (cfun));
     124    326560146 :   edge_checksum = XCNEWVEC (size_t, last_basic_block_for_fn (cfun));
     125              : 
     126              :   /* Check bb chain & numbers.  */
     127    326560146 :   last_bb_seen = ENTRY_BLOCK_PTR_FOR_FN (cfun);
     128   3671343772 :   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb, NULL, next_bb)
     129              :     {
     130   3344783626 :       if (bb != EXIT_BLOCK_PTR_FOR_FN (cfun)
     131   3344783626 :           && bb != BASIC_BLOCK_FOR_FN (cfun, bb->index))
     132              :         {
     133            0 :           error ("bb %d on wrong place", bb->index);
     134            0 :           err = true;
     135              :         }
     136              : 
     137   3344783626 :       if (bb->prev_bb != last_bb_seen)
     138              :         {
     139            0 :           error ("prev_bb of %d should be %d, not %d",
     140              :                  bb->index, last_bb_seen->index, bb->prev_bb->index);
     141            0 :           err = true;
     142              :         }
     143              : 
     144   3344783626 :       last_bb_seen = bb;
     145              :     }
     146              : 
     147              :   /* Now check the basic blocks (boundaries etc.) */
     148   3344783626 :   FOR_EACH_BB_REVERSE_FN (bb, cfun)
     149              :     {
     150   3018223480 :       int n_fallthru = 0;
     151   3018223480 :       edge e;
     152   3018223480 :       edge_iterator ei;
     153              : 
     154   3018223480 :       if (bb->loop_father != NULL && current_loops == NULL)
     155              :         {
     156            0 :           error ("verify_flow_info: Block %i has loop_father, but there are no loops",
     157              :                  bb->index);
     158            0 :           err = true;
     159              :         }
     160   3018223480 :       if (bb->loop_father == NULL && current_loops != NULL)
     161              :         {
     162            0 :           error ("verify_flow_info: Block %i lacks loop_father", bb->index);
     163            0 :           err = true;
     164              :         }
     165              : 
     166   3018223480 :       if (!bb->count.verify ())
     167              :         {
     168            0 :           error ("verify_flow_info: Wrong count of block %i", bb->index);
     169            0 :           err = true;
     170              :         }
     171              :       /* FIXME: Graphite and SLJL and target code still tends to produce
     172              :          edges with no probability.  */
     173   3018223480 :       if (profile_status_for_fn (cfun) >= PROFILE_GUESSED
     174              :           && !bb->count.initialized_p () && !flag_graphite && 0)
     175              :         {
     176              :           error ("verify_flow_info: Missing count of block %i", bb->index);
     177              :           err = true;
     178              :         }
     179              : 
     180   3018223480 :       if (bb->flags & ~cfun->cfg->bb_flags_allocated)
     181              :         {
     182            0 :           error ("verify_flow_info: unallocated flag set on BB %d", bb->index);
     183            0 :           err = true;
     184              :         }
     185              : 
     186   7296483892 :       FOR_EACH_EDGE (e, ei, bb->succs)
     187              :         {
     188   4278260412 :           if (last_visited [e->dest->index] == bb)
     189              :             {
     190            0 :               error ("verify_flow_info: Duplicate edge %i->%i",
     191            0 :                      e->src->index, e->dest->index);
     192            0 :               err = true;
     193              :             }
     194              :           /* FIXME: Graphite and SLJL and target code still tends to produce
     195              :              edges with no probability.  */
     196   4278260412 :           if (profile_status_for_fn (cfun) >= PROFILE_GUESSED
     197              :               && !e->probability.initialized_p () && !flag_graphite && 0)
     198              :             {
     199              :               error ("Uninitialized probability of edge %i->%i", e->src->index,
     200              :                      e->dest->index);
     201              :               err = true;
     202              :             }
     203   4278260412 :           if (!e->probability.verify ())
     204              :             {
     205            0 :               error ("verify_flow_info: Wrong probability of edge %i->%i",
     206            0 :                      e->src->index, e->dest->index);
     207            0 :               err = true;
     208              :             }
     209              : 
     210   4278260412 :           last_visited [e->dest->index] = bb;
     211              : 
     212   4278260412 :           if (e->flags & EDGE_FALLTHRU)
     213   1635595135 :             n_fallthru++;
     214              : 
     215   4278260412 :           if (e->src != bb)
     216              :             {
     217            0 :               error ("verify_flow_info: Basic block %d succ edge is corrupted",
     218              :                      bb->index);
     219            0 :               fprintf (stderr, "Predecessor: ");
     220            0 :               dump_edge_info (stderr, e, TDF_DETAILS, 0);
     221            0 :               fprintf (stderr, "\nSuccessor: ");
     222            0 :               dump_edge_info (stderr, e, TDF_DETAILS, 1);
     223            0 :               fprintf (stderr, "\n");
     224            0 :               err = true;
     225              :             }
     226              : 
     227   4278260412 :           if (e->flags & ~cfun->cfg->edge_flags_allocated)
     228              :             {
     229            0 :               error ("verify_flow_info: unallocated edge flag set on %d -> %d",
     230            0 :                      e->src->index, e->dest->index);
     231            0 :               err = true;
     232              :             }
     233              : 
     234   4278260412 :           edge_checksum[e->dest->index] += (size_t) e;
     235              :         }
     236   3018223480 :       if (n_fallthru > 1)
     237              :         {
     238            0 :           error ("wrong amount of branch edges after unconditional jump %i", bb->index);
     239            0 :           err = true;
     240              :         }
     241              : 
     242   7293991467 :       FOR_EACH_EDGE (e, ei, bb->preds)
     243              :         {
     244   4275767987 :           if (e->dest != bb)
     245              :             {
     246            0 :               error ("basic block %d pred edge is corrupted", bb->index);
     247            0 :               fputs ("Predecessor: ", stderr);
     248            0 :               dump_edge_info (stderr, e, TDF_DETAILS, 0);
     249            0 :               fputs ("\nSuccessor: ", stderr);
     250            0 :               dump_edge_info (stderr, e, TDF_DETAILS, 1);
     251            0 :               fputc ('\n', stderr);
     252            0 :               err = true;
     253              :             }
     254              : 
     255   4275767987 :           if (ei.index != e->dest_idx)
     256              :             {
     257            0 :               error ("basic block %d pred edge is corrupted", bb->index);
     258            0 :               error ("its dest_idx should be %d, not %d",
     259              :                      ei.index, e->dest_idx);
     260            0 :               fputs ("Predecessor: ", stderr);
     261            0 :               dump_edge_info (stderr, e, TDF_DETAILS, 0);
     262            0 :               fputs ("\nSuccessor: ", stderr);
     263            0 :               dump_edge_info (stderr, e, TDF_DETAILS, 1);
     264            0 :               fputc ('\n', stderr);
     265            0 :               err = true;
     266              :             }
     267              : 
     268   4275767987 :           edge_checksum[e->dest->index] -= (size_t) e;
     269              :         }
     270              :     }
     271              : 
     272              :   /* Complete edge checksumming for ENTRY and EXIT.  */
     273    326560146 :   {
     274    326560146 :     edge e;
     275    326560146 :     edge_iterator ei;
     276              : 
     277    653120292 :     FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs)
     278    326560146 :       edge_checksum[e->dest->index] += (size_t) e;
     279              : 
     280    655612717 :     FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
     281    329052571 :       edge_checksum[e->dest->index] -= (size_t) e;
     282              :   }
     283              : 
     284   3997903918 :   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
     285   3671343772 :     if (edge_checksum[bb->index])
     286              :       {
     287            0 :         error ("basic block %i edge lists are corrupted", bb->index);
     288            0 :         err = true;
     289              :       }
     290              : 
     291              :   /* Clean up.  */
     292    326560146 :   free (last_visited);
     293    326560146 :   free (edge_checksum);
     294              : 
     295    326560146 :   if (cfg_hooks->verify_flow_info)
     296    326560146 :     if (cfg_hooks->verify_flow_info ())
     297              :       err = true;
     298              : 
     299    326560146 :   if (err)
     300            0 :     internal_error ("verify_flow_info failed");
     301    326560146 :   timevar_pop (TV_CFG_VERIFY);
     302    326560146 : }
     303              : 
     304              : /* Print out one basic block BB to file OUTF.  INDENT is printed at the
     305              :    start of each new line.  FLAGS are the TDF_* flags in dumpfile.h.
     306              : 
     307              :    This function takes care of the purely graph related information.
     308              :    The cfg hook for the active representation should dump
     309              :    representation-specific information.  */
     310              : 
     311              : void
     312       299937 : dump_bb (FILE *outf, basic_block bb, int indent, dump_flags_t flags)
     313              : {
     314       299937 :   if (flags & TDF_BLOCKS)
     315        46906 :     dump_bb_info (outf, bb, indent, flags, true, false);
     316       299937 :   if (cfg_hooks->dump_bb)
     317       299937 :     cfg_hooks->dump_bb (outf, bb, indent, flags);
     318       299937 :   if (flags & TDF_BLOCKS)
     319        46906 :     dump_bb_info (outf, bb, indent, flags, false, true);
     320       299937 :   fputc ('\n', outf);
     321       299937 : }
     322              : 
     323              : DEBUG_FUNCTION void
     324            0 : debug (basic_block_def &ref)
     325              : {
     326            0 :   dump_bb (stderr, &ref, 0, TDF_NONE);
     327            0 : }
     328              : 
     329              : DEBUG_FUNCTION void
     330            0 : debug (basic_block_def *ptr)
     331              : {
     332            0 :   if (ptr)
     333            0 :     debug (*ptr);
     334              :   else
     335            0 :     fprintf (stderr, "<nil>\n");
     336            0 : }
     337              : 
     338              : static void
     339            0 : debug_slim (basic_block ptr)
     340              : {
     341            0 :   fprintf (stderr, "<basic_block %p (%d)>", (void *) ptr, ptr->index);
     342            0 : }
     343              : 
     344            0 : DEFINE_DEBUG_VEC (basic_block_def *)
     345            0 : DEFINE_DEBUG_HASH_SET (basic_block_def *)
     346              : 
     347              : /* Dumps basic block BB to pretty-printer PP, for use as a label of
     348              :    a DOT graph record-node.  The implementation of this hook is
     349              :    expected to write the label to the stream that is attached to PP.
     350              :    Field separators between instructions are pipe characters printed
     351              :    verbatim.  Instructions should be written with some characters
     352              :    escaped, using pp_write_text_as_dot_label_to_stream().  */
     353              : 
     354              : void
     355          451 : dump_bb_for_graph (pretty_printer *pp, basic_block bb)
     356              : {
     357          451 :   if (!cfg_hooks->dump_bb_for_graph)
     358            0 :     internal_error ("%s does not support dump_bb_for_graph",
     359              :                     current_ir_name ());
     360              :   /* TODO: Add pretty printer for counter.  */
     361          451 :   if (bb->count.initialized_p ())
     362          352 :     pp_printf (pp, "COUNT:" "%" PRId64, bb->count.to_gcov_type ());
     363          451 :   pp_write_text_to_stream (pp);
     364          451 :   if (!(dump_flags & TDF_SLIM))
     365          451 :     cfg_hooks->dump_bb_for_graph (pp, bb);
     366          451 : }
     367              : 
     368              : void
     369          540 : dump_bb_as_sarif_properties (diagnostics::sarif_builder *builder,
     370              :                              json::object &output_bag,
     371              :                              basic_block bb)
     372              : {
     373          540 :   if (!cfg_hooks->dump_bb_for_graph)
     374            0 :     internal_error ("%s does not support dump_bb_as_sarif_properties",
     375              :                     current_ir_name ());
     376          540 :   namespace bb_property_names = custom_sarif_properties::cfg::basic_block;
     377          540 :   if (bb->index == ENTRY_BLOCK)
     378           90 :     output_bag.set_string (bb_property_names::kind, "entry");
     379          450 :   else if (bb->index == EXIT_BLOCK)
     380           90 :     output_bag.set_string (bb_property_names::kind, "exit");
     381          360 :   else if (BB_PARTITION (bb) == BB_HOT_PARTITION)
     382            0 :     output_bag.set_string (bb_property_names::kind, "hot");
     383          360 :   else if (BB_PARTITION (bb) == BB_COLD_PARTITION)
     384            0 :     output_bag.set_string (bb_property_names::kind, "cold");
     385          540 :   if (bb->count.initialized_p ())
     386              :     {
     387            0 :       pretty_printer pp;
     388            0 :       pp_printf (&pp, "%" PRId64, bb->count.to_gcov_type ());
     389            0 :       output_bag.set_string (bb_property_names::count,
     390              :                              pp_formatted_text (&pp));
     391            0 :     }
     392          540 :   cfg_hooks->dump_bb_as_sarif_properties (builder, output_bag, bb);
     393          540 : }
     394              : 
     395              : /* Dump the complete CFG to FILE.  FLAGS are the TDF_* flags in dumpfile.h.  */
     396              : void
     397          288 : dump_flow_info (FILE *file, dump_flags_t flags)
     398              : {
     399          288 :   basic_block bb;
     400              : 
     401          288 :   fprintf (file, "\n%d basic blocks, %d edges.\n", n_basic_blocks_for_fn (cfun),
     402          288 :            n_edges_for_fn (cfun));
     403         2591 :   FOR_ALL_BB_FN (bb, cfun)
     404         2303 :     dump_bb (file, bb, 0, flags);
     405              : 
     406          288 :   putc ('\n', file);
     407          288 : }
     408              : 
     409              : /* Like above, but dump to stderr.  To be called from debuggers.  */
     410              : void debug_flow_info (void);
     411              : DEBUG_FUNCTION void
     412            0 : debug_flow_info (void)
     413              : {
     414            0 :   dump_flow_info (stderr, TDF_DETAILS);
     415            0 : }
     416              : 
     417              : /* Redirect edge E to the given basic block DEST and update underlying program
     418              :    representation.  Returns edge representing redirected branch (that may not
     419              :    be equivalent to E in the case of duplicate edges being removed) or NULL
     420              :    if edge is not easily redirectable for whatever reason.  */
     421              : 
     422              : edge
     423     74517444 : redirect_edge_and_branch (edge e, basic_block dest)
     424              : {
     425     74517444 :   edge ret;
     426              : 
     427     74517444 :   if (!cfg_hooks->redirect_edge_and_branch)
     428            0 :     internal_error ("%s does not support redirect_edge_and_branch",
     429              :                     current_ir_name ());
     430              : 
     431     74517444 :   ret = cfg_hooks->redirect_edge_and_branch (e, dest);
     432              : 
     433              :   /* If RET != E, then either the redirection failed, or the edge E
     434              :      was removed since RET already lead to the same destination.  */
     435     74517444 :   if (current_loops != NULL && ret == e)
     436     61893463 :     rescan_loop_exit (e, false, false);
     437              : 
     438     74517444 :   return ret;
     439              : }
     440              : 
     441              : /* Returns true if it is possible to remove the edge E by redirecting it
     442              :    to the destination of the other edge going from its source.  */
     443              : 
     444              : bool
     445       443734 : can_remove_branch_p (const_edge e)
     446              : {
     447       443734 :   if (!cfg_hooks->can_remove_branch_p)
     448            0 :     internal_error ("%s does not support can_remove_branch_p",
     449              :                     current_ir_name ());
     450              : 
     451       443734 :   if (EDGE_COUNT (e->src->succs) != 2)
     452              :     return false;
     453              : 
     454       443734 :   return cfg_hooks->can_remove_branch_p (e);
     455              : }
     456              : 
     457              : /* Removes E, by redirecting it to the destination of the other edge going
     458              :    from its source.  Can_remove_branch_p must be true for E, hence this
     459              :    operation cannot fail.  */
     460              : 
     461              : void
     462       443792 : remove_branch (edge e)
     463              : {
     464       443792 :   edge other;
     465       443792 :   basic_block src = e->src;
     466       443792 :   int irr;
     467              : 
     468       443792 :   gcc_assert (EDGE_COUNT (e->src->succs) == 2);
     469              : 
     470       443792 :   other = EDGE_SUCC (src, EDGE_SUCC (src, 0) == e);
     471       443792 :   irr = other->flags & EDGE_IRREDUCIBLE_LOOP;
     472              : 
     473       443792 :   e = redirect_edge_and_branch (e, other->dest);
     474       443792 :   gcc_assert (e != NULL);
     475              : 
     476       443792 :   e->flags &= ~EDGE_IRREDUCIBLE_LOOP;
     477       443792 :   e->flags |= irr;
     478       443792 : }
     479              : 
     480              : /* Removes edge E from cfg.  Unlike remove_branch, it does not update IL.  */
     481              : 
     482              : void
     483     83560565 : remove_edge (edge e)
     484              : {
     485     83560565 :   if (current_loops != NULL)
     486              :     {
     487     74407139 :       rescan_loop_exit (e, false, true);
     488              : 
     489              :       /* Removal of an edge inside an irreducible region or which leads
     490              :          to an irreducible region can turn the region into a natural loop.
     491              :          In that case, ask for the loop structure fixups.
     492              : 
     493              :          FIXME: Note that LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS is not always
     494              :          set, so always ask for fixups when removing an edge in that case.  */
     495     74407139 :       if (!loops_state_satisfies_p (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
     496      7992602 :           || (e->flags & EDGE_IRREDUCIBLE_LOOP)
     497     82396823 :           || (e->dest->flags & BB_IRREDUCIBLE_LOOP))
     498     66417992 :         loops_state_set (LOOPS_NEED_FIXUP);
     499              :     }
     500              : 
     501              :   /* This is probably not needed, but it doesn't hurt.  */
     502              :   /* FIXME: This should be called via a remove_edge hook.  */
     503     83560565 :   if (current_ir_type () == IR_GIMPLE)
     504     67574662 :     redirect_edge_var_map_clear (e);
     505              : 
     506     83560565 :   remove_edge_raw (e);
     507     83560565 : }
     508              : 
     509              : /* Like redirect_edge_succ but avoid possible duplicate edge.  */
     510              : 
     511              : edge
     512     79782857 : redirect_edge_succ_nodup (edge e, basic_block new_succ)
     513              : {
     514     79782857 :   edge s;
     515              : 
     516     79782857 :   s = find_edge (e->src, new_succ);
     517     79782857 :   if (s && s != e)
     518              :     {
     519       422529 :       s->flags |= e->flags;
     520       422529 :       s->probability += e->probability;
     521              :       /* FIXME: This should be called via a hook and only for IR_GIMPLE.  */
     522       422529 :       redirect_edge_var_map_dup (s, e);
     523       422529 :       remove_edge (e);
     524       422529 :       e = s;
     525              :     }
     526              :   else
     527     79360328 :     redirect_edge_succ (e, new_succ);
     528              : 
     529     79782857 :   return e;
     530              : }
     531              : 
     532              : /* Redirect the edge E to basic block DEST even if it requires creating
     533              :    of a new basic block; then it returns the newly created basic block.
     534              :    Aborts when redirection is impossible.  */
     535              : 
     536              : basic_block
     537      9037194 : redirect_edge_and_branch_force (edge e, basic_block dest)
     538              : {
     539      9037194 :   basic_block ret, src = e->src;
     540              : 
     541      9037194 :   if (!cfg_hooks->redirect_edge_and_branch_force)
     542            0 :     internal_error ("%s does not support redirect_edge_and_branch_force",
     543              :                     current_ir_name ());
     544              : 
     545      9037194 :   if (current_loops != NULL)
     546      7391033 :     rescan_loop_exit (e, false, true);
     547              : 
     548      9037194 :   ret = cfg_hooks->redirect_edge_and_branch_force (e, dest);
     549              : 
     550      9037194 :   if (ret != NULL && dom_info_available_p (CDI_DOMINATORS))
     551        42816 :     set_immediate_dominator (CDI_DOMINATORS, ret, src);
     552              : 
     553      9037194 :   if (current_loops != NULL)
     554              :     {
     555      7391033 :       if (ret != NULL)
     556              :         {
     557            3 :           class loop *loop
     558            3 :             = find_common_loop (single_pred (ret)->loop_father,
     559            3 :                                 single_succ (ret)->loop_father);
     560            3 :           add_bb_to_loop (ret, loop);
     561              :         }
     562      7391030 :       else if (find_edge (src, dest) == e)
     563      7391028 :         rescan_loop_exit (e, true, false);
     564              :     }
     565              : 
     566      9037194 :   return ret;
     567              : }
     568              : 
     569              : /* Splits basic block BB after the specified instruction I (but at least after
     570              :    the labels).  If I is NULL, splits just after labels.  The newly created edge
     571              :    is returned.  The new basic block is created just after the old one.  */
     572              : 
     573              : static edge
     574      8485299 : split_block_1 (basic_block bb, void *i)
     575              : {
     576      8485299 :   basic_block new_bb;
     577      8485299 :   edge res;
     578              : 
     579      8485299 :   if (!cfg_hooks->split_block)
     580            0 :     internal_error ("%s does not support split_block", current_ir_name ());
     581              : 
     582      8485299 :   new_bb = cfg_hooks->split_block (bb, i);
     583      8485299 :   if (!new_bb)
     584              :     return NULL;
     585              : 
     586      8485299 :   new_bb->count = bb->count;
     587              : 
     588      8485299 :   if (dom_info_available_p (CDI_DOMINATORS))
     589              :     {
     590       662887 :       redirect_immediate_dominators (CDI_DOMINATORS, bb, new_bb);
     591       662887 :       set_immediate_dominator (CDI_DOMINATORS, new_bb, bb);
     592              :     }
     593              : 
     594      8485299 :   if (current_loops != NULL)
     595              :     {
     596      7546749 :       edge_iterator ei;
     597      7546749 :       edge e;
     598      7546749 :       add_bb_to_loop (new_bb, bb->loop_father);
     599              :       /* Identify all loops bb may have been the latch of and adjust them.  */
     600     18579096 :       FOR_EACH_EDGE (e, ei, new_bb->succs)
     601     11032347 :         if (e->dest->loop_father->latch == bb)
     602       122086 :           e->dest->loop_father->latch = new_bb;
     603              :     }
     604              : 
     605      8485299 :   res = make_single_succ_edge (bb, new_bb, EDGE_FALLTHRU);
     606              : 
     607      8485299 :   if (bb->flags & BB_IRREDUCIBLE_LOOP)
     608              :     {
     609         5355 :       new_bb->flags |= BB_IRREDUCIBLE_LOOP;
     610         5355 :       res->flags |= EDGE_IRREDUCIBLE_LOOP;
     611              :     }
     612              : 
     613              :   return res;
     614              : }
     615              : 
     616              : edge
     617      5387157 : split_block (basic_block bb, gimple *i)
     618              : {
     619      5387157 :   return split_block_1 (bb, i);
     620              : }
     621              : 
     622              : edge
     623      2982290 : split_block (basic_block bb, rtx i)
     624              : {
     625      2982290 :   return split_block_1 (bb, i);
     626              : }
     627              : 
     628              : /* Splits block BB just after labels.  The newly created edge is returned.  */
     629              : 
     630              : edge
     631       115852 : split_block_after_labels (basic_block bb)
     632              : {
     633       115852 :   return split_block_1 (bb, NULL);
     634              : }
     635              : 
     636              : /* Moves block BB immediately after block AFTER.  Returns false if the
     637              :    movement was impossible.  */
     638              : 
     639              : bool
     640     23205111 : move_block_after (basic_block bb, basic_block after)
     641              : {
     642     23205111 :   bool ret;
     643              : 
     644     23205111 :   if (!cfg_hooks->move_block_after)
     645            0 :     internal_error ("%s does not support move_block_after",
     646              :                     current_ir_name ());
     647              : 
     648     23205111 :   ret = cfg_hooks->move_block_after (bb, after);
     649              : 
     650     23205111 :   return ret;
     651              : }
     652              : 
     653              : /* Deletes the basic block BB.  */
     654              : 
     655              : void
     656     42401657 : delete_basic_block (basic_block bb)
     657              : {
     658     42401657 :   if (!cfg_hooks->delete_basic_block)
     659            0 :     internal_error ("%s does not support delete_basic_block",
     660              :                     current_ir_name ());
     661              : 
     662     42401657 :   cfg_hooks->delete_basic_block (bb);
     663              : 
     664     42401657 :   if (current_loops != NULL)
     665              :     {
     666     37377058 :       class loop *loop = bb->loop_father;
     667              : 
     668              :       /* If we remove the header or the latch of a loop, mark the loop for
     669              :          removal.  */
     670     37377058 :       if (loop->latch == bb
     671     37176473 :           || loop->header == bb)
     672       246726 :         mark_loop_for_removal (loop);
     673              : 
     674     37377058 :       remove_bb_from_loops (bb);
     675              :     }
     676              : 
     677              :   /* Remove the edges into and out of this block.  Note that there may
     678              :      indeed be edges in, if we are removing an unreachable loop.  */
     679     85455354 :   while (EDGE_COUNT (bb->preds) != 0)
     680       659178 :     remove_edge (EDGE_PRED (bb, 0));
     681     49009904 :   while (EDGE_COUNT (bb->succs) != 0)
     682      6608247 :     remove_edge (EDGE_SUCC (bb, 0));
     683              : 
     684     42401657 :   if (dom_info_available_p (CDI_DOMINATORS))
     685     29741398 :     delete_from_dominance_info (CDI_DOMINATORS, bb);
     686     42401657 :   if (dom_info_available_p (CDI_POST_DOMINATORS))
     687       407352 :     delete_from_dominance_info (CDI_POST_DOMINATORS, bb);
     688              : 
     689              :   /* Remove the basic block from the array.  */
     690     42401657 :   expunge_block (bb);
     691     42401657 : }
     692              : 
     693              : /* Splits edge E and returns the newly created basic block.  */
     694              : 
     695              : basic_block
     696     29688241 : split_edge (edge e)
     697              : {
     698     29688241 :   basic_block ret;
     699     29688241 :   profile_count count = e->count ();
     700     29688241 :   edge f;
     701     29688241 :   bool irr = (e->flags & EDGE_IRREDUCIBLE_LOOP) != 0;
     702     29688241 :   bool back = (e->flags & EDGE_DFS_BACK) != 0;
     703     29688241 :   class loop *loop;
     704     29688241 :   basic_block src = e->src, dest = e->dest;
     705              : 
     706     29688241 :   if (!cfg_hooks->split_edge)
     707            0 :     internal_error ("%s does not support split_edge", current_ir_name ());
     708              : 
     709     29688241 :   if (current_loops != NULL)
     710     28242580 :     rescan_loop_exit (e, false, true);
     711              : 
     712     29688241 :   ret = cfg_hooks->split_edge (e);
     713     29688241 :   ret->count = count;
     714     29688241 :   single_succ_edge (ret)->probability = profile_probability::always ();
     715              : 
     716     29688241 :   if (irr)
     717              :     {
     718        67047 :       ret->flags |= BB_IRREDUCIBLE_LOOP;
     719        67047 :       single_pred_edge (ret)->flags |= EDGE_IRREDUCIBLE_LOOP;
     720        67047 :       single_succ_edge (ret)->flags |= EDGE_IRREDUCIBLE_LOOP;
     721              :     }
     722     29688241 :   if (back)
     723              :     {
     724      2076552 :       single_pred_edge (ret)->flags &= ~EDGE_DFS_BACK;
     725      2076552 :       single_succ_edge (ret)->flags |= EDGE_DFS_BACK;
     726              :     }
     727              : 
     728     29688241 :   if (dom_info_available_p (CDI_DOMINATORS))
     729     25597392 :     set_immediate_dominator (CDI_DOMINATORS, ret, single_pred (ret));
     730              : 
     731     29688241 :   if (dom_info_state (CDI_DOMINATORS) >= DOM_NO_FAST_QUERY)
     732              :     {
     733              :       /* There are two cases:
     734              : 
     735              :          If the immediate dominator of e->dest is not e->src, it
     736              :          remains unchanged.
     737              : 
     738              :          If immediate dominator of e->dest is e->src, it may become
     739              :          ret, provided that all other predecessors of e->dest are
     740              :          dominated by e->dest.  */
     741              : 
     742     25597392 :       if (get_immediate_dominator (CDI_DOMINATORS, single_succ (ret))
     743     25597392 :           == single_pred (ret))
     744              :         {
     745      8916970 :           edge_iterator ei;
     746     19593474 :           FOR_EACH_EDGE (f, ei, single_succ (ret)->preds)
     747              :             {
     748     15403884 :               if (f == single_succ_edge (ret))
     749      6745003 :                 continue;
     750              : 
     751      8658881 :               if (!dominated_by_p (CDI_DOMINATORS, f->src,
     752      8658881 :                                    single_succ (ret)))
     753              :                 break;
     754              :             }
     755              : 
     756      8916970 :           if (!f)
     757      4189590 :             set_immediate_dominator (CDI_DOMINATORS, single_succ (ret), ret);
     758              :         }
     759              :     }
     760              : 
     761     29688241 :   if (current_loops != NULL)
     762              :     {
     763     28242580 :       loop = find_common_loop (src->loop_father, dest->loop_father);
     764     28242580 :       add_bb_to_loop (ret, loop);
     765              : 
     766              :       /* If we split the latch edge of loop adjust the latch block.  */
     767     28242580 :       if (loop->latch == src
     768      6252197 :           && loop->header == dest)
     769      6252139 :         loop->latch = ret;
     770              :     }
     771              : 
     772     29688241 :   return ret;
     773              : }
     774              : 
     775              : /* Creates a new basic block just after the basic block AFTER.
     776              :    HEAD and END are the first and the last statement belonging
     777              :    to the block.  If both are NULL, an empty block is created.  */
     778              : 
     779              : static basic_block
     780     83215714 : create_basic_block_1 (void *head, void *end, basic_block after)
     781              : {
     782     83215714 :   basic_block ret;
     783              : 
     784     83215714 :   if (!cfg_hooks->create_basic_block)
     785            0 :     internal_error ("%s does not support create_basic_block",
     786              :                     current_ir_name ());
     787              : 
     788     83215714 :   ret = cfg_hooks->create_basic_block (head, end, after);
     789              : 
     790     83215714 :   if (dom_info_available_p (CDI_DOMINATORS))
     791     31148524 :     add_to_dominance_info (CDI_DOMINATORS, ret);
     792     83215714 :   if (dom_info_available_p (CDI_POST_DOMINATORS))
     793       177592 :     add_to_dominance_info (CDI_POST_DOMINATORS, ret);
     794              : 
     795     83215714 :   return ret;
     796              : }
     797              : 
     798              : basic_block
     799     35596502 : create_basic_block (gimple_seq seq, basic_block after)
     800              : {
     801     35596502 :   return create_basic_block_1 (seq, NULL, after);
     802              : }
     803              : 
     804              : basic_block
     805     13088683 : create_basic_block (rtx head, rtx end, basic_block after)
     806              : {
     807     13088683 :   return create_basic_block_1 (head, end, after);
     808              : }
     809              : 
     810              : 
     811              : /* Creates an empty basic block just after basic block AFTER.  */
     812              : 
     813              : basic_block
     814     34530529 : create_empty_bb (basic_block after)
     815              : {
     816     34530529 :   return create_basic_block_1 (NULL, NULL, after);
     817              : }
     818              : 
     819              : /* Checks whether we may merge blocks BB1 and BB2.  */
     820              : 
     821              : bool
     822    411672146 : can_merge_blocks_p (basic_block bb1, basic_block bb2)
     823              : {
     824    411672146 :   bool ret;
     825              : 
     826    411672146 :   if (!cfg_hooks->can_merge_blocks_p)
     827            0 :     internal_error ("%s does not support can_merge_blocks_p",
     828              :                     current_ir_name ());
     829              : 
     830    411672146 :   ret = cfg_hooks->can_merge_blocks_p (bb1, bb2);
     831              : 
     832    411672146 :   return ret;
     833              : }
     834              : 
     835              : void
     836      6141862 : predict_edge (edge e, enum br_predictor predictor, int probability)
     837              : {
     838      6141862 :   if (!cfg_hooks->predict_edge)
     839            0 :     internal_error ("%s does not support predict_edge",
     840              :                     current_ir_name ());
     841              : 
     842      6141862 :   cfg_hooks->predict_edge (e, predictor, probability);
     843      6141862 : }
     844              : 
     845              : bool
     846      3178752 : predicted_by_p (const_basic_block bb, enum br_predictor predictor)
     847              : {
     848      3178752 :   if (!cfg_hooks->predict_edge)
     849            0 :     internal_error ("%s does not support predicted_by_p",
     850              :                     current_ir_name ());
     851              : 
     852      3178752 :   return cfg_hooks->predicted_by_p (bb, predictor);
     853              : }
     854              : 
     855              : /* Merges basic block B into basic block A.  */
     856              : 
     857              : void
     858     21391395 : merge_blocks (basic_block a, basic_block b)
     859              : {
     860     21391395 :   edge e;
     861     21391395 :   edge_iterator ei;
     862              : 
     863     21391395 :   if (!cfg_hooks->merge_blocks)
     864            0 :     internal_error ("%s does not support merge_blocks",
     865              :                     current_ir_name ());
     866              : 
     867              :   /* Pick the more reliable count.  If both qualities agrees, pick the larger
     868              :      one since turning mistakely hot code to cold is more harmful.  */
     869     21391395 :   if (!a->count.initialized_p ())
     870     11526801 :     a->count = b->count;
     871      9864594 :   else if (a->count.quality () < b->count.quality ())
     872         5073 :     a->count = b->count;
     873      9859521 :   else if (a->count.quality () == b->count.quality ())
     874      9853782 :     a->count = profile_count::max_prefer_initialized (a->count, b->count);
     875              : 
     876     21391395 :   cfg_hooks->merge_blocks (a, b);
     877              : 
     878     21391395 :   if (current_loops != NULL)
     879              :     {
     880              :       /* If the block we merge into is a loop header do nothing unless ... */
     881     18225186 :       if (a->loop_father->header == a)
     882              :         {
     883              :           /* ... we merge two loop headers, in which case we kill
     884              :              the inner loop.  */
     885       637999 :           if (b->loop_father->header == b)
     886          424 :             mark_loop_for_removal (b->loop_father);
     887              :         }
     888              :       /* If we merge a loop header into its predecessor, update the loop
     889              :          structure.  */
     890     17587187 :       else if (b->loop_father->header == b)
     891              :         {
     892          171 :           remove_bb_from_loops (a);
     893          171 :           add_bb_to_loop  (a, b->loop_father);
     894          171 :           a->loop_father->header = a;
     895              :         }
     896              :       /* If we merge a loop latch into its predecessor, update the loop
     897              :          structure.  */
     898     18225186 :       if (b->loop_father->latch
     899     18109750 :           && b->loop_father->latch == b)
     900       251194 :         b->loop_father->latch = a;
     901     18225186 :       remove_bb_from_loops (b);
     902              :     }
     903              : 
     904              :   /* Normally there should only be one successor of A and that is B, but
     905              :      partway though the merge of blocks for conditional_execution we'll
     906              :      be merging a TEST block with THEN and ELSE successors.  Free the
     907              :      whole lot of them and hope the caller knows what they're doing.  */
     908              : 
     909     42782790 :   while (EDGE_COUNT (a->succs) != 0)
     910     21391395 :     remove_edge (EDGE_SUCC (a, 0));
     911              : 
     912              :   /* Adjust the edges out of B for the new owner.  */
     913     48549115 :   FOR_EACH_EDGE (e, ei, b->succs)
     914              :     {
     915     27157720 :       e->src = a;
     916     27157720 :       if (current_loops != NULL)
     917              :         {
     918              :           /* If b was a latch, a now is.  */
     919     23598248 :           if (e->dest->loop_father->latch == b)
     920          674 :             e->dest->loop_father->latch = a;
     921     23598248 :           rescan_loop_exit (e, true, false);
     922              :         }
     923              :     }
     924     21391395 :   a->succs = b->succs;
     925     21391395 :   a->flags |= b->flags;
     926              : 
     927              :   /* B hasn't quite yet ceased to exist.  Attempt to prevent mishap.  */
     928     21391395 :   b->preds = b->succs = NULL;
     929              : 
     930     21391395 :   if (dom_info_available_p (CDI_DOMINATORS))
     931     16724404 :     redirect_immediate_dominators (CDI_DOMINATORS, b, a);
     932              : 
     933     21391395 :   if (dom_info_available_p (CDI_DOMINATORS))
     934     16724404 :     delete_from_dominance_info (CDI_DOMINATORS, b);
     935     21391395 :   if (dom_info_available_p (CDI_POST_DOMINATORS))
     936       114246 :     delete_from_dominance_info (CDI_POST_DOMINATORS, b);
     937              : 
     938     21391395 :   expunge_block (b);
     939     21391395 : }
     940              : 
     941              : /* Split BB into entry part and the rest (the rest is the newly created block).
     942              :    Redirect those edges for that REDIRECT_EDGE_P returns true to the entry
     943              :    part.  Returns the edge connecting the entry part to the rest.
     944              :    DATA gets passed on to REDIRECT_EDGE_P.  */
     945              : 
     946              : edge
     947        89858 : make_forwarder_block (basic_block bb, bool (*redirect_edge_p) (edge, void*), void *data)
     948              : {
     949        89858 :   edge e, fallthru;
     950        89858 :   edge_iterator ei;
     951        89858 :   basic_block dummy, jump;
     952        89858 :   class loop *loop, *ploop, *cloop;
     953              : 
     954        89858 :   if (!cfg_hooks->make_forwarder_block)
     955            0 :     internal_error ("%s does not support make_forwarder_block",
     956              :                     current_ir_name ());
     957              : 
     958        89858 :   fallthru = split_block_after_labels (bb);
     959        89858 :   dummy = fallthru->src;
     960        89858 :   dummy->count = profile_count::zero ();
     961        89858 :   bb = fallthru->dest;
     962              : 
     963              :   /* Redirect back edges we want to keep.  */
     964       385971 :   for (ei = ei_start (dummy->preds); (e = ei_safe_edge (ei)); )
     965              :     {
     966       296113 :       basic_block e_src;
     967              : 
     968       296113 :       if (redirect_edge_p (e, data))
     969              :         {
     970       203960 :           dummy->count += e->count ();
     971       203960 :           ei_next (&ei);
     972       203960 :           continue;
     973              :         }
     974              : 
     975        92153 :       e_src = e->src;
     976        92153 :       jump = redirect_edge_and_branch_force (e, bb);
     977        92153 :       if (jump != NULL)
     978              :         {
     979              :           /* If we redirected the loop latch edge, the JUMP block now acts like
     980              :              the new latch of the loop.  */
     981            2 :           if (current_loops != NULL
     982            2 :               && dummy->loop_father != NULL
     983            2 :               && dummy->loop_father->header == dummy
     984            2 :               && dummy->loop_father->latch == e_src)
     985            0 :             dummy->loop_father->latch = jump;
     986              :         }
     987              :     }
     988              : 
     989        89858 :   if (dom_info_available_p (CDI_DOMINATORS))
     990              :     {
     991        47614 :       vec<basic_block> doms_to_fix;
     992        47614 :       doms_to_fix.create (2);
     993        47614 :       doms_to_fix.quick_push (dummy);
     994        47614 :       doms_to_fix.quick_push (bb);
     995        47614 :       iterate_fix_dominators (CDI_DOMINATORS, doms_to_fix, false);
     996        47614 :       doms_to_fix.release ();
     997              :     }
     998              : 
     999        89858 :   if (current_loops != NULL)
    1000              :     {
    1001              :       /* If we do not split a loop header, then both blocks belong to the
    1002              :          same loop.  In case we split loop header and do not redirect the
    1003              :          latch edge to DUMMY, then DUMMY belongs to the outer loop, and
    1004              :          BB becomes the new header.  If latch is not recorded for the loop,
    1005              :          we leave this updating on the caller (this may only happen during
    1006              :          loop analysis).  */
    1007        89858 :       loop = dummy->loop_father;
    1008        89858 :       if (loop->header == dummy
    1009        89694 :           && loop->latch != NULL
    1010       156040 :           && find_edge (loop->latch, dummy) == NULL)
    1011              :         {
    1012        66150 :           remove_bb_from_loops (dummy);
    1013        66150 :           loop->header = bb;
    1014              : 
    1015        66150 :           cloop = loop;
    1016       214027 :           FOR_EACH_EDGE (e, ei, dummy->preds)
    1017              :             {
    1018       147877 :               cloop = find_common_loop (cloop, e->src->loop_father);
    1019              :             }
    1020        66150 :           add_bb_to_loop (dummy, cloop);
    1021              :         }
    1022              : 
    1023              :       /* In case we split loop latch, update it.  */
    1024       298570 :       for (ploop = loop; ploop; ploop = loop_outer (ploop))
    1025       208712 :         if (ploop->latch == dummy)
    1026            0 :           ploop->latch = bb;
    1027              :     }
    1028              : 
    1029        89858 :   cfg_hooks->make_forwarder_block (fallthru);
    1030              : 
    1031        89858 :   return fallthru;
    1032              : }
    1033              : 
    1034              : /* Try to make the edge fallthru.  */
    1035              : 
    1036              : void
    1037       857989 : tidy_fallthru_edge (edge e)
    1038              : {
    1039       857989 :   if (cfg_hooks->tidy_fallthru_edge)
    1040       857989 :     cfg_hooks->tidy_fallthru_edge (e);
    1041       857989 : }
    1042              : 
    1043              : /* Fix up edges that now fall through, or rather should now fall through
    1044              :    but previously required a jump around now deleted blocks.  Simplify
    1045              :    the search by only examining blocks numerically adjacent, since this
    1046              :    is how they were created.
    1047              : 
    1048              :    ??? This routine is currently RTL specific.  */
    1049              : 
    1050              : void
    1051       444084 : tidy_fallthru_edges (void)
    1052              : {
    1053       444084 :   basic_block b, c;
    1054              : 
    1055       444084 :   if (!cfg_hooks->tidy_fallthru_edge)
    1056              :     return;
    1057              : 
    1058       127767 :   if (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
    1059              :     return;
    1060              : 
    1061      4574118 :   FOR_BB_BETWEEN (b, ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb,
    1062              :                   EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb, next_bb)
    1063              :     {
    1064      4446351 :       edge s;
    1065              : 
    1066      4446351 :       c = b->next_bb;
    1067              : 
    1068              :       /* We care about simple conditional or unconditional jumps with
    1069              :          a single successor.
    1070              : 
    1071              :          If we had a conditional branch to the next instruction when
    1072              :          CFG was built, then there will only be one out edge for the
    1073              :          block which ended with the conditional branch (since we do
    1074              :          not create duplicate edges).
    1075              : 
    1076              :          Furthermore, the edge will be marked as a fallthru because we
    1077              :          merge the flags for the duplicate edges.  So we do not want to
    1078              :          check that the edge is not a FALLTHRU edge.  */
    1079              : 
    1080      6515888 :       if (single_succ_p (b))
    1081              :         {
    1082      2069537 :           s = single_succ_edge (b);
    1083      2069537 :           if (! (s->flags & EDGE_COMPLEX)
    1084      2002209 :               && s->dest == c
    1085      2961269 :               && !(JUMP_P (BB_END (b)) && CROSSING_JUMP_P (BB_END (b))))
    1086       850930 :             tidy_fallthru_edge (s);
    1087              :         }
    1088              :     }
    1089              : }
    1090              : 
    1091              : /* Edge E is assumed to be fallthru edge.  Emit needed jump instruction
    1092              :    (and possibly create new basic block) to make edge non-fallthru.
    1093              :    Return newly created BB or NULL if none.  */
    1094              : 
    1095              : basic_block
    1096       757029 : force_nonfallthru (edge e)
    1097              : {
    1098       757029 :   basic_block ret, src = e->src;
    1099              : 
    1100       757029 :   if (!cfg_hooks->force_nonfallthru)
    1101            0 :     internal_error ("%s does not support force_nonfallthru",
    1102              :                     current_ir_name ());
    1103              : 
    1104       757029 :   ret = cfg_hooks->force_nonfallthru (e);
    1105       757029 :   if (ret != NULL)
    1106              :     {
    1107       177662 :       if (dom_info_available_p (CDI_DOMINATORS))
    1108         9241 :         set_immediate_dominator (CDI_DOMINATORS, ret, src);
    1109              : 
    1110       177662 :       if (current_loops != NULL)
    1111              :         {
    1112        65696 :           basic_block pred = single_pred (ret);
    1113        65696 :           basic_block succ = single_succ (ret);
    1114        65696 :           class loop *loop
    1115        65696 :             = find_common_loop (pred->loop_father, succ->loop_father);
    1116        65696 :           rescan_loop_exit (e, false, true);
    1117        65696 :           add_bb_to_loop (ret, loop);
    1118              : 
    1119              :           /* If we split the latch edge of loop adjust the latch block.  */
    1120        65696 :           if (loop->latch == pred
    1121         4480 :               && loop->header == succ)
    1122         4480 :             loop->latch = ret;
    1123              :         }
    1124              :     }
    1125              : 
    1126       757029 :   return ret;
    1127              : }
    1128              : 
    1129              : /* Returns true if we can duplicate basic block BB.  */
    1130              : 
    1131              : bool
    1132     17990948 : can_duplicate_block_p (const_basic_block bb)
    1133              : {
    1134     17990948 :   if (!cfg_hooks->can_duplicate_block_p)
    1135            0 :     internal_error ("%s does not support can_duplicate_block_p",
    1136              :                     current_ir_name ());
    1137              : 
    1138     17990948 :   if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun) || bb == ENTRY_BLOCK_PTR_FOR_FN (cfun))
    1139              :     return false;
    1140              : 
    1141     17990948 :   return cfg_hooks->can_duplicate_block_p (bb);
    1142              : }
    1143              : 
    1144              : /* Duplicate basic block BB, place it after AFTER (if non-null) and redirect
    1145              :    edge E to it (if non-null).  Return the new basic block.
    1146              : 
    1147              :    If BB contains a returns_twice call, the caller is responsible for recreating
    1148              :    incoming abnormal edges corresponding to the "second return" for the copy.
    1149              :    gimple_can_duplicate_bb_p rejects such blocks, while RTL likes to live
    1150              :    dangerously.
    1151              : 
    1152              :    If BB has incoming abnormal edges for some other reason, their destinations
    1153              :    should be tied to label(s) of the original BB and not the copy.  */
    1154              : 
    1155              : basic_block
    1156      4571707 : duplicate_block (basic_block bb, edge e, basic_block after, copy_bb_data *id)
    1157              : {
    1158      4571707 :   edge s, n;
    1159      4571707 :   basic_block new_bb;
    1160      4844093 :   profile_count new_count = e ? e->count (): profile_count::uninitialized ();
    1161      4571707 :   edge_iterator ei;
    1162              : 
    1163      4571707 :   if (!cfg_hooks->duplicate_block)
    1164            0 :     internal_error ("%s does not support duplicate_block",
    1165              :                     current_ir_name ());
    1166              : 
    1167      4571707 :   if (bb->count < new_count)
    1168         1263 :     new_count = bb->count;
    1169              : 
    1170      4571707 :   gcc_checking_assert (can_duplicate_block_p (bb));
    1171              : 
    1172      4571707 :   new_bb = cfg_hooks->duplicate_block (bb, id);
    1173      4571707 :   if (after)
    1174      4204246 :     move_block_after (new_bb, after);
    1175              : 
    1176      4571707 :   new_bb->flags = (bb->flags & ~BB_DUPLICATED);
    1177     12613043 :   FOR_EACH_EDGE (s, ei, bb->succs)
    1178              :     {
    1179              :       /* Since we are creating edges from a new block to successors
    1180              :          of another block (which therefore are known to be disjoint), there
    1181              :          is no need to actually check for duplicated edges.  */
    1182      8041336 :       n = unchecked_make_edge (new_bb, s->dest, s->flags);
    1183      8041336 :       n->probability = s->probability;
    1184      8041336 :       n->aux = s->aux;
    1185              :     }
    1186              : 
    1187      4571707 :   if (e)
    1188              :     {
    1189       272386 :       new_bb->count = new_count;
    1190       272386 :       bb->count -= new_count;
    1191              : 
    1192       272386 :       redirect_edge_and_branch_force (e, new_bb);
    1193              :     }
    1194              :   else
    1195      4299321 :     new_bb->count = bb->count;
    1196              : 
    1197      4571707 :   set_bb_original (new_bb, bb);
    1198      4571707 :   set_bb_copy (bb, new_bb);
    1199              : 
    1200              :   /* Add the new block to the copy of the loop of BB, or directly to the loop
    1201              :      of BB if the loop is not being copied.  */
    1202      4571707 :   if (current_loops != NULL)
    1203              :     {
    1204      4274461 :       class loop *cloop = bb->loop_father;
    1205      4274461 :       class loop *copy = get_loop_copy (cloop);
    1206              :       /* If we copied the loop header block but not the loop
    1207              :          we have created a loop with multiple entries.  Ditch the loop,
    1208              :          add the new block to the outer loop and arrange for a fixup.  */
    1209      4274461 :       if (!copy
    1210       373802 :           && cloop->header == bb)
    1211              :         {
    1212          369 :           add_bb_to_loop (new_bb, loop_outer (cloop));
    1213          369 :           mark_loop_for_removal (cloop);
    1214              :         }
    1215              :       else
    1216              :         {
    1217      4274092 :           add_bb_to_loop (new_bb, copy ? copy : cloop);
    1218              :           /* If we copied the loop latch block but not the loop, adjust
    1219              :              loop state.  */
    1220      4274092 :           if (!copy
    1221       373433 :               && cloop->latch == bb)
    1222              :             {
    1223          610 :               cloop->latch = NULL;
    1224          610 :               loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
    1225              :             }
    1226              :         }
    1227              :     }
    1228              : 
    1229      4571707 :   return new_bb;
    1230              : }
    1231              : 
    1232              : /* Return 1 if BB ends with a call, possibly followed by some
    1233              :    instructions that must stay with the call, 0 otherwise.  */
    1234              : 
    1235              : bool
    1236      9707689 : block_ends_with_call_p (basic_block bb)
    1237              : {
    1238      9707689 :   if (!cfg_hooks->block_ends_with_call_p)
    1239            0 :     internal_error ("%s does not support block_ends_with_call_p",
    1240              :                     current_ir_name ());
    1241              : 
    1242      9707689 :   return (cfg_hooks->block_ends_with_call_p) (bb);
    1243              : }
    1244              : 
    1245              : /* Return 1 if BB ends with a conditional branch, 0 otherwise.  */
    1246              : 
    1247              : bool
    1248         1793 : block_ends_with_condjump_p (const_basic_block bb)
    1249              : {
    1250         1793 :   if (!cfg_hooks->block_ends_with_condjump_p)
    1251            0 :     internal_error ("%s does not support block_ends_with_condjump_p",
    1252              :                     current_ir_name ());
    1253              : 
    1254         1793 :   return (cfg_hooks->block_ends_with_condjump_p) (bb);
    1255              : }
    1256              : 
    1257              : /* Add fake edges to the function exit for any non constant and non noreturn
    1258              :    calls, volatile inline assembly in the bitmap of blocks specified by
    1259              :    BLOCKS or to the whole CFG if BLOCKS is zero.  Return the number of blocks
    1260              :    that were split.
    1261              : 
    1262              :    The goal is to expose cases in which entering a basic block does not imply
    1263              :    that all subsequent instructions must be executed.  */
    1264              : 
    1265              : int
    1266         2591 : flow_call_edges_add (sbitmap blocks)
    1267              : {
    1268         2591 :   if (!cfg_hooks->flow_call_edges_add)
    1269            0 :     internal_error ("%s does not support flow_call_edges_add",
    1270              :                     current_ir_name ());
    1271              : 
    1272         2591 :   return (cfg_hooks->flow_call_edges_add) (blocks);
    1273              : }
    1274              : 
    1275              : /* This function is called immediately after edge E is added to the
    1276              :    edge vector E->dest->preds.  */
    1277              : 
    1278              : void
    1279    200394799 : execute_on_growing_pred (edge e)
    1280              : {
    1281    200394799 :   if (! (e->dest->flags & BB_DUPLICATED)
    1282    198150634 :       && cfg_hooks->execute_on_growing_pred)
    1283    157853515 :     cfg_hooks->execute_on_growing_pred (e);
    1284    200394799 : }
    1285              : 
    1286              : /* This function is called immediately before edge E is removed from
    1287              :    the edge vector E->dest->preds.  */
    1288              : 
    1289              : void
    1290    169236160 : execute_on_shrinking_pred (edge e)
    1291              : {
    1292    169236160 :   if (! (e->dest->flags & BB_DUPLICATED)
    1293    166991995 :       && cfg_hooks->execute_on_shrinking_pred)
    1294    129320066 :     cfg_hooks->execute_on_shrinking_pred (e);
    1295    169236160 : }
    1296              : 
    1297              : /* This is used inside loop versioning when we want to insert
    1298              :    stmts/insns on the edges, which have a different behavior
    1299              :    in tree's and in RTL, so we made a CFG hook.  */
    1300              : void
    1301        38643 : lv_flush_pending_stmts (edge e)
    1302              : {
    1303        38643 :   if (cfg_hooks->flush_pending_stmts)
    1304        38643 :     cfg_hooks->flush_pending_stmts (e);
    1305        38643 : }
    1306              : 
    1307              : /* Loop versioning uses the duplicate_loop_body_to_header_edge to create
    1308              :    a new version of the loop basic-blocks, the parameters here are
    1309              :    exactly the same as in duplicate_loop_body_to_header_edge or
    1310              :    tree_duplicate_loop_body_to_header_edge; while in tree-ssa there is
    1311              :    additional work to maintain ssa information that's why there is
    1312              :    a need to call the tree_duplicate_loop_body_to_header_edge rather
    1313              :    than duplicate_loop_body_to_header_edge when we are in tree mode.  */
    1314              : bool
    1315        38653 : cfg_hook_duplicate_loop_body_to_header_edge (class loop *loop, edge e,
    1316              :                                              unsigned int ndupl,
    1317              :                                              sbitmap wont_exit, edge orig,
    1318              :                                              vec<edge> *to_remove, int flags)
    1319              : {
    1320        38653 :   gcc_assert (cfg_hooks->cfg_hook_duplicate_loop_body_to_header_edge);
    1321        38653 :   return cfg_hooks->cfg_hook_duplicate_loop_body_to_header_edge (
    1322        38653 :     loop, e, ndupl, wont_exit, orig, to_remove, flags);
    1323              : }
    1324              : 
    1325              : /* Conditional jumps are represented differently in trees and RTL,
    1326              :    this hook takes a basic block that is known to have a cond jump
    1327              :    at its end and extracts the taken and not taken edges out of it
    1328              :    and store it in E1 and E2 respectively.  */
    1329              : void
    1330            0 : extract_cond_bb_edges (basic_block b, edge *e1, edge *e2)
    1331              : {
    1332            0 :   gcc_assert (cfg_hooks->extract_cond_bb_edges);
    1333            0 :   cfg_hooks->extract_cond_bb_edges (b, e1, e2);
    1334            0 : }
    1335              : 
    1336              : /* Responsible for updating the ssa info (PHI nodes) on the
    1337              :    new condition basic block that guards the versioned loop.  */
    1338              : void
    1339        38643 : lv_adjust_loop_header_phi (basic_block first, basic_block second,
    1340              :                            basic_block new_block, edge e)
    1341              : {
    1342        38643 :   if (cfg_hooks->lv_adjust_loop_header_phi)
    1343        38643 :     cfg_hooks->lv_adjust_loop_header_phi (first, second, new_block, e);
    1344        38643 : }
    1345              : 
    1346              : /* Conditions in trees and RTL are different so we need
    1347              :    a different handling when we add the condition to the
    1348              :    versioning code.  */
    1349              : void
    1350        38643 : lv_add_condition_to_bb (basic_block first, basic_block second,
    1351              :                         basic_block new_block, void *cond)
    1352              : {
    1353        38643 :   gcc_assert (cfg_hooks->lv_add_condition_to_bb);
    1354        38643 :   cfg_hooks->lv_add_condition_to_bb (first, second, new_block, cond);
    1355        38643 : }
    1356              : 
    1357              : /* Checks whether all N blocks in BBS array can be copied.  */
    1358              : bool
    1359      3259376 : can_copy_bbs_p (basic_block *bbs, unsigned n)
    1360              : {
    1361      3259376 :   unsigned i;
    1362      3259376 :   edge e;
    1363      3259376 :   int ret = true;
    1364              : 
    1365     11655998 :   for (i = 0; i < n; i++)
    1366      8396622 :     bbs[i]->flags |= BB_DUPLICATED;
    1367              : 
    1368     11512123 :   for (i = 0; i < n; i++)
    1369              :     {
    1370              :       /* In case we should redirect abnormal edge during duplication, fail.  */
    1371      8263480 :       edge_iterator ei;
    1372     21973573 :       FOR_EACH_EDGE (e, ei, bbs[i]->succs)
    1373     13719252 :         if ((e->flags & EDGE_ABNORMAL)
    1374       110138 :             && (e->dest->flags & BB_DUPLICATED))
    1375              :           {
    1376         9159 :             ret = false;
    1377         9159 :             goto end;
    1378              :           }
    1379              : 
    1380      8254321 :       if (!can_duplicate_block_p (bbs[i]))
    1381              :         {
    1382         1574 :           ret = false;
    1383         1574 :           break;
    1384              :         }
    1385              :     }
    1386              : 
    1387      3248643 : end:
    1388     11655998 :   for (i = 0; i < n; i++)
    1389      8396622 :     bbs[i]->flags &= ~BB_DUPLICATED;
    1390              : 
    1391      3259376 :   return ret;
    1392              : }
    1393              : 
    1394              : /* Duplicates N basic blocks stored in array BBS.  Newly created basic blocks
    1395              :    are placed into array NEW_BBS in the same order.  Edges from basic blocks
    1396              :    in BBS are also duplicated and copies of those that lead into BBS are
    1397              :    redirected to appropriate newly created block.  The function assigns bbs
    1398              :    into loops (copy of basic block bb is assigned to bb->loop_father->copy
    1399              :    loop, so this must be set up correctly in advance)
    1400              : 
    1401              :    If UPDATE_DOMINANCE is true then this function updates dominators locally
    1402              :    (LOOPS structure that contains the information about dominators is passed
    1403              :    to enable this), otherwise it does not update the dominator information
    1404              :    and it assumed that the caller will do this, perhaps by destroying and
    1405              :    recreating it instead of trying to do an incremental update like this
    1406              :    function does when update_dominance is true.
    1407              : 
    1408              :    BASE is the superloop to that basic block belongs; if its header or latch
    1409              :    is copied, we do not set the new blocks as header or latch.
    1410              : 
    1411              :    Created copies of N_EDGES edges in array EDGES are stored in array NEW_EDGES,
    1412              :    also in the same order.
    1413              : 
    1414              :    Newly created basic blocks are put after the basic block AFTER in the
    1415              :    instruction stream, and the order of the blocks in BBS array is preserved.  */
    1416              : 
    1417              : void
    1418      2380927 : copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs,
    1419              :           edge *edges, unsigned num_edges, edge *new_edges,
    1420              :           class loop *base, basic_block after, bool update_dominance)
    1421              : {
    1422      2380927 :   unsigned i, j;
    1423      2380927 :   basic_block bb, new_bb, dom_bb;
    1424      2380927 :   edge e;
    1425      2380927 :   copy_bb_data id;
    1426              : 
    1427              :   /* Mark the blocks to be copied.  This is used by edge creation hooks
    1428              :      to decide whether to reallocate PHI nodes capacity to avoid reallocating
    1429              :      PHIs in the set of source BBs.  */
    1430      6312961 :   for (i = 0; i < n; i++)
    1431      3932034 :     bbs[i]->flags |= BB_DUPLICATED;
    1432              : 
    1433              :   /* Duplicate bbs, update dominators, assign bbs to loops.  */
    1434      6312961 :   for (i = 0; i < n; i++)
    1435              :     {
    1436              :       /* Duplicate.  */
    1437      3932034 :       bb = bbs[i];
    1438      3932034 :       new_bb = new_bbs[i] = duplicate_block (bb, NULL, after, &id);
    1439      3932034 :       after = new_bb;
    1440      3932034 :       if (bb->loop_father)
    1441              :         {
    1442              :           /* Possibly set loop header.  */
    1443      3932034 :           if (bb->loop_father->header == bb && bb->loop_father != base)
    1444        40868 :             new_bb->loop_father->header = new_bb;
    1445              :           /* Or latch.  */
    1446      3932034 :           if (bb->loop_father->latch == bb && bb->loop_father != base)
    1447        40868 :             new_bb->loop_father->latch = new_bb;
    1448              :         }
    1449              :     }
    1450              : 
    1451              :   /* Set dominators.  */
    1452      2380927 :   if (update_dominance)
    1453              :     {
    1454      3388489 :       for (i = 0; i < n; i++)
    1455              :         {
    1456      2241200 :           bb = bbs[i];
    1457      2241200 :           new_bb = new_bbs[i];
    1458              : 
    1459      2241200 :           dom_bb = get_immediate_dominator (CDI_DOMINATORS, bb);
    1460      2241200 :           if (dom_bb->flags & BB_DUPLICATED)
    1461              :             {
    1462      1093911 :               dom_bb = get_bb_copy (dom_bb);
    1463      1093911 :               set_immediate_dominator (CDI_DOMINATORS, new_bb, dom_bb);
    1464              :             }
    1465              :         }
    1466              :     }
    1467              : 
    1468              :   /* Redirect edges.  */
    1469      6312961 :   for (i = 0; i < n; i++)
    1470              :     {
    1471      3932034 :       edge_iterator ei;
    1472      3932034 :       new_bb = new_bbs[i];
    1473      3932034 :       bb = bbs[i];
    1474              : 
    1475     10914745 :       FOR_EACH_EDGE (e, ei, new_bb->succs)
    1476              :         {
    1477      6982711 :           if (!(e->dest->flags & BB_DUPLICATED))
    1478      4738546 :             continue;
    1479      2244165 :           redirect_edge_and_branch_force (e, get_bb_copy (e->dest));
    1480              :         }
    1481              :     }
    1482      5309752 :   for (j = 0; j < num_edges; j++)
    1483              :     {
    1484      2928825 :       if (!edges[j])
    1485        79209 :         new_edges[j] = NULL;
    1486              :       else
    1487              :         {
    1488      2849616 :           basic_block src = edges[j]->src;
    1489      2849616 :           basic_block dest = edges[j]->dest;
    1490      2849616 :           if (src->flags & BB_DUPLICATED)
    1491      2849616 :             src = get_bb_copy (src);
    1492      2849616 :           if (dest->flags & BB_DUPLICATED)
    1493       495440 :             dest = get_bb_copy (dest);
    1494      2849616 :           new_edges[j] = find_edge (src, dest);
    1495              :         }
    1496              :     }
    1497              : 
    1498              :   /* Clear information about duplicates.  */
    1499      6312961 :   for (i = 0; i < n; i++)
    1500      3932034 :     bbs[i]->flags &= ~BB_DUPLICATED;
    1501      2380927 : }
    1502              : 
    1503              : /* Return true if BB contains only labels or non-executable
    1504              :    instructions */
    1505              : bool
    1506     14119829 : empty_block_p (basic_block bb)
    1507              : {
    1508     14119829 :   gcc_assert (cfg_hooks->empty_block_p);
    1509     14119829 :   return cfg_hooks->empty_block_p (bb);
    1510              : }
    1511              : 
    1512              : /* Split a basic block if it ends with a conditional branch and if
    1513              :    the other part of the block is not empty.  */
    1514              : basic_block
    1515          558 : split_block_before_cond_jump (basic_block bb)
    1516              : {
    1517          558 :   gcc_assert (cfg_hooks->split_block_before_cond_jump);
    1518          558 :   return cfg_hooks->split_block_before_cond_jump (bb);
    1519              : }
    1520              : 
    1521              : /* Work-horse for passes.cc:check_profile_consistency.
    1522              :    Do book-keeping of the CFG for the profile consistency checker.
    1523              :    Store the counting in RECORD.  */
    1524              : 
    1525              : void
    1526            0 : profile_record_check_consistency (profile_record *record)
    1527              : {
    1528            0 :   basic_block bb;
    1529            0 :   edge_iterator ei;
    1530            0 :   edge e;
    1531              : 
    1532            0 :   FOR_ALL_BB_FN (bb, cfun)
    1533              :    {
    1534            0 :       if (bb != EXIT_BLOCK_PTR_FOR_FN (cfun)
    1535            0 :           && profile_status_for_fn (cfun) != PROFILE_ABSENT
    1536            0 :           && EDGE_COUNT (bb->succs))
    1537              :         {
    1538            0 :           sreal sum = 0;
    1539            0 :           bool found = false;
    1540            0 :           FOR_EACH_EDGE (e, ei, bb->succs)
    1541              :             {
    1542            0 :               if (!(e->flags & (EDGE_EH | EDGE_FAKE)))
    1543            0 :                 found = true;
    1544            0 :               if (e->probability.initialized_p ())
    1545            0 :                 sum += e->probability.to_sreal ();
    1546              :             }
    1547            0 :           double dsum = sum.to_double ();
    1548            0 :           if (found && (dsum < 0.9 || dsum > 1.1)
    1549            0 :               && !(bb->count == profile_count::zero ()))
    1550              :             {
    1551            0 :               record->num_mismatched_prob_out++;
    1552            0 :               dsum = dsum > 1 ? dsum - 1 : 1 - dsum;
    1553            0 :               if (profile_info)
    1554              :                 {
    1555            0 :                   if (ENTRY_BLOCK_PTR_FOR_FN
    1556            0 :                          (cfun)->count.ipa ().initialized_p ()
    1557            0 :                       && ENTRY_BLOCK_PTR_FOR_FN
    1558            0 :                          (cfun)->count.ipa ().nonzero_p ()
    1559            0 :                       && bb->count.ipa ().initialized_p ())
    1560            0 :                     record->dyn_mismatched_prob_out
    1561            0 :                         += dsum * bb->count.ipa ().to_gcov_type ();
    1562              :                 }
    1563            0 :               else if (bb->count.initialized_p ())
    1564            0 :                 record->dyn_mismatched_prob_out
    1565            0 :                     += dsum * bb->count.to_sreal_scale
    1566            0 :                         (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count).to_double ();
    1567              :             }
    1568              :         }
    1569            0 :       if (bb != ENTRY_BLOCK_PTR_FOR_FN (cfun)
    1570            0 :           && profile_status_for_fn (cfun) != PROFILE_ABSENT)
    1571              :         {
    1572            0 :           profile_count lsum = profile_count::zero ();
    1573            0 :           FOR_EACH_EDGE (e, ei, bb->preds)
    1574            0 :             lsum += e->count ();
    1575            0 :           if (lsum.differs_from_p (bb->count))
    1576              :             {
    1577            0 :               record->num_mismatched_count_in++;
    1578            0 :               profile_count max;
    1579            0 :               if (lsum < bb->count)
    1580            0 :                 max = bb->count;
    1581              :               else
    1582            0 :                 max = lsum;
    1583            0 :               if (profile_info)
    1584              :                 {
    1585            0 :                   if (ENTRY_BLOCK_PTR_FOR_FN
    1586            0 :                          (cfun)->count.ipa ().initialized_p ()
    1587            0 :                       && ENTRY_BLOCK_PTR_FOR_FN
    1588            0 :                          (cfun)->count.ipa ().nonzero_p ()
    1589            0 :                       && max.ipa ().initialized_p ())
    1590            0 :                     record->dyn_mismatched_count_in
    1591            0 :                         += max.ipa ().to_gcov_type ();
    1592              :                 }
    1593            0 :               else if (bb->count.initialized_p ())
    1594            0 :                 record->dyn_mismatched_prob_out
    1595            0 :                     += max.to_sreal_scale
    1596            0 :                         (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count).to_double ();
    1597              :             }
    1598              :         }
    1599            0 :       if (bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)
    1600              :           || bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
    1601            0 :         continue;
    1602              :    }
    1603            0 : }
    1604              : 
    1605              : /* Work-horse for passes.cc:acount_profile.
    1606              :    Do book-keeping of the CFG for the profile accounting.
    1607              :    Store the counting in RECORD.  */
    1608              : 
    1609              : void
    1610            0 : profile_record_account_profile (profile_record *record)
    1611              : {
    1612            0 :   basic_block bb;
    1613              : 
    1614            0 :   FOR_ALL_BB_FN (bb, cfun)
    1615              :    {
    1616            0 :       gcc_assert (cfg_hooks->account_profile_record);
    1617            0 :       cfg_hooks->account_profile_record (bb, record);
    1618              :    }
    1619            0 : }
    1620              : 
    1621              : #if __GNUC__ >= 10
    1622              : #  pragma GCC diagnostic pop
    1623              : #endif
        

Generated by: LCOV version 2.4-beta

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