LCOV - code coverage report
Current view: top level - gcc - profile.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 85.7 % 976 836
Test Date: 2026-08-22 16:33:35 Functions: 90.9 % 33 30
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Calculate branch probabilities, and basic block execution counts.
       2              :    Copyright (C) 1990-2026 Free Software Foundation, Inc.
       3              :    Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
       4              :    based on some ideas from Dain Samples of UC Berkeley.
       5              :    Further mangling by Bob Manson, Cygnus Support.
       6              : 
       7              : This file is part of GCC.
       8              : 
       9              : GCC is free software; you can redistribute it and/or modify it under
      10              : the terms of the GNU General Public License as published by the Free
      11              : Software Foundation; either version 3, or (at your option) any later
      12              : version.
      13              : 
      14              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      15              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      16              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      17              : for more details.
      18              : 
      19              : You should have received a copy of the GNU General Public License
      20              : along with GCC; see the file COPYING3.  If not see
      21              : <http://www.gnu.org/licenses/>.  */
      22              : 
      23              : /* Generate basic block profile instrumentation and auxiliary files.
      24              :    Profile generation is optimized, so that not all arcs in the basic
      25              :    block graph need instrumenting. First, the BB graph is closed with
      26              :    one entry (function start), and one exit (function exit).  Any
      27              :    ABNORMAL_EDGE cannot be instrumented (because there is no control
      28              :    path to place the code). We close the graph by inserting fake
      29              :    EDGE_FAKE edges to the EXIT_BLOCK, from the sources of abnormal
      30              :    edges that do not go to the exit_block. We ignore such abnormal
      31              :    edges.  Naturally these fake edges are never directly traversed,
      32              :    and so *cannot* be directly instrumented.  Some other graph
      33              :    massaging is done. To optimize the instrumentation we generate the
      34              :    BB minimal span tree, only edges that are not on the span tree
      35              :    (plus the entry point) need instrumenting. From that information
      36              :    all other edge counts can be deduced.  By construction all fake
      37              :    edges must be on the spanning tree. We also attempt to place
      38              :    EDGE_CRITICAL edges on the spanning tree.
      39              : 
      40              :    The auxiliary files generated are <dumpbase>.gcno (at compile time)
      41              :    and <dumpbase>.gcda (at run time).  The format is
      42              :    described in full in gcov-io.h.  */
      43              : 
      44              : /* ??? Register allocation should use basic block execution counts to
      45              :    give preference to the most commonly executed blocks.  */
      46              : 
      47              : /* ??? Should calculate branch probabilities before instrumenting code, since
      48              :    then we can use arc counts to help decide which arcs to instrument.  */
      49              : 
      50              : #include "config.h"
      51              : #include "system.h"
      52              : #include "coretypes.h"
      53              : #include "backend.h"
      54              : #include "rtl.h"
      55              : #include "tree.h"
      56              : #include "gimple.h"
      57              : #include "cfghooks.h"
      58              : #include "cgraph.h"
      59              : #include "coverage.h"
      60              : #include "diagnostic-core.h"
      61              : #include "cfganal.h"
      62              : #include "value-prof.h"
      63              : #include "gimple-iterator.h"
      64              : #include "tree-cfg.h"
      65              : #include "dumpfile.h"
      66              : #include "cfgloop.h"
      67              : #include "sreal.h"
      68              : #include "file-prefix-map.h"
      69              : #include "stringpool.h"
      70              : #include "attribs.h"
      71              : 
      72              : #include "profile.h"
      73              : #include "auto-profile.h"
      74              : 
      75              : struct condcov;
      76              : struct condcov *find_conditions (struct function*);
      77              : size_t cov_length (const struct condcov*);
      78              : array_slice<basic_block> cov_blocks (struct condcov*, size_t);
      79              : array_slice<uint64_t> cov_masks (struct condcov*, size_t);
      80              : array_slice<sbitmap> cov_maps (struct condcov* cov, size_t n);
      81              : void cov_free (struct condcov*);
      82              : size_t instrument_decisions (array_slice<basic_block>, size_t,
      83              :                              array_slice<sbitmap>,
      84              :                              array_slice<gcov_type_unsigned>);
      85              : 
      86              : /* Map from BBs/edges to gcov counters.  */
      87              : vec<gcov_type> bb_gcov_counts;
      88              : hash_map<edge,gcov_type> *edge_gcov_counts;
      89              : 
      90              : struct bb_profile_info {
      91              :   unsigned int count_valid : 1;
      92              : 
      93              :   /* Number of successor and predecessor edges.  */
      94              :   gcov_type succ_count;
      95              :   gcov_type pred_count;
      96              : };
      97              : 
      98              : #define BB_INFO(b)  ((struct bb_profile_info *) (b)->aux)
      99              : 
     100              : 
     101              : /* Counter summary from the last set of coverage counts read.  */
     102              : 
     103              : gcov_summary *profile_info, *gcov_profile_info;
     104              : 
     105              : /* Collect statistics on the performance of this pass for the entire source
     106              :    file.  */
     107              : 
     108              : static int total_num_blocks;
     109              : static int total_num_edges;
     110              : static int total_num_edges_ignored;
     111              : static int total_num_edges_instrumented;
     112              : static int total_num_blocks_created;
     113              : static int total_num_passes;
     114              : static int total_num_times_called;
     115              : static int total_hist_br_prob[20];
     116              : static int total_num_branches;
     117              : static int total_num_conds;
     118              : 
     119              : /* Map between auto-fdo and fdo counts used to compare quality
     120              :    of the profiles.  */
     121              : struct afdo_fdo_record
     122              : {
     123              :   cgraph_node *node;
     124              :   struct bb_record
     125              :   {
     126              :     /* Index of the  basic block.  */
     127              :     int index;
     128              :     profile_count afdo;
     129              :     profile_count fdo;
     130              : 
     131              :     /* Successors and predecessors in CFG.  */
     132              :     vec <int> preds;
     133              :     vec <int> succs;
     134              :   };
     135              :   vec <bb_record> bbs;
     136              : };
     137              : 
     138              : static vec <afdo_fdo_record> afdo_fdo_records;
     139              : 
     140              : /* Forward declarations.  */
     141              : static void find_spanning_tree (struct edge_list *);
     142              : 
     143              : /* Add edge instrumentation code to the entire insn chain.
     144              : 
     145              :    F is the first insn of the chain.
     146              :    NUM_BLOCKS is the number of basic blocks found in F.  */
     147              : 
     148              : static unsigned
     149         2140 : instrument_edges (struct edge_list *el)
     150              : {
     151         2140 :   unsigned num_instr_edges = 0;
     152         2140 :   int num_edges = NUM_EDGES (el);
     153         2140 :   basic_block bb;
     154              : 
     155        18293 :   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
     156              :     {
     157        16153 :       edge e;
     158        16153 :       edge_iterator ei;
     159              : 
     160        32673 :       FOR_EACH_EDGE (e, ei, bb->succs)
     161              :         {
     162        16520 :           struct edge_profile_info *inf = EDGE_INFO (e);
     163              : 
     164        16520 :           if (!inf->ignore && !inf->on_tree)
     165              :             {
     166         8582 :               gcc_assert (!(e->flags & EDGE_ABNORMAL));
     167         8582 :               if (dump_file)
     168          696 :                 fprintf (dump_file, "Edge %d to %d instrumented%s\n",
     169          232 :                          e->src->index, e->dest->index,
     170          462 :                          EDGE_CRITICAL_P (e) ? " (and split)" : "");
     171         8582 :               gimple_gen_edge_profiler (num_instr_edges++, e);
     172              :             }
     173              :         }
     174              :     }
     175              : 
     176         2140 :   total_num_blocks_created += num_edges;
     177         2140 :   if (dump_file)
     178           90 :     fprintf (dump_file, "%d edges instrumented\n", num_instr_edges);
     179         2140 :   return num_instr_edges;
     180              : }
     181              : 
     182              : /* Add code to measure histograms for values in list VALUES.  */
     183              : static void
     184          589 : instrument_values (histogram_values values)
     185              : {
     186          589 :   unsigned i;
     187              : 
     188              :   /* Emit code to generate the histograms before the insns.  */
     189              : 
     190         1373 :   for (i = 0; i < values.length (); i++)
     191              :     {
     192          784 :       histogram_value hist = values[i];
     193          784 :       unsigned t = COUNTER_FOR_HIST_TYPE (hist->type);
     194              : 
     195          784 :       if (!coverage_counter_alloc (t, hist->n_counters))
     196            0 :         continue;
     197              : 
     198          784 :       switch (hist->type)
     199              :         {
     200            5 :         case HIST_TYPE_INTERVAL:
     201            5 :           gimple_gen_interval_profiler (hist, t);
     202            5 :           break;
     203              : 
     204            5 :         case HIST_TYPE_POW2:
     205            5 :           gimple_gen_pow2_profiler (hist, t);
     206            5 :           break;
     207              : 
     208           54 :         case HIST_TYPE_TOPN_VALUES:
     209           54 :           gimple_gen_topn_values_profiler (hist, t);
     210           54 :           break;
     211              : 
     212           49 :         case HIST_TYPE_INDIR_CALL:
     213           49 :           gimple_gen_ic_profiler (hist, t);
     214           49 :           break;
     215              : 
     216           41 :         case HIST_TYPE_AVERAGE:
     217           41 :           gimple_gen_average_profiler (hist, t);
     218           41 :           break;
     219              : 
     220           41 :         case HIST_TYPE_IOR:
     221           41 :           gimple_gen_ior_profiler (hist, t);
     222           41 :           break;
     223              : 
     224          589 :         case HIST_TYPE_TIME_PROFILE:
     225          589 :           gimple_gen_time_profiler (t);
     226          589 :           break;
     227              : 
     228            0 :         default:
     229            0 :           gcc_unreachable ();
     230              :         }
     231              :     }
     232          589 : }
     233              : 
     234              : 
     235              : /* Computes hybrid profile for all matching entries in da_file.
     236              : 
     237              :    CFG_CHECKSUM is the precomputed checksum for the CFG.  */
     238              : 
     239              : static gcov_type *
     240          581 : get_exec_counts (unsigned cfg_checksum, unsigned lineno_checksum)
     241              : {
     242          581 :   unsigned num_edges = 0;
     243          581 :   basic_block bb;
     244          581 :   gcov_type *counts;
     245              : 
     246              :   /* Count the edges to be (possibly) instrumented.  */
     247         4613 :   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
     248              :     {
     249         4032 :       edge e;
     250         4032 :       edge_iterator ei;
     251              : 
     252         8993 :       FOR_EACH_EDGE (e, ei, bb->succs)
     253         4961 :         if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
     254         2074 :           num_edges++;
     255              :     }
     256              : 
     257          581 :   counts = get_coverage_counts (GCOV_COUNTER_ARCS, cfg_checksum,
     258              :                                 lineno_checksum, num_edges);
     259          581 :   if (!counts)
     260              :     return NULL;
     261              : 
     262              :   return counts;
     263              : }
     264              : 
     265              : static bool
     266         4998 : is_edge_inconsistent (vec<edge, va_gc> *edges)
     267              : {
     268         4998 :   edge e;
     269         4998 :   edge_iterator ei;
     270        12007 :   FOR_EACH_EDGE (e, ei, edges)
     271              :     {
     272         7009 :       if (!EDGE_INFO (e)->ignore)
     273              :         {
     274         6977 :           if (edge_gcov_count (e) < 0
     275         6977 :               && (!(e->flags & EDGE_FAKE)
     276            1 :                   || !block_ends_with_call_p (e->src)))
     277              :             {
     278            0 :               if (dump_file)
     279              :                 {
     280            0 :                   fprintf (dump_file,
     281              :                            "Edge %i->%i is inconsistent, count%" PRId64,
     282            0 :                            e->src->index, e->dest->index, edge_gcov_count (e));
     283            0 :                   dump_bb (dump_file, e->src, 0, TDF_DETAILS);
     284            0 :                   dump_bb (dump_file, e->dest, 0, TDF_DETAILS);
     285              :                 }
     286              :               return true;
     287              :             }
     288              :         }
     289              :     }
     290              :   return false;
     291              : }
     292              : 
     293              : static void
     294            0 : correct_negative_edge_counts (void)
     295              : {
     296            0 :   basic_block bb;
     297            0 :   edge e;
     298            0 :   edge_iterator ei;
     299              : 
     300            0 :   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
     301              :     {
     302            0 :       FOR_EACH_EDGE (e, ei, bb->succs)
     303              :         {
     304            0 :            if (edge_gcov_count (e) < 0)
     305            0 :              edge_gcov_count (e) = 0;
     306              :         }
     307              :     }
     308            0 : }
     309              : 
     310              : /* Check consistency.
     311              :    Return true if inconsistency is found.  */
     312              : static bool
     313          499 : is_inconsistent (void)
     314              : {
     315          499 :   basic_block bb;
     316          499 :   bool inconsistent = false;
     317         2998 :   FOR_EACH_BB_FN (bb, cfun)
     318              :     {
     319         2499 :       inconsistent |= is_edge_inconsistent (bb->preds);
     320         2499 :       if (!dump_file && inconsistent)
     321              :         return true;
     322         2499 :       inconsistent |= is_edge_inconsistent (bb->succs);
     323         2499 :       if (!dump_file && inconsistent)
     324              :         return true;
     325         2499 :       if (bb_gcov_count (bb) < 0)
     326              :         {
     327            0 :           if (dump_file)
     328              :             {
     329            0 :               fprintf (dump_file, "BB %i count is negative "
     330              :                        "%" PRId64,
     331              :                        bb->index,
     332            0 :                        bb_gcov_count (bb));
     333            0 :               dump_bb (dump_file, bb, 0, TDF_DETAILS);
     334              :             }
     335              :           inconsistent = true;
     336              :         }
     337         2499 :       if (bb_gcov_count (bb) != sum_edge_counts (bb->preds))
     338              :         {
     339            0 :           if (dump_file)
     340              :             {
     341            0 :               fprintf (dump_file, "BB %i count does not match sum of incoming edges "
     342              :                        "%" PRId64" should be %" PRId64,
     343              :                        bb->index,
     344            0 :                        bb_gcov_count (bb),
     345              :                        sum_edge_counts (bb->preds));
     346            0 :               dump_bb (dump_file, bb, 0, TDF_DETAILS);
     347              :             }
     348              :           inconsistent = true;
     349              :         }
     350         2499 :       if (bb_gcov_count (bb) != sum_edge_counts (bb->succs) &&
     351            0 :           ! (find_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun)) != NULL
     352            0 :              && block_ends_with_call_p (bb)))
     353              :         {
     354            0 :           if (dump_file)
     355              :             {
     356            0 :               fprintf (dump_file, "BB %i count does not match sum of outgoing edges "
     357              :                        "%" PRId64" should be %" PRId64,
     358              :                        bb->index,
     359            0 :                        bb_gcov_count (bb),
     360              :                        sum_edge_counts (bb->succs));
     361            0 :               dump_bb (dump_file, bb, 0, TDF_DETAILS);
     362              :             }
     363              :           inconsistent = true;
     364              :         }
     365         2499 :       if (!dump_file && inconsistent)
     366              :         return true;
     367              :     }
     368              : 
     369              :   return inconsistent;
     370              : }
     371              : 
     372              : /* Set each basic block count to the sum of its outgoing edge counts */
     373              : static void
     374            0 : set_bb_counts (void)
     375              : {
     376            0 :   basic_block bb;
     377            0 :   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
     378              :     {
     379            0 :       bb_gcov_count (bb) = sum_edge_counts (bb->succs);
     380            0 :       gcc_assert (bb_gcov_count (bb) >= 0);
     381              :     }
     382            0 : }
     383              : 
     384              : /* Reads profile data and returns total number of edge counts read */
     385              : static int
     386          499 : read_profile_edge_counts (gcov_type *exec_counts)
     387              : {
     388          499 :   basic_block bb;
     389          499 :   int num_edges = 0;
     390          499 :   int exec_counts_pos = 0;
     391              :   /* For each edge not on the spanning tree, set its execution count from
     392              :      the .da file.  */
     393              :   /* The first count in the .da file is the number of times that the function
     394              :      was entered.  This is the exec_count for block zero.  */
     395              : 
     396         3996 :   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
     397              :     {
     398         3497 :       edge e;
     399         3497 :       edge_iterator ei;
     400              : 
     401         7798 :       FOR_EACH_EDGE (e, ei, bb->succs)
     402         4301 :         if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
     403              :           {
     404         1785 :             num_edges++;
     405         1785 :             if (exec_counts)
     406         1778 :               edge_gcov_count (e) = exec_counts[exec_counts_pos++];
     407              :             else
     408            7 :               edge_gcov_count (e) = 0;
     409              : 
     410         1785 :             EDGE_INFO (e)->count_valid = 1;
     411         1785 :             BB_INFO (bb)->succ_count--;
     412         1785 :             BB_INFO (e->dest)->pred_count--;
     413         1785 :             if (dump_file)
     414              :               {
     415          234 :                 fprintf (dump_file, "\nRead edge from %i to %i, count:",
     416              :                          bb->index, e->dest->index);
     417          234 :                 fprintf (dump_file, "%" PRId64,
     418          234 :                          (int64_t) edge_gcov_count (e));
     419              :               }
     420              :           }
     421              :     }
     422              : 
     423          499 :     return num_edges;
     424              : }
     425              : 
     426              : /* BB statistics comparing guessed frequency of BB with feedback.  */
     427              : 
     428              : struct bb_stats
     429              : {
     430              :   basic_block bb;
     431              :   double guessed, feedback;
     432              :   int64_t count;
     433              : };
     434              : 
     435              : /* Compare limit_tuple intervals by first item in descending order.  */
     436              : 
     437              : static int
     438          857 : cmp_stats (const void *ptr1, const void *ptr2)
     439              : {
     440          857 :   const bb_stats *p1 = (const bb_stats *)ptr1;
     441          857 :   const bb_stats *p2 = (const bb_stats *)ptr2;
     442              : 
     443          857 :   if (p1->feedback < p2->feedback)
     444              :     return 1;
     445          625 :   else if (p1->feedback > p2->feedback)
     446          277 :     return -1;
     447              :   return 0;
     448              : }
     449              : 
     450              : 
     451              : /* Compute the branch probabilities for the various branches.
     452              :    Annotate them accordingly.
     453              : 
     454              :    CFG_CHECKSUM is the precomputed checksum for the CFG.  */
     455              : 
     456              : static void
     457          581 : compute_branch_probabilities (unsigned cfg_checksum, unsigned lineno_checksum)
     458              : {
     459          581 :   basic_block bb;
     460          581 :   int i;
     461          581 :   int num_edges = 0;
     462          581 :   int changes;
     463          581 :   int passes;
     464          581 :   int hist_br_prob[20];
     465          581 :   int num_branches;
     466          581 :   gcov_type *exec_counts = get_exec_counts (cfg_checksum, lineno_checksum);
     467          581 :   int inconsistent = 0;
     468              : 
     469              :   /* Very simple sanity checks so we catch bugs in our profiling code.  */
     470          581 :   if (!profile_info)
     471              :     {
     472           82 :       if (dump_file)
     473            0 :         fprintf (dump_file, "Profile info is missing; giving up\n");
     474           82 :       return;
     475              :     }
     476              : 
     477          499 :   bb_gcov_counts.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
     478          499 :   edge_gcov_counts = new hash_map<edge,gcov_type>;
     479              : 
     480              :   /* Attach extra info block to each bb.  */
     481          499 :   alloc_aux_for_blocks (sizeof (struct bb_profile_info));
     482         3996 :   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
     483              :     {
     484         3497 :       edge e;
     485         3497 :       edge_iterator ei;
     486              : 
     487         7798 :       FOR_EACH_EDGE (e, ei, bb->succs)
     488         4301 :         if (!EDGE_INFO (e)->ignore)
     489         4284 :           BB_INFO (bb)->succ_count++;
     490         7798 :       FOR_EACH_EDGE (e, ei, bb->preds)
     491         4301 :         if (!EDGE_INFO (e)->ignore)
     492         4284 :           BB_INFO (bb)->pred_count++;
     493              :     }
     494              : 
     495              :   /* Avoid predicting entry on exit nodes.  */
     496          499 :   BB_INFO (EXIT_BLOCK_PTR_FOR_FN (cfun))->succ_count = 2;
     497          499 :   BB_INFO (ENTRY_BLOCK_PTR_FOR_FN (cfun))->pred_count = 2;
     498              : 
     499          499 :   afdo_fdo_record record = {cgraph_node::get (current_function_decl), vNULL};;
     500          499 :   if (dump_file && flag_auto_profile)
     501              :     {
     502            0 :       FOR_ALL_BB_FN (bb, cfun)
     503              :         {
     504            0 :           record.bbs.safe_push ({bb->index, bb->count.ipa (),
     505            0 :                                 profile_count::uninitialized (), vNULL, vNULL});
     506            0 :           record.bbs.last ().preds.reserve (EDGE_COUNT (bb->preds));
     507            0 :           for (auto &e : bb->preds)
     508            0 :             record.bbs.last ().preds.safe_push (e->src->index);
     509            0 :           record.bbs.last ().succs.reserve (EDGE_COUNT (bb->succs));
     510            0 :           for (auto &e : bb->succs)
     511            0 :             record.bbs.last ().succs.safe_push (e->dest->index);
     512              :         }
     513              :     }
     514              : 
     515          499 :   num_edges = read_profile_edge_counts (exec_counts);
     516              : 
     517          499 :   if (dump_file)
     518           91 :     fprintf (dump_file, "\n%d edge counts read\n", num_edges);
     519              : 
     520              :   /* For every block in the file,
     521              :      - if every exit/entrance edge has a known count, then set the block count
     522              :      - if the block count is known, and every exit/entrance edge but one has
     523              :      a known execution count, then set the count of the remaining edge
     524              : 
     525              :      As edge counts are set, decrement the succ/pred count, but don't delete
     526              :      the edge, that way we can easily tell when all edges are known, or only
     527              :      one edge is unknown.  */
     528              : 
     529              :   /* The order that the basic blocks are iterated through is important.
     530              :      Since the code that finds spanning trees starts with block 0, low numbered
     531              :      edges are put on the spanning tree in preference to high numbered edges.
     532              :      Hence, most instrumented edges are at the end.  Graph solving works much
     533              :      faster if we propagate numbers from the end to the start.
     534              : 
     535              :      This takes an average of slightly more than 3 passes.  */
     536              : 
     537          499 :   changes = 1;
     538          499 :   passes = 0;
     539         2574 :   while (changes)
     540              :     {
     541         2075 :       passes++;
     542         2075 :       changes = 0;
     543        19573 :       FOR_BB_BETWEEN (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), NULL, prev_bb)
     544              :         {
     545        17498 :           struct bb_profile_info *bi = BB_INFO (bb);
     546        17498 :           if (! bi->count_valid)
     547              :             {
     548         6201 :               if (bi->succ_count == 0)
     549              :                 {
     550          827 :                   edge e;
     551          827 :                   edge_iterator ei;
     552          827 :                   gcov_type total = 0;
     553              : 
     554         1885 :                   FOR_EACH_EDGE (e, ei, bb->succs)
     555         1058 :                     total += edge_gcov_count (e);
     556          827 :                   bb_gcov_count (bb) = total;
     557          827 :                   bi->count_valid = 1;
     558          827 :                   changes = 1;
     559              :                 }
     560         5374 :               else if (bi->pred_count == 0)
     561              :                 {
     562         2670 :                   edge e;
     563         2670 :                   edge_iterator ei;
     564         2670 :                   gcov_type total = 0;
     565              : 
     566         6513 :                   FOR_EACH_EDGE (e, ei, bb->preds)
     567         3843 :                     total += edge_gcov_count (e);
     568         2670 :                   bb_gcov_count (bb) = total;
     569         2670 :                   bi->count_valid = 1;
     570         2670 :                   changes = 1;
     571              :                 }
     572              :             }
     573        17498 :           if (bi->count_valid)
     574              :             {
     575        14794 :               if (bi->succ_count == 1)
     576              :                 {
     577         2171 :                   edge e;
     578         2171 :                   edge_iterator ei;
     579         2171 :                   gcov_type total = 0;
     580              : 
     581              :                   /* One of the counts will be invalid, but it is zero,
     582              :                      so adding it in also doesn't hurt.  */
     583         5414 :                   FOR_EACH_EDGE (e, ei, bb->succs)
     584         3243 :                     total += edge_gcov_count (e);
     585              : 
     586              :                   /* Search for the invalid edge, and set its count.  */
     587         3077 :                   FOR_EACH_EDGE (e, ei, bb->succs)
     588         3077 :                     if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
     589              :                       break;
     590              : 
     591              :                   /* Calculate count for remaining edge by conservation.  */
     592         2171 :                   total = bb_gcov_count (bb) - total;
     593              : 
     594         2171 :                   gcc_assert (e);
     595         2171 :                   EDGE_INFO (e)->count_valid = 1;
     596         2171 :                   edge_gcov_count (e) = total;
     597         2171 :                   bi->succ_count--;
     598              : 
     599         2171 :                   BB_INFO (e->dest)->pred_count--;
     600         2171 :                   changes = 1;
     601              :                 }
     602        14794 :               if (bi->pred_count == 1)
     603              :                 {
     604          328 :                   edge e;
     605          328 :                   edge_iterator ei;
     606          328 :                   gcov_type total = 0;
     607              : 
     608              :                   /* One of the counts will be invalid, but it is zero,
     609              :                      so adding it in also doesn't hurt.  */
     610          786 :                   FOR_EACH_EDGE (e, ei, bb->preds)
     611          458 :                     total += edge_gcov_count (e);
     612              : 
     613              :                   /* Search for the invalid edge, and set its count.  */
     614          386 :                   FOR_EACH_EDGE (e, ei, bb->preds)
     615          386 :                     if (!EDGE_INFO (e)->count_valid && !EDGE_INFO (e)->ignore)
     616              :                       break;
     617              : 
     618              :                   /* Calculate count for remaining edge by conservation.  */
     619          328 :                   total = bb_gcov_count (bb) - total + edge_gcov_count (e);
     620              : 
     621          328 :                   gcc_assert (e);
     622          328 :                   EDGE_INFO (e)->count_valid = 1;
     623          328 :                   edge_gcov_count (e) = total;
     624          328 :                   bi->pred_count--;
     625              : 
     626          328 :                   BB_INFO (e->src)->succ_count--;
     627          328 :                   changes = 1;
     628              :                 }
     629              :             }
     630              :         }
     631              :     }
     632              : 
     633          499 :   total_num_passes += passes;
     634          499 :   if (dump_file)
     635           91 :     fprintf (dump_file, "Graph solving took %d passes.\n\n", passes);
     636              : 
     637              :   /* If the graph has been correctly solved, every block will have a
     638              :      succ and pred count of zero.  */
     639         2998 :   FOR_EACH_BB_FN (bb, cfun)
     640              :     {
     641         2499 :       gcc_assert (!BB_INFO (bb)->succ_count && !BB_INFO (bb)->pred_count);
     642              :     }
     643              : 
     644              :   /* Check for inconsistent basic block counts */
     645          499 :   inconsistent = is_inconsistent ();
     646              : 
     647          499 :   if (inconsistent)
     648              :    {
     649            0 :      if (flag_profile_correction)
     650              :        {
     651              :          /* Inconsistency detected. Make it flow-consistent. */
     652            0 :          static int informed = 0;
     653            0 :          if (dump_enabled_p () && informed == 0)
     654              :            {
     655            0 :              informed = 1;
     656            0 :              dump_printf_loc (MSG_NOTE,
     657            0 :                               dump_user_location_t::from_location_t (input_location),
     658              :                               "correcting inconsistent profile data\n");
     659              :            }
     660            0 :          correct_negative_edge_counts ();
     661              :          /* Set bb counts to the sum of the outgoing edge counts */
     662            0 :          set_bb_counts ();
     663            0 :          if (dump_file)
     664            0 :            fprintf (dump_file, "\nCalling mcf_smooth_cfg\n");
     665            0 :          mcf_smooth_cfg ();
     666              :        }
     667              :      else
     668            0 :        error ("corrupted profile info: profile data is not flow-consistent");
     669              :    }
     670              : 
     671              :   /* For every edge, calculate its branch probability and add a reg_note
     672              :      to the branch insn to indicate this.  */
     673              : 
     674        10479 :   for (i = 0; i < 20; i++)
     675         9980 :     hist_br_prob[i] = 0;
     676          499 :   num_branches = 0;
     677              : 
     678         3996 :   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
     679              :     {
     680         3497 :       edge e;
     681         3497 :       edge_iterator ei;
     682              : 
     683         3497 :       if (bb_gcov_count (bb) < 0)
     684              :         {
     685            0 :           error ("corrupted profile info: number of iterations for basic block %d thought to be %i",
     686            0 :                  bb->index, (int)bb_gcov_count (bb));
     687            0 :           bb_gcov_count (bb) = 0;
     688              :         }
     689         7798 :       FOR_EACH_EDGE (e, ei, bb->succs)
     690              :         {
     691              :           /* Function may return twice in the cased the called function is
     692              :              setjmp or calls fork, but we can't represent this by extra
     693              :              edge from the entry, since extra edge from the exit is
     694              :              already present.  We get negative frequency from the entry
     695              :              point.  */
     696         4301 :           if ((edge_gcov_count (e) < 0
     697            1 :                && e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
     698         4301 :               || (edge_gcov_count (e) > bb_gcov_count (bb)
     699            1 :                   && e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)))
     700              :             {
     701            2 :               if (block_ends_with_call_p (bb))
     702            4 :                 edge_gcov_count (e) = edge_gcov_count (e) < 0
     703            3 :                                       ? 0 : bb_gcov_count (bb);
     704              :             }
     705         4301 :           if (edge_gcov_count (e) < 0
     706         4301 :               || edge_gcov_count (e) > bb_gcov_count (bb))
     707              :             {
     708            0 :               error ("corrupted profile info: number of executions for edge %d-%d thought to be %i",
     709            0 :                      e->src->index, e->dest->index,
     710            0 :                      (int)edge_gcov_count (e));
     711            0 :               edge_gcov_count (e) = bb_gcov_count (bb) / 2;
     712              :             }
     713              :         }
     714         3497 :       if (bb_gcov_count (bb))
     715              :         {
     716         2508 :           bool set_to_guessed = false;
     717         5680 :           FOR_EACH_EDGE (e, ei, bb->succs)
     718              :             {
     719         3172 :               bool prev_never = e->probability == profile_probability::never ();
     720         3172 :               e->probability = profile_probability::probability_in_gcov_type
     721         3172 :                   (edge_gcov_count (e), bb_gcov_count (bb));
     722         3890 :               if (e->probability == profile_probability::never ()
     723          718 :                   && !prev_never
     724         3750 :                   && flag_profile_partial_training)
     725            0 :                 set_to_guessed = true;
     726              :             }
     727         2508 :           if (set_to_guessed)
     728            0 :             FOR_EACH_EDGE (e, ei, bb->succs)
     729            0 :               e->probability = e->probability.guessed ();
     730         2508 :           if (bb->index >= NUM_FIXED_BLOCKS
     731         1780 :               && block_ends_with_condjump_p (bb)
     732         2990 :               && EDGE_COUNT (bb->succs) >= 2)
     733              :             {
     734          482 :               int prob;
     735          482 :               edge e;
     736          482 :               int index;
     737              : 
     738              :               /* Find the branch edge.  It is possible that we do have fake
     739              :                  edges here.  */
     740          482 :               FOR_EACH_EDGE (e, ei, bb->succs)
     741          482 :                 if (!(e->flags & (EDGE_FAKE | EDGE_FALLTHRU)))
     742              :                   break;
     743              : 
     744          482 :               prob = e->probability.to_reg_br_prob_base ();
     745          482 :               index = prob * 20 / REG_BR_PROB_BASE;
     746              : 
     747          482 :               if (index == 20)
     748           56 :                 index = 19;
     749          482 :               hist_br_prob[index]++;
     750              : 
     751          482 :               num_branches++;
     752              :             }
     753              :         }
     754              :       /* As a last resort, distribute the probabilities evenly.
     755              :          Use simple heuristics that if there are normal edges,
     756              :          give all abnormals frequency of 0, otherwise distribute the
     757              :          frequency over abnormals (this is the case of noreturn
     758              :          calls).  */
     759          989 :       else if (profile_status_for_fn (cfun) == PROFILE_ABSENT)
     760              :         {
     761           16 :           int total = 0;
     762              : 
     763           34 :           FOR_EACH_EDGE (e, ei, bb->succs)
     764           18 :             if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
     765           11 :               total ++;
     766           16 :           if (total)
     767              :             {
     768           22 :               FOR_EACH_EDGE (e, ei, bb->succs)
     769           11 :                 if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
     770           11 :                   e->probability
     771           11 :                     = profile_probability::guessed_always () / total;
     772              :                 else
     773            0 :                   e->probability = profile_probability::never ();
     774              :             }
     775              :           else
     776              :             {
     777            5 :               total += EDGE_COUNT (bb->succs);
     778           12 :               FOR_EACH_EDGE (e, ei, bb->succs)
     779            7 :                 e->probability = profile_probability::guessed_always () / total;
     780              :             }
     781           16 :           if (bb->index >= NUM_FIXED_BLOCKS
     782           16 :               && block_ends_with_condjump_p (bb)
     783         3513 :               && EDGE_COUNT (bb->succs) >= 2)
     784            0 :             num_branches++;
     785              :         }
     786              :     }
     787              : 
     788          499 :   if (exec_counts
     789          499 :       && (bb_gcov_count (ENTRY_BLOCK_PTR_FOR_FN (cfun))
     790          133 :           || !flag_profile_partial_training))
     791          497 :     profile_status_for_fn (cfun) = PROFILE_READ;
     792              : 
     793              :   /* If we have real data, use them!  */
     794          499 :   if (bb_gcov_count (ENTRY_BLOCK_PTR_FOR_FN (cfun))
     795          499 :       || !flag_guess_branch_prob)
     796              :     {
     797          364 :       profile_count old_entry_cnt = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count;
     798          364 :       auto_vec <bb_stats> stats;
     799          364 :       double sum1 = 0, sum2 = 0;
     800              : 
     801         3101 :       FOR_ALL_BB_FN (bb, cfun)
     802              :         {
     803         2737 :           profile_count cnt = bb->count;
     804         2737 :           if (bb_gcov_count (bb) || !flag_profile_partial_training)
     805         2737 :             bb->count = profile_count::from_gcov_type (bb_gcov_count (bb));
     806              :           else
     807            0 :             bb->count = profile_count::guessed_zero ();
     808              : 
     809         2737 :           if (dump_file && (dump_flags & TDF_DETAILS) && bb->index >= 0)
     810              :             {
     811           85 :               double freq1 = cnt.to_sreal_scale (old_entry_cnt).to_double ();
     812           85 :               double freq2 = bb->count.to_sreal_scale
     813           85 :                                         (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count).
     814           85 :                                   to_double ();
     815           85 :               bb_stats stat = {bb, freq1, freq2,
     816           85 :                                (int64_t) bb_gcov_count (bb)};
     817           85 :               stats.safe_push (stat);
     818           85 :               sum1 += freq1;
     819           85 :               sum2 += freq2;
     820              :             }
     821              :         }
     822          364 :       if (dump_file && (dump_flags & TDF_DETAILS))
     823              :         {
     824           12 :           double nsum1 = 0, nsum2 = 0;
     825           12 :           stats.qsort (cmp_stats);
     826          121 :           for (auto stat : stats)
     827              :             {
     828           85 :               nsum1 += stat.guessed;
     829           85 :               nsum2 += stat.feedback;
     830           85 :               fprintf (dump_file,
     831              :                        " Basic block %4i guessed freq: %12.3f"
     832              :                        " cumulative:%6.2f%% "
     833              :                        " feedback freq: %12.3f cumulative:%7.2f%%"
     834              :                        " cnt: 10%" PRId64 "\n", stat.bb->index,
     835              :                        stat.guessed,
     836           85 :                        nsum1 * 100 / sum1,
     837              :                        stat.feedback,
     838           85 :                        nsum2 * 100 / sum2,
     839              :                        stat.count);
     840              :             }
     841              :         }
     842          364 :     }
     843              :   /* If function was not trained, preserve local estimates including statically
     844              :      determined zero counts.  */
     845          135 :   else if (profile_status_for_fn (cfun) == PROFILE_READ
     846          133 :            && !flag_profile_partial_training)
     847          882 :     FOR_ALL_BB_FN (bb, cfun)
     848          756 :       if (!(bb->count == profile_count::zero ()))
     849          742 :         bb->count = bb->count.global0 ();
     850              : 
     851          499 :   bb_gcov_counts.release ();
     852          998 :   delete edge_gcov_counts;
     853          499 :   edge_gcov_counts = NULL;
     854              : 
     855          499 :   if (dump_file && flag_auto_profile)
     856              :     {
     857            0 :       int i = 0;
     858            0 :       FOR_ALL_BB_FN (bb, cfun)
     859              :         {
     860            0 :           gcc_checking_assert (record.bbs[i].index == bb->index);
     861            0 :           record.bbs[i].fdo = bb->count.ipa ();
     862            0 :           i++;
     863              :         }
     864            0 :       afdo_fdo_records.safe_push (record);
     865              :     }
     866              : 
     867          499 :   update_max_bb_count ();
     868              : 
     869          499 :   if (dump_file)
     870              :     {
     871           91 :       fprintf (dump_file, " Profile feedback for function");
     872           93 :       fprintf (dump_file, ((profile_status_for_fn (cfun) == PROFILE_READ)
     873              :                            ? " is available \n"
     874              :                            : " is not available \n"));
     875              : 
     876           91 :       fprintf (dump_file, "%d branches\n", num_branches);
     877           91 :       if (num_branches)
     878          286 :         for (i = 0; i < 10; i++)
     879          260 :           fprintf (dump_file, "%d%% branches in range %d-%d%%\n",
     880          260 :                    (hist_br_prob[i] + hist_br_prob[19-i]) * 100 / num_branches,
     881          260 :                    5 * i, 5 * i + 5);
     882              : 
     883           91 :       total_num_branches += num_branches;
     884         1911 :       for (i = 0; i < 20; i++)
     885         1820 :         total_hist_br_prob[i] += hist_br_prob[i];
     886              : 
     887           91 :       fputc ('\n', dump_file);
     888           91 :       fputc ('\n', dump_file);
     889              : 
     890           91 :       gimple_dump_cfg (dump_file, TDF_BLOCKS);
     891              :     }
     892              : 
     893          499 :   free_aux_for_blocks ();
     894              : }
     895              : 
     896              : /* Sort the histogram value and count for TOPN and INDIR_CALL type.  */
     897              : 
     898              : static void
     899           83 : sort_hist_values (histogram_value hist)
     900              : {
     901           83 :   gcc_assert (hist->type == HIST_TYPE_TOPN_VALUES
     902              :               || hist->type == HIST_TYPE_INDIR_CALL);
     903              : 
     904           83 :   int counters = hist->hvalue.counters[1];
     905          125 :   for (int i = 0; i < counters - 1; i++)
     906              :   /* Hist value is organized as:
     907              :      [total_executions, N, value1, counter1, ..., valueN, counterN]
     908              :      Use decrease bubble sort to rearrange it.  The sort starts from <value1,
     909              :      counter1> and compares counter first.  If counter is same, compares the
     910              :      value, exchange it if small to keep stable.  */
     911              : 
     912              :     {
     913              :       bool swapped = false;
     914          611 :       for (int j = 0; j < counters - 1 - i; j++)
     915              :         {
     916          543 :           gcov_type *p = &hist->hvalue.counters[2 * j + 2];
     917          543 :           if (p[1] < p[3] || (p[1] == p[3] && p[0] < p[2]))
     918              :             {
     919          483 :               std::swap (p[0], p[2]);
     920          483 :               std::swap (p[1], p[3]);
     921          483 :               swapped = true;
     922              :             }
     923              :         }
     924           68 :       if (!swapped)
     925              :         break;
     926              :     }
     927           83 : }
     928              : /* Load value histograms values whose description is stored in VALUES array
     929              :    from .gcda file.
     930              : 
     931              :    CFG_CHECKSUM is the precomputed checksum for the CFG.  */
     932              : 
     933              : static void
     934          435 : compute_value_histograms (histogram_values values, unsigned cfg_checksum,
     935              :                           unsigned lineno_checksum)
     936              : {
     937          435 :   unsigned i, j, t, any;
     938          435 :   unsigned n_histogram_counters[GCOV_N_VALUE_COUNTERS];
     939          435 :   gcov_type *histogram_counts[GCOV_N_VALUE_COUNTERS];
     940          435 :   gcov_type *act_count[GCOV_N_VALUE_COUNTERS];
     941          435 :   gcov_type *aact_count;
     942          435 :   struct cgraph_node *node;
     943              : 
     944         4350 :   for (t = 0; t < GCOV_N_VALUE_COUNTERS; t++)
     945         3915 :     n_histogram_counters[t] = 0;
     946              : 
     947         2136 :   for (i = 0; i < values.length (); i++)
     948              :     {
     949          633 :       histogram_value hist = values[i];
     950          633 :       n_histogram_counters[(int) hist->type] += hist->n_counters;
     951              :     }
     952              : 
     953              :   any = 0;
     954         4350 :   for (t = 0; t < GCOV_N_VALUE_COUNTERS; t++)
     955              :     {
     956         3915 :       if (!n_histogram_counters[t])
     957              :         {
     958         3295 :           histogram_counts[t] = NULL;
     959         3295 :           continue;
     960              :         }
     961              : 
     962          620 :       histogram_counts[t] = get_coverage_counts (COUNTER_FOR_HIST_TYPE (t),
     963              :                                                  cfg_checksum,
     964              :                                                  lineno_checksum,
     965              :                                                  n_histogram_counters[t]);
     966          620 :       if (histogram_counts[t])
     967          492 :         any = 1;
     968          620 :       act_count[t] = histogram_counts[t];
     969              :     }
     970          435 :   if (!any)
     971           98 :     return;
     972              : 
     973         1666 :   for (i = 0; i < values.length (); i++)
     974              :     {
     975          496 :       histogram_value hist = values[i];
     976          496 :       gimple *stmt = hist->hvalue.stmt;
     977              : 
     978          496 :       t = (int) hist->type;
     979          496 :       bool topn_p = (hist->type == HIST_TYPE_TOPN_VALUES
     980          496 :                      || hist->type == HIST_TYPE_INDIR_CALL);
     981              : 
     982              :       /* TOP N counter uses variable number of counters.  */
     983          496 :       if (topn_p)
     984              :         {
     985           83 :           unsigned total_size;
     986           83 :           if (act_count[t])
     987           83 :             total_size = 2 + 2 * act_count[t][1];
     988              :           else
     989              :             total_size = 2;
     990           83 :           gimple_add_histogram_value (cfun, stmt, hist);
     991           83 :           hist->n_counters = total_size;
     992           83 :           hist->hvalue.counters = XNEWVEC (gcov_type, hist->n_counters);
     993          539 :           for (j = 0; j < hist->n_counters; j++)
     994          456 :             if (act_count[t])
     995          456 :               hist->hvalue.counters[j] = act_count[t][j];
     996              :             else
     997            0 :               hist->hvalue.counters[j] = 0;
     998           83 :           act_count[t] += hist->n_counters;
     999           83 :           sort_hist_values (hist);
    1000              :         }
    1001              :       else
    1002              :         {
    1003          413 :           aact_count = act_count[t];
    1004              : 
    1005          413 :           if (act_count[t])
    1006          413 :             act_count[t] += hist->n_counters;
    1007              : 
    1008          413 :           gimple_add_histogram_value (cfun, stmt, hist);
    1009          413 :           hist->hvalue.counters = XNEWVEC (gcov_type, hist->n_counters);
    1010          879 :           for (j = 0; j < hist->n_counters; j++)
    1011          466 :             if (aact_count)
    1012          466 :               hist->hvalue.counters[j] = aact_count[j];
    1013              :             else
    1014            0 :               hist->hvalue.counters[j] = 0;
    1015              :         }
    1016              : 
    1017              :       /* Time profiler counter is not related to any statement,
    1018              :          so that we have to read the counter and set the value to
    1019              :          the corresponding call graph node.  */
    1020          496 :       if (hist->type == HIST_TYPE_TIME_PROFILE)
    1021              :         {
    1022          337 :           node = cgraph_node::get (hist->fun->decl);
    1023          337 :           if (hist->hvalue.counters[0] >= 0
    1024          337 :               && hist->hvalue.counters[0] < INT_MAX / 2)
    1025          337 :             node->tp_first_run = hist->hvalue.counters[0];
    1026              :           else
    1027              :             {
    1028            0 :               if (flag_profile_correction)
    1029            0 :                 error ("corrupted profile info: invalid time profile");
    1030            0 :               node->tp_first_run = 0;
    1031              :             }
    1032              : 
    1033              :           /* Drop profile for -fprofile-reproducible=multithreaded.  */
    1034          337 :           bool drop
    1035          337 :             = (flag_profile_reproducible == PROFILE_REPRODUCIBILITY_MULTITHREADED);
    1036          337 :           if (drop)
    1037            0 :             node->tp_first_run = 0;
    1038              : 
    1039          337 :           if (dump_file)
    1040          178 :             fprintf (dump_file, "Read tp_first_run: %d%s\n", node->tp_first_run,
    1041              :                      drop ? "; ignored because profile reproducibility is "
    1042              :                      "multi-threaded" : "");
    1043              :         }
    1044              :     }
    1045              : 
    1046         3370 :   for (t = 0; t < GCOV_N_VALUE_COUNTERS; t++)
    1047         3033 :     free (histogram_counts[t]);
    1048              : }
    1049              : 
    1050              : /* Location triplet which records a location.  */
    1051              : struct location_triplet
    1052              : {
    1053              :   const char *filename;
    1054              :   int lineno;
    1055              :   int bb_index;
    1056              : };
    1057              : 
    1058              : /* Traits class for streamed_locations hash set below.  */
    1059              : 
    1060              : struct location_triplet_hash : typed_noop_remove <location_triplet>
    1061              : {
    1062              :   typedef location_triplet value_type;
    1063              :   typedef location_triplet compare_type;
    1064              : 
    1065              :   static hashval_t
    1066        87096 :   hash (const location_triplet &ref)
    1067              :   {
    1068        87096 :     inchash::hash hstate (0);
    1069        87096 :     if (ref.filename)
    1070        84995 :       hstate.add_int (strlen (ref.filename));
    1071        87096 :     hstate.add_int (ref.lineno);
    1072        87096 :     hstate.add_int (ref.bb_index);
    1073        87096 :     return hstate.end ();
    1074              :   }
    1075              : 
    1076              :   static bool
    1077        75895 :   equal (const location_triplet &ref1, const location_triplet &ref2)
    1078              :   {
    1079        75895 :     return ref1.lineno == ref2.lineno
    1080        10211 :       && ref1.bb_index == ref2.bb_index
    1081         5083 :       && ref1.filename != NULL
    1082         5083 :       && ref2.filename != NULL
    1083        80978 :       && strcmp (ref1.filename, ref2.filename) == 0;
    1084              :   }
    1085              : 
    1086              :   static void
    1087              :   mark_deleted (location_triplet &ref)
    1088              :   {
    1089              :     ref.lineno = -1;
    1090              :   }
    1091              : 
    1092              :   static const bool empty_zero_p = false;
    1093              : 
    1094              :   static void
    1095        59115 :   mark_empty (location_triplet &ref)
    1096              :   {
    1097        59115 :     ref.lineno = -2;
    1098              :   }
    1099              : 
    1100              :   static bool
    1101       100472 :   is_deleted (const location_triplet &ref)
    1102              :   {
    1103       100472 :     return ref.lineno == -1;
    1104              :   }
    1105              : 
    1106              :   static bool
    1107       448590 :   is_empty (const location_triplet &ref)
    1108              :   {
    1109       434739 :     return ref.lineno == -2;
    1110              :   }
    1111              : };
    1112              : 
    1113              : 
    1114              : 
    1115              : 
    1116              : /* When passed NULL as file_name, initialize.
    1117              :    When passed something else, output the necessary commands to change
    1118              :    line to LINE and offset to FILE_NAME.  */
    1119              : static void
    1120        18930 : output_location (hash_set<location_triplet_hash> *streamed_locations,
    1121              :                  char const *file_name, int line,
    1122              :                  gcov_position_t *offset, basic_block bb)
    1123              : {
    1124        18930 :   static char const *prev_file_name;
    1125        18930 :   static int prev_line;
    1126        18930 :   bool name_differs, line_differs;
    1127              : 
    1128        18930 :   if (file_name != NULL)
    1129        17433 :     file_name = remap_profile_filename (file_name);
    1130              : 
    1131        18930 :   location_triplet triplet;
    1132        18930 :   triplet.filename = file_name;
    1133        18930 :   triplet.lineno = line;
    1134        18930 :   triplet.bb_index = bb ? bb->index : 0;
    1135              : 
    1136        18930 :   if (streamed_locations->add (triplet))
    1137         6576 :     return;
    1138              : 
    1139        13851 :   if (!file_name)
    1140              :     {
    1141         1497 :       prev_file_name = NULL;
    1142         1497 :       prev_line = -1;
    1143         1497 :       return;
    1144              :     }
    1145              : 
    1146        12354 :   name_differs = !prev_file_name || filename_cmp (file_name, prev_file_name);
    1147        12354 :   line_differs = prev_line != line;
    1148              : 
    1149        12354 :   if (!*offset)
    1150              :     {
    1151         9572 :       *offset = gcov_write_tag (GCOV_TAG_LINES);
    1152         9572 :       gcov_write_unsigned (bb->index);
    1153         9572 :       name_differs = line_differs = true;
    1154              :     }
    1155              : 
    1156              :   /* If this is a new source file, then output the
    1157              :      file's name to the .bb file.  */
    1158        12354 :   if (name_differs)
    1159              :     {
    1160         9657 :       prev_file_name = file_name;
    1161         9657 :       gcov_write_unsigned (0);
    1162         9657 :       gcov_write_filename (prev_file_name);
    1163              :     }
    1164        12354 :   if (line_differs)
    1165              :     {
    1166        12351 :       gcov_write_unsigned (line);
    1167        12351 :       prev_line = line;
    1168              :     }
    1169              : }
    1170              : 
    1171              : /* Helper for qsort so edges get sorted from highest frequency to smallest.
    1172              :    This controls the weight for minimal spanning tree algorithm  */
    1173              : static int
    1174       601249 : compare_freqs (const void *p1, const void *p2)
    1175              : {
    1176       601249 :   const_edge e1 = *(const const_edge *)p1;
    1177       601249 :   const_edge e2 = *(const const_edge *)p2;
    1178              : 
    1179              :   /* Critical edges needs to be split which introduce extra control flow.
    1180              :      Make them more heavy.  */
    1181       601249 :   int m1 = EDGE_CRITICAL_P (e1) ? 2 : 1;
    1182       601249 :   int m2 = EDGE_CRITICAL_P (e2) ? 2 : 1;
    1183              : 
    1184       601249 :   if (EDGE_FREQUENCY (e1) * m1 + m1 != EDGE_FREQUENCY (e2) * m2 + m2)
    1185       206786 :     return EDGE_FREQUENCY (e2) * m2 + m2 - EDGE_FREQUENCY (e1) * m1 - m1;
    1186              :   /* Stabilize sort.  */
    1187       394463 :   if (e1->src->index != e2->src->index)
    1188       360282 :     return e2->src->index - e1->src->index;
    1189        34181 :   return e2->dest->index - e1->dest->index;
    1190              : }
    1191              : 
    1192              : /* Only read execution count for thunks.  */
    1193              : 
    1194              : void
    1195            7 : read_thunk_profile (struct cgraph_node *node)
    1196              : {
    1197            7 :   tree old = current_function_decl;
    1198            7 :   current_function_decl = node->decl;
    1199            7 :   gcov_type *counts = get_coverage_counts (GCOV_COUNTER_ARCS, 0, 0, 1);
    1200            7 :   if (counts)
    1201              :     {
    1202           14 :       node->callees->count = node->count
    1203            7 :          = profile_count::from_gcov_type (counts[0]);
    1204            7 :       free (counts);
    1205              :     }
    1206            7 :   current_function_decl = old;
    1207            7 :   return;
    1208              : }
    1209              : 
    1210              : /* Disable coverage for BB.  This is used for #pragma GCC suppress_coverage.  */
    1211              : void
    1212         2309 : suppress_coverage (basic_block bb)
    1213              : {
    1214         2309 :   bb->flags |= BB_COVERAGE_SUPPRESSED;
    1215         2309 : }
    1216              : 
    1217              : /* Unset the flag set by suppress_coverage.  This is only useful when merging
    1218              :    blocks.  */
    1219              : void
    1220           23 : suppress_coverage_unset (basic_block bb)
    1221              : {
    1222           23 :   bb->flags &= ~BB_COVERAGE_SUPPRESSED;
    1223           23 : }
    1224              : 
    1225              : /* Check if BB has coverage disabled by #pragma GCC suppress_coverage.  */
    1226              : bool
    1227    212444357 : coverage_suppressed_p (basic_block bb)
    1228              : {
    1229    212444357 :   return bb->flags & BB_COVERAGE_SUPPRESSED;
    1230              : }
    1231              : 
    1232              : /* Check if any blocks are disabled by #pragma suppress_coverage in the current
    1233              :    function.  */
    1234              : static bool
    1235         1465 : any_block_coverage_suppressed_p ()
    1236              : {
    1237         1465 :   basic_block bb;
    1238         9769 :   FOR_EACH_BB_FN (bb, cfun)
    1239         8557 :     if (coverage_suppressed_p (bb))
    1240              :       return true;
    1241              :   return false;
    1242              : }
    1243              : 
    1244              : /* The source locations of #pragma GCC suppress_coverage begin/end.  For each
    1245              :    entry, the source_range m_finish/m_end should be the (expanded) source
    1246              :    location of the begin/end.  If there is no end, m_finish will be
    1247              :    UNKNOWN_LOCATION.  */
    1248              : static vec<source_range> suppress_coverage_ranges;
    1249              : 
    1250              : /* Try to add LOC as the beginning of a new range.  If a range was started
    1251              :    already, this is a no-op.  Returns true if a new range was created.  */
    1252              : bool
    1253          349 : suppress_coverage_begin (location_t loc)
    1254              : {
    1255          685 :   if (!suppress_coverage_ranges.is_empty ()
    1256          336 :       && suppress_coverage_ranges.last ().m_finish == UNKNOWN_LOCATION)
    1257              :     return false;
    1258              : 
    1259          348 :   loc = get_pure_location (expansion_point_location (loc));
    1260          348 :   source_range range = source_range::from_locations (loc, UNKNOWN_LOCATION);
    1261          348 :   suppress_coverage_ranges.safe_push (range);
    1262          348 :   return true;
    1263              : }
    1264              : 
    1265              : /* Try to close the last range created by suppress_coverage_begin at LOC.  If
    1266              :    the range has been closed already (or not opened), this is a no-op.  Returns
    1267              :    true if a range was closed.  */
    1268              : bool
    1269          348 : suppress_coverage_end (location_t loc)
    1270              : {
    1271          695 :   if (suppress_coverage_ranges.is_empty ()
    1272          347 :       || suppress_coverage_ranges.last ().m_finish != UNKNOWN_LOCATION)
    1273              :       return false;
    1274          347 :   loc = get_pure_location (expansion_point_location (loc));
    1275          347 :   suppress_coverage_ranges.last ().m_finish = loc;
    1276          347 :   return true;
    1277              : }
    1278              : 
    1279              : /* Check if STMT is anchored to a line of code in a range disabled by #pragma
    1280              :    GCC suppress_coverage begin/end.  This function always returns false if
    1281              :    coverage is disabled as it is the faster check, and nothing should be
    1282              :    suppressed anyway.
    1283              : 
    1284              :    If STMT is at an UNKNOWN_LOCATION or ADHOC_LOC, this function returns PREV.
    1285              :    This is probably a compiler-generated statement that should inherit the
    1286              :    disabled state of the previous statement since it is really tied to it, and
    1287              :    there is no opportunity for a #pragma in-between.  */
    1288              : bool
    1289     96692736 : in_pragma_suppress_coverage_p (gimple* stmt, bool prev)
    1290              : {
    1291     96692736 :   if (!coverage_instrumentation_p ())
    1292              :     return false;
    1293              : 
    1294        53087 :   location_t loc = expansion_point_location (gimple_location (stmt));
    1295        53087 :   if (loc == UNKNOWN_LOCATION || IS_ADHOC_LOC (loc))
    1296              :     return prev;
    1297              : 
    1298        39621 :   return location_in_pragma_suppress_coverage_p (loc);
    1299              : }
    1300              : 
    1301              : /* Check if LOC is within a #pragma GCC suppress_coverage block.  */
    1302              : bool
    1303      3066708 : location_in_pragma_suppress_coverage_p (location_t loc)
    1304              : {
    1305      3066708 :   loc = get_pure_location (expansion_point_location (loc));
    1306      3323107 :   for (const source_range& dl : suppress_coverage_ranges)
    1307       245995 :     if (linemap_location_before_p (line_table, dl.m_start, loc)
    1308       245995 :         && (linemap_location_before_p (line_table, loc, dl.m_finish)
    1309       147783 :             || dl.m_finish == UNKNOWN_LOCATION))
    1310              :       return true;
    1311              :   return false;
    1312              : }
    1313              : 
    1314              : /* Check if FN is fully between #pragma GCC suppress_coverage begin/end.  In
    1315              :    that case we can disable the whole function rather than every block, and
    1316              :    omit MC/DC (-fcondition-coverage) and prime path coverage (-fpath-coverage)
    1317              :    instrumentation.  */
    1318              : static bool
    1319         3012 : fn_in_pragma_suppress_coverage_p (function *fn)
    1320              : {
    1321         3012 :   if (!coverage_instrumentation_p ())
    1322              :     return false;
    1323              : 
    1324         2420 :   if (lookup_attribute ("gnu", "suppress_coverage",
    1325         2420 :                         DECL_ATTRIBUTES (fn->decl)))
    1326              :     return true;
    1327              : 
    1328         2393 :   const location_t start = fn->function_start_locus;
    1329         2393 :   const location_t end = fn->function_end_locus;
    1330              : 
    1331        19507 :   for (const source_range& dl : suppress_coverage_ranges)
    1332        16361 :     if (linemap_location_before_p (line_table, dl.m_start, start)
    1333        16361 :         && (linemap_location_before_p (line_table, end, dl.m_finish)
    1334         7394 :             || dl.m_finish == UNKNOWN_LOCATION))
    1335              :       return true;
    1336              :   return false;
    1337              : }
    1338              : 
    1339              : /* Instrument and/or analyze program behavior based on program the CFG.
    1340              : 
    1341              :    This function creates a representation of the control flow graph (of
    1342              :    the function being compiled) that is suitable for the instrumentation
    1343              :    of edges and/or converting measured edge counts to counts on the
    1344              :    complete CFG.
    1345              : 
    1346              :    When FLAG_PROFILE_ARCS is nonzero, this function instruments the edges in
    1347              :    the flow graph that are needed to reconstruct the dynamic behavior of the
    1348              :    flow graph.  This data is written to the gcno file for gcov.
    1349              : 
    1350              :    When FLAG_PROFILE_CONDITIONS is nonzero, this functions instruments the
    1351              :    edges in the control flow graph to track what conditions are evaluated to in
    1352              :    order to determine what conditions are covered and have an independent
    1353              :    effect on the outcome (modified condition/decision coverage).  This data is
    1354              :    written to the gcno file for gcov.
    1355              : 
    1356              :    When FLAG_BRANCH_PROBABILITIES is nonzero, this function reads auxiliary
    1357              :    information from the gcda file containing edge count information from
    1358              :    previous executions of the function being compiled.  In this case, the
    1359              :    control flow graph is annotated with actual execution counts by
    1360              :    compute_branch_probabilities().
    1361              : 
    1362              :    Main entry point of this file.  */
    1363              : 
    1364              : void
    1365         3012 : branch_prob (bool thunk)
    1366              : {
    1367         3012 :   basic_block bb;
    1368         3012 :   unsigned i;
    1369         3012 :   unsigned num_edges, ignored_edges;
    1370         3012 :   unsigned num_instrumented;
    1371         3012 :   struct edge_list *el;
    1372         3012 :   histogram_values values = histogram_values ();
    1373         3012 :   unsigned cfg_checksum, lineno_checksum;
    1374         3012 :   bool output_to_file;
    1375              : 
    1376         3012 :   total_num_times_called++;
    1377              : 
    1378         3012 :   flow_call_edges_add (NULL);
    1379         3012 :   add_noreturn_fake_exit_edges ();
    1380              : 
    1381         3012 :   hash_set <location_triplet_hash> streamed_locations;
    1382              : 
    1383         3012 :   if (!thunk)
    1384              :     {
    1385              :       /* We can't handle cyclic regions constructed using abnormal edges.
    1386              :          To avoid these we replace every source of abnormal edge by a fake
    1387              :          edge from entry node and every destination by fake edge to exit.
    1388              :          This keeps graph acyclic and our calculation exact for all normal
    1389              :          edges except for exit and entrance ones.
    1390              : 
    1391              :          We also add fake exit edges for each call and asm statement in the
    1392              :          basic, since it may not return.  */
    1393              : 
    1394        20428 :       FOR_EACH_BB_FN (bb, cfun)
    1395              :         {
    1396        17423 :           int need_exit_edge = 0, need_entry_edge = 0;
    1397        17423 :           int have_exit_edge = 0, have_entry_edge = 0;
    1398        17423 :           edge e;
    1399        17423 :           edge_iterator ei;
    1400              : 
    1401              :           /* Functions returning multiple times are not handled by extra edges.
    1402              :              Instead we simply allow negative counts on edges from exit to the
    1403              :              block past call and corresponding probabilities.  We can't go
    1404              :              with the extra edges because that would result in flowgraph that
    1405              :              needs to have fake edges outside the spanning tree.  */
    1406              : 
    1407        44640 :           FOR_EACH_EDGE (e, ei, bb->succs)
    1408              :             {
    1409        27217 :               gimple_stmt_iterator gsi;
    1410        27217 :               gimple *last = NULL;
    1411              : 
    1412              :               /* It may happen that there are compiler generated statements
    1413              :                  without a locus at all.  Go through the basic block from the
    1414              :                  last to the first statement looking for a locus.  */
    1415        27217 :               for (gsi = gsi_last_nondebug_bb (bb);
    1416        30439 :                    !gsi_end_p (gsi);
    1417         3222 :                    gsi_prev_nondebug (&gsi))
    1418              :                 {
    1419        27736 :                   last = gsi_stmt (gsi);
    1420        27736 :                   if (!RESERVED_LOCATION_P (gimple_location (last)))
    1421              :                     break;
    1422              :                 }
    1423              : 
    1424              :               /* Edge with goto locus might get wrong coverage info unless
    1425              :                  it is the only edge out of BB.
    1426              :                  Don't do that when the locuses match, so
    1427              :                  if (blah) goto something;
    1428              :                  is not computed twice.  */
    1429        27217 :               if (last
    1430        26323 :                   && gimple_has_location (last)
    1431        24583 :                   && !RESERVED_LOCATION_P (e->goto_locus)
    1432         4970 :                   && !single_succ_p (bb)
    1433        27500 :                   && (LOCATION_FILE (e->goto_locus)
    1434          283 :                       != LOCATION_FILE (gimple_location (last))
    1435          279 :                       || (LOCATION_LINE (e->goto_locus)
    1436        27217 :                           != LOCATION_LINE (gimple_location (last)))))
    1437              :                 {
    1438          125 :                   basic_block new_bb = split_edge (e);
    1439          125 :                   edge ne = single_succ_edge (new_bb);
    1440          125 :                   ne->goto_locus = e->goto_locus;
    1441              :                 }
    1442        27217 :               if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
    1443          182 :                    && e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
    1444        27217 :                 need_exit_edge = 1;
    1445        27217 :               if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
    1446         8149 :                 have_exit_edge = 1;
    1447              :             }
    1448        39498 :           FOR_EACH_EDGE (e, ei, bb->preds)
    1449              :             {
    1450        22075 :               if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
    1451          182 :                    && e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun))
    1452        22075 :                 need_entry_edge = 1;
    1453        22075 :               if (e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
    1454         3005 :                 have_entry_edge = 1;
    1455              :             }
    1456              : 
    1457        17423 :           if (need_exit_edge && !have_exit_edge)
    1458              :             {
    1459           29 :               if (dump_file)
    1460            0 :                 fprintf (dump_file, "Adding fake exit edge to bb %i\n",
    1461              :                          bb->index);
    1462           29 :               make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), EDGE_FAKE);
    1463              :             }
    1464        17423 :           if (need_entry_edge && !have_entry_edge)
    1465              :             {
    1466          115 :               if (dump_file)
    1467            0 :                 fprintf (dump_file, "Adding fake entry edge to bb %i\n",
    1468              :                          bb->index);
    1469          115 :               make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), bb, EDGE_FAKE);
    1470              :               /* Avoid bbs that have both fake entry edge and also some
    1471              :                  exit edge.  One of those edges wouldn't be added to the
    1472              :                  spanning tree, but we can't instrument any of them.  */
    1473          115 :               if (have_exit_edge || need_exit_edge)
    1474              :                 {
    1475           80 :                   gimple_stmt_iterator gsi;
    1476           80 :                   gimple *first;
    1477              : 
    1478           80 :                   gsi = gsi_start_nondebug_after_labels_bb (bb);
    1479           80 :                   gcc_checking_assert (!gsi_end_p (gsi));
    1480           80 :                   first = gsi_stmt (gsi);
    1481              :                   /* Don't split the bbs containing __builtin_setjmp_receiver
    1482              :                      or ABNORMAL_DISPATCHER calls.  These are very
    1483              :                      special and don't expect anything to be inserted before
    1484              :                      them.  */
    1485           80 :                   if (is_gimple_call (first)
    1486           80 :                       && (gimple_call_builtin_p (first, BUILT_IN_SETJMP_RECEIVER)
    1487           76 :                           || (gimple_call_flags (first) & ECF_RETURNS_TWICE)
    1488           39 :                           || (gimple_call_internal_p (first)
    1489           39 :                               && (gimple_call_internal_fn (first)
    1490              :                                   == IFN_ABNORMAL_DISPATCHER))))
    1491           76 :                     continue;
    1492              : 
    1493            4 :                   if (dump_file)
    1494            0 :                     fprintf (dump_file, "Splitting bb %i after labels\n",
    1495              :                              bb->index);
    1496            4 :                   split_block_after_labels (bb);
    1497              :                 }
    1498              :             }
    1499              :         }
    1500              :     }
    1501              : 
    1502         3012 :   el = create_edge_list ();
    1503         3012 :   num_edges = NUM_EDGES (el);
    1504         3012 :   qsort (el->index_to_edge, num_edges, sizeof (edge), compare_freqs);
    1505         3012 :   alloc_aux_for_edges (sizeof (struct edge_profile_info));
    1506              : 
    1507              :   /* The basic blocks are expected to be numbered sequentially.  */
    1508         3012 :   compact_blocks ();
    1509              : 
    1510         3012 :   ignored_edges = 0;
    1511        36416 :   for (i = 0 ; i < num_edges ; i++)
    1512              :     {
    1513        30392 :       edge e = INDEX_EDGE (el, i);
    1514              : 
    1515              :       /* Mark edges we've replaced by fake edges above as ignored.  */
    1516        30392 :       if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
    1517          182 :           && e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun)
    1518          182 :           && e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
    1519              :         {
    1520          182 :           EDGE_INFO (e)->ignore = 1;
    1521          182 :           ignored_edges++;
    1522              :         }
    1523              :       /* Ignore edges after musttail calls.  */
    1524        30392 :       if (cfun->has_musttail
    1525          160 :           && e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun))
    1526              :         {
    1527          140 :           gimple_stmt_iterator gsi = gsi_last_nondebug_bb (e->src);
    1528          140 :           gimple *stmt = gsi_stmt (gsi);
    1529          140 :           if (stmt
    1530          140 :               && is_gimple_call (stmt)
    1531          220 :               && gimple_call_must_tail_p (as_a <const gcall *> (stmt)))
    1532              :             {
    1533           48 :               EDGE_INFO (e)->ignore = 1;
    1534           48 :               ignored_edges++;
    1535              :             }
    1536              :         }
    1537              :     }
    1538              : 
    1539              :   /* Create spanning tree from basic block graph, mark each edge that is
    1540              :      on the spanning tree.  We insert as many abnormal and critical edges
    1541              :      as possible to minimize number of edge splits necessary.  */
    1542              : 
    1543         3012 :   if (!thunk)
    1544         3005 :     find_spanning_tree (el);
    1545              :   else
    1546              :     {
    1547            7 :       edge e;
    1548            7 :       edge_iterator ei;
    1549              :       /* Keep only edge from entry block to be instrumented.  */
    1550           21 :       FOR_EACH_BB_FN (bb, cfun)
    1551           35 :         FOR_EACH_EDGE (e, ei, bb->succs)
    1552           21 :           EDGE_INFO (e)->ignore = true;
    1553              :     }
    1554              : 
    1555              : 
    1556              :   /* Fake edges that are not on the tree will not be instrumented, so
    1557              :      mark them ignored.  */
    1558        33404 :   for (num_instrumented = i = 0; i < num_edges; i++)
    1559              :     {
    1560        30392 :       edge e = INDEX_EDGE (el, i);
    1561        30392 :       struct edge_profile_info *inf = EDGE_INFO (e);
    1562              : 
    1563        30392 :       if (inf->ignore || inf->on_tree)
    1564              :         /*NOP*/;
    1565        12718 :       else if (e->flags & EDGE_FAKE)
    1566              :         {
    1567           76 :           inf->ignore = 1;
    1568           76 :           ignored_edges++;
    1569              :         }
    1570              :       else
    1571        12642 :         num_instrumented++;
    1572              :     }
    1573              : 
    1574         3012 :   total_num_blocks += n_basic_blocks_for_fn (cfun);
    1575         3012 :   if (dump_file)
    1576          181 :     fprintf (dump_file, "%d basic blocks\n", n_basic_blocks_for_fn (cfun));
    1577              : 
    1578         3012 :   total_num_edges += num_edges;
    1579         3012 :   if (dump_file)
    1580          181 :     fprintf (dump_file, "%d edges\n", num_edges);
    1581              : 
    1582         3012 :   total_num_edges_ignored += ignored_edges;
    1583         3012 :   if (dump_file)
    1584          181 :     fprintf (dump_file, "%d ignored edges\n", ignored_edges);
    1585              : 
    1586         3012 :   total_num_edges_instrumented += num_instrumented;
    1587         3012 :   if (dump_file)
    1588          181 :     fprintf (dump_file, "%d instrumentation edges\n", num_instrumented);
    1589              : 
    1590              :   /* Dump function body before it's instrumented.
    1591              :      It helps to debug gcov tool.  */
    1592         3012 :   if (dump_file && (dump_flags & TDF_DETAILS))
    1593           24 :     dump_function_to_file (cfun->decl, dump_file, dump_flags);
    1594              : 
    1595              :   /* Compute two different checksums. Note that we want to compute
    1596              :      the checksum in only once place, since it depends on the shape
    1597              :      of the control flow which can change during
    1598              :      various transformations.  */
    1599         3012 :   if (thunk)
    1600              :     {
    1601              :       /* At stream in time we do not have CFG, so we cannot do checksums.  */
    1602              :       cfg_checksum = 0;
    1603              :       lineno_checksum = 0;
    1604              :     }
    1605              :   else
    1606              :     {
    1607         3005 :       cfg_checksum = coverage_compute_cfg_checksum (cfun);
    1608         3005 :       lineno_checksum = coverage_compute_lineno_checksum ();
    1609              :     }
    1610              : 
    1611         3012 :   const bool fn_coverage_suppressed_p = fn_in_pragma_suppress_coverage_p (cfun);
    1612              : 
    1613              :   /* Write the data from which gcov can reconstruct the basic block
    1614              :      graph and function line numbers (the gcno file).  */
    1615         3012 :   output_to_file = false;
    1616         3012 :   if (coverage_begin_function (lineno_checksum, cfg_checksum))
    1617              :     {
    1618         1497 :       gcov_position_t offset;
    1619              : 
    1620              :       /* The condition coverage needs a deeper analysis to identify expressions
    1621              :          of conditions, which means it is not yet ready to write to the gcno
    1622              :          file.  It will write its entries later, but needs to know if it do it
    1623              :          in the first place, which is controlled by the return value of
    1624              :          coverage_begin_function.  */
    1625         1497 :       output_to_file = true;
    1626              : 
    1627              :       /* Basic block flags */
    1628         1497 :       offset = gcov_write_tag (GCOV_TAG_BLOCKS);
    1629         1497 :       gcov_write_unsigned (n_basic_blocks_for_fn (cfun));
    1630         1497 :       gcov_write_length (offset);
    1631              : 
    1632              :       /* Arcs */
    1633        13148 :       FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun),
    1634              :                       EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
    1635              :         {
    1636        11651 :           edge e;
    1637        11651 :           edge_iterator ei;
    1638              : 
    1639        11651 :           offset = gcov_write_tag (GCOV_TAG_ARCS);
    1640        11651 :           gcov_write_unsigned (bb->index);
    1641              : 
    1642        29407 :           FOR_EACH_EDGE (e, ei, bb->succs)
    1643              :             {
    1644        17756 :               struct edge_profile_info *i = EDGE_INFO (e);
    1645        17756 :               if (!i->ignore)
    1646              :                 {
    1647        17539 :                   unsigned flag_bits = 0;
    1648              : 
    1649        17539 :                   if (i->on_tree)
    1650        10154 :                     flag_bits |= GCOV_ARC_ON_TREE;
    1651        17539 :                   if (e->flags & EDGE_FAKE)
    1652         3284 :                     flag_bits |= GCOV_ARC_FAKE;
    1653        17539 :                   if (e->flags & EDGE_FALLTHRU)
    1654         7905 :                     flag_bits |= GCOV_ARC_FALLTHROUGH;
    1655        17539 :                   if (e->flags & EDGE_TRUE_VALUE)
    1656         1798 :                     flag_bits |= GCOV_ARC_TRUE;
    1657        17539 :                   if (e->flags & EDGE_FALSE_VALUE)
    1658         1798 :                     flag_bits |= GCOV_ARC_FALSE;
    1659              :                   /* On trees we don't have fallthru flags, but we can
    1660              :                      recompute them from CFG shape.  */
    1661        17539 :                   if (e->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)
    1662         3596 :                       && e->src->next_bb == e->dest)
    1663         1781 :                     flag_bits |= GCOV_ARC_FALLTHROUGH;
    1664              : 
    1665        17539 :                   gcov_write_unsigned (e->dest->index);
    1666        17539 :                   gcov_write_unsigned (flag_bits);
    1667              :                 }
    1668              :             }
    1669              : 
    1670        11651 :           gcov_write_length (offset);
    1671              :         }
    1672              : 
    1673              :       /* Disabled blocks or function.  Lines, arcs, path segments through
    1674              :          ignored blocks should not count towards coverage.  Ignoring coverage
    1675              :          is a matter of interpretation and does not change the instrumentation;
    1676              :          gcov sorts it out.  If the whole function is disabled (by the
    1677              :          attribute on the function, not the statements), the entry block is
    1678              :          recorded as ignored.  */
    1679         1497 :         if (fn_coverage_suppressed_p)
    1680              :           {
    1681           32 :             offset = gcov_write_tag (GCOV_TAG_SUPPRESS);
    1682           32 :             gcov_write_unsigned (ENTRY_BLOCK);
    1683           32 :             gcov_write_length (offset);
    1684              :           }
    1685         1465 :         else if (any_block_coverage_suppressed_p ())
    1686              :           {
    1687          253 :             offset = gcov_write_tag (GCOV_TAG_SUPPRESS);
    1688         2488 :             FOR_EACH_BB_FN (bb, cfun)
    1689         2235 :               if (coverage_suppressed_p (bb))
    1690          825 :                 gcov_write_unsigned (bb->index);
    1691          253 :             gcov_write_length (offset);
    1692              :           }
    1693              : 
    1694              :       /* Line numbers.  */
    1695              :       /* Initialize the output.  */
    1696         1497 :       output_location (&streamed_locations, NULL, 0, NULL, NULL);
    1697              : 
    1698         1497 :       hash_set<location_hash> seen_locations;
    1699              : 
    1700        11651 :       FOR_EACH_BB_FN (bb, cfun)
    1701              :         {
    1702        10154 :           gimple_stmt_iterator gsi;
    1703        10154 :           gcov_position_t offset = 0;
    1704              : 
    1705        10154 :           if (bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb)
    1706              :             {
    1707         1497 :               location_t loc = DECL_SOURCE_LOCATION (current_function_decl);
    1708         1497 :               if (!RESERVED_LOCATION_P (loc))
    1709              :                 {
    1710         1497 :                   seen_locations.add (get_pure_location (loc));
    1711         1497 :                   expanded_location curr_location = expand_location (loc);
    1712         1497 :                   output_location (&streamed_locations, curr_location.file,
    1713         1497 :                                    MAX (1, curr_location.line), &offset, bb);
    1714              :                 }
    1715              :             }
    1716              : 
    1717        37301 :           for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    1718              :             {
    1719        16993 :               gimple *stmt = gsi_stmt (gsi);
    1720        16993 :               location_t loc = gimple_location (stmt);
    1721        16993 :               if (!RESERVED_LOCATION_P (loc))
    1722              :                 {
    1723        14646 :                   seen_locations.add (get_pure_location (loc));
    1724        29292 :                   output_location (&streamed_locations, gimple_filename (stmt),
    1725        29292 :                                    MAX (1, gimple_lineno (stmt)), &offset, bb);
    1726              :                 }
    1727              :             }
    1728              : 
    1729              :           /* Notice GOTO expressions eliminated while constructing the CFG.
    1730              :              It's hard to distinguish such expression, but goto_locus should
    1731              :              not be any of already seen location.  */
    1732        10154 :           location_t loc;
    1733        10154 :           if (single_succ_p (bb)
    1734         5253 :               && (loc = single_succ_edge (bb)->goto_locus)
    1735         3607 :               && !RESERVED_LOCATION_P (loc)
    1736        15407 :               && !seen_locations.contains (get_pure_location (loc)))
    1737              :             {
    1738         1290 :               expanded_location curr_location = expand_location (loc);
    1739         1290 :               output_location (&streamed_locations, curr_location.file,
    1740         1290 :                                MAX (1, curr_location.line), &offset, bb);
    1741              :             }
    1742              : 
    1743        10154 :           if (offset)
    1744              :             {
    1745              :               /* A file of NULL indicates the end of run.  */
    1746         9572 :               gcov_write_unsigned (0);
    1747         9572 :               gcov_write_string (NULL);
    1748         9572 :               gcov_write_length (offset);
    1749              :             }
    1750              :         }
    1751         1497 :     }
    1752              : 
    1753         3012 :   if (flag_profile_values)
    1754         1023 :     gimple_find_values_to_profile (&values);
    1755              : 
    1756         3012 :   if (flag_branch_probabilities)
    1757              :     {
    1758          581 :       compute_branch_probabilities (cfg_checksum, lineno_checksum);
    1759          581 :       if (flag_profile_values)
    1760          435 :         compute_value_histograms (values, cfg_checksum, lineno_checksum);
    1761              :     }
    1762              : 
    1763         3012 :   remove_fake_edges ();
    1764              : 
    1765         3012 :   if (condition_coverage_flag || path_coverage_flag || profile_arc_flag)
    1766         2420 :       gimple_init_gcov_profiler ();
    1767              : 
    1768         3012 :   if (condition_coverage_flag && !fn_coverage_suppressed_p)
    1769              :     {
    1770          166 :       struct condcov *cov = find_conditions (cfun);
    1771          166 :       gcc_assert (cov);
    1772          166 :       const size_t nconds = cov_length (cov);
    1773          166 :       total_num_conds += nconds;
    1774              : 
    1775          166 :       if (coverage_counter_alloc (GCOV_COUNTER_CONDS, 2 * nconds))
    1776              :         {
    1777          166 :           gcov_position_t offset {};
    1778          166 :           if (output_to_file)
    1779          166 :               offset = gcov_write_tag (GCOV_TAG_CONDS);
    1780              : 
    1781          463 :           for (size_t i = 0; i != nconds; ++i)
    1782              :             {
    1783          297 :               array_slice<basic_block> expr = cov_blocks (cov, i);
    1784          297 :               array_slice<uint64_t> masks = cov_masks (cov, i);
    1785          297 :               array_slice<sbitmap> maps = cov_maps (cov, i);
    1786          297 :               gcc_assert (expr.is_valid ());
    1787          297 :               gcc_assert (masks.is_valid ());
    1788          297 :               gcc_assert (maps.is_valid ());
    1789              : 
    1790          297 :               size_t terms = instrument_decisions (expr, i, maps, masks);
    1791          297 :               if (output_to_file)
    1792              :                 {
    1793          297 :                   gcov_write_unsigned (expr.front ()->index);
    1794          297 :                   gcov_write_unsigned (terms);
    1795              :                 }
    1796              :             }
    1797          166 :           if (output_to_file)
    1798          166 :               gcov_write_length (offset);
    1799              :         }
    1800          166 :       cov_free (cov);
    1801              :     }
    1802              : 
    1803              :   /* For each edge not on the spanning tree, add counting code.  */
    1804         3012 :   if (profile_arc_flag
    1805         3012 :       && coverage_counter_alloc (GCOV_COUNTER_ARCS, num_instrumented))
    1806              :     {
    1807         2140 :       unsigned n_instrumented;
    1808              : 
    1809         2140 :       n_instrumented = instrument_edges (el);
    1810              : 
    1811         2140 :       gcc_assert (n_instrumented == num_instrumented);
    1812              : 
    1813         2140 :       if (flag_profile_values)
    1814          589 :         instrument_values (values);
    1815              :     }
    1816              : 
    1817         3012 :   unsigned instrument_prime_paths (struct function*);
    1818         3012 :   if (path_coverage_flag && !fn_coverage_suppressed_p)
    1819              :     {
    1820          298 :       const unsigned npaths = instrument_prime_paths (cfun);
    1821          298 :       if (output_to_file)
    1822              :         {
    1823          298 :           gcov_position_t offset = gcov_write_tag (GCOV_TAG_PATHS);
    1824          298 :           gcov_write_unsigned (npaths);
    1825          298 :           gcov_write_length (offset);
    1826              :         }
    1827              :     }
    1828              : 
    1829         3012 :   free_aux_for_edges ();
    1830              : 
    1831         3012 :   values.release ();
    1832         3012 :   free_edge_list (el);
    1833              :   /* Commit changes done by instrumentation.  */
    1834         3012 :   gsi_commit_edge_inserts ();
    1835              : 
    1836         3012 :   coverage_end_function (lineno_checksum, cfg_checksum);
    1837         3012 :   if (flag_branch_probabilities
    1838          581 :       && (profile_status_for_fn (cfun) == PROFILE_READ))
    1839              :     {
    1840          497 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1841           12 :         report_predictor_hitrates ();
    1842          497 :       sreal nit;
    1843          497 :       bool reliable;
    1844              : 
    1845              :       /* At this moment we have precise loop iteration count estimates.
    1846              :          Record them to loop structure before the profile gets out of date. */
    1847         1695 :       for (auto loop : loops_list (cfun, 0))
    1848          233 :         if (loop->header->count.ipa ().nonzero_p ()
    1849          175 :             && expected_loop_iterations_by_profile (loop, &nit, &reliable)
    1850          175 :             && reliable)
    1851              :           {
    1852          175 :             widest_int bound = nit.to_nearest_int ();
    1853          175 :             loop->any_estimate = false;
    1854          175 :             record_niter_bound (loop, bound, true, false);
    1855          175 :           }
    1856          497 :       compute_function_frequency ();
    1857              :     }
    1858         3012 : }
    1859              : 
    1860              : /* Union find algorithm implementation for the basic blocks using
    1861              :    aux fields.  */
    1862              : 
    1863              : static basic_block
    1864        97226 : find_group (basic_block bb)
    1865              : {
    1866        97226 :   basic_block group = bb, bb1;
    1867              : 
    1868       158372 :   while ((basic_block) group->aux != group)
    1869              :     group = (basic_block) group->aux;
    1870              : 
    1871              :   /* Compress path.  */
    1872       123693 :   while ((basic_block) bb->aux != group)
    1873              :     {
    1874         6039 :       bb1 = (basic_block) bb->aux;
    1875         6039 :       bb->aux = (void *) group;
    1876         6039 :       bb = bb1;
    1877              :     }
    1878        97226 :   return group;
    1879              : }
    1880              : 
    1881              : static void
    1882        20428 : union_groups (basic_block bb1, basic_block bb2)
    1883              : {
    1884        20428 :   basic_block bb1g = find_group (bb1);
    1885        35442 :   basic_block bb2g = find_group (bb2);
    1886              : 
    1887              :   /* ??? I don't have a place for the rank field.  OK.  Lets go w/o it,
    1888              :      this code is unlikely going to be performance problem anyway.  */
    1889        20428 :   gcc_assert (bb1g != bb2g);
    1890              : 
    1891        20428 :   bb1g->aux = bb2g;
    1892        20428 : }
    1893              : 
    1894              : /* This function searches all of the edges in the program flow graph, and puts
    1895              :    as many bad edges as possible onto the spanning tree.  Bad edges include
    1896              :    abnormals edges, which can't be instrumented at the moment.  Since it is
    1897              :    possible for fake edges to form a cycle, we will have to develop some
    1898              :    better way in the future.  Also put critical edges to the tree, since they
    1899              :    are more expensive to instrument.  */
    1900              : 
    1901              : static void
    1902         3005 : find_spanning_tree (struct edge_list *el)
    1903              : {
    1904         3005 :   int i;
    1905         3005 :   int num_edges = NUM_EDGES (el);
    1906         3005 :   basic_block bb;
    1907              : 
    1908              :   /* We use aux field for standard union-find algorithm.  */
    1909        26438 :   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
    1910        23433 :     bb->aux = bb;
    1911              : 
    1912              :   /* Add fake edge exit to entry we can't instrument.  */
    1913         3005 :   union_groups (EXIT_BLOCK_PTR_FOR_FN (cfun), ENTRY_BLOCK_PTR_FOR_FN (cfun));
    1914              : 
    1915              :   /* First add all abnormal edges to the tree unless they form a cycle. Also
    1916              :      add all edges to the exit block to avoid inserting profiling code behind
    1917              :      setting return value from function.  */
    1918        36374 :   for (i = 0; i < num_edges; i++)
    1919              :     {
    1920        30364 :       edge e = INDEX_EDGE (el, i);
    1921        30364 :       if (((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_FAKE))
    1922        24803 :            || e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
    1923         8471 :           && !EDGE_INFO (e)->ignore
    1924        55159 :           && (find_group (e->src) != find_group (e->dest)))
    1925              :         {
    1926         8189 :           if (dump_file)
    1927          330 :             fprintf (dump_file, "Abnormal edge %d to %d put to tree\n",
    1928              :                      e->src->index, e->dest->index);
    1929         8189 :           EDGE_INFO (e)->on_tree = 1;
    1930         8189 :           union_groups (e->src, e->dest);
    1931              :         }
    1932              :     }
    1933              : 
    1934              :   /* And now the rest.  Edge list is sorted according to frequencies and
    1935              :      thus we will produce minimal spanning tree.  */
    1936        33369 :   for (i = 0; i < num_edges; i++)
    1937              :     {
    1938        30364 :       edge e = INDEX_EDGE (el, i);
    1939        30364 :       if (!EDGE_INFO (e)->ignore
    1940        90632 :           && find_group (e->src) != find_group (e->dest))
    1941              :         {
    1942         9234 :           if (dump_file)
    1943          302 :             fprintf (dump_file, "Normal edge %d to %d put to tree\n",
    1944              :                      e->src->index, e->dest->index);
    1945         9234 :           EDGE_INFO (e)->on_tree = 1;
    1946         9234 :           union_groups (e->src, e->dest);
    1947              :         }
    1948              :     }
    1949              : 
    1950         3005 :   clear_aux_for_blocks ();
    1951         3005 : }
    1952              : 
    1953              : /* Perform file-level initialization for branch-prob processing.  */
    1954              : 
    1955              : void
    1956            0 : init_branch_prob (void)
    1957              : {
    1958            0 :   int i;
    1959              : 
    1960            0 :   total_num_blocks = 0;
    1961            0 :   total_num_edges = 0;
    1962            0 :   total_num_edges_ignored = 0;
    1963            0 :   total_num_edges_instrumented = 0;
    1964            0 :   total_num_blocks_created = 0;
    1965            0 :   total_num_passes = 0;
    1966            0 :   total_num_times_called = 0;
    1967            0 :   total_num_branches = 0;
    1968            0 :   total_num_conds = 0;
    1969            0 :   for (i = 0; i < 20; i++)
    1970            0 :     total_hist_br_prob[i] = 0;
    1971            0 : }
    1972              : 
    1973              : /* Performs file-level cleanup after branch-prob processing
    1974              :    is completed.  */
    1975              : 
    1976              : void
    1977          630 : end_branch_prob (void)
    1978              : {
    1979          630 :   if (dump_file)
    1980              :     {
    1981           48 :       fprintf (dump_file, "\n");
    1982           48 :       fprintf (dump_file, "Total number of blocks: %d\n",
    1983              :                total_num_blocks);
    1984           48 :       fprintf (dump_file, "Total number of edges: %d\n", total_num_edges);
    1985           48 :       fprintf (dump_file, "Total number of ignored edges: %d\n",
    1986              :                total_num_edges_ignored);
    1987           48 :       fprintf (dump_file, "Total number of instrumented edges: %d\n",
    1988              :                total_num_edges_instrumented);
    1989           48 :       fprintf (dump_file, "Total number of blocks created: %d\n",
    1990              :                total_num_blocks_created);
    1991           48 :       fprintf (dump_file, "Total number of graph solution passes: %d\n",
    1992              :                total_num_passes);
    1993           48 :       if (total_num_times_called != 0)
    1994           48 :         fprintf (dump_file, "Average number of graph solution passes: %d\n",
    1995           48 :                  (total_num_passes + (total_num_times_called  >> 1))
    1996              :                  / total_num_times_called);
    1997           48 :       fprintf (dump_file, "Total number of branches: %d\n",
    1998              :                total_num_branches);
    1999           48 :       if (total_num_branches)
    2000              :         {
    2001              :           int i;
    2002              : 
    2003          220 :           for (i = 0; i < 10; i++)
    2004          200 :             fprintf (dump_file, "%d%% branches in range %d-%d%%\n",
    2005          200 :                      (total_hist_br_prob[i] + total_hist_br_prob[19-i]) * 100
    2006          200 :                      / total_num_branches, 5*i, 5*i+5);
    2007              :         }
    2008           48 :       fprintf (dump_file, "Total number of conditions: %d\n",
    2009              :                total_num_conds);
    2010           48 :       if (afdo_fdo_records.length ())
    2011              :         {
    2012            0 :           profile_count fdo_sum = profile_count::zero ();
    2013            0 :           profile_count afdo_sum = profile_count::zero ();
    2014            0 :           for (const auto &r : afdo_fdo_records)
    2015            0 :             for (const auto &b : r.bbs)
    2016            0 :               if (b.fdo.initialized_p () && b.afdo.initialized_p ())
    2017              :                 {
    2018            0 :                   fdo_sum += b.fdo;
    2019            0 :                   afdo_sum += b.afdo;
    2020              :                 }
    2021            0 :           for (auto &r : afdo_fdo_records)
    2022              :             {
    2023            0 :               for (auto &b : r.bbs)
    2024            0 :                 if (b.fdo.initialized_p () && b.afdo.initialized_p ())
    2025              :                   {
    2026            0 :                     fprintf (dump_file, "%s bb %i fdo %" PRIu64 " (%s) afdo ",
    2027            0 :                              r.node->dump_name (), b.index,
    2028            0 :                              (int64_t)b.fdo.to_gcov_type (),
    2029              :                              maybe_hot_count_p
    2030            0 :                                      (NULL, b.fdo.apply_scale (1, 1000))
    2031              :                              ? "very hot"
    2032            0 :                              : maybe_hot_count_p (NULL, b.fdo)
    2033            0 :                              ?  "hot" : "cold");
    2034            0 :                     b.afdo.dump (dump_file);
    2035            0 :                     fprintf (dump_file, " (%s) ",
    2036              :                              maybe_hot_afdo_count_p
    2037            0 :                                      (b.afdo.apply_scale (1, 1000))
    2038              :                              ? "very hot"
    2039            0 :                              : maybe_hot_afdo_count_p (b.afdo)
    2040            0 :                              ?  "hot" : "cold");
    2041            0 :                     if (afdo_sum.nonzero_p ())
    2042              :                       {
    2043            0 :                         profile_count scaled
    2044            0 :                                 = b.afdo.apply_scale (fdo_sum, afdo_sum);
    2045            0 :                         fprintf (dump_file, "scaled %" PRIu64,
    2046              :                                  scaled.to_gcov_type ());
    2047            0 :                         if (b.fdo.to_gcov_type ())
    2048            0 :                           fprintf (dump_file, " diff %" PRId64 ", %+2.2f%%",
    2049              :                                    scaled.to_gcov_type ()
    2050              :                                    - b.fdo.to_gcov_type (),
    2051            0 :                                    (scaled.to_gcov_type ()
    2052            0 :                                     - b.fdo.to_gcov_type ()) * 100.0
    2053              :                                    / b.fdo.to_gcov_type ());
    2054              :                       }
    2055            0 :                     fprintf (dump_file, "\n preds");
    2056            0 :                     for (int val : b.preds)
    2057            0 :                       fprintf (dump_file, " %i", val);
    2058            0 :                     b.preds.release ();
    2059            0 :                     fprintf (dump_file, "\n succs");
    2060            0 :                     for (int val : b.succs)
    2061            0 :                       fprintf (dump_file, " %i", val);
    2062            0 :                     b.succs.release ();
    2063            0 :                     fprintf (dump_file, "\n");
    2064              :                   }
    2065            0 :                r.bbs.release ();
    2066              :              }
    2067              :         }
    2068           48 :       afdo_fdo_records.release ();
    2069              :     }
    2070          630 : }
    2071              : 
    2072              : /* Return true if any cfg coverage/profiling is enabled; -fprofile-arcs
    2073              :    -fcondition-coverage -fpath-coverage.  */
    2074    101342403 : bool coverage_instrumentation_p ()
    2075              : {
    2076    101342403 :   return profile_arc_flag || condition_coverage_flag || path_coverage_flag;
    2077              : }
        

Generated by: LCOV version 2.4-beta

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