LCOV - code coverage report
Current view: top level - gcc - cfg.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 91.4 % 558 510
Test Date: 2024-04-20 14:03:02 Functions: 77.8 % 63 49
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Control flow graph manipulation code for GNU compiler.
       2                 :             :    Copyright (C) 1987-2024 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                 :             : /* This file contains low level functions to manipulate the CFG and
      21                 :             :    analyze it.  All other modules should not transform the data structure
      22                 :             :    directly and use abstraction instead.  The file is supposed to be
      23                 :             :    ordered bottom-up and should not contain any code dependent on a
      24                 :             :    particular intermediate language (RTL or trees).
      25                 :             : 
      26                 :             :    Available functionality:
      27                 :             :      - Initialization/deallocation
      28                 :             :          init_flow, free_cfg
      29                 :             :      - Low level basic block manipulation
      30                 :             :          alloc_block, expunge_block
      31                 :             :      - Edge manipulation
      32                 :             :          make_edge, make_single_succ_edge, cached_make_edge, remove_edge
      33                 :             :          - Low level edge redirection (without updating instruction chain)
      34                 :             :              redirect_edge_succ, redirect_edge_succ_nodup, redirect_edge_pred
      35                 :             :      - Dumping and debugging
      36                 :             :          dump_flow_info, debug_flow_info, dump_edge_info
      37                 :             :      - Allocation of AUX fields for basic blocks
      38                 :             :          alloc_aux_for_blocks, free_aux_for_blocks, alloc_aux_for_block
      39                 :             :      - clear_bb_flags
      40                 :             :      - Consistency checking
      41                 :             :          verify_flow_info
      42                 :             :      - Dumping and debugging
      43                 :             :          print_rtl_with_bb, dump_bb, debug_bb, debug_bb_n
      44                 :             : 
      45                 :             :    TODO: Document these "Available functionality" functions in the files
      46                 :             :    that implement them.
      47                 :             :  */
      48                 :             : 
      49                 :             : #include "config.h"
      50                 :             : #include "system.h"
      51                 :             : #include "coretypes.h"
      52                 :             : #include "backend.h"
      53                 :             : #include "hard-reg-set.h"
      54                 :             : #include "tree.h"
      55                 :             : #include "cfghooks.h"
      56                 :             : #include "df.h"
      57                 :             : #include "cfganal.h"
      58                 :             : #include "cfgloop.h" /* FIXME: For struct loop.  */
      59                 :             : #include "dumpfile.h"
      60                 :             : 
      61                 :             : 
      62                 :             : 
      63                 :             : /* Called once at initialization time.  */
      64                 :             : 
      65                 :             : void
      66                 :     3032382 : init_flow (struct function *the_fun)
      67                 :             : {
      68                 :     3032382 :   if (!the_fun->cfg)
      69                 :     3032382 :     the_fun->cfg = ggc_cleared_alloc<control_flow_graph> ();
      70                 :     3032382 :   n_edges_for_fn (the_fun) = 0;
      71                 :     3032382 :   the_fun->cfg->count_max = profile_count::uninitialized ();
      72                 :     3032382 :   ENTRY_BLOCK_PTR_FOR_FN (the_fun)
      73                 :     3032382 :     = alloc_block ();
      74                 :     3032382 :   ENTRY_BLOCK_PTR_FOR_FN (the_fun)->index = ENTRY_BLOCK;
      75                 :     3032382 :   EXIT_BLOCK_PTR_FOR_FN (the_fun)
      76                 :     3032382 :     = alloc_block ();
      77                 :     3032382 :   EXIT_BLOCK_PTR_FOR_FN (the_fun)->index = EXIT_BLOCK;
      78                 :     3032382 :   ENTRY_BLOCK_PTR_FOR_FN (the_fun)->next_bb
      79                 :     3032382 :     = EXIT_BLOCK_PTR_FOR_FN (the_fun);
      80                 :     3032382 :   EXIT_BLOCK_PTR_FOR_FN (the_fun)->prev_bb
      81                 :     3032382 :     = ENTRY_BLOCK_PTR_FOR_FN (the_fun);
      82                 :     3032382 :   the_fun->cfg->edge_flags_allocated = EDGE_ALL_FLAGS;
      83                 :     3032382 :   the_fun->cfg->bb_flags_allocated = BB_ALL_FLAGS;
      84                 :     3032382 :   the_fun->cfg->full_profile = false;
      85                 :     3032382 : }
      86                 :             : 
      87                 :             : /* Helper function for remove_edge and free_cffg.  Frees edge structure
      88                 :             :    without actually removing it from the pred/succ arrays.  */
      89                 :             : 
      90                 :             : static void
      91                 :    79723579 : free_edge (function *fn, edge e)
      92                 :             : {
      93                 :    79723579 :   n_edges_for_fn (fn)--;
      94                 :           0 :   ggc_free (e);
      95                 :           0 : }
      96                 :             : 
      97                 :             : /* Free basic block BB.  */
      98                 :             : 
      99                 :             : static void
     100                 :     7641731 : free_block (basic_block bb)
     101                 :             : {
     102                 :     7641731 :    vec_free (bb->succs);
     103                 :     7641731 :    bb->succs = NULL;
     104                 :     7641731 :    vec_free (bb->preds);
     105                 :     7641731 :    bb->preds = NULL;
     106                 :     7641731 :    ggc_free (bb);
     107                 :     7641731 : }
     108                 :             : 
     109                 :             : /* Free the memory associated with the CFG in FN.  */
     110                 :             : 
     111                 :             : void
     112                 :     1501913 : free_cfg (struct function *fn)
     113                 :             : {
     114                 :     1501913 :   edge e;
     115                 :     1501913 :   edge_iterator ei;
     116                 :     1501913 :   basic_block next;
     117                 :             : 
     118                 :     9143644 :   for (basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (fn); bb; bb = next)
     119                 :             :     {
     120                 :     7641731 :       next = bb->next_bb;
     121                 :    14932922 :       FOR_EACH_EDGE (e, ei, bb->succs)
     122                 :     7291191 :         free_edge (fn, e);
     123                 :     7641731 :       free_block (bb);
     124                 :             :     }
     125                 :             : 
     126                 :     1501913 :   gcc_assert (!n_edges_for_fn (fn));
     127                 :             :   /* Sanity check that dominance tree is freed.  */
     128                 :     1501913 :   gcc_assert (!fn->cfg->x_dom_computed[0] && !fn->cfg->x_dom_computed[1]);
     129                 :             :   
     130                 :     1501913 :   vec_free (fn->cfg->x_label_to_block_map);
     131                 :     1501913 :   vec_free (basic_block_info_for_fn (fn));
     132                 :     1501913 :   ggc_free (fn->cfg);
     133                 :     1501913 :   fn->cfg = NULL;
     134                 :     1501913 : }
     135                 :             : 
     136                 :             : /* Allocate memory for basic_block.  */
     137                 :             : 
     138                 :             : basic_block
     139                 :    79762439 : alloc_block (void)
     140                 :             : {
     141                 :    79762439 :   basic_block bb;
     142                 :    79762439 :   bb = ggc_cleared_alloc<basic_block_def> ();
     143                 :    79762439 :   bb->count = profile_count::uninitialized ();
     144                 :    79762439 :   return bb;
     145                 :             : }
     146                 :             : 
     147                 :             : /* Link block B to chain after AFTER.  */
     148                 :             : void
     149                 :    77667611 : link_block (basic_block b, basic_block after)
     150                 :             : {
     151                 :    77667611 :   b->next_bb = after->next_bb;
     152                 :    77667611 :   b->prev_bb = after;
     153                 :    77667611 :   after->next_bb = b;
     154                 :    77667611 :   b->next_bb->prev_bb = b;
     155                 :    77667611 : }
     156                 :             : 
     157                 :             : /* Unlink block B from chain.  */
     158                 :             : void
     159                 :    60248014 : unlink_block (basic_block b)
     160                 :             : {
     161                 :    60248014 :   b->next_bb->prev_bb = b->prev_bb;
     162                 :    60248014 :   b->prev_bb->next_bb = b->next_bb;
     163                 :    60248014 :   b->prev_bb = NULL;
     164                 :    60248014 :   b->next_bb = NULL;
     165                 :    60248014 : }
     166                 :             : 
     167                 :             : /* Sequentially order blocks and compact the arrays.  */
     168                 :             : void
     169                 :    50734961 : compact_blocks (void)
     170                 :             : {
     171                 :    50734961 :   int i;
     172                 :             : 
     173                 :    50734961 :   SET_BASIC_BLOCK_FOR_FN (cfun, ENTRY_BLOCK, ENTRY_BLOCK_PTR_FOR_FN (cfun));
     174                 :    50734961 :   SET_BASIC_BLOCK_FOR_FN (cfun, EXIT_BLOCK, EXIT_BLOCK_PTR_FOR_FN (cfun));
     175                 :             : 
     176                 :    50734961 :   if (df)
     177                 :    17014756 :     df_compact_blocks ();
     178                 :             :   else
     179                 :             :     {
     180                 :    33720205 :       basic_block bb;
     181                 :             : 
     182                 :    33720205 :       i = NUM_FIXED_BLOCKS;
     183                 :   375411031 :       FOR_EACH_BB_FN (bb, cfun)
     184                 :             :         {
     185                 :   341690826 :           SET_BASIC_BLOCK_FOR_FN (cfun, i, bb);
     186                 :   341690826 :           bb->index = i;
     187                 :   341690826 :           i++;
     188                 :             :         }
     189                 :    33720205 :       gcc_assert (i == n_basic_blocks_for_fn (cfun));
     190                 :             : 
     191                 :    91630665 :       for (; i < last_basic_block_for_fn (cfun); i++)
     192                 :    57910460 :         SET_BASIC_BLOCK_FOR_FN (cfun, i, NULL);
     193                 :             :     }
     194                 :    50734961 :   last_basic_block_for_fn (cfun) = n_basic_blocks_for_fn (cfun);
     195                 :    50734961 : }
     196                 :             : 
     197                 :             : /* Remove block B from the basic block array.  */
     198                 :             : 
     199                 :             : void
     200                 :    55711038 : expunge_block (basic_block b)
     201                 :             : {
     202                 :    55711038 :   unlink_block (b);
     203                 :    55711038 :   SET_BASIC_BLOCK_FOR_FN (cfun, b->index, NULL);
     204                 :    55711038 :   n_basic_blocks_for_fn (cfun)--;
     205                 :             :   /* We should be able to ggc_free here, but we are not.
     206                 :             :      The dead SSA_NAMES are left pointing to dead statements that are pointing
     207                 :             :      to dead basic blocks making garbage collector to die.
     208                 :             :      We should be able to release all dead SSA_NAMES and at the same time we
     209                 :             :      should clear out BB pointer of dead statements consistently.  */
     210                 :    55711038 : }
     211                 :             : 
     212                 :             : /* Connect E to E->src.  */
     213                 :             : 
     214                 :             : static inline void
     215                 :   102507440 : connect_src (edge e)
     216                 :             : {
     217                 :   102507440 :   vec_safe_push (e->src->succs, e);
     218                 :   102507440 :   df_mark_solutions_dirty ();
     219                 :   102507440 : }
     220                 :             : 
     221                 :             : /* Connect E to E->dest.  */
     222                 :             : 
     223                 :             : static inline void
     224                 :   176825441 : connect_dest (edge e)
     225                 :             : {
     226                 :   176825441 :   basic_block dest = e->dest;
     227                 :   176825441 :   vec_safe_push (dest->preds, e);
     228                 :   176825441 :   e->dest_idx = EDGE_COUNT (dest->preds) - 1;
     229                 :   176825441 :   df_mark_solutions_dirty ();
     230                 :   176825441 : }
     231                 :             : 
     232                 :             : /* Disconnect edge E from E->src.  */
     233                 :             : 
     234                 :             : static inline void
     235                 :    74386845 : disconnect_src (edge e)
     236                 :             : {
     237                 :    74386845 :   basic_block src = e->src;
     238                 :    74386845 :   edge_iterator ei;
     239                 :    74386845 :   edge tmp;
     240                 :             : 
     241                 :    78417405 :   for (ei = ei_start (src->succs); (tmp = ei_safe_edge (ei)); )
     242                 :             :     {
     243                 :    78417405 :       if (tmp == e)
     244                 :             :         {
     245                 :    74386845 :           src->succs->unordered_remove (ei.index);
     246                 :    74386845 :           df_mark_solutions_dirty ();
     247                 :    74386845 :           return;
     248                 :             :         }
     249                 :             :       else
     250                 :     4030560 :         ei_next (&ei);
     251                 :             :     }
     252                 :             : 
     253                 :           0 :   gcc_unreachable ();
     254                 :             : }
     255                 :             : 
     256                 :             : /* Disconnect edge E from E->dest.  */
     257                 :             : 
     258                 :             : static inline void
     259                 :   148704846 : disconnect_dest (edge e)
     260                 :             : {
     261                 :   148704846 :   basic_block dest = e->dest;
     262                 :   148704846 :   unsigned int dest_idx = e->dest_idx;
     263                 :             : 
     264                 :   148704846 :   dest->preds->unordered_remove (dest_idx);
     265                 :             : 
     266                 :             :   /* If we removed an edge in the middle of the edge vector, we need
     267                 :             :      to update dest_idx of the edge that moved into the "hole".  */
     268                 :   148704846 :   if (dest_idx < EDGE_COUNT (dest->preds))
     269                 :    74016683 :     EDGE_PRED (dest, dest_idx)->dest_idx = dest_idx;
     270                 :   148704846 :   df_mark_solutions_dirty ();
     271                 :   148704846 : }
     272                 :             : 
     273                 :             : /* Create an edge connecting SRC and DEST with flags FLAGS.  Return newly
     274                 :             :    created edge.  Use this only if you are sure that this edge can't
     275                 :             :    possibly already exist.  */
     276                 :             : 
     277                 :             : edge
     278                 :   100552983 : unchecked_make_edge (basic_block src, basic_block dst, int flags)
     279                 :             : {
     280                 :   100552983 :   edge e;
     281                 :   100552983 :   e = ggc_cleared_alloc<edge_def> ();
     282                 :   100552983 :   n_edges_for_fn (cfun)++;
     283                 :             : 
     284                 :   100552983 :   e->probability = profile_probability::uninitialized ();
     285                 :   100552983 :   e->src = src;
     286                 :   100552983 :   e->dest = dst;
     287                 :   100552983 :   e->flags = flags;
     288                 :             : 
     289                 :   100552983 :   connect_src (e);
     290                 :   100552983 :   connect_dest (e);
     291                 :             : 
     292                 :   100552983 :   execute_on_growing_pred (e);
     293                 :   100552983 :   return e;
     294                 :             : }
     295                 :             : 
     296                 :             : /* Create an edge connecting SRC and DST with FLAGS optionally using
     297                 :             :    edge cache CACHE.  Return the new edge, NULL if already exist.  */
     298                 :             : 
     299                 :             : edge
     300                 :    34657034 : cached_make_edge (sbitmap edge_cache, basic_block src, basic_block dst, int flags)
     301                 :             : {
     302                 :    34657034 :   if (edge_cache == NULL
     303                 :      292577 :       || src == ENTRY_BLOCK_PTR_FOR_FN (cfun)
     304                 :      292577 :       || dst == EXIT_BLOCK_PTR_FOR_FN (cfun))
     305                 :    34386755 :     return make_edge (src, dst, flags);
     306                 :             : 
     307                 :             :   /* Does the requested edge already exist?  */
     308                 :      270279 :   if (! bitmap_bit_p (edge_cache, dst->index))
     309                 :             :     {
     310                 :             :       /* The edge does not exist.  Create one and update the
     311                 :             :          cache.  */
     312                 :       36087 :       bitmap_set_bit (edge_cache, dst->index);
     313                 :       36087 :       return unchecked_make_edge (src, dst, flags);
     314                 :             :     }
     315                 :             : 
     316                 :             :   /* At this point, we know that the requested edge exists.  Adjust
     317                 :             :      flags if necessary.  */
     318                 :      234192 :   if (flags)
     319                 :             :     {
     320                 :      111082 :       edge e = find_edge (src, dst);
     321                 :      111082 :       e->flags |= flags;
     322                 :             :     }
     323                 :             : 
     324                 :             :   return NULL;
     325                 :             : }
     326                 :             : 
     327                 :             : /* Create an edge connecting SRC and DEST with flags FLAGS.  Return newly
     328                 :             :    created edge or NULL if already exist.  */
     329                 :             : 
     330                 :             : edge
     331                 :   129217533 : make_edge (basic_block src, basic_block dest, int flags)
     332                 :             : {
     333                 :   129217533 :   edge e = find_edge (src, dest);
     334                 :             : 
     335                 :             :   /* Make sure we don't add duplicate edges.  */
     336                 :   129217533 :   if (e)
     337                 :             :     {
     338                 :    35014519 :       e->flags |= flags;
     339                 :    35014519 :       return NULL;
     340                 :             :     }
     341                 :             : 
     342                 :    94203014 :   return unchecked_make_edge (src, dest, flags);
     343                 :             : }
     344                 :             : 
     345                 :             : /* Create an edge connecting SRC to DEST and set probability by knowing
     346                 :             :    that it is the single edge leaving SRC.  */
     347                 :             : 
     348                 :             : edge
     349                 :    38246264 : make_single_succ_edge (basic_block src, basic_block dest, int flags)
     350                 :             : {
     351                 :    38246264 :   edge e = make_edge (src, dest, flags);
     352                 :             : 
     353                 :    38246264 :   e->probability = profile_probability::always ();
     354                 :    38246264 :   return e;
     355                 :             : }
     356                 :             : 
     357                 :             : /* This function will remove an edge from the flow graph.  */
     358                 :             : 
     359                 :             : void
     360                 :    72432388 : remove_edge_raw (edge e)
     361                 :             : {
     362                 :    72432388 :   remove_predictions_associated_with_edge (e);
     363                 :    72432388 :   execute_on_shrinking_pred (e);
     364                 :             : 
     365                 :    72432388 :   disconnect_src (e);
     366                 :    72432388 :   disconnect_dest (e);
     367                 :             : 
     368                 :    72432388 :   free_edge (cfun, e);
     369                 :    72432388 : }
     370                 :             : 
     371                 :             : /* Redirect an edge's successor from one block to another.  */
     372                 :             : 
     373                 :             : void
     374                 :    76272458 : redirect_edge_succ (edge e, basic_block new_succ)
     375                 :             : {
     376                 :    76272458 :   execute_on_shrinking_pred (e);
     377                 :             : 
     378                 :    76272458 :   disconnect_dest (e);
     379                 :             : 
     380                 :    76272458 :   e->dest = new_succ;
     381                 :             : 
     382                 :             :   /* Reconnect the edge to the new successor block.  */
     383                 :    76272458 :   connect_dest (e);
     384                 :             : 
     385                 :    76272458 :   execute_on_growing_pred (e);
     386                 :    76272458 : }
     387                 :             : 
     388                 :             : /* Redirect an edge's predecessor from one block to another.  */
     389                 :             : 
     390                 :             : void
     391                 :     1954457 : redirect_edge_pred (edge e, basic_block new_pred)
     392                 :             : {
     393                 :     1954457 :   disconnect_src (e);
     394                 :             : 
     395                 :     1954457 :   e->src = new_pred;
     396                 :             : 
     397                 :             :   /* Reconnect the edge to the new predecessor block.  */
     398                 :     1954457 :   connect_src (e);
     399                 :     1954457 : }
     400                 :             : 
     401                 :             : /* Clear all basic block flags that do not have to be preserved.  */
     402                 :             : void
     403                 :     5220487 : clear_bb_flags (void)
     404                 :             : {
     405                 :     5220487 :   basic_block bb;
     406                 :     5220487 :   int flags_to_preserve = BB_FLAGS_TO_PRESERVE;
     407                 :     5220487 :   if (current_loops
     408                 :     5220487 :       && loops_state_satisfies_p (cfun, LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS))
     409                 :             :     flags_to_preserve |= BB_IRREDUCIBLE_LOOP;
     410                 :             : 
     411                 :    71670119 :   FOR_ALL_BB_FN (bb, cfun)
     412                 :    66449632 :     bb->flags &= flags_to_preserve;
     413                 :     5220487 : }
     414                 :             : 
     415                 :             : /* Check the consistency of profile information.  We can't do that
     416                 :             :    in verify_flow_info, as the counts may get invalid for incompletely
     417                 :             :    solved graphs, later eliminating of conditionals or roundoff errors.
     418                 :             :    It is still practical to have them reported for debugging of simple
     419                 :             :    testcases.  */
     420                 :             : static void
     421                 :       14612 : check_bb_profile (basic_block bb, FILE * file, int indent)
     422                 :             : {
     423                 :       14612 :   edge e;
     424                 :       14612 :   edge_iterator ei;
     425                 :       14612 :   struct function *fun = DECL_STRUCT_FUNCTION (current_function_decl);
     426                 :       14612 :   char *s_indent = (char *) alloca ((size_t) indent + 1);
     427                 :       14612 :   memset ((void *) s_indent, ' ', (size_t) indent);
     428                 :       14612 :   s_indent[indent] = '\0';
     429                 :             : 
     430                 :       14612 :   if (profile_status_for_fn (fun) == PROFILE_ABSENT)
     431                 :        2263 :     return;
     432                 :             : 
     433                 :       12349 :   if (bb != EXIT_BLOCK_PTR_FOR_FN (fun))
     434                 :             :     {
     435                 :       12349 :       bool found = false;
     436                 :       12349 :       profile_probability sum = profile_probability::never ();
     437                 :       12349 :       int isum = 0;
     438                 :             : 
     439                 :       28513 :       FOR_EACH_EDGE (e, ei, bb->succs)
     440                 :             :         {
     441                 :       16164 :           if (!(e->flags & (EDGE_EH | EDGE_FAKE)))
     442                 :       16160 :             found = true;
     443                 :       16164 :           sum += e->probability;
     444                 :       16164 :           if (e->probability.initialized_p ())
     445                 :       16164 :             isum += e->probability.to_reg_br_prob_base ();
     446                 :             :         }
     447                 :             :       /* Only report mismatches for non-EH control flow. If there are only EH
     448                 :             :          edges it means that the BB ends by noreturn call.  Here the control
     449                 :             :          flow may just terminate.  */
     450                 :       12349 :       if (found)
     451                 :             :         {
     452                 :       11097 :           if (sum.differs_from_p (profile_probability::always ()))
     453                 :             :             {
     454                 :           0 :               fprintf (file,
     455                 :             :                        ";; %sInvalid sum of outgoing probabilities ",
     456                 :             :                        s_indent);
     457                 :           0 :               sum.dump (file);
     458                 :           0 :               fprintf (file, "\n");
     459                 :             :             }
     460                 :             :           /* Probabilities caps to 100% and thus the previous test will never
     461                 :             :              fire if the sum of probabilities is too large.  */
     462                 :       11097 :           else if (isum > REG_BR_PROB_BASE + 100)
     463                 :             :             {
     464                 :         199 :               fprintf (file,
     465                 :             :                        ";; %sInvalid sum of outgoing probabilities %.1f%%\n",
     466                 :         199 :                        s_indent, isum * 100.0 / REG_BR_PROB_BASE);
     467                 :             :             }
     468                 :             :         }
     469                 :             :     }
     470                 :       12349 :   if (bb != ENTRY_BLOCK_PTR_FOR_FN (fun))
     471                 :             :     {
     472                 :       12349 :       profile_count sum = profile_count::zero ();
     473                 :       28890 :       FOR_EACH_EDGE (e, ei, bb->preds)
     474                 :       16541 :         sum += e->count ();
     475                 :       12349 :       if (sum.differs_from_p (bb->count))
     476                 :             :         {
     477                 :         416 :           fprintf (file, ";; %sInvalid sum of incoming counts ",
     478                 :             :                    s_indent);
     479                 :         416 :           sum.dump (file, fun);
     480                 :         416 :           fprintf (file, ", should be ");
     481                 :         416 :           bb->count.dump (file, fun);
     482                 :         416 :           fprintf (file, "\n");
     483                 :             :         }
     484                 :             :     }
     485                 :       12349 :   if (BB_PARTITION (bb) == BB_COLD_PARTITION)
     486                 :             :     {
     487                 :             :       /* Warn about inconsistencies in the partitioning that are
     488                 :             :          currently caused by profile insanities created via optimization.  */
     489                 :           1 :       if (!probably_never_executed_bb_p (fun, bb))
     490                 :           0 :         fprintf (file, ";; %sBlock in cold partition with hot count\n",
     491                 :             :                  s_indent);
     492                 :           2 :       FOR_EACH_EDGE (e, ei, bb->preds)
     493                 :             :         {
     494                 :           1 :           if (!probably_never_executed_edge_p (fun, e))
     495                 :           0 :             fprintf (file,
     496                 :             :                      ";; %sBlock in cold partition with incoming hot edge\n",
     497                 :             :                      s_indent);
     498                 :             :         }
     499                 :             :     }
     500                 :             : }
     501                 :             : 
     502                 :             : void
     503                 :       74049 : dump_edge_info (FILE *file, edge e, dump_flags_t flags, int do_succ)
     504                 :             : {
     505                 :       74049 :   basic_block side = (do_succ ? e->dest : e->src);
     506                 :       74049 :   bool do_details = false;
     507                 :             :   
     508                 :       74049 :   if ((flags & TDF_DETAILS) != 0
     509                 :       74049 :       && (flags & TDF_SLIM) == 0)
     510                 :             :     do_details = true;
     511                 :             : 
     512                 :       74049 :   if (side->index == ENTRY_BLOCK)
     513                 :        4729 :     fputs (" ENTRY", file);
     514                 :       69320 :   else if (side->index == EXIT_BLOCK)
     515                 :        4333 :     fputs (" EXIT", file);
     516                 :             :   else
     517                 :       64987 :     fprintf (file, " %d", side->index);
     518                 :             : 
     519                 :       74049 :   if (e->probability.initialized_p () && do_details)
     520                 :             :     {
     521                 :       38798 :       fprintf (file, " [");
     522                 :       38798 :       e->probability.dump (file);
     523                 :       38798 :       fprintf (file, "] ");
     524                 :             :     }
     525                 :             : 
     526                 :       74049 :   if (e->count ().initialized_p () && do_details)
     527                 :             :     {
     528                 :       36032 :       fputs (" count:", file);
     529                 :       36032 :       e->count ().dump (file, cfun);
     530                 :             :     }
     531                 :             : 
     532                 :       74049 :   if (e->flags && do_details)
     533                 :             :     {
     534                 :       39242 :       static const char * const bitnames[] =
     535                 :             :         {
     536                 :             : #define DEF_EDGE_FLAG(NAME,IDX) #NAME ,
     537                 :             : #include "cfg-flags.def"
     538                 :             :           NULL
     539                 :             : #undef DEF_EDGE_FLAG
     540                 :             :         };
     541                 :       39242 :       bool comma = false;
     542                 :       39242 :       int i, flags = e->flags;
     543                 :             : 
     544                 :       39242 :       gcc_assert (e->flags <= EDGE_ALL_FLAGS);
     545                 :       39242 :       fputs (" (", file);
     546                 :      424766 :       for (i = 0; flags; i++)
     547                 :      346282 :         if (flags & (1 << i))
     548                 :             :           {
     549                 :       67553 :             flags &= ~(1 << i);
     550                 :             : 
     551                 :       67553 :             if (comma)
     552                 :       28311 :               fputc (',', file);
     553                 :       67553 :             fputs (bitnames[i], file);
     554                 :       67553 :             comma = true;
     555                 :             :           }
     556                 :             : 
     557                 :       39242 :       fputc (')', file);
     558                 :             :     }
     559                 :             : 
     560                 :       43246 :   if (do_details && LOCATION_LOCUS (e->goto_locus) > BUILTINS_LOCATION)
     561                 :        3219 :     fprintf (file, " %s:%d:%d", LOCATION_FILE (e->goto_locus),
     562                 :        6438 :              LOCATION_LINE (e->goto_locus), LOCATION_COLUMN (e->goto_locus));
     563                 :       74049 : }
     564                 :             : 
     565                 :             : DEBUG_FUNCTION void
     566                 :           0 : debug (edge_def &ref)
     567                 :             : {
     568                 :           0 :   fprintf (stderr, "<edge (%d -> %d)>\n",
     569                 :           0 :            ref.src->index, ref.dest->index);
     570                 :           0 :   dump_edge_info (stderr, &ref, TDF_DETAILS, false);
     571                 :           0 :   fprintf (stderr, "\n");
     572                 :           0 : }
     573                 :             : 
     574                 :             : DEBUG_FUNCTION void
     575                 :           0 : debug (edge_def *ptr)
     576                 :             : {
     577                 :           0 :   if (ptr)
     578                 :           0 :     debug (*ptr);
     579                 :             :   else
     580                 :           0 :     fprintf (stderr, "<nil>\n");
     581                 :           0 : }
     582                 :             : 
     583                 :             : static void
     584                 :           0 : debug_slim (edge e)
     585                 :             : {
     586                 :           0 :   fprintf (stderr, "<edge 0x%p (%d -> %d)>", (void *) e,
     587                 :           0 :            e->src->index, e->dest->index);
     588                 :           0 : }
     589                 :             : 
     590                 :           0 : DEFINE_DEBUG_VEC (edge)
     591                 :           0 : DEFINE_DEBUG_HASH_SET (edge)
     592                 :             : 
     593                 :             : /* Simple routines to easily allocate AUX fields of basic blocks.  */
     594                 :             : 
     595                 :             : static struct obstack block_aux_obstack;
     596                 :             : static void *first_block_aux_obj = 0;
     597                 :             : static struct obstack edge_aux_obstack;
     598                 :             : static void *first_edge_aux_obj = 0;
     599                 :             : 
     600                 :             : /* Allocate a memory block of SIZE as BB->aux.  The obstack must
     601                 :             :    be first initialized by alloc_aux_for_blocks.  */
     602                 :             : 
     603                 :             : static void
     604                 :    53224485 : alloc_aux_for_block (basic_block bb, int size)
     605                 :             : {
     606                 :             :   /* Verify that aux field is clear.  */
     607                 :    53224485 :   gcc_assert (!bb->aux && first_block_aux_obj);
     608                 :    53224485 :   bb->aux = obstack_alloc (&block_aux_obstack, size);
     609                 :    53224485 :   memset (bb->aux, 0, size);
     610                 :    53224485 : }
     611                 :             : 
     612                 :             : /* Initialize the block_aux_obstack and if SIZE is nonzero, call
     613                 :             :    alloc_aux_for_block for each basic block.  */
     614                 :             : 
     615                 :             : void
     616                 :     4652564 : alloc_aux_for_blocks (int size)
     617                 :             : {
     618                 :     4652564 :   static int initialized;
     619                 :             : 
     620                 :     4652564 :   if (!initialized)
     621                 :             :     {
     622                 :      145991 :       gcc_obstack_init (&block_aux_obstack);
     623                 :      145991 :       initialized = 1;
     624                 :             :     }
     625                 :             :   else
     626                 :             :     /* Check whether AUX data are still allocated.  */
     627                 :     4506573 :     gcc_assert (!first_block_aux_obj);
     628                 :             : 
     629                 :     4652564 :   first_block_aux_obj = obstack_alloc (&block_aux_obstack, 0);
     630                 :     4652564 :   if (size)
     631                 :             :     {
     632                 :     4652564 :       basic_block bb;
     633                 :             : 
     634                 :    57877049 :       FOR_ALL_BB_FN (bb, cfun)
     635                 :    53224485 :         alloc_aux_for_block (bb, size);
     636                 :             :     }
     637                 :     4652564 : }
     638                 :             : 
     639                 :             : /* Clear AUX pointers of all blocks.  */
     640                 :             : 
     641                 :             : void
     642                 :    11968055 : clear_aux_for_blocks (void)
     643                 :             : {
     644                 :    11968055 :   basic_block bb;
     645                 :             : 
     646                 :   176110808 :   FOR_ALL_BB_FN (bb, cfun)
     647                 :   164142753 :     bb->aux = NULL;
     648                 :    11968055 : }
     649                 :             : 
     650                 :             : /* Free data allocated in block_aux_obstack and clear AUX pointers
     651                 :             :    of all blocks.  */
     652                 :             : 
     653                 :             : void
     654                 :     4652564 : free_aux_for_blocks (void)
     655                 :             : {
     656                 :     4652564 :   gcc_assert (first_block_aux_obj);
     657                 :     4652564 :   obstack_free (&block_aux_obstack, first_block_aux_obj);
     658                 :     4652564 :   first_block_aux_obj = NULL;
     659                 :             : 
     660                 :     4652564 :   clear_aux_for_blocks ();
     661                 :     4652564 : }
     662                 :             : 
     663                 :             : /* Allocate a memory edge of SIZE as E->aux.  The obstack must
     664                 :             :    be first initialized by alloc_aux_for_edges.  */
     665                 :             : 
     666                 :             : void
     667                 :    19470623 : alloc_aux_for_edge (edge e, int size)
     668                 :             : {
     669                 :             :   /* Verify that aux field is clear.  */
     670                 :    19470623 :   gcc_assert (!e->aux && first_edge_aux_obj);
     671                 :    19470623 :   e->aux = obstack_alloc (&edge_aux_obstack, size);
     672                 :    19470623 :   memset (e->aux, 0, size);
     673                 :    19470623 : }
     674                 :             : 
     675                 :             : /* Initialize the edge_aux_obstack and if SIZE is nonzero, call
     676                 :             :    alloc_aux_for_edge for each basic edge.  */
     677                 :             : 
     678                 :             : void
     679                 :     2277389 : alloc_aux_for_edges (int size)
     680                 :             : {
     681                 :     2277389 :   static int initialized;
     682                 :             : 
     683                 :     2277389 :   if (!initialized)
     684                 :             :     {
     685                 :      136335 :       gcc_obstack_init (&edge_aux_obstack);
     686                 :      136335 :       initialized = 1;
     687                 :             :     }
     688                 :             :   else
     689                 :             :     /* Check whether AUX data are still allocated.  */
     690                 :     2141054 :     gcc_assert (!first_edge_aux_obj);
     691                 :             : 
     692                 :     2277389 :   first_edge_aux_obj = obstack_alloc (&edge_aux_obstack, 0);
     693                 :     2277389 :   if (size)
     694                 :             :     {
     695                 :     2277389 :       basic_block bb;
     696                 :             : 
     697                 :    16685729 :       FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun),
     698                 :             :                       EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
     699                 :             :         {
     700                 :    14408340 :           edge e;
     701                 :    14408340 :           edge_iterator ei;
     702                 :             : 
     703                 :    33878963 :           FOR_EACH_EDGE (e, ei, bb->succs)
     704                 :    19470623 :             alloc_aux_for_edge (e, size);
     705                 :             :         }
     706                 :             :     }
     707                 :     2277389 : }
     708                 :             : 
     709                 :             : /* Clear AUX pointers of all edges.  */
     710                 :             : 
     711                 :             : void
     712                 :     5045925 : clear_aux_for_edges (void)
     713                 :             : {
     714                 :     5045925 :   basic_block bb;
     715                 :     5045925 :   edge e;
     716                 :             : 
     717                 :    76674938 :   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun),
     718                 :             :                   EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
     719                 :             :     {
     720                 :    71629013 :       edge_iterator ei;
     721                 :   174775099 :       FOR_EACH_EDGE (e, ei, bb->succs)
     722                 :   103146086 :         e->aux = NULL;
     723                 :             :     }
     724                 :     5045925 : }
     725                 :             : 
     726                 :             : /* Free data allocated in edge_aux_obstack and clear AUX pointers
     727                 :             :    of all edges.  */
     728                 :             : 
     729                 :             : void
     730                 :     2277389 : free_aux_for_edges (void)
     731                 :             : {
     732                 :     2277389 :   gcc_assert (first_edge_aux_obj);
     733                 :     2277389 :   obstack_free (&edge_aux_obstack, first_edge_aux_obj);
     734                 :     2277389 :   first_edge_aux_obj = NULL;
     735                 :             : 
     736                 :     2277389 :   clear_aux_for_edges ();
     737                 :     2277389 : }
     738                 :             : 
     739                 :             : DEBUG_FUNCTION void
     740                 :           0 : debug_bb (basic_block bb)
     741                 :             : {
     742                 :           0 :   debug_bb (bb, dump_flags);
     743                 :           0 : }
     744                 :             : 
     745                 :             : DEBUG_FUNCTION basic_block
     746                 :           0 : debug_bb_n (int n)
     747                 :             : {
     748                 :           0 :   basic_block bb = BASIC_BLOCK_FOR_FN (cfun, n);
     749                 :           0 :   debug_bb (bb);
     750                 :           0 :   return bb;
     751                 :             : }
     752                 :             : 
     753                 :             : /* Print BB with specified FLAGS.  */
     754                 :             : 
     755                 :             : DEBUG_FUNCTION void
     756                 :           0 : debug_bb (basic_block bb, dump_flags_t flags)
     757                 :             : {
     758                 :           0 :   dump_bb (stderr, bb, 0, flags);
     759                 :           0 : }
     760                 :             : 
     761                 :             : /* Print basic block numbered N with specified FLAGS.  */
     762                 :             : 
     763                 :             : DEBUG_FUNCTION basic_block
     764                 :           0 : debug_bb_n (int n, dump_flags_t flags)
     765                 :             : {
     766                 :           0 :   basic_block bb = BASIC_BLOCK_FOR_FN (cfun, n);
     767                 :           0 :   debug_bb (bb, flags);
     768                 :           0 :   return bb;
     769                 :             : }
     770                 :             : 
     771                 :             : /* Dumps cfg related information about basic block BB to OUTF.
     772                 :             :    If HEADER is true, dump things that appear before the instructions
     773                 :             :    contained in BB.  If FOOTER is true, dump things that appear after.
     774                 :             :    Flags are the TDF_* masks as documented in dumpfile.h.
     775                 :             :    NB: With TDF_DETAILS, it is assumed that cfun is available, so
     776                 :             :    that maybe_hot_bb_p and probably_never_executed_bb_p don't ICE.  */
     777                 :             : 
     778                 :             : void
     779                 :       83726 : dump_bb_info (FILE *outf, basic_block bb, int indent, dump_flags_t flags,
     780                 :             :               bool do_header, bool do_footer)
     781                 :             : {
     782                 :       83726 :   edge_iterator ei;
     783                 :       83726 :   edge e;
     784                 :       83726 :   static const char * const bb_bitnames[] =
     785                 :             :     {
     786                 :             : #define DEF_BASIC_BLOCK_FLAG(NAME,IDX) #NAME ,
     787                 :             : #include "cfg-flags.def"
     788                 :             :       NULL
     789                 :             : #undef DEF_BASIC_BLOCK_FLAG
     790                 :             :     };
     791                 :       83726 :   const unsigned n_bitnames = ARRAY_SIZE (bb_bitnames);
     792                 :       83726 :   bool first;
     793                 :       83726 :   char *s_indent = (char *) alloca ((size_t) indent + 1);
     794                 :       83726 :   memset ((void *) s_indent, ' ', (size_t) indent);
     795                 :       83726 :   s_indent[indent] = '\0';
     796                 :             : 
     797                 :       83726 :   gcc_assert (bb->flags <= BB_ALL_FLAGS);
     798                 :             : 
     799                 :       83726 :   if (do_header)
     800                 :             :     {
     801                 :       41945 :       unsigned i;
     802                 :             : 
     803                 :       41945 :       fputs (";; ", outf);
     804                 :       41945 :       fprintf (outf, "%sbasic block %d, loop depth %d",
     805                 :             :                s_indent, bb->index, bb_loop_depth (bb));
     806                 :       41945 :       if (flags & TDF_DETAILS)
     807                 :             :         {
     808                 :       14612 :           struct function *fun = DECL_STRUCT_FUNCTION (current_function_decl);
     809                 :       14612 :           if (bb->count.initialized_p ())
     810                 :             :             {
     811                 :       13462 :               fputs (", count ", outf);
     812                 :       13462 :               bb->count.dump (outf, cfun);
     813                 :             :             }
     814                 :       14612 :           if (maybe_hot_bb_p (fun, bb))
     815                 :       12702 :             fputs (", maybe hot", outf);
     816                 :       14612 :           if (probably_never_executed_bb_p (fun, bb))
     817                 :        1354 :             fputs (", probably never executed", outf);
     818                 :             :         }
     819                 :       41945 :       fputc ('\n', outf);
     820                 :             : 
     821                 :       41945 :       if (flags & TDF_DETAILS)
     822                 :             :         {
     823                 :       14612 :           check_bb_profile (bb, outf, indent);
     824                 :       14612 :           fputs (";; ", outf);
     825                 :       14612 :           fprintf (outf, "%s prev block ", s_indent);
     826                 :       14612 :           if (bb->prev_bb)
     827                 :       14582 :             fprintf (outf, "%d", bb->prev_bb->index);
     828                 :             :           else
     829                 :          30 :             fprintf (outf, "(nil)");
     830                 :       14612 :           fprintf (outf, ", next block ");
     831                 :       14612 :           if (bb->next_bb)
     832                 :       14582 :             fprintf (outf, "%d", bb->next_bb->index);
     833                 :             :           else
     834                 :          30 :             fprintf (outf, "(nil)");
     835                 :             : 
     836                 :       14612 :           fputs (", flags:", outf);
     837                 :       14612 :           first = true;
     838                 :      263016 :           for (i = 0; i < n_bitnames; i++)
     839                 :      233792 :             if (bb->flags & (1 << i))
     840                 :             :               {
     841                 :       37367 :                 if (first)
     842                 :       14612 :                   fputs (" (", outf);
     843                 :             :                 else
     844                 :       22755 :                   fputs (", ", outf);
     845                 :       37367 :                 first = false;
     846                 :       37367 :                 fputs (bb_bitnames[i], outf);
     847                 :             :               }
     848                 :       14612 :           if (!first)
     849                 :       14612 :             fputc (')', outf);
     850                 :       14612 :           fputc ('\n', outf);
     851                 :             :         }
     852                 :             : 
     853                 :       41945 :       fputs (";; ", outf);
     854                 :       41945 :       fprintf (outf, "%s pred:      ", s_indent);
     855                 :       41945 :       first = true;
     856                 :       69095 :       FOR_EACH_EDGE (e, ei, bb->preds)
     857                 :             :         {
     858                 :       27150 :           if (! first)
     859                 :             :             {
     860                 :        6142 :               fputs (";; ", outf);
     861                 :        6142 :               fprintf (outf, "%s            ", s_indent);
     862                 :             :             }
     863                 :       27150 :           first = false;
     864                 :       27150 :           dump_edge_info (outf, e, flags, 0);
     865                 :       27150 :           fputc ('\n', outf);
     866                 :             :         }
     867                 :       41945 :       if (first)
     868                 :       20937 :         fputc ('\n', outf);
     869                 :             :     }
     870                 :             : 
     871                 :       83726 :   if (do_footer)
     872                 :             :     {
     873                 :       41945 :       fputs (";; ", outf);
     874                 :       41945 :       fprintf (outf, "%s succ:      ", s_indent);
     875                 :       41945 :       first = true;
     876                 :       83687 :       FOR_EACH_EDGE (e, ei, bb->succs)
     877                 :             :         {
     878                 :       41742 :           if (! first)
     879                 :             :             {
     880                 :        8234 :               fputs (";; ", outf);
     881                 :        8234 :               fprintf (outf, "%s            ", s_indent);
     882                 :             :             }
     883                 :       41742 :           first = false;
     884                 :       41742 :           dump_edge_info (outf, e, flags, 1);
     885                 :       41742 :           fputc ('\n', outf);
     886                 :             :         }
     887                 :       41945 :       if (first)
     888                 :        8437 :         fputc ('\n', outf);
     889                 :             :     }
     890                 :       83726 : }
     891                 :             : 
     892                 :             : /* Dumps a brief description of cfg to FILE.  */
     893                 :             : 
     894                 :             : void
     895                 :          22 : brief_dump_cfg (FILE *file, dump_flags_t flags)
     896                 :             : {
     897                 :          22 :   basic_block bb;
     898                 :             : 
     899                 :         186 :   FOR_EACH_BB_FN (bb, cfun)
     900                 :             :     {
     901                 :         164 :       dump_bb_info (file, bb, 0, flags & TDF_DETAILS, true, true);
     902                 :             :     }
     903                 :          22 : }
     904                 :             : 
     905                 :             : /* Set probability of E to NEW_PROB and rescale other edges
     906                 :             :    from E->src so their sum remains the same.  */
     907                 :             : 
     908                 :             : void
     909                 :     1328505 : set_edge_probability_and_rescale_others (edge e, profile_probability new_prob)
     910                 :             : {
     911                 :     1328505 :   edge e2;
     912                 :     1328505 :   edge_iterator ei;
     913                 :     1328505 :   if (e->probability == new_prob)
     914                 :       40183 :     return;
     915                 :             :   /* If we made E unconditional, drop other frequencies to 0.  */
     916                 :     1288322 :   if (new_prob == profile_probability::always ())
     917                 :             :     {
     918                 :           3 :       FOR_EACH_EDGE (e2, ei, e->src->succs)
     919                 :           2 :         if (e2 != e)
     920                 :           1 :           e2->probability = profile_probability::never ();
     921                 :             :     }
     922                 :             :   else
     923                 :             :     {
     924                 :     1288321 :       int n = 0;
     925                 :     1288321 :       edge other_e = NULL;
     926                 :             : 
     927                 :             :       /* See how many other edges are leaving exit_edge->src.  */
     928                 :     3870260 :       FOR_EACH_EDGE (e2, ei, e->src->succs)
     929                 :     2581939 :         if (e2 != e && !(e2->flags & EDGE_FAKE))
     930                 :             :           {
     931                 :     1293618 :             other_e = e2;
     932                 :     1293618 :             n++;
     933                 :             :           }
     934                 :             :       /* If there is only one other edge with non-zero probability we do not
     935                 :             :          need to scale which drops quality of profile from precise
     936                 :             :          to adjusted.  */
     937                 :     1288321 :       if (n == 1)
     938                 :     1287066 :         other_e->probability = new_prob.invert ();
     939                 :             :       /* Nothing to do if there are no other edges.  */
     940                 :        1255 :       else if (!n)
     941                 :             :         ;
     942                 :             :       /* Do scaling if possible.  */
     943                 :        1255 :       else if (e->probability.invert ().nonzero_p ())
     944                 :             :         {
     945                 :        1255 :           profile_probability num = new_prob.invert (),
     946                 :        1255 :                               den = e->probability.invert ();
     947                 :        9062 :           FOR_EACH_EDGE (e2, ei, e->src->succs)
     948                 :        7807 :             if (e2 != e && !(e2->flags & EDGE_FAKE))
     949                 :        6552 :               e2->probability = e2->probability.apply_scale (num, den);
     950                 :             :         }
     951                 :             :       else
     952                 :             :         {
     953                 :           0 :           if (dump_file && (dump_flags & TDF_DETAILS))
     954                 :           0 :             fprintf (dump_file,
     955                 :             :                      ";; probability of edge %i->%i set reduced from 1."
     956                 :             :                      " The remaining edges are left inconsistent.\n",
     957                 :           0 :                      e->src->index, e->dest->index);
     958                 :           0 :           FOR_EACH_EDGE (e2, ei, e->src->succs)
     959                 :           0 :             if (e2 != e && !(e2->flags & EDGE_FAKE))
     960                 :           0 :               e2->probability = new_prob.invert ().guessed () / n;
     961                 :             :         }
     962                 :             :     }
     963                 :     1288322 :   e->probability = new_prob;
     964                 :             : }
     965                 :             : 
     966                 :             : /* An edge originally destinating BB of COUNT has been proved to
     967                 :             :    leave the block by TAKEN_EDGE.  Update profile of BB such that edge E can be
     968                 :             :    redirected to destination of TAKEN_EDGE.
     969                 :             : 
     970                 :             :    This function may leave the profile inconsistent in the case TAKEN_EDGE
     971                 :             :    frequency or count is believed to be lower than COUNT
     972                 :             :    respectively.  */
     973                 :             : void
     974                 :      876158 : update_bb_profile_for_threading (basic_block bb, 
     975                 :             :                                  profile_count count, edge taken_edge)
     976                 :             : {
     977                 :      876158 :   gcc_assert (bb == taken_edge->src);
     978                 :             : 
     979                 :             :   /* If there is no profile or the threaded path is never executed
     980                 :             :      we don't need to upate.  */
     981                 :      876158 :   if (!bb->count.initialized_p ()
     982                 :     1752316 :       || count == profile_count::zero ())
     983                 :         218 :     return;
     984                 :             : 
     985                 :      875940 :   if (bb->count < count)
     986                 :             :     {
     987                 :         493 :       if (dump_file)
     988                 :           0 :         fprintf (dump_file, "bb %i count became negative after threading",
     989                 :             :                  bb->index);
     990                 :             :       /* If probabilities looks very off, scale down and reduce to guesses
     991                 :             :          to avoid dropping the other path close to zero.  */
     992                 :         493 :       if (bb->count < count.apply_scale (7, 8))
     993                 :         210 :         count = bb->count.apply_scale (1, 2).guessed ();
     994                 :             :     }
     995                 :             : 
     996                 :             :   /* If bb->count will become zero, the probabilities on the original path
     997                 :             :      are not really known, but it is probably better to keep original ones
     998                 :             :      then try to invent something new.  */
     999                 :      875940 :   if (!(bb->count <= count))
    1000                 :             :     {
    1001                 :      748875 :       profile_probability prob;
    1002                 :             :       /* Compute the probability of TAKEN_EDGE being reached via threaded edge.
    1003                 :             :          Watch for overflows.  */
    1004                 :      748875 :       if (bb->count.nonzero_p ())
    1005                 :      748875 :         prob = count.probability_in (bb->count);
    1006                 :             :       else
    1007                 :           0 :         prob = taken_edge->probability.apply_scale (1, 2).guessed ();
    1008                 :      748875 :       if (prob > taken_edge->probability)
    1009                 :             :         {
    1010                 :      155704 :           if (dump_file)
    1011                 :             :             {
    1012                 :          18 :               fprintf (dump_file, "Jump threading proved that the probability "
    1013                 :             :                        "of edge %i->%i was originally estimated too small. "
    1014                 :             :                        "(it is ",
    1015                 :          18 :                        taken_edge->src->index, taken_edge->dest->index);
    1016                 :          18 :               taken_edge->probability.dump (dump_file);
    1017                 :          18 :               fprintf (dump_file, " should be ");
    1018                 :          18 :               prob.dump (dump_file);
    1019                 :          18 :               fprintf (dump_file, ")\n");
    1020                 :             :             }
    1021                 :      155704 :           prob = taken_edge->probability.apply_scale (6, 8).guessed ();
    1022                 :             :         }
    1023                 :      748875 :       set_edge_probability_and_rescale_others (taken_edge,
    1024                 :     1497750 :                                                (taken_edge->probability - prob)
    1025                 :     1497750 :                                                / prob.invert ());
    1026                 :             :     }
    1027                 :      875940 :   bb->count -= count;
    1028                 :             : }
    1029                 :             : 
    1030                 :             : /* Multiply all frequencies of basic blocks in array BBS of length NBBS
    1031                 :             :    by NUM/DEN, in profile_count arithmetic.  More accurate than previous
    1032                 :             :    function but considerably slower.  */
    1033                 :             : void
    1034                 :     1714236 : scale_bbs_frequencies_profile_count (basic_block *bbs, int nbbs,
    1035                 :             :                                      profile_count num, profile_count den)
    1036                 :             : {
    1037                 :     1714236 :   int i;
    1038                 :     3528967 :   if (num == profile_count::zero () || den.nonzero_p ())
    1039                 :     3426366 :     for (i = 0; i < nbbs; i++)
    1040                 :     1713185 :       bbs[i]->count = bbs[i]->count.apply_scale (num, den);
    1041                 :     1714236 : }
    1042                 :             : 
    1043                 :             : /* Multiply all frequencies of basic blocks in array BBS of length NBBS
    1044                 :             :    by NUM/DEN, in profile_count arithmetic.  More accurate than previous
    1045                 :             :    function but considerably slower.  */
    1046                 :             : void
    1047                 :      823931 : scale_bbs_frequencies (basic_block *bbs, int nbbs,
    1048                 :             :                        profile_probability p)
    1049                 :             : {
    1050                 :      823931 :   int i;
    1051                 :             : 
    1052                 :     2930526 :   for (i = 0; i < nbbs; i++)
    1053                 :     2106595 :     bbs[i]->count = bbs[i]->count.apply_probability (p);
    1054                 :      823931 : }
    1055                 :             : 
    1056                 :             : /* Data structures used to maintain mapping between basic blocks and
    1057                 :             :    copies.  */
    1058                 :             : typedef hash_map<int_hash<int, -1, -2>, int> copy_map_t;
    1059                 :             : static copy_map_t *bb_original;
    1060                 :             : static copy_map_t *bb_copy;
    1061                 :             : 
    1062                 :             : /* And between loops and copies.  */
    1063                 :             : static copy_map_t *loop_copy;
    1064                 :             : 
    1065                 :             : /* Initialize the data structures to maintain mapping between blocks
    1066                 :             :    and its copies.  */
    1067                 :             : void
    1068                 :     5853774 : initialize_original_copy_tables (void)
    1069                 :             : {
    1070                 :     5853774 :   bb_original = new copy_map_t (10);
    1071                 :     5853774 :   bb_copy = new copy_map_t (10);
    1072                 :     5853774 :   loop_copy = new copy_map_t (10);
    1073                 :     5853774 : }
    1074                 :             : 
    1075                 :             : /* Reset the data structures to maintain mapping between blocks and
    1076                 :             :    its copies.  */
    1077                 :             : 
    1078                 :             : void
    1079                 :         210 : reset_original_copy_tables (void)
    1080                 :             : {
    1081                 :         210 :   bb_original->empty ();
    1082                 :         210 :   bb_copy->empty ();
    1083                 :         210 :   loop_copy->empty ();
    1084                 :         210 : }
    1085                 :             : 
    1086                 :             : /* Free the data structures to maintain mapping between blocks and
    1087                 :             :    its copies.  */
    1088                 :             : void
    1089                 :     5853774 : free_original_copy_tables (void)
    1090                 :             : {
    1091                 :    11707548 :   delete bb_copy;
    1092                 :     5853774 :   bb_copy = NULL;
    1093                 :    11707548 :   delete bb_original;
    1094                 :     5853774 :   bb_original = NULL;
    1095                 :    11707548 :   delete loop_copy;
    1096                 :     5853774 :   loop_copy = NULL;
    1097                 :     5853774 : }
    1098                 :             : 
    1099                 :             : /* Return true iff we have had a call to initialize_original_copy_tables
    1100                 :             :    without a corresponding call to free_original_copy_tables.  */
    1101                 :             : 
    1102                 :             : bool
    1103                 :    26033713 : original_copy_tables_initialized_p (void)
    1104                 :             : {
    1105                 :    26033713 :   return bb_copy != NULL;
    1106                 :             : }
    1107                 :             : 
    1108                 :             : /* Removes the value associated with OBJ from table TAB.  */
    1109                 :             : 
    1110                 :             : static void
    1111                 :      243996 : copy_original_table_clear (copy_map_t *tab, unsigned obj)
    1112                 :             : {
    1113                 :      243996 :   if (!original_copy_tables_initialized_p ())
    1114                 :             :     return;
    1115                 :             : 
    1116                 :      243996 :   tab->remove (obj);
    1117                 :             : }
    1118                 :             : 
    1119                 :             : /* Sets the value associated with OBJ in table TAB to VAL.
    1120                 :             :    Do nothing when data structures are not initialized.  */
    1121                 :             : 
    1122                 :             : static void
    1123                 :     9209787 : copy_original_table_set (copy_map_t *tab,
    1124                 :             :                          unsigned obj, unsigned val)
    1125                 :             : {
    1126                 :     9209787 :   if (!original_copy_tables_initialized_p ())
    1127                 :             :     return;
    1128                 :             : 
    1129                 :     9164823 :   tab->put (obj, val);
    1130                 :             : }
    1131                 :             : 
    1132                 :             : /* Set original for basic block.  Do nothing when data structures are not
    1133                 :             :    initialized so passes not needing this don't need to care.  */
    1134                 :             : void
    1135                 :     3627402 : set_bb_original (basic_block bb, basic_block original)
    1136                 :             : {
    1137                 :     3627402 :   copy_original_table_set (bb_original, bb->index, original->index);
    1138                 :     3627402 : }
    1139                 :             : 
    1140                 :             : /* Get the original basic block.  */
    1141                 :             : basic_block
    1142                 :     3215992 : get_bb_original (basic_block bb)
    1143                 :             : {
    1144                 :     3215992 :   gcc_assert (original_copy_tables_initialized_p ());
    1145                 :             : 
    1146                 :     3215992 :   int *entry = bb_original->get (bb->index);
    1147                 :     3215992 :   if (entry)
    1148                 :     2974566 :     return BASIC_BLOCK_FOR_FN (cfun, *entry);
    1149                 :             :   else
    1150                 :             :     return NULL;
    1151                 :             : }
    1152                 :             : 
    1153                 :             : /* Set copy for basic block.  Do nothing when data structures are not
    1154                 :             :    initialized so passes not needing this don't need to care.  */
    1155                 :             : void
    1156                 :     3627402 : set_bb_copy (basic_block bb, basic_block copy)
    1157                 :             : {
    1158                 :     3627402 :   copy_original_table_set (bb_copy, bb->index, copy->index);
    1159                 :     3627402 : }
    1160                 :             : 
    1161                 :             : /* Get the copy of basic block.  */
    1162                 :             : basic_block
    1163                 :     6980795 : get_bb_copy (basic_block bb)
    1164                 :             : {
    1165                 :     6980795 :   gcc_assert (original_copy_tables_initialized_p ());
    1166                 :             : 
    1167                 :     6980795 :   int *entry = bb_copy->get (bb->index);
    1168                 :     6980795 :   if (entry)
    1169                 :     6961049 :     return BASIC_BLOCK_FOR_FN (cfun, *entry);
    1170                 :             :   else
    1171                 :             :     return NULL;
    1172                 :             : }
    1173                 :             : 
    1174                 :             : /* Set copy for LOOP to COPY.  Do nothing when data structures are not
    1175                 :             :    initialized so passes not needing this don't need to care.  */
    1176                 :             : 
    1177                 :             : void
    1178                 :     2198979 : set_loop_copy (class loop *loop, class loop *copy)
    1179                 :             : {
    1180                 :     2198979 :   if (!copy)
    1181                 :      243996 :     copy_original_table_clear (loop_copy, loop->num);
    1182                 :             :   else
    1183                 :     1954983 :     copy_original_table_set (loop_copy, loop->num, copy->num);
    1184                 :     2198979 : }
    1185                 :             : 
    1186                 :             : /* Get the copy of LOOP.  */
    1187                 :             : 
    1188                 :             : class loop *
    1189                 :     3361633 : get_loop_copy (class loop *loop)
    1190                 :             : {
    1191                 :     3361633 :   gcc_assert (original_copy_tables_initialized_p ());
    1192                 :             : 
    1193                 :     3361633 :   int *entry = loop_copy->get (loop->num);
    1194                 :     3361633 :   if (entry)
    1195                 :     3080143 :     return get_loop (cfun, *entry);
    1196                 :             :   else
    1197                 :             :     return NULL;
    1198                 :             : }
    1199                 :             : 
    1200                 :             : /* Scales the frequencies of all basic blocks that are strictly
    1201                 :             :    dominated by BB by NUM/DEN.  */
    1202                 :             : 
    1203                 :             : void
    1204                 :          14 : scale_strictly_dominated_blocks (basic_block bb,
    1205                 :             :                                  profile_count num, profile_count den)
    1206                 :             : {
    1207                 :          14 :   basic_block son;
    1208                 :             : 
    1209                 :          14 :   if (!den.nonzero_p () && !(num == profile_count::zero ()))
    1210                 :           0 :     return;
    1211                 :          14 :   auto_vec <basic_block, 8> worklist;
    1212                 :          14 :   worklist.safe_push (bb);
    1213                 :             : 
    1214                 :         104 :   while (!worklist.is_empty ())
    1215                 :          62 :     for (son = first_dom_son (CDI_DOMINATORS, worklist.pop ());
    1216                 :         110 :          son;
    1217                 :          48 :          son = next_dom_son (CDI_DOMINATORS, son))
    1218                 :             :       {
    1219                 :          48 :         son->count = son->count.apply_scale (num, den);
    1220                 :          48 :         worklist.safe_push (son);
    1221                 :             :       }
    1222                 :          14 : }
        

Generated by: LCOV version 2.1-beta

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