LCOV - code coverage report
Current view: top level - gcc - cfgbuild.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 89.9 % 327 294
Test Date: 2026-10-17 16:30:31 Functions: 100.0 % 12 12
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Control flow graph building code for GNU compiler.
       2              :    Copyright (C) 1987-2026 Free Software Foundation, Inc.
       3              : 
       4              : This file is part of GCC.
       5              : 
       6              : GCC is free software; you can redistribute it and/or modify it under
       7              : the terms of the GNU General Public License as published by the Free
       8              : Software Foundation; either version 3, or (at your option) any later
       9              : version.
      10              : 
      11              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14              : for more details.
      15              : 
      16              : You should have received a copy of the GNU General Public License
      17              : along with GCC; see the file COPYING3.  If not see
      18              : <http://www.gnu.org/licenses/>.  */
      19              : 
      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 "memmodel.h"
      28              : #include "emit-rtl.h"
      29              : #include "cfgrtl.h"
      30              : #include "cfganal.h"
      31              : #include "cfgbuild.h"
      32              : #include "except.h"
      33              : #include "stmt.h"
      34              : 
      35              : static void make_edges (basic_block, basic_block, int);
      36              : static void make_label_edge (sbitmap, basic_block, rtx, int);
      37              : static void find_bb_boundaries (basic_block);
      38              : static void compute_outgoing_frequencies (basic_block);
      39              : 
      40              : /* Return true if insn is something that should be contained inside basic
      41              :    block.  */
      42              : 
      43              : bool
      44    205144964 : inside_basic_block_p (const rtx_insn *insn)
      45              : {
      46    205144964 :   switch (GET_CODE (insn))
      47              :     {
      48     11774768 :     case CODE_LABEL:
      49              :       /* Avoid creating of basic block for jumptables.  */
      50     11774768 :       return (NEXT_INSN (insn) == 0
      51     11774768 :               || ! JUMP_TABLE_DATA_P (NEXT_INSN (insn)));
      52              : 
      53              :     case JUMP_INSN:
      54              :     case CALL_INSN:
      55              :     case INSN:
      56              :     case DEBUG_INSN:
      57              :       return true;
      58              : 
      59              :     case JUMP_TABLE_DATA:
      60              :     case BARRIER:
      61              :     case NOTE:
      62              :       return false;
      63              : 
      64            0 :     default:
      65            0 :       gcc_unreachable ();
      66              :     }
      67              : }
      68              : 
      69              : /* Return true if INSN may cause control flow transfer, so it should be last in
      70              :    the basic block.  */
      71              : 
      72              : bool
      73  11485873992 : control_flow_insn_p (const rtx_insn *insn)
      74              : {
      75  11485873992 :   switch (GET_CODE (insn))
      76              :     {
      77              :     case NOTE:
      78              :     case CODE_LABEL:
      79              :     case DEBUG_INSN:
      80              :       return false;
      81              : 
      82              :     case JUMP_INSN:
      83              :       return true;
      84              : 
      85    410303411 :     case CALL_INSN:
      86              :       /* Noreturn and sibling call instructions terminate the basic blocks
      87              :          (but only if they happen unconditionally).  */
      88    410303411 :       if ((SIBLING_CALL_P (insn)
      89    409401550 :            || find_reg_note (insn, REG_NORETURN, 0))
      90    413829279 :           && GET_CODE (PATTERN (insn)) != COND_EXEC)
      91              :         return true;
      92              : 
      93              :       /* Call insn may return to the nonlocal goto handler.  */
      94    405875682 :       if (can_nonlocal_goto (insn))
      95              :         return true;
      96              :       break;
      97              : 
      98   5425258194 :     case INSN:
      99              :       /* Treat trap instructions like noreturn calls (same provision).  */
     100   5425258194 :       if (GET_CODE (PATTERN (insn)) == TRAP_IF
     101   5425258194 :           && XEXP (PATTERN (insn), 0) == const1_rtx)
     102              :         return true;
     103   5425177259 :       if (!cfun->can_throw_non_call_exceptions)
     104              :         return false;
     105              :       break;
     106              : 
     107              :     case JUMP_TABLE_DATA:
     108              :     case BARRIER:
     109              :       /* It is nonsense to reach this when looking for the
     110              :          end of basic block, but before dead code is eliminated
     111              :          this may happen.  */
     112              :       return false;
     113              : 
     114            0 :     default:
     115            0 :       gcc_unreachable ();
     116              :     }
     117              : 
     118   1760412832 :   return can_throw_internal (insn);
     119              : }
     120              : 
     121              : 
     122              : /* Create an edge between two basic blocks.  FLAGS are auxiliary information
     123              :    about the edge that is accumulated between calls.  */
     124              : 
     125              : /* Create an edge from a basic block to a label.  */
     126              : 
     127              : static void
     128     16288261 : make_label_edge (sbitmap edge_cache, basic_block src, rtx label, int flags)
     129              : {
     130     16288261 :   gcc_assert (LABEL_P (label));
     131              : 
     132              :   /* If the label was never emitted, this insn is junk, but avoid a
     133              :      crash trying to refer to BLOCK_FOR_INSN (label).  This can happen
     134              :      as a result of a syntax error and a diagnostic has already been
     135              :      printed.  */
     136              : 
     137     16288261 :   if (INSN_UID (label) == 0)
     138              :     return;
     139              : 
     140     16288261 :   cached_make_edge (edge_cache, src, BLOCK_FOR_INSN (label), flags);
     141              : }
     142              : 
     143              : /* Create the edges generated by INSN in REGION.  */
     144              : 
     145              : void
     146      9884592 : rtl_make_eh_edge (sbitmap edge_cache, basic_block src, rtx_insn *insn)
     147              : {
     148      9884592 :   eh_landing_pad lp = get_eh_landing_pad_from_rtx (insn);
     149              : 
     150      9884592 :   if (lp)
     151              :     {
     152      1309432 :       rtx_insn *label = lp->landing_pad;
     153              : 
     154              :       /* During initial rtl generation, use the post_landing_pad.  */
     155      1309432 :       if (label == NULL)
     156              :         {
     157       766610 :           gcc_assert (lp->post_landing_pad);
     158       766610 :           label = label_rtx (lp->post_landing_pad);
     159              :         }
     160              : 
     161      1309432 :       make_label_edge (edge_cache, src, label,
     162              :                        EDGE_ABNORMAL | EDGE_EH
     163      1309432 :                        | (CALL_P (insn) ? EDGE_ABNORMAL_CALL : 0));
     164              :     }
     165      9884592 : }
     166              : 
     167              : /* States of basic block as seen by find_many_sub_basic_blocks.  */
     168              : enum state {
     169              :   /* Basic blocks created via split_block belong to this state.
     170              :      make_edges will examine these basic blocks to see if we need to
     171              :      create edges going out of them.  */
     172              :   BLOCK_NEW = 0,
     173              : 
     174              :   /* Basic blocks that do not need examining belong to this state.
     175              :      These blocks will be left intact.  In particular, make_edges will
     176              :      not create edges going out of these basic blocks.  */
     177              :   BLOCK_ORIGINAL,
     178              : 
     179              :   /* Basic blocks that may need splitting (due to a label appearing in
     180              :      the middle, etc) belong to this state.  After splitting them,
     181              :      make_edges will create edges going out of them as needed.  */
     182              :   BLOCK_TO_SPLIT
     183              : };
     184              : 
     185              : #define STATE(BB) (enum state) ((size_t) (BB)->aux)
     186              : #define SET_STATE(BB, STATE) ((BB)->aux = (void *) (size_t) (STATE))
     187              : 
     188              : /* Used internally by purge_dead_tablejump_edges, ORed into state.  */
     189              : #define BLOCK_USED_BY_TABLEJUMP         32
     190              : #define FULL_STATE(BB) ((size_t) (BB)->aux)
     191              : 
     192              : /* Identify the edges going out of basic blocks between MIN and MAX,
     193              :    inclusive, that have their states set to BLOCK_NEW or
     194              :    BLOCK_TO_SPLIT.
     195              : 
     196              :    UPDATE_P should be nonzero if we are updating CFG and zero if we
     197              :    are building CFG from scratch.  */
     198              : 
     199              : static void
     200      4007259 : make_edges (basic_block min, basic_block max, int update_p)
     201              : {
     202      4007259 :   basic_block bb;
     203      4007259 :   sbitmap edge_cache = NULL;
     204              : 
     205              :   /* Heavy use of computed goto in machine-generated code can lead to
     206              :      nearly fully-connected CFGs.  In that case we spend a significant
     207              :      amount of time searching the edge lists for duplicates.  */
     208      4007259 :   if (!vec_safe_is_empty (forced_labels)
     209      3961559 :       || cfun->cfg->max_jumptable_ents > 100)
     210        46177 :     edge_cache = sbitmap_alloc (last_basic_block_for_fn (cfun));
     211              : 
     212              :   /* By nature of the way these get numbered, ENTRY_BLOCK_PTR->next_bb block
     213              :      is always the entry.  */
     214      4007259 :   if (min == ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb)
     215      3516007 :     make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), min, EDGE_FALLTHRU);
     216              : 
     217     40419269 :   FOR_BB_BETWEEN (bb, min, max->next_bb, next_bb)
     218              :     {
     219     36412010 :       rtx_insn *insn;
     220     36412010 :       enum rtx_code code;
     221     36412010 :       edge e;
     222     36412010 :       edge_iterator ei;
     223              : 
     224     36412010 :       if (STATE (bb) == BLOCK_ORIGINAL)
     225      9326821 :         continue;
     226              : 
     227              :       /* If we have an edge cache, cache edges going out of BB.  */
     228     27085189 :       if (edge_cache)
     229              :         {
     230       241824 :           bitmap_clear (edge_cache);
     231       241824 :           if (update_p)
     232              :             {
     233       549868 :               FOR_EACH_EDGE (e, ei, bb->succs)
     234       308044 :                 if (e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
     235       284995 :                   bitmap_set_bit (edge_cache, e->dest->index);
     236              :             }
     237              :         }
     238              : 
     239     27085189 :       if (LABEL_P (BB_HEAD (bb))
     240     27085189 :           && LABEL_ALT_ENTRY_P (BB_HEAD (bb)))
     241            0 :         cached_make_edge (NULL, ENTRY_BLOCK_PTR_FOR_FN (cfun), bb, 0);
     242              : 
     243              :       /* Examine the last instruction of the block, and discover the
     244              :          ways we can leave the block.  */
     245              : 
     246     27085189 :       insn = BB_END (bb);
     247     27085189 :       code = GET_CODE (insn);
     248              : 
     249              :       /* A branch.  */
     250     27085189 :       if (code == JUMP_INSN)
     251              :         {
     252     15297747 :           rtx tmp;
     253     15297747 :           rtx_jump_table_data *table;
     254              : 
     255              :           /* Recognize a non-local goto as a branch outside the
     256              :              current function.  */
     257     15297747 :           if (find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX))
     258              :             ;
     259              : 
     260              :           /* Recognize a tablejump and do the right thing.  */
     261     15296311 :           else if (tablejump_p (insn, NULL, &table))
     262              :             {
     263         8834 :               rtvec vec = table->get_labels ();
     264         8834 :               int j;
     265              : 
     266       208313 :               for (j = GET_NUM_ELEM (vec) - 1; j >= 0; --j)
     267       398958 :                 make_label_edge (edge_cache, bb,
     268       199479 :                                  label_ref_label (RTVEC_ELT (vec, j)), 0);
     269              : 
     270              :               /* Some targets (eg, ARM) emit a conditional jump that also
     271              :                  contains the out-of-range target.  Scan for these and
     272              :                  add an edge if necessary.  */
     273         8834 :               if ((tmp = single_set (insn)) != NULL
     274         8834 :                   && SET_DEST (tmp) == pc_rtx
     275         8834 :                   && GET_CODE (SET_SRC (tmp)) == IF_THEN_ELSE
     276         8834 :                   && GET_CODE (XEXP (SET_SRC (tmp), 2)) == LABEL_REF)
     277            0 :                 make_label_edge (edge_cache, bb,
     278            0 :                                  label_ref_label (XEXP (SET_SRC (tmp), 2)), 0);
     279              :             }
     280              : 
     281              :           /* If this is a computed jump, then mark it as reaching
     282              :              everything on the forced_labels list.  */
     283     15287477 :           else if (computed_jump_p (insn))
     284              :             {
     285              :               rtx_insn *insn;
     286              :               unsigned int i;
     287     15299552 :               FOR_EACH_VEC_SAFE_ELT (forced_labels, i, insn)
     288         1394 :                 make_label_edge (edge_cache, bb, insn, EDGE_ABNORMAL);
     289              :             }
     290              : 
     291              :           /* Returns create an exit out.  */
     292     15287001 :           else if (returnjump_p (insn))
     293       577696 :             cached_make_edge (edge_cache, bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
     294              : 
     295              :           /* Recognize asm goto and do the right thing.  */
     296     14709305 :           else if ((tmp = extract_asm_operands (PATTERN (insn))) != NULL)
     297              :             {
     298          780 :               int i, n = ASM_OPERANDS_LABEL_LENGTH (tmp);
     299         1919 :               for (i = 0; i < n; ++i)
     300         2278 :                 make_label_edge (edge_cache, bb,
     301         1139 :                                  label_ref_label (ASM_OPERANDS_LABEL (tmp, i)),
     302              :                                  0);
     303              :             }
     304              : 
     305              :           /* Otherwise, we have a plain conditional or unconditional jump.  */
     306              :           else
     307              :             {
     308     14708525 :               gcc_assert (JUMP_LABEL (insn));
     309     14708525 :               make_label_edge (edge_cache, bb, JUMP_LABEL (insn), 0);
     310              :             }
     311              :         }
     312              : 
     313              :       /* If this is a sibling call insn, then this is in effect a combined call
     314              :          and return, and so we need an edge to the exit block.  No need to
     315              :          worry about EH edges, since we wouldn't have created the sibling call
     316              :          in the first place.  */
     317     27085189 :       if (code == CALL_INSN && SIBLING_CALL_P (insn))
     318       162744 :         cached_make_edge (edge_cache, bb, EXIT_BLOCK_PTR_FOR_FN (cfun),
     319              :                           EDGE_SIBCALL | EDGE_ABNORMAL);
     320              : 
     321              :       /* If this is a CALL_INSN, then mark it as reaching the active EH
     322              :          handler for this CALL_INSN.  If we're handling non-call
     323              :          exceptions then any insn can reach any of the active handlers.
     324              :          Also mark the CALL_INSN as reaching any nonlocal goto handler.  */
     325     26922445 :       else if (code == CALL_INSN || cfun->can_throw_non_call_exceptions)
     326              :         {
     327              :           /* Add any appropriate EH edges.  */
     328      9874621 :           rtl_make_eh_edge (edge_cache, bb, insn);
     329              : 
     330      9874621 :           if (code == CALL_INSN)
     331              :             {
     332      2608692 :               if (can_nonlocal_goto (insn))
     333              :                 {
     334              :                   /* ??? This could be made smarter: in some cases it's
     335              :                      possible to tell that certain calls will not do a
     336              :                      nonlocal goto.  For example, if the nested functions
     337              :                      that do the nonlocal gotos do not have their addresses
     338              :                      taken, then only calls to those functions or to other
     339              :                      nested functions that use them could possibly do
     340              :                      nonlocal gotos.  */
     341        72716 :                   for (rtx_insn_list *x = nonlocal_goto_handler_labels;
     342        72716 :                        x;
     343        68292 :                        x = x->next ())
     344        68292 :                     make_label_edge (edge_cache, bb, x->insn (),
     345              :                                      EDGE_ABNORMAL | EDGE_ABNORMAL_CALL);
     346              :                 }
     347              : 
     348      2608692 :               if (flag_tm)
     349              :                 {
     350         1524 :                   rtx note;
     351         5004 :                   for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
     352         3480 :                     if (REG_NOTE_KIND (note) == REG_TM)
     353            0 :                       make_label_edge (edge_cache, bb, XEXP (note, 0),
     354              :                                        EDGE_ABNORMAL | EDGE_ABNORMAL_CALL);
     355              :                 }
     356              :             }
     357              :         }
     358              : 
     359              :       /* Find out if we can drop through to the next block.  */
     360     27085189 :       insn = NEXT_INSN (insn);
     361     27085189 :       e = find_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun));
     362     27085189 :       if (e && e->flags & EDGE_FALLTHRU)
     363     27085189 :         insn = NULL;
     364              : 
     365              :       while (insn
     366     25173037 :              && NOTE_P (insn)
     367     39488421 :              && NOTE_KIND (insn) != NOTE_INSN_BASIC_BLOCK)
     368         3658 :         insn = NEXT_INSN (insn);
     369              : 
     370     27085189 :       if (!insn)
     371      1915810 :         cached_make_edge (edge_cache, bb, EXIT_BLOCK_PTR_FOR_FN (cfun),
     372              :                           EDGE_FALLTHRU);
     373     25169379 :       else if (bb->next_bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
     374              :         {
     375     24544858 :           if (insn == BB_HEAD (bb->next_bb))
     376     18710369 :             cached_make_edge (edge_cache, bb, bb->next_bb, EDGE_FALLTHRU);
     377              :         }
     378              :     }
     379              : 
     380      4007259 :   if (edge_cache)
     381        46177 :     sbitmap_free (edge_cache);
     382      4007259 : }
     383              : 
     384              : static void
     385       169389 : mark_tablejump_edge (rtx_insn *label)
     386              : {
     387       169389 :   basic_block bb;
     388              : 
     389       169389 :   gcc_assert (LABEL_P (label));
     390              :   /* See comment in make_label_edge.  */
     391       169389 :   if (INSN_UID (label) == 0)
     392              :     return;
     393       169389 :   bb = BLOCK_FOR_INSN (label);
     394       169389 :   SET_STATE (bb, FULL_STATE (bb) | BLOCK_USED_BY_TABLEJUMP);
     395              : }
     396              : 
     397              : static void
     398         7415 : purge_dead_tablejump_edges (basic_block bb, rtx_jump_table_data *table)
     399              : {
     400         7415 :   rtx_insn *insn = BB_END (bb);
     401         7415 :   rtx tmp;
     402         7415 :   rtvec vec;
     403         7415 :   int j;
     404         7415 :   edge_iterator ei;
     405         7415 :   edge e;
     406              : 
     407         7415 :   vec = table->get_labels ();
     408              : 
     409       176804 :   for (j = GET_NUM_ELEM (vec) - 1; j >= 0; --j)
     410       169389 :     mark_tablejump_edge (label_ref_label (RTVEC_ELT (vec, j)));
     411              : 
     412              :   /* Some targets (eg, ARM) emit a conditional jump that also
     413              :      contains the out-of-range target.  Scan for these and
     414              :      add an edge if necessary.  */
     415         7415 :   if ((tmp = single_set (insn)) != NULL
     416         7415 :        && SET_DEST (tmp) == pc_rtx
     417         7415 :        && GET_CODE (SET_SRC (tmp)) == IF_THEN_ELSE
     418         7415 :        && GET_CODE (XEXP (SET_SRC (tmp), 2)) == LABEL_REF)
     419            0 :     mark_tablejump_edge (label_ref_label (XEXP (SET_SRC (tmp), 2)));
     420              : 
     421        89605 :   for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
     422              :     {
     423        82190 :       if (FULL_STATE (e->dest) & BLOCK_USED_BY_TABLEJUMP)
     424        80742 :         SET_STATE (e->dest, FULL_STATE (e->dest)
     425              :                             & ~(size_t) BLOCK_USED_BY_TABLEJUMP);
     426         1448 :       else if (!(e->flags & (EDGE_ABNORMAL | EDGE_EH)))
     427              :         {
     428         1448 :           remove_edge (e);
     429         1448 :           continue;
     430              :         }
     431        80742 :       ei_next (&ei);
     432              :     }
     433         7415 : }
     434              : 
     435              : /* Scan basic block BB for possible BB boundaries inside the block
     436              :    and create new basic blocks in the progress.  */
     437              : 
     438              : static void
     439     27313240 : find_bb_boundaries (basic_block bb)
     440              : {
     441     27313240 :   basic_block orig_bb = bb;
     442     27313240 :   rtx_insn *insn = BB_HEAD (bb);
     443     27313240 :   rtx_insn *end = BB_END (bb), *x;
     444     27313240 :   rtx_jump_table_data *table;
     445     27313240 :   rtx_insn *flow_transfer_insn = NULL;
     446     27313240 :   rtx_insn *debug_insn = NULL;
     447     27313240 :   edge fallthru = NULL;
     448     27313240 :   bool skip_purge;
     449     27313240 :   bool seen_note_after_debug = false;
     450              : 
     451     27313240 :   if (insn == end)
     452       157506 :     return;
     453              : 
     454     27167280 :   if (DEBUG_INSN_P (insn) || DEBUG_INSN_P (end))
     455              :     {
     456              :       /* Check whether, without debug insns, the insn==end test above
     457              :          would have caused us to return immediately, and behave the
     458              :          same way even with debug insns.  If we don't do this, debug
     459              :          insns could cause us to purge dead edges at different times,
     460              :          which could in turn change the cfg and affect codegen
     461              :          decisions in subtle but undesirable ways.  */
     462       420786 :       while (insn != end && DEBUG_INSN_P (insn))
     463            0 :         insn = NEXT_INSN (insn);
     464              :       rtx_insn *e = end;
     465      3485120 :       while (insn != e && DEBUG_INSN_P (e))
     466      3064334 :         e = PREV_INSN (e);
     467       420786 :       if (insn == e)
     468              :         {
     469              :           /* If there are debug insns after a single insn that is a
     470              :              control flow insn in the block, we'd have left right
     471              :              away, but we should clean up the debug insns after the
     472              :              control flow insn, because they can't remain in the same
     473              :              block.  So, do the debug insn cleaning up, but then bail
     474              :              out without purging dead edges as we would if the debug
     475              :              insns hadn't been there.  */
     476        11546 :           if (e != end && !DEBUG_INSN_P (e) && control_flow_insn_p (e))
     477              :             {
     478            0 :               skip_purge = true;
     479            0 :               flow_transfer_insn = e;
     480            0 :               goto clean_up_debug_after_control_flow;
     481              :             }
     482              :           return;
     483              :         }
     484              :     }
     485              : 
     486     27155734 :   if (LABEL_P (insn))
     487     12759466 :     insn = NEXT_INSN (insn);
     488              : 
     489              :   /* Scan insn chain and try to find new basic block boundaries.  */
     490    321995156 :   while (1)
     491              :     {
     492    349150890 :       enum rtx_code code = GET_CODE (insn);
     493              : 
     494    349150890 :       if (code == DEBUG_INSN)
     495              :         {
     496     88949517 :           if (flow_transfer_insn && !debug_insn)
     497              :             {
     498          477 :               debug_insn = insn;
     499          477 :               seen_note_after_debug = false;
     500              :             }
     501              :         }
     502              :       /* In case we've previously seen an insn that effects a control
     503              :          flow transfer, split the block.  */
     504    260201373 :       else if ((flow_transfer_insn || code == CODE_LABEL)
     505    260201373 :                && inside_basic_block_p (insn))
     506              :         {
     507      2597800 :           rtx_insn *prev = PREV_INSN (insn);
     508              : 
     509              :           /* If the first non-debug inside_basic_block_p insn after a control
     510              :              flow transfer is not a label, split the block before the debug
     511              :              insn instead of before the non-debug insn, so that the debug
     512              :              insns are not lost.  */
     513      2597800 :           if (debug_insn && code != CODE_LABEL && code != BARRIER)
     514              :             {
     515          477 :               prev = PREV_INSN (debug_insn);
     516          477 :               if (seen_note_after_debug)
     517              :                 {
     518              :                   /* Though, if there are NOTEs intermixed with DEBUG_INSNs,
     519              :                      move the NOTEs before the DEBUG_INSNs and split after
     520              :                      the last NOTE.  */
     521              :                   rtx_insn *first = NULL, *last = NULL;
     522            0 :                   for (x = debug_insn; x != insn; x = NEXT_INSN (x))
     523              :                     {
     524            0 :                       if (NOTE_P (x))
     525              :                         {
     526            0 :                           if (first == NULL)
     527            0 :                             first = x;
     528              :                           last = x;
     529              :                         }
     530              :                       else
     531              :                         {
     532            0 :                           gcc_assert (DEBUG_INSN_P (x));
     533            0 :                           if (first)
     534              :                             {
     535            0 :                               reorder_insns_nobb (first, last, prev);
     536            0 :                               prev = last;
     537            0 :                               first = last = NULL;
     538              :                             }
     539              :                         }
     540              :                     }
     541            0 :                   if (first)
     542              :                     {
     543            0 :                       reorder_insns_nobb (first, last, prev);
     544            0 :                       prev = last;
     545              :                     }
     546              :                 }
     547              :             }
     548      2597800 :           fallthru = split_block (bb, prev);
     549      2597800 :           if (flow_transfer_insn)
     550              :             {
     551      2062513 :               BB_END (bb) = flow_transfer_insn;
     552              : 
     553      2062513 :               rtx_insn *next;
     554              :               /* Clean up the bb field for the insns between the blocks.  */
     555      2062513 :               for (x = NEXT_INSN (flow_transfer_insn);
     556      2548088 :                    x != BB_HEAD (fallthru->dest);
     557       485575 :                    x = next)
     558              :                 {
     559       485575 :                   next = NEXT_INSN (x);
     560              :                   /* Debug insns should not be in between basic blocks,
     561              :                      drop them on the floor.  */
     562       485575 :                   if (DEBUG_INSN_P (x))
     563            0 :                     delete_insn (x);
     564       485575 :                   else if (!BARRIER_P (x))
     565            0 :                     set_block_for_insn (x, NULL);
     566              :                 }
     567              :             }
     568              : 
     569      2597800 :           bb = fallthru->dest;
     570      2597800 :           remove_edge (fallthru);
     571              :           /* BB is unreachable at this point - we need to determine its profile
     572              :              once edges are built.  */
     573      2597800 :           bb->count = profile_count::uninitialized ();
     574      2597800 :           flow_transfer_insn = NULL;
     575      2597800 :           debug_insn = NULL;
     576      2597800 :           if (code == CODE_LABEL && LABEL_ALT_ENTRY_P (insn))
     577            0 :             make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), bb, 0);
     578              :         }
     579    257603573 :       else if (code == BARRIER)
     580              :         {
     581              :           /* __builtin_unreachable () may cause a barrier to be emitted in
     582              :              the middle of a BB.  We need to split it in the same manner as
     583              :              if the barrier were preceded by a control_flow_insn_p insn.  */
     584       617821 :           if (!flow_transfer_insn)
     585            0 :             flow_transfer_insn = prev_nonnote_nondebug_insn_bb (insn);
     586              :           debug_insn = NULL;
     587              :         }
     588    256985752 :       else if (debug_insn)
     589              :         {
     590            0 :           if (code == NOTE)
     591              :             seen_note_after_debug = true;
     592              :           else
     593              :             /* Jump tables.  */
     594    256985752 :             debug_insn = NULL;
     595              :         }
     596              : 
     597    349150890 :       if (control_flow_insn_p (insn))
     598     20583923 :         flow_transfer_insn = insn;
     599    349150890 :       if (insn == end)
     600              :         break;
     601    321995156 :       insn = NEXT_INSN (insn);
     602    321995156 :     }
     603              : 
     604              :   /* In case expander replaced normal insn by sequence terminating by
     605              :      return and barrier, or possibly other sequence not behaving like
     606              :      ordinary jump, we need to take care and move basic block boundary.  */
     607     27155734 :   if (flow_transfer_insn && flow_transfer_insn != end)
     608              :     {
     609              :       skip_purge = false;
     610              : 
     611       132246 :     clean_up_debug_after_control_flow:
     612       132246 :       BB_END (bb) = flow_transfer_insn;
     613              : 
     614              :       /* Clean up the bb field for the insns that do not belong to BB.  */
     615       132246 :       rtx_insn *next;
     616       132246 :       for (x = NEXT_INSN (flow_transfer_insn); ; x = next)
     617              :         {
     618       132246 :           next = NEXT_INSN (x);
     619              :           /* Debug insns should not be in between basic blocks,
     620              :              drop them on the floor.  */
     621       132246 :           if (DEBUG_INSN_P (x))
     622            0 :             delete_insn (x);
     623       132246 :           else if (!BARRIER_P (x))
     624            0 :             set_block_for_insn (x, NULL);
     625       132246 :           if (x == end)
     626              :             break;
     627              :         }
     628              : 
     629       132246 :       if (skip_purge)
     630              :         return;
     631              :     }
     632              : 
     633              :   /* We've possibly replaced the conditional jump by conditional jump
     634              :      followed by cleanup at fallthru edge, so the outgoing edges may
     635              :      be dead.  */
     636     27155734 :   purge_dead_edges (bb);
     637              : 
     638              :   /* purge_dead_edges doesn't handle tablejump's, but if we have split the
     639              :      basic block, we might need to kill some edges.  */
     640     27155734 :   if (bb != orig_bb && tablejump_p (BB_END (bb), NULL, &table))
     641         7415 :     purge_dead_tablejump_edges (bb, table);
     642              : }
     643              : 
     644              : /*  Assume that frequency of basic block B is known.  Compute frequencies
     645              :     and probabilities of outgoing edges.  */
     646              : 
     647              : static void
     648      3257167 : compute_outgoing_frequencies (basic_block b)
     649              : {
     650      3257167 :   edge e, f;
     651      3257167 :   edge_iterator ei;
     652              : 
     653      3257167 :   if (EDGE_COUNT (b->succs) == 2)
     654              :     {
     655      1744040 :       rtx note = find_reg_note (BB_END (b), REG_BR_PROB, NULL);
     656      1744040 :       int probability;
     657              : 
     658      1744040 :       if (note)
     659              :         {
     660      1128363 :           probability = XINT (note, 0);
     661      1128363 :           e = BRANCH_EDGE (b);
     662      1128363 :           e->probability
     663      1128363 :                  = profile_probability::from_reg_br_prob_note (probability);
     664      1128363 :           f = FALLTHRU_EDGE (b);
     665      1128363 :           f->probability = e->probability.invert ();
     666      2630487 :           return;
     667              :         }
     668              :       else
     669              :         {
     670       615677 :           guess_outgoing_edge_probabilities (b);
     671              :         }
     672              :     }
     673      1513127 :   else if (single_succ_p (b))
     674              :     {
     675      1502124 :       e = single_succ_edge (b);
     676      1502124 :       e->probability = profile_probability::always ();
     677      1502124 :       return;
     678              :     }
     679              :   else
     680              :     {
     681              :       /* We rely on BBs with more than two successors to have sane probabilities
     682              :          and do not guess them here. For BBs terminated by switch statements
     683              :          expanded to jump-table jump, we have done the right thing during
     684              :          expansion. For EH edges, we still guess the probabilities here.  */
     685        11003 :       bool complex_edge = false;
     686        91804 :       FOR_EACH_EDGE (e, ei, b->succs)
     687        81879 :         if (e->flags & EDGE_COMPLEX)
     688              :           {
     689              :             complex_edge = true;
     690              :             break;
     691              :           }
     692        11003 :       if (complex_edge)
     693         1078 :         guess_outgoing_edge_probabilities (b);
     694              :     }
     695              : }
     696              : 
     697              : /* Update the profile information for BB, which was created by splitting
     698              :    an RTL block that had a non-final jump.  */
     699              : 
     700              : static void
     701      2205415 : update_profile_for_new_sub_basic_block (basic_block bb)
     702              : {
     703      2205415 :   edge e;
     704      2205415 :   edge_iterator ei;
     705              : 
     706      2205415 :   bool initialized_src = false, uninitialized_src = false;
     707      2205415 :   bb->count = profile_count::zero ();
     708      5037579 :   FOR_EACH_EDGE (e, ei, bb->preds)
     709              :     {
     710      2832164 :       if (e->count ().initialized_p ())
     711              :         {
     712      2799429 :           bb->count += e->count ();
     713      2799429 :           initialized_src = true;
     714              :         }
     715              :       else
     716              :         uninitialized_src = true;
     717              :     }
     718              :   /* When some edges are missing with read profile, this is
     719              :      most likely because RTL expansion introduced loop.
     720              :      When profile is guessed we may have BB that is reachable
     721              :      from unlikely path as well as from normal path.
     722              : 
     723              :      TODO: We should handle loops created during BB expansion
     724              :      correctly here.  For now we assume all those loop to cycle
     725              :      precisely once.  */
     726      2205415 :   if (!initialized_src
     727      2189892 :       || (uninitialized_src
     728        28496 :            && profile_status_for_fn (cfun) < PROFILE_GUESSED))
     729        15523 :     bb->count = profile_count::uninitialized ();
     730              : 
     731      2205415 :   compute_outgoing_frequencies (bb);
     732      2205415 : }
     733              : 
     734              : /* Assume that some pass has inserted labels or control flow
     735              :    instructions within a basic block.  Split basic blocks as needed
     736              :    and create edges.  */
     737              : 
     738              : void
     739      3747267 : find_many_sub_basic_blocks (sbitmap blocks)
     740              : {
     741      3747267 :   basic_block bb, min, max;
     742      3747267 :   bool found = false;
     743      3747267 :   auto_vec<unsigned int> n_succs;
     744      3747267 :   n_succs.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
     745              : 
     746     60458811 :   FOR_EACH_BB_FN (bb, cfun)
     747     89195691 :     SET_STATE (bb,
     748              :                bitmap_bit_p (blocks, bb->index) ? BLOCK_TO_SPLIT : BLOCK_ORIGINAL);
     749              : 
     750     62536615 :   FOR_EACH_BB_FN (bb, cfun)
     751     58789348 :     if (STATE (bb) == BLOCK_TO_SPLIT)
     752              :       {
     753     24227397 :         int n = last_basic_block_for_fn (cfun);
     754     24227397 :         unsigned int ns = EDGE_COUNT (bb->succs);
     755              : 
     756     24227397 :         find_bb_boundaries (bb);
     757     47316282 :         if (n == last_basic_block_for_fn (cfun) && ns == EDGE_COUNT (bb->succs))
     758     23295835 :           n_succs[bb->index] = EDGE_COUNT (bb->succs);
     759              :       }
     760              : 
     761      8649894 :   FOR_EACH_BB_FN (bb, cfun)
     762      8649894 :     if (STATE (bb) != BLOCK_ORIGINAL)
     763              :       {
     764              :         found = true;
     765              :         break;
     766              :       }
     767              : 
     768      3747267 :   if (!found)
     769            0 :     return;
     770              : 
     771              :   min = max = bb;
     772     57633988 :   for (; bb != EXIT_BLOCK_PTR_FOR_FN (cfun); bb = bb->next_bb)
     773     53886721 :     if (STATE (bb) != BLOCK_ORIGINAL)
     774     26305201 :       max = bb;
     775              : 
     776              :   /* Now re-scan and wire in all edges.  This expect simple (conditional)
     777              :      jumps at the end of each new basic blocks.  */
     778      3747267 :   make_edges (min, max, 1);
     779              : 
     780              :   /* Update branch probabilities.  Expect only (un)conditional jumps
     781              :      to be created with only the forward edges.  */
     782      3747267 :   if (profile_status_for_fn (cfun) != PROFILE_ABSENT)
     783     31299859 :     FOR_BB_BETWEEN (bb, min, max->next_bb, next_bb)
     784              :       {
     785     28659540 :         if (STATE (bb) == BLOCK_ORIGINAL)
     786      8185422 :           continue;
     787     20474118 :         if (STATE (bb) == BLOCK_NEW)
     788              :           {
     789      1716153 :             update_profile_for_new_sub_basic_block (bb);
     790      1716153 :             continue;
     791              :           }
     792              :         /* If nothing changed, there is no need to create new BBs.  */
     793     37498505 :         if (EDGE_COUNT (bb->succs) == n_succs[bb->index])
     794              :           {
     795              :             /* In rare occasions RTL expansion might have mistakely assigned
     796              :                a probabilities different from what is in CFG.  This happens
     797              :                when we try to split branch to two but optimize out the
     798              :                second branch during the way. See PR81030.  */
     799     10437268 :             if (JUMP_P (BB_END (bb)) && any_condjump_p (BB_END (bb))
     800     24748491 :                 && EDGE_COUNT (bb->succs) >= 2)
     801      6797651 :               update_br_prob_note (bb);
     802     17950840 :             continue;
     803              :           }
     804       807125 :         compute_outgoing_frequencies (bb);
     805              :       }
     806              : 
     807     62536615 :   FOR_EACH_BB_FN (bb, cfun)
     808     58789348 :     SET_STATE (bb, 0);
     809      3747267 : }
     810              : 
     811              : /* Like find_many_sub_basic_blocks, but look only within BB.  */
     812              : 
     813              : void
     814      3085843 : find_sub_basic_blocks (basic_block bb)
     815              : {
     816      3085843 :   basic_block end_bb = bb->next_bb;
     817      3085843 :   find_bb_boundaries (bb);
     818      3085843 :   if (bb->next_bb == end_bb)
     819              :     return;
     820              : 
     821              :   /* Re-scan and wire in all edges.  This expects simple (conditional)
     822              :      jumps at the end of each new basic blocks.  */
     823       259992 :   make_edges (bb, end_bb->prev_bb, 1);
     824              : 
     825              :   /* Update branch probabilities.  Expect only (un)conditional jumps
     826              :      to be created with only the forward edges.  */
     827       259992 :   if (profile_status_for_fn (cfun) != PROFILE_ABSENT)
     828              :     {
     829       244627 :       compute_outgoing_frequencies (bb);
     830       733889 :       for (bb = bb->next_bb; bb != end_bb; bb = bb->next_bb)
     831       489262 :         update_profile_for_new_sub_basic_block (bb);
     832              :     }
     833              : }
        

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