LCOV - code coverage report
Current view: top level - gcc - value-prof.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 82.8 % 969 802
Test Date: 2026-02-28 14:20:25 Functions: 93.0 % 43 40
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Transformations based on profile information for values.
       2              :    Copyright (C) 2003-2026 Free Software Foundation, Inc.
       3              : 
       4              : This file is part of GCC.
       5              : 
       6              : GCC is free software; you can redistribute it and/or modify it under
       7              : the terms of the GNU General Public License as published by the Free
       8              : Software Foundation; either version 3, or (at your option) any later
       9              : version.
      10              : 
      11              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14              : for more details.
      15              : 
      16              : You should have received a copy of the GNU General Public License
      17              : along with GCC; see the file COPYING3.  If not see
      18              : <http://www.gnu.org/licenses/>.  */
      19              : 
      20              : #include "config.h"
      21              : #include "system.h"
      22              : #include "coretypes.h"
      23              : #include "backend.h"
      24              : #include "rtl.h"
      25              : #include "tree.h"
      26              : #include "gimple.h"
      27              : #include "cfghooks.h"
      28              : #include "ssa.h"
      29              : #include "cgraph.h"
      30              : #include "coverage.h"
      31              : #include "data-streamer.h"
      32              : #include "diagnostic.h"
      33              : #include "fold-const.h"
      34              : #include "tree-nested.h"
      35              : #include "calls.h"
      36              : #include "expr.h"
      37              : #include "value-prof.h"
      38              : #include "tree-eh.h"
      39              : #include "gimplify.h"
      40              : #include "gimple-iterator.h"
      41              : #include "tree-cfg.h"
      42              : #include "gimple-pretty-print.h"
      43              : #include "dumpfile.h"
      44              : #include "builtins.h"
      45              : 
      46              : /* In this file value profile based optimizations are placed.  Currently the
      47              :    following optimizations are implemented (for more detailed descriptions
      48              :    see comments at value_profile_transformations):
      49              : 
      50              :    1) Division/modulo specialization.  Provided that we can determine that the
      51              :       operands of the division have some special properties, we may use it to
      52              :       produce more effective code.
      53              : 
      54              :    2) Indirect/virtual call specialization. If we can determine most
      55              :       common function callee in indirect/virtual call. We can use this
      56              :       information to improve code effectiveness (especially info for
      57              :       the inliner).
      58              : 
      59              :    3) Speculative prefetching.  If we are able to determine that the difference
      60              :       between addresses accessed by a memory reference is usually constant, we
      61              :       may add the prefetch instructions.
      62              :       FIXME: This transformation was removed together with RTL based value
      63              :       profiling.
      64              : 
      65              : 
      66              :    Value profiling internals
      67              :    ==========================
      68              : 
      69              :    Every value profiling transformation starts with defining what values
      70              :    to profile.  There are different histogram types (see HIST_TYPE_* in
      71              :    value-prof.h) and each transformation can request one or more histogram
      72              :    types per GIMPLE statement.  The function gimple_find_values_to_profile()
      73              :    collects the values to profile in a vec, and adds the number of counters
      74              :    required for the different histogram types.
      75              : 
      76              :    For a -fprofile-generate run, the statements for which values should be
      77              :    recorded, are instrumented in instrument_values().  The instrumentation
      78              :    is done by helper functions that can be found in tree-profile.cc, where
      79              :    new types of histograms can be added if necessary.
      80              : 
      81              :    After a -fprofile-use, the value profiling data is read back in by
      82              :    compute_value_histograms() that translates the collected data to
      83              :    histograms and attaches them to the profiled statements via
      84              :    gimple_add_histogram_value().  Histograms are stored in a hash table
      85              :    that is attached to every intrumented function, see VALUE_HISTOGRAMS
      86              :    in function.h.
      87              : 
      88              :    The value-profile transformations driver is the function
      89              :    gimple_value_profile_transformations().  It traverses all statements in
      90              :    the to-be-transformed function, and looks for statements with one or
      91              :    more histograms attached to it.  If a statement has histograms, the
      92              :    transformation functions are called on the statement.
      93              : 
      94              :    Limitations / FIXME / TODO:
      95              :    * Only one histogram of each type can be associated with a statement.
      96              :    * Some value profile transformations are done in builtins.cc (?!)
      97              :    * Updating of histograms needs some TLC.
      98              :    * The value profiling code could be used to record analysis results
      99              :      from non-profiling (e.g. VRP).
     100              :    * Adding new profilers should be simplified, starting with a cleanup
     101              :      of what-happens-where and with making gimple_find_values_to_profile
     102              :      and gimple_value_profile_transformations table-driven, perhaps...
     103              : */
     104              : 
     105              : static bool gimple_divmod_fixed_value_transform (gimple_stmt_iterator *);
     106              : static bool gimple_mod_pow2_value_transform (gimple_stmt_iterator *);
     107              : static bool gimple_mod_subtract_transform (gimple_stmt_iterator *);
     108              : static bool gimple_stringops_transform (gimple_stmt_iterator *);
     109              : static void dump_ic_profile (gimple_stmt_iterator *gsi);
     110              : 
     111              : /* Allocate histogram value.  */
     112              : 
     113              : histogram_value
     114         1307 : gimple_alloc_histogram_value (struct function *fun ATTRIBUTE_UNUSED,
     115              :                               enum hist_type type, gimple *stmt, tree value)
     116              : {
     117         1307 :    histogram_value hist = (histogram_value) xcalloc (1, sizeof (*hist));
     118         1307 :    hist->hvalue.value = value;
     119         1307 :    hist->hvalue.stmt = stmt;
     120         1307 :    hist->type = type;
     121         1307 :    return hist;
     122              : }
     123              : 
     124              : /* Hash value for histogram.  */
     125              : 
     126              : static hashval_t
     127            0 : histogram_hash (const void *x)
     128              : {
     129            0 :   return htab_hash_pointer (((const_histogram_value)x)->hvalue.stmt);
     130              : }
     131              : 
     132              : /* Return nonzero if statement for histogram_value X is Y.  */
     133              : 
     134              : static int
     135        56342 : histogram_eq (const void *x, const void *y)
     136              : {
     137        56342 :   return ((const_histogram_value) x)->hvalue.stmt == (const gimple *) y;
     138              : }
     139              : 
     140              : /* Set histogram for STMT.  */
     141              : 
     142              : static void
     143          534 : set_histogram_value (struct function *fun, gimple *stmt, histogram_value hist)
     144              : {
     145          534 :   void **loc;
     146          534 :   if (!hist && !VALUE_HISTOGRAMS (fun))
     147              :     return;
     148          534 :   if (!VALUE_HISTOGRAMS (fun))
     149          318 :     VALUE_HISTOGRAMS (fun) = htab_create (1, histogram_hash,
     150              :                                            histogram_eq, NULL);
     151          605 :   loc = htab_find_slot_with_hash (VALUE_HISTOGRAMS (fun), stmt,
     152              :                                   htab_hash_pointer (stmt),
     153              :                                   hist ? INSERT : NO_INSERT);
     154          534 :   if (!hist)
     155              :     {
     156           71 :       if (loc)
     157           71 :         htab_clear_slot (VALUE_HISTOGRAMS (fun), loc);
     158           71 :       return;
     159              :     }
     160          463 :   *loc = hist;
     161              : }
     162              : 
     163              : /* Get histogram list for STMT.  */
     164              : 
     165              : histogram_value
     166  12852636144 : gimple_histogram_value (struct function *fun, gimple *stmt)
     167              : {
     168  12852636144 :   if (!VALUE_HISTOGRAMS (fun))
     169              :     return NULL;
     170       322715 :   return (histogram_value) htab_find_with_hash (VALUE_HISTOGRAMS (fun), stmt,
     171       322715 :                                                 htab_hash_pointer (stmt));
     172              : }
     173              : 
     174              : /* Add histogram for STMT.  */
     175              : 
     176              : void
     177          447 : gimple_add_histogram_value (struct function *fun, gimple *stmt,
     178              :                             histogram_value hist)
     179              : {
     180          447 :   hist->hvalue.next = gimple_histogram_value (fun, stmt);
     181          447 :   set_histogram_value (fun, stmt, hist);
     182          447 :   hist->fun = fun;
     183          447 : }
     184              : 
     185              : /* Remove histogram HIST from STMT's histogram list.  */
     186              : 
     187              : void
     188          124 : gimple_remove_histogram_value (struct function *fun, gimple *stmt,
     189              :                                histogram_value hist)
     190              : {
     191          124 :   histogram_value hist2 = gimple_histogram_value (fun, stmt);
     192          124 :   if (hist == hist2)
     193              :     {
     194           87 :       set_histogram_value (fun, stmt, hist->hvalue.next);
     195              :     }
     196              :   else
     197              :     {
     198           56 :       while (hist2->hvalue.next != hist)
     199              :         hist2 = hist2->hvalue.next;
     200           37 :       hist2->hvalue.next = hist->hvalue.next;
     201              :     }
     202          124 :   free (hist->hvalue.counters);
     203          124 :   if (flag_checking)
     204              :     memset (hist, 0xab, sizeof (*hist));
     205          124 :   free (hist);
     206          124 : }
     207              : 
     208              : /* Lookup histogram of type TYPE in the STMT.  */
     209              : 
     210              : histogram_value
     211       353296 : gimple_histogram_value_of_type (struct function *fun, gimple *stmt,
     212              :                                 enum hist_type type)
     213              : {
     214       353296 :   histogram_value hist;
     215       353358 :   for (hist = gimple_histogram_value (fun, stmt); hist;
     216           62 :        hist = hist->hvalue.next)
     217          184 :     if (hist->type == type)
     218              :       return hist;
     219              :   return NULL;
     220              : }
     221              : 
     222              : /* Dump information about HIST to DUMP_FILE.  */
     223              : 
     224              : static void
     225          271 : dump_histogram_value (FILE *dump_file, histogram_value hist)
     226              : {
     227          271 :   switch (hist->type)
     228              :     {
     229           13 :     case HIST_TYPE_INTERVAL:
     230           13 :       if (hist->hvalue.counters)
     231              :         {
     232            5 :           fprintf (dump_file, "Interval counter range [%d,%d]: [",
     233              :                    hist->hdata.intvl.int_start,
     234            5 :                    (hist->hdata.intvl.int_start
     235            5 :                     + hist->hdata.intvl.steps - 1));
     236              : 
     237            5 :           unsigned int i;
     238           20 :           for (i = 0; i < hist->hdata.intvl.steps; i++)
     239              :             {
     240           10 :               fprintf (dump_file, "%d:%" PRId64,
     241           10 :                        hist->hdata.intvl.int_start + i,
     242           10 :                        (int64_t) hist->hvalue.counters[i]);
     243           10 :               if (i != hist->hdata.intvl.steps - 1)
     244            5 :                 fprintf (dump_file, ", ");
     245              :             }
     246            5 :           fprintf (dump_file, "] outside range: %" PRId64 ".\n",
     247            5 :                    (int64_t) hist->hvalue.counters[i]);
     248              :         }
     249              :       break;
     250              : 
     251           16 :     case HIST_TYPE_POW2:
     252           16 :       if (hist->hvalue.counters)
     253            8 :         fprintf (dump_file, "Pow2 counter pow2:%" PRId64
     254              :                  " nonpow2:%" PRId64 ".\n",
     255              :                  (int64_t) hist->hvalue.counters[1],
     256              :                  (int64_t) hist->hvalue.counters[0]);
     257              :       break;
     258              : 
     259          112 :     case HIST_TYPE_TOPN_VALUES:
     260          112 :     case HIST_TYPE_INDIR_CALL:
     261          112 :       if (hist->hvalue.counters)
     262              :         {
     263           68 :           fprintf (dump_file,
     264              :                    (hist->type == HIST_TYPE_TOPN_VALUES
     265              :                     ? "Top N value counter" : "Indirect call counter"));
     266           48 :           if (hist->hvalue.counters)
     267              :             {
     268           48 :               unsigned count = hist->hvalue.counters[1];
     269           48 :               fprintf (dump_file, " all: %" PRId64 ", %" PRId64 " values: ",
     270              :                        (int64_t) hist->hvalue.counters[0], (int64_t) count);
     271          117 :               for (unsigned i = 0; i < count; i++)
     272              :                 {
     273           69 :                   fprintf (dump_file, "[%" PRId64 ":%" PRId64 "]",
     274           69 :                            (int64_t) hist->hvalue.counters[2 * i + 2],
     275           69 :                            (int64_t) hist->hvalue.counters[2 * i + 3]);
     276           69 :                   if (i != count - 1)
     277           25 :                     fprintf (dump_file, ", ");
     278              :                 }
     279           48 :               fprintf (dump_file, ".\n");
     280              :             }
     281              :         }
     282              :       break;
     283              : 
     284           65 :     case HIST_TYPE_AVERAGE:
     285           65 :       if (hist->hvalue.counters)
     286           35 :         fprintf (dump_file, "Average value sum:%" PRId64
     287              :                  " times:%" PRId64 ".\n",
     288              :                  (int64_t) hist->hvalue.counters[0],
     289              :                  (int64_t) hist->hvalue.counters[1]);
     290              :       break;
     291              : 
     292           65 :     case HIST_TYPE_IOR:
     293           65 :       if (hist->hvalue.counters)
     294           35 :         fprintf (dump_file, "IOR value ior:%" PRId64 ".\n",
     295              :                  (int64_t) hist->hvalue.counters[0]);
     296              :       break;
     297              : 
     298            0 :     case HIST_TYPE_TIME_PROFILE:
     299            0 :       if (hist->hvalue.counters)
     300            0 :         fprintf (dump_file, "Time profile time:%" PRId64 ".\n",
     301              :                  (int64_t) hist->hvalue.counters[0]);
     302              :       break;
     303            0 :     default:
     304            0 :       gcc_unreachable ();
     305              :    }
     306          271 : }
     307              : 
     308              : /* Dump information about HIST to DUMP_FILE.  */
     309              : 
     310              : void
     311            1 : stream_out_histogram_value (struct output_block *ob, histogram_value hist)
     312              : {
     313            2 :   struct bitpack_d bp;
     314            2 :   unsigned int i;
     315              : 
     316            2 :   bp = bitpack_create (ob->main_stream);
     317            2 :   bp_pack_enum (&bp, hist_type, HIST_TYPE_MAX, hist->type);
     318            2 :   bp_pack_value (&bp, hist->hvalue.next != NULL, 1);
     319            2 :   streamer_write_bitpack (&bp);
     320            2 :   switch (hist->type)
     321              :     {
     322            0 :     case HIST_TYPE_INTERVAL:
     323            0 :       streamer_write_hwi (ob, hist->hdata.intvl.int_start);
     324            0 :       streamer_write_uhwi (ob, hist->hdata.intvl.steps);
     325            0 :       break;
     326              :     default:
     327              :       break;
     328              :     }
     329            8 :   for (i = 0; i < hist->n_counters; i++)
     330              :     {
     331              :       /* When user uses an unsigned type with a big value, constant converted
     332              :          to gcov_type (a signed type) can be negative.  */
     333            6 :       gcov_type value = hist->hvalue.counters[i];
     334            6 :       streamer_write_gcov_count (ob, value);
     335              :     }
     336            2 :   if (hist->hvalue.next)
     337              :     stream_out_histogram_value (ob, hist->hvalue.next);
     338            1 : }
     339              : 
     340              : /* Dump information about HIST to DUMP_FILE.  */
     341              : 
     342              : void
     343            1 : stream_in_histogram_value (class lto_input_block *ib, gimple *stmt)
     344              : {
     345            1 :   enum hist_type type;
     346            1 :   unsigned int ncounters = 0;
     347            1 :   struct bitpack_d bp;
     348            1 :   unsigned int i;
     349            1 :   histogram_value new_val;
     350            1 :   bool next;
     351            1 :   histogram_value *next_p = NULL;
     352              : 
     353            4 :   do
     354              :     {
     355            2 :       bp = streamer_read_bitpack (ib);
     356            2 :       type = bp_unpack_enum (&bp, hist_type, HIST_TYPE_MAX);
     357            2 :       next = bp_unpack_value (&bp, 1);
     358            2 :       new_val = gimple_alloc_histogram_value (cfun, type, stmt);
     359            2 :       switch (type)
     360              :         {
     361            0 :         case HIST_TYPE_INTERVAL:
     362            0 :           new_val->hdata.intvl.int_start = streamer_read_hwi (ib);
     363            0 :           new_val->hdata.intvl.steps = streamer_read_uhwi (ib);
     364            0 :           ncounters = new_val->hdata.intvl.steps + 2;
     365            0 :           break;
     366              : 
     367            1 :         case HIST_TYPE_POW2:
     368            1 :         case HIST_TYPE_AVERAGE:
     369            1 :           ncounters = 2;
     370            1 :           break;
     371              : 
     372              :         case HIST_TYPE_TOPN_VALUES:
     373              :         case HIST_TYPE_INDIR_CALL:
     374              :           break;
     375              : 
     376            0 :         case HIST_TYPE_IOR:
     377            0 :         case HIST_TYPE_TIME_PROFILE:
     378            0 :           ncounters = 1;
     379            0 :           break;
     380              : 
     381            0 :         default:
     382            0 :           gcc_unreachable ();
     383              :         }
     384              : 
     385              :       /* TOP N counters have variable number of counters.  */
     386            2 :       if (type == HIST_TYPE_INDIR_CALL || type == HIST_TYPE_TOPN_VALUES)
     387              :         {
     388            1 :           gcov_type total = streamer_read_gcov_count (ib);
     389            1 :           gcov_type ncounters = streamer_read_gcov_count (ib);
     390            1 :           new_val->hvalue.counters = XNEWVAR (gcov_type,
     391              :                                               sizeof (*new_val->hvalue.counters)
     392              :                                               * (2 + 2 * ncounters));
     393            1 :           new_val->hvalue.counters[0] = total;
     394            1 :           new_val->hvalue.counters[1] = ncounters;
     395            1 :           new_val->n_counters = 2 + 2 * ncounters;
     396            3 :           for (i = 0; i < 2 * ncounters; i++)
     397            2 :             new_val->hvalue.counters[2 + i] = streamer_read_gcov_count (ib);
     398              :         }
     399              :       else
     400              :         {
     401            1 :           new_val->hvalue.counters = XNEWVAR (gcov_type,
     402              :                                               sizeof (*new_val->hvalue.counters)
     403              :                                               * ncounters);
     404            1 :           new_val->n_counters = ncounters;
     405            3 :           for (i = 0; i < ncounters; i++)
     406            2 :             new_val->hvalue.counters[i] = streamer_read_gcov_count (ib);
     407              :         }
     408              : 
     409            2 :       if (!next_p)
     410            1 :         gimple_add_histogram_value (cfun, stmt, new_val);
     411              :       else
     412            1 :         *next_p = new_val;
     413            2 :       next_p = &new_val->hvalue.next;
     414              :     }
     415              :   while (next);
     416            1 : }
     417              : 
     418              : /* Dump all histograms attached to STMT to DUMP_FILE.  */
     419              : 
     420              : void
     421      1134969 : dump_histograms_for_stmt (struct function *fun, FILE *dump_file, gimple *stmt)
     422              : {
     423      1134969 :   histogram_value hist;
     424      1135100 :   for (hist = gimple_histogram_value (fun, stmt); hist; hist = hist->hvalue.next)
     425          131 :     dump_histogram_value (dump_file, hist);
     426      1134969 : }
     427              : 
     428              : /* Remove all histograms associated with STMT.  */
     429              : 
     430              : void
     431    121390099 : gimple_remove_stmt_histograms (struct function *fun, gimple *stmt)
     432              : {
     433    121390099 :   histogram_value val;
     434    121390117 :   while ((val = gimple_histogram_value (fun, stmt)) != NULL)
     435           18 :     gimple_remove_histogram_value (fun, stmt, val);
     436    121390099 : }
     437              : 
     438              : /* Duplicate all histograms associates with OSTMT to STMT.  */
     439              : 
     440              : void
     441    111760930 : gimple_duplicate_stmt_histograms (struct function *fun, gimple *stmt,
     442              :                                   struct function *ofun, gimple *ostmt)
     443              : {
     444    111760930 :   histogram_value val;
     445    111760937 :   for (val = gimple_histogram_value (ofun, ostmt); val != NULL; val = val->hvalue.next)
     446              :     {
     447            7 :       histogram_value new_val = gimple_alloc_histogram_value (fun, val->type);
     448            7 :       memcpy (new_val, val, sizeof (*val));
     449            7 :       new_val->hvalue.stmt = stmt;
     450            7 :       new_val->hvalue.counters = XNEWVAR (gcov_type, sizeof (*new_val->hvalue.counters) * new_val->n_counters);
     451            7 :       memcpy (new_val->hvalue.counters, val->hvalue.counters, sizeof (*new_val->hvalue.counters) * new_val->n_counters);
     452            7 :       gimple_add_histogram_value (fun, stmt, new_val);
     453              :     }
     454    111760930 : }
     455              : 
     456              : /* Move all histograms associated with OSTMT to STMT.  */
     457              : 
     458              : void
     459            0 : gimple_move_stmt_histograms (struct function *fun, gimple *stmt, gimple *ostmt)
     460              : {
     461            0 :   histogram_value val = gimple_histogram_value (fun, ostmt);
     462            0 :   if (val)
     463              :     {
     464              :       /* The following three statements can't be reordered,
     465              :          because histogram hashtab relies on stmt field value
     466              :          for finding the exact slot. */
     467            0 :       set_histogram_value (fun, ostmt, NULL);
     468            0 :       for (; val != NULL; val = val->hvalue.next)
     469            0 :         val->hvalue.stmt = stmt;
     470            0 :       set_histogram_value (fun, stmt, val);
     471              :     }
     472            0 : }
     473              : 
     474              : static bool error_found = false;
     475              : 
     476              : /* Helper function for verify_histograms.  For each histogram reachable via htab
     477              :    walk verify that it was reached via statement walk.  */
     478              : 
     479              : static int
     480        33222 : visit_hist (void **slot, void *data)
     481              : {
     482        33222 :   hash_set<histogram_value> *visited = (hash_set<histogram_value> *) data;
     483        33222 :   histogram_value hist = *(histogram_value *) slot;
     484              : 
     485        33222 :   if (!visited->contains (hist)
     486        33222 :       && hist->type != HIST_TYPE_TIME_PROFILE)
     487              :     {
     488            0 :       error ("dead histogram");
     489            0 :       dump_histogram_value (stderr, hist);
     490            0 :       debug_gimple_stmt (hist->hvalue.stmt);
     491            0 :       error_found = true;
     492              :     }
     493        33222 :   return 1;
     494              : }
     495              : 
     496              : /* Verify sanity of the histograms.  */
     497              : 
     498              : DEBUG_FUNCTION void
     499    243399861 : verify_histograms (void)
     500              : {
     501    243399861 :   basic_block bb;
     502    243399861 :   gimple_stmt_iterator gsi;
     503    243399861 :   histogram_value hist;
     504              : 
     505    243399861 :   error_found = false;
     506    243399861 :   hash_set<histogram_value> visited_hists;
     507   2185687315 :   FOR_EACH_BB_FN (bb, cfun)
     508  16500883835 :     for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
     509              :       {
     510  12616308927 :         gimple *stmt = gsi_stmt (gsi);
     511              : 
     512  12616314158 :         for (hist = gimple_histogram_value (cfun, stmt); hist;
     513         5231 :              hist = hist->hvalue.next)
     514              :           {
     515         5231 :             if (hist->hvalue.stmt != stmt)
     516              :               {
     517            0 :                 error ("histogram value statement does not correspond to "
     518              :                        "the statement it is associated with");
     519            0 :                 debug_gimple_stmt (stmt);
     520            0 :                 dump_histogram_value (stderr, hist);
     521            0 :                 error_found = true;
     522              :               }
     523         5231 :             visited_hists.add (hist);
     524              :           }
     525              :       }
     526    243399861 :   if (VALUE_HISTOGRAMS (cfun))
     527        30765 :     htab_traverse (VALUE_HISTOGRAMS (cfun), visit_hist, &visited_hists);
     528    243399861 :   if (error_found)
     529            0 :     internal_error ("%qs failed", __func__);
     530    243399861 : }
     531              : 
     532              : /* Helper function for verify_histograms.  For each histogram reachable via htab
     533              :    walk verify that it was reached via statement walk.  */
     534              : 
     535              : static int
     536          306 : free_hist (void **slot, void *data ATTRIBUTE_UNUSED)
     537              : {
     538          306 :   histogram_value hist = *(histogram_value *) slot;
     539          306 :   free (hist->hvalue.counters);
     540          306 :   free (hist);
     541          306 :   return 1;
     542              : }
     543              : 
     544              : void
     545      1472152 : free_histograms (struct function *fn)
     546              : {
     547      1472152 :   if (VALUE_HISTOGRAMS (fn))
     548              :     {
     549          303 :       htab_traverse (VALUE_HISTOGRAMS (fn), free_hist, NULL);
     550          303 :       htab_delete (VALUE_HISTOGRAMS (fn));
     551          303 :       VALUE_HISTOGRAMS (fn) = NULL;
     552              :     }
     553      1472152 : }
     554              : 
     555              : /* The overall number of invocations of the counter should match
     556              :    execution count of basic block.  Report it as error rather than
     557              :    internal error as it might mean that user has misused the profile
     558              :    somehow.  */
     559              : 
     560              : static bool
     561           43 : check_counter (gimple *stmt, const char * name,
     562              :                gcov_type *count, gcov_type *all, profile_count bb_count_d)
     563              : {
     564           43 :   gcov_type bb_count = bb_count_d.ipa ().to_gcov_type ();
     565           43 :   if (*all != bb_count || *count > *all)
     566              :     {
     567            0 :       dump_user_location_t locus;
     568            0 :       locus = ((stmt != NULL)
     569            0 :                ? dump_user_location_t (stmt)
     570              :                : dump_user_location_t::from_function_decl
     571            0 :                    (current_function_decl));
     572            0 :       if (flag_profile_correction)
     573              :         {
     574            0 :           if (dump_enabled_p ())
     575            0 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, locus,
     576              :                              "correcting inconsistent value profile: %s "
     577              :                              "profiler overall count (%d) does not match BB "
     578            0 :                              "count (%d)\n", name, (int)*all, (int)bb_count);
     579            0 :           *all = bb_count;
     580            0 :           if (*count > *all)
     581            0 :             *count = *all;
     582            0 :           return false;
     583              :         }
     584              :       else
     585              :         {
     586            0 :           error_at (locus.get_location_t (), "corrupted value profile: %s "
     587              :                     "profile counter (%d out of %d) inconsistent with "
     588              :                     "basic-block count (%d)",
     589              :                     name,
     590            0 :                     (int) *count,
     591            0 :                     (int) *all,
     592              :                     (int) bb_count);
     593            0 :           return true;
     594              :         }
     595              :     }
     596              : 
     597              :   return false;
     598              : }
     599              : 
     600              : /* GIMPLE based transformations. */
     601              : 
     602              : bool
     603          333 : gimple_value_profile_transformations (void)
     604              : {
     605          333 :   basic_block bb;
     606          333 :   gimple_stmt_iterator gsi;
     607          333 :   bool changed = false;
     608              : 
     609         1784 :   FOR_EACH_BB_FN (bb, cfun)
     610              :     {
     611         5246 :       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
     612              :         {
     613         2344 :           gimple *stmt = gsi_stmt (gsi);
     614         2344 :           histogram_value th = gimple_histogram_value (cfun, stmt);
     615         2344 :           if (!th)
     616         2273 :             continue;
     617              : 
     618           71 :           if (dump_file)
     619              :             {
     620           32 :               fprintf (dump_file, "Trying transformations on stmt ");
     621           32 :               print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
     622           32 :               dump_histograms_for_stmt (cfun, dump_file, stmt);
     623              :             }
     624              : 
     625              :           /* Transformations:  */
     626              :           /* The order of things in this conditional controls which
     627              :              transformation is used when more than one is applicable.  */
     628              :           /* It is expected that any code added by the transformations
     629              :              will be added before the current statement, and that the
     630              :              current statement remain valid (although possibly
     631              :              modified) upon return.  */
     632           71 :           if (gimple_mod_subtract_transform (&gsi)
     633           67 :               || gimple_divmod_fixed_value_transform (&gsi)
     634           63 :               || gimple_mod_pow2_value_transform (&gsi)
     635          134 :               || gimple_stringops_transform (&gsi))
     636              :             {
     637           19 :               stmt = gsi_stmt (gsi);
     638           19 :               changed = true;
     639              :               /* Original statement may no longer be in the same block. */
     640           19 :               if (bb != gimple_bb (stmt))
     641              :                 {
     642           19 :                   bb = gimple_bb (stmt);
     643           19 :                   gsi = gsi_for_stmt (stmt);
     644              :                 }
     645              :             }
     646              : 
     647              :           /* The function never thansforms a GIMPLE statement.  */
     648           71 :           if (dump_enabled_p ())
     649           32 :             dump_ic_profile (&gsi);
     650              :         }
     651              :     }
     652              : 
     653          333 :   return changed;
     654              : }
     655              : 
     656              : /* Generate code for transformation 1 (with parent gimple assignment
     657              :    STMT and probability of taking the optimal path PROB, which is
     658              :    equivalent to COUNT/ALL within roundoff error).  This generates the
     659              :    result into a temp and returns the temp; it does not replace or
     660              :    alter the original STMT.  */
     661              : 
     662              : static tree
     663            4 : gimple_divmod_fixed_value (gassign *stmt, tree value, profile_probability prob,
     664              :                            gcov_type count, gcov_type all)
     665              : {
     666            4 :   gassign *stmt1, *stmt2;
     667            4 :   gcond *stmt3;
     668            4 :   tree tmp0, tmp1, tmp2;
     669            4 :   gimple *bb1end, *bb2end, *bb3end;
     670            4 :   basic_block bb, bb2, bb3, bb4;
     671            4 :   tree optype, op1, op2;
     672            4 :   edge e12, e13, e23, e24, e34;
     673            4 :   gimple_stmt_iterator gsi;
     674              : 
     675            8 :   gcc_assert (is_gimple_assign (stmt)
     676              :               && (gimple_assign_rhs_code (stmt) == TRUNC_DIV_EXPR
     677              :                   || gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR));
     678              : 
     679            4 :   optype = TREE_TYPE (gimple_assign_lhs (stmt));
     680            4 :   op1 = gimple_assign_rhs1 (stmt);
     681            4 :   op2 = gimple_assign_rhs2 (stmt);
     682              : 
     683            4 :   bb = gimple_bb (stmt);
     684            4 :   gsi = gsi_for_stmt (stmt);
     685              : 
     686            4 :   tmp0 = make_temp_ssa_name (optype, NULL, "PROF");
     687            4 :   tmp1 = make_temp_ssa_name (optype, NULL, "PROF");
     688            4 :   stmt1 = gimple_build_assign (tmp0, fold_convert (optype, value));
     689            4 :   stmt2 = gimple_build_assign (tmp1, op2);
     690            4 :   stmt3 = gimple_build_cond (NE_EXPR, tmp1, tmp0, NULL_TREE, NULL_TREE);
     691            4 :   gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
     692            4 :   gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
     693            4 :   gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
     694            4 :   bb1end = stmt3;
     695              : 
     696            4 :   tmp2 = create_tmp_reg (optype, "PROF");
     697            4 :   stmt1 = gimple_build_assign (tmp2, gimple_assign_rhs_code (stmt), op1, tmp0);
     698            4 :   gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
     699            4 :   bb2end = stmt1;
     700              : 
     701            4 :   stmt1 = gimple_build_assign (tmp2, gimple_assign_rhs_code (stmt), op1, op2);
     702            4 :   gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
     703            4 :   bb3end = stmt1;
     704              : 
     705              :   /* Fix CFG. */
     706              :   /* Edge e23 connects bb2 to bb3, etc. */
     707            4 :   e12 = split_block (bb, bb1end);
     708            4 :   bb2 = e12->dest;
     709            4 :   bb2->count = profile_count::from_gcov_type (count);
     710            4 :   e23 = split_block (bb2, bb2end);
     711            4 :   bb3 = e23->dest;
     712            4 :   bb3->count = profile_count::from_gcov_type (all - count);
     713            4 :   e34 = split_block (bb3, bb3end);
     714            4 :   bb4 = e34->dest;
     715            4 :   bb4->count = profile_count::from_gcov_type (all);
     716              : 
     717            4 :   e12->flags &= ~EDGE_FALLTHRU;
     718            4 :   e12->flags |= EDGE_FALSE_VALUE;
     719            4 :   e12->probability = prob;
     720              : 
     721            4 :   e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE);
     722            4 :   e13->probability = prob.invert ();
     723              : 
     724            4 :   remove_edge (e23);
     725              : 
     726            4 :   e24 = make_edge (bb2, bb4, EDGE_FALLTHRU);
     727            4 :   e24->probability = profile_probability::always ();
     728              : 
     729            4 :   e34->probability = profile_probability::always ();
     730              : 
     731            4 :   return tmp2;
     732              : }
     733              : 
     734              : /* Return the n-th value count of TOPN_VALUE histogram.  If
     735              :    there's a value, return true and set VALUE and COUNT
     736              :    arguments.
     737              : 
     738              :    Counters have the following meaning.
     739              : 
     740              :    abs (counters[0]) is the number of executions
     741              :    for i in 0 ... TOPN-1
     742              :      counters[2 * i + 2] is target
     743              :      counters[2 * i + 3] is corresponding hitrate counter.
     744              : 
     745              :    Value of counters[0] negative when counter became
     746              :    full during merging and some values are lost.  */
     747              : 
     748              : bool
     749         1329 : get_nth_most_common_value (gimple *stmt, const char *counter_type,
     750              :                            histogram_value hist, gcov_type *value,
     751              :                            gcov_type *count, gcov_type *all, unsigned n)
     752              : {
     753         1329 :   unsigned counters = hist->hvalue.counters[1];
     754         1329 :   if (n >= counters)
     755              :     return false;
     756              : 
     757           85 :   *count = 0;
     758           85 :   *value = 0;
     759              : 
     760           85 :   gcov_type read_all = abs_hwi (hist->hvalue.counters[0]);
     761           85 :   gcov_type covered = 0;
     762          254 :   for (unsigned i = 0; i < counters; ++i)
     763          169 :     covered += hist->hvalue.counters[2 * i + 3];
     764              : 
     765           85 :   gcov_type v = hist->hvalue.counters[2 * n + 2];
     766           85 :   gcov_type c = hist->hvalue.counters[2 * n + 3];
     767              : 
     768           85 :   if (hist->hvalue.counters[0] < 0
     769            0 :       && flag_profile_reproducible == PROFILE_REPRODUCIBILITY_PARALLEL_RUNS)
     770              :     {
     771            0 :       if (dump_file)
     772            0 :         fprintf (dump_file, "Histogram value dropped in '%s' mode\n",
     773              :                  "-fprofile-reproducible=parallel-runs");
     774            0 :       return false;
     775              :     }
     776           85 :   else if (covered != read_all
     777            1 :            && flag_profile_reproducible == PROFILE_REPRODUCIBILITY_MULTITHREADED)
     778              :     {
     779            0 :       if (dump_file)
     780            0 :         fprintf (dump_file, "Histogram value dropped in '%s' mode\n",
     781              :                  "-fprofile-reproducible=multithreaded");
     782            0 :       return false;
     783              :     }
     784              : 
     785              :   /* Indirect calls can't be verified.  */
     786           85 :   if (stmt
     787          107 :       && check_counter (stmt, counter_type, &c, &read_all,
     788           22 :                         gimple_bb (stmt)->count))
     789              :     return false;
     790              : 
     791           85 :   *all = read_all;
     792              : 
     793           85 :   *value = v;
     794           85 :   *count = c;
     795           85 :   return true;
     796              : }
     797              : 
     798              : /* Do transform 1) on INSN if applicable.  */
     799              : 
     800              : static bool
     801           67 : gimple_divmod_fixed_value_transform (gimple_stmt_iterator *si)
     802              : {
     803           67 :   histogram_value histogram;
     804           67 :   enum tree_code code;
     805           67 :   gcov_type val, count, all;
     806           67 :   tree result, value, tree_val;
     807           67 :   profile_probability prob;
     808           67 :   gassign *stmt;
     809              : 
     810           69 :   stmt = dyn_cast <gassign *> (gsi_stmt (*si));
     811            6 :   if (!stmt)
     812              :     return false;
     813              : 
     814            6 :   if (!INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt))))
     815              :     return false;
     816              : 
     817            6 :   code = gimple_assign_rhs_code (stmt);
     818              : 
     819            6 :   if (code != TRUNC_DIV_EXPR && code != TRUNC_MOD_EXPR)
     820              :     return false;
     821              : 
     822            6 :   histogram = gimple_histogram_value_of_type (cfun, stmt,
     823              :                                               HIST_TYPE_TOPN_VALUES);
     824            6 :   if (!histogram)
     825              :     return false;
     826              : 
     827            6 :   if (!get_nth_most_common_value (stmt, "divmod", histogram, &val, &count,
     828              :                                   &all))
     829              :     return false;
     830              : 
     831            4 :   value = histogram->hvalue.value;
     832            4 :   gimple_remove_histogram_value (cfun, stmt, histogram);
     833              : 
     834              :   /* We require that count is at least half of all.  */
     835            8 :   if (simple_cst_equal (gimple_assign_rhs2 (stmt), value) != 1
     836            4 :       || 2 * count < all
     837            8 :       || optimize_bb_for_size_p (gimple_bb (stmt)))
     838            0 :     return false;
     839              : 
     840              :   /* Compute probability of taking the optimal path.  */
     841            4 :   if (all > 0)
     842            4 :     prob = profile_probability::probability_in_gcov_type (count, all);
     843              :   else
     844            0 :     prob = profile_probability::never ();
     845              : 
     846            4 :   if (sizeof (gcov_type) == sizeof (HOST_WIDE_INT))
     847            4 :     tree_val = build_int_cst (get_gcov_type (), val);
     848              :   else
     849              :     {
     850              :       HOST_WIDE_INT a[2];
     851              :       a[0] = (unsigned HOST_WIDE_INT) val;
     852              :       a[1] = val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1;
     853              : 
     854              :       tree_val = wide_int_to_tree (get_gcov_type (), wide_int::from_array (a, 2,
     855              :         TYPE_PRECISION (get_gcov_type ()), false));
     856              :     }
     857            4 :   result = gimple_divmod_fixed_value (stmt, tree_val, prob, count, all);
     858              : 
     859            4 :   if (dump_enabled_p ())
     860            3 :     dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt,
     861              :                      "Transformation done: div/mod by constant %T\n", tree_val);
     862              : 
     863            4 :   gimple_assign_set_rhs_from_tree (si, result);
     864            4 :   update_stmt (gsi_stmt (*si));
     865              : 
     866            4 :   return true;
     867              : }
     868              : 
     869              : /* Generate code for transformation 2 (with parent gimple assign STMT and
     870              :    probability of taking the optimal path PROB, which is equivalent to COUNT/ALL
     871              :    within roundoff error).  This generates the result into a temp and returns
     872              :    the temp; it does not replace or alter the original STMT.  */
     873              : 
     874              : static tree
     875            0 : gimple_mod_pow2 (gassign *stmt, profile_probability prob, gcov_type count, gcov_type all)
     876              : {
     877            0 :   gassign *stmt1, *stmt2, *stmt3;
     878            0 :   gcond *stmt4;
     879            0 :   tree tmp2, tmp3;
     880            0 :   gimple *bb1end, *bb2end, *bb3end;
     881            0 :   basic_block bb, bb2, bb3, bb4;
     882            0 :   tree optype, op1, op2;
     883            0 :   edge e12, e13, e23, e24, e34;
     884            0 :   gimple_stmt_iterator gsi;
     885            0 :   tree result;
     886              : 
     887            0 :   gcc_assert (is_gimple_assign (stmt)
     888              :               && gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR);
     889              : 
     890            0 :   optype = TREE_TYPE (gimple_assign_lhs (stmt));
     891            0 :   op1 = gimple_assign_rhs1 (stmt);
     892            0 :   op2 = gimple_assign_rhs2 (stmt);
     893              : 
     894            0 :   bb = gimple_bb (stmt);
     895            0 :   gsi = gsi_for_stmt (stmt);
     896              : 
     897            0 :   result = create_tmp_reg (optype, "PROF");
     898            0 :   tmp2 = make_temp_ssa_name (optype, NULL, "PROF");
     899            0 :   tmp3 = make_temp_ssa_name (optype, NULL, "PROF");
     900            0 :   stmt2 = gimple_build_assign (tmp2, PLUS_EXPR, op2,
     901              :                                build_int_cst (optype, -1));
     902            0 :   stmt3 = gimple_build_assign (tmp3, BIT_AND_EXPR, tmp2, op2);
     903            0 :   stmt4 = gimple_build_cond (NE_EXPR, tmp3, build_int_cst (optype, 0),
     904              :                              NULL_TREE, NULL_TREE);
     905            0 :   gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
     906            0 :   gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
     907            0 :   gsi_insert_before (&gsi, stmt4, GSI_SAME_STMT);
     908            0 :   bb1end = stmt4;
     909              : 
     910              :   /* tmp2 == op2-1 inherited from previous block.  */
     911            0 :   stmt1 = gimple_build_assign (result, BIT_AND_EXPR, op1, tmp2);
     912            0 :   gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
     913            0 :   bb2end = stmt1;
     914              : 
     915            0 :   stmt1 = gimple_build_assign (result, gimple_assign_rhs_code (stmt),
     916              :                                op1, op2);
     917            0 :   gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
     918            0 :   bb3end = stmt1;
     919              : 
     920              :   /* Fix CFG. */
     921              :   /* Edge e23 connects bb2 to bb3, etc. */
     922            0 :   e12 = split_block (bb, bb1end);
     923            0 :   bb2 = e12->dest;
     924            0 :   bb2->count = profile_count::from_gcov_type (count);
     925            0 :   e23 = split_block (bb2, bb2end);
     926            0 :   bb3 = e23->dest;
     927            0 :   bb3->count = profile_count::from_gcov_type (all - count);
     928            0 :   e34 = split_block (bb3, bb3end);
     929            0 :   bb4 = e34->dest;
     930            0 :   bb4->count = profile_count::from_gcov_type (all);
     931              : 
     932            0 :   e12->flags &= ~EDGE_FALLTHRU;
     933            0 :   e12->flags |= EDGE_FALSE_VALUE;
     934            0 :   e12->probability = prob;
     935              : 
     936            0 :   e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE);
     937            0 :   e13->probability = prob.invert ();
     938              : 
     939            0 :   remove_edge (e23);
     940              : 
     941            0 :   e24 = make_edge (bb2, bb4, EDGE_FALLTHRU);
     942            0 :   e24->probability = profile_probability::always ();
     943              : 
     944            0 :   e34->probability = profile_probability::always ();
     945              : 
     946            0 :   return result;
     947              : }
     948              : 
     949              : /* Do transform 2) on INSN if applicable.  */
     950              : 
     951              : static bool
     952           63 : gimple_mod_pow2_value_transform (gimple_stmt_iterator *si)
     953              : {
     954           63 :   histogram_value histogram;
     955           63 :   enum tree_code code;
     956           63 :   gcov_type count, wrong_values, all;
     957           63 :   tree lhs_type, result, value;
     958           63 :   profile_probability prob;
     959           63 :   gassign *stmt;
     960              : 
     961           65 :   stmt = dyn_cast <gassign *> (gsi_stmt (*si));
     962            2 :   if (!stmt)
     963              :     return false;
     964              : 
     965            2 :   lhs_type = TREE_TYPE (gimple_assign_lhs (stmt));
     966            2 :   if (!INTEGRAL_TYPE_P (lhs_type))
     967              :     return false;
     968              : 
     969            2 :   code = gimple_assign_rhs_code (stmt);
     970              : 
     971            2 :   if (code != TRUNC_MOD_EXPR || !TYPE_UNSIGNED (lhs_type))
     972              :     return false;
     973              : 
     974            0 :   histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_POW2);
     975            0 :   if (!histogram)
     976              :     return false;
     977              : 
     978            0 :   value = histogram->hvalue.value;
     979            0 :   wrong_values = histogram->hvalue.counters[0];
     980            0 :   count = histogram->hvalue.counters[1];
     981              : 
     982            0 :   gimple_remove_histogram_value (cfun, stmt, histogram);
     983              : 
     984              :   /* We require that we hit a power of 2 at least half of all evaluations.  */
     985            0 :   if (simple_cst_equal (gimple_assign_rhs2 (stmt), value) != 1
     986            0 :       || count < wrong_values
     987            0 :       || optimize_bb_for_size_p (gimple_bb (stmt)))
     988            0 :     return false;
     989              : 
     990              :   /* Compute probability of taking the optimal path.  */
     991            0 :   all = count + wrong_values;
     992              : 
     993            0 :   if (check_counter (stmt, "pow2", &count, &all, gimple_bb (stmt)->count))
     994              :     return false;
     995              : 
     996            0 :   if (dump_enabled_p ())
     997            0 :     dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt,
     998              :                      "Transformation done: mod power of 2\n");
     999              : 
    1000            0 :   if (all > 0)
    1001            0 :     prob = profile_probability::probability_in_gcov_type (count, all);
    1002              :   else
    1003            0 :     prob = profile_probability::never ();
    1004              : 
    1005            0 :   result = gimple_mod_pow2 (stmt, prob, count, all);
    1006              : 
    1007            0 :   gimple_assign_set_rhs_from_tree (si, result);
    1008            0 :   update_stmt (gsi_stmt (*si));
    1009              : 
    1010            0 :   return true;
    1011              : }
    1012              : 
    1013              : /* Generate code for transformations 3 and 4 (with parent gimple assign STMT, and
    1014              :    NCOUNTS the number of cases to support.  Currently only NCOUNTS==0 or 1 is
    1015              :    supported and this is built into this interface.  The probabilities of taking
    1016              :    the optimal paths are PROB1 and PROB2, which are equivalent to COUNT1/ALL and
    1017              :    COUNT2/ALL respectively within roundoff error).  This generates the
    1018              :    result into a temp and returns the temp; it does not replace or alter
    1019              :    the original STMT.  */
    1020              : /* FIXME: Generalize the interface to handle NCOUNTS > 1.  */
    1021              : 
    1022              : static tree
    1023            4 : gimple_mod_subtract (gassign *stmt, profile_probability prob1,
    1024              :                      profile_probability prob2, int ncounts,
    1025              :                      gcov_type count1, gcov_type count2, gcov_type all)
    1026              : {
    1027            4 :   gassign *stmt1;
    1028            4 :   gimple *stmt2;
    1029            4 :   gcond *stmt3;
    1030            4 :   tree tmp1;
    1031            4 :   gimple *bb1end, *bb2end = NULL, *bb3end;
    1032            4 :   basic_block bb, bb2, bb3, bb4;
    1033            4 :   tree optype, op1, op2;
    1034            4 :   edge e12, e23 = 0, e24, e34, e14;
    1035            4 :   gimple_stmt_iterator gsi;
    1036            4 :   tree result;
    1037              : 
    1038            8 :   gcc_assert (is_gimple_assign (stmt)
    1039              :               && gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR);
    1040              : 
    1041            4 :   optype = TREE_TYPE (gimple_assign_lhs (stmt));
    1042            4 :   op1 = gimple_assign_rhs1 (stmt);
    1043            4 :   op2 = gimple_assign_rhs2 (stmt);
    1044              : 
    1045            4 :   bb = gimple_bb (stmt);
    1046            4 :   gsi = gsi_for_stmt (stmt);
    1047              : 
    1048            4 :   result = create_tmp_reg (optype, "PROF");
    1049            4 :   tmp1 = make_temp_ssa_name (optype, NULL, "PROF");
    1050            4 :   stmt1 = gimple_build_assign (result, op1);
    1051            4 :   stmt2 = gimple_build_assign (tmp1, op2);
    1052            4 :   stmt3 = gimple_build_cond (LT_EXPR, result, tmp1, NULL_TREE, NULL_TREE);
    1053            4 :   gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
    1054            4 :   gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
    1055            4 :   gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
    1056            4 :   bb1end = stmt3;
    1057              : 
    1058            4 :   if (ncounts)  /* Assumed to be 0 or 1 */
    1059              :     {
    1060            1 :       stmt1 = gimple_build_assign (result, MINUS_EXPR, result, tmp1);
    1061            1 :       stmt2 = gimple_build_cond (LT_EXPR, result, tmp1, NULL_TREE, NULL_TREE);
    1062            1 :       gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
    1063            1 :       gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
    1064            1 :       bb2end = stmt2;
    1065              :     }
    1066              : 
    1067              :   /* Fallback case. */
    1068            4 :   stmt1 = gimple_build_assign (result, gimple_assign_rhs_code (stmt),
    1069              :                                result, tmp1);
    1070            4 :   gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
    1071            4 :   bb3end = stmt1;
    1072              : 
    1073              :   /* Fix CFG. */
    1074              :   /* Edge e23 connects bb2 to bb3, etc. */
    1075              :   /* However block 3 is optional; if it is not there, references
    1076              :      to 3 really refer to block 2. */
    1077            4 :   e12 = split_block (bb, bb1end);
    1078            4 :   bb2 = e12->dest;
    1079            4 :   bb2->count = profile_count::from_gcov_type (all - count1);
    1080              : 
    1081            4 :   if (ncounts)  /* Assumed to be 0 or 1.  */
    1082              :     {
    1083            1 :       e23 = split_block (bb2, bb2end);
    1084            1 :       bb3 = e23->dest;
    1085            1 :       bb3->count = profile_count::from_gcov_type (all - count1 - count2);
    1086              :     }
    1087              : 
    1088            4 :   e34 = split_block (ncounts ? bb3 : bb2, bb3end);
    1089            4 :   bb4 = e34->dest;
    1090            4 :   bb4->count = profile_count::from_gcov_type (all);
    1091              : 
    1092            4 :   e12->flags &= ~EDGE_FALLTHRU;
    1093            4 :   e12->flags |= EDGE_FALSE_VALUE;
    1094            4 :   e12->probability = prob1.invert ();
    1095              : 
    1096            4 :   e14 = make_edge (bb, bb4, EDGE_TRUE_VALUE);
    1097            4 :   e14->probability = prob1;
    1098              : 
    1099            4 :   if (ncounts)  /* Assumed to be 0 or 1.  */
    1100              :     {
    1101            1 :       e23->flags &= ~EDGE_FALLTHRU;
    1102            1 :       e23->flags |= EDGE_FALSE_VALUE;
    1103            1 :       e23->probability = prob2.invert ();
    1104              : 
    1105            1 :       e24 = make_edge (bb2, bb4, EDGE_TRUE_VALUE);
    1106            1 :       e24->probability = prob2;
    1107              :     }
    1108              : 
    1109            4 :   e34->probability = profile_probability::always ();
    1110              : 
    1111            4 :   return result;
    1112              : }
    1113              : 
    1114              : /* Do transforms 3) and 4) on the statement pointed-to by SI if applicable.  */
    1115              : 
    1116              : static bool
    1117           71 : gimple_mod_subtract_transform (gimple_stmt_iterator *si)
    1118              : {
    1119           71 :   histogram_value histogram;
    1120           71 :   enum tree_code code;
    1121           71 :   gcov_type count, wrong_values, all;
    1122           71 :   tree lhs_type, result;
    1123           71 :   profile_probability prob1, prob2;
    1124           71 :   unsigned int i, steps;
    1125           71 :   gcov_type count1, count2;
    1126           71 :   gassign *stmt;
    1127           77 :   stmt = dyn_cast <gassign *> (gsi_stmt (*si));
    1128           10 :   if (!stmt)
    1129              :     return false;
    1130              : 
    1131           10 :   lhs_type = TREE_TYPE (gimple_assign_lhs (stmt));
    1132           10 :   if (!INTEGRAL_TYPE_P (lhs_type))
    1133              :     return false;
    1134              : 
    1135           10 :   code = gimple_assign_rhs_code (stmt);
    1136              : 
    1137           10 :   if (code != TRUNC_MOD_EXPR || !TYPE_UNSIGNED (lhs_type))
    1138              :     return false;
    1139              : 
    1140            5 :   histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_INTERVAL);
    1141            5 :   if (!histogram)
    1142              :     return false;
    1143              : 
    1144            5 :   all = 0;
    1145            5 :   wrong_values = 0;
    1146           15 :   for (i = 0; i < histogram->hdata.intvl.steps; i++)
    1147           10 :     all += histogram->hvalue.counters[i];
    1148              : 
    1149            5 :   wrong_values += histogram->hvalue.counters[i];
    1150            5 :   wrong_values += histogram->hvalue.counters[i+1];
    1151            5 :   steps = histogram->hdata.intvl.steps;
    1152            5 :   all += wrong_values;
    1153            5 :   count1 = histogram->hvalue.counters[0];
    1154            5 :   count2 = histogram->hvalue.counters[1];
    1155              : 
    1156            5 :   if (check_counter (stmt, "interval", &count1, &all, gimple_bb (stmt)->count))
    1157              :     {
    1158            0 :       gimple_remove_histogram_value (cfun, stmt, histogram);
    1159            0 :       return false;
    1160              :     }
    1161              : 
    1162            5 :   if (flag_profile_correction && count1 + count2 > all)
    1163            0 :       all = count1 + count2;
    1164              : 
    1165            5 :   gcc_assert (count1 + count2 <= all);
    1166              : 
    1167              :   /* We require that we use just subtractions in at least 50% of all
    1168              :      evaluations.  */
    1169              :   count = 0;
    1170            8 :   for (i = 0; i < histogram->hdata.intvl.steps; i++)
    1171              :     {
    1172            7 :       count += histogram->hvalue.counters[i];
    1173            7 :       if (count * 2 >= all)
    1174              :         break;
    1175              :     }
    1176            5 :   if (i == steps
    1177            5 :       || optimize_bb_for_size_p (gimple_bb (stmt)))
    1178            1 :     return false;
    1179              : 
    1180            4 :   gimple_remove_histogram_value (cfun, stmt, histogram);
    1181            4 :   if (dump_enabled_p ())
    1182            3 :     dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt,
    1183              :                      "Transformation done: mod subtract\n");
    1184              : 
    1185              :   /* Compute probability of taking the optimal path(s).  */
    1186            4 :   if (all > 0)
    1187              :     {
    1188            4 :       prob1 = profile_probability::probability_in_gcov_type (count1, all);
    1189            4 :       if (all == count1)
    1190            3 :         prob2 = profile_probability::even ();
    1191              :       else
    1192            1 :         prob2 = profile_probability::probability_in_gcov_type (count2, all
    1193              :                                                                - count1);
    1194              :     }
    1195              :   else
    1196              :     {
    1197            0 :       prob1 = prob2 = profile_probability::never ();
    1198              :     }
    1199              : 
    1200              :   /* In practice, "steps" is always 2.  This interface reflects this,
    1201              :      and will need to be changed if "steps" can change.  */
    1202            4 :   result = gimple_mod_subtract (stmt, prob1, prob2, i, count1, count2, all);
    1203              : 
    1204            4 :   gimple_assign_set_rhs_from_tree (si, result);
    1205            4 :   update_stmt (gsi_stmt (*si));
    1206              : 
    1207            4 :   return true;
    1208              : }
    1209              : 
    1210              : typedef int_hash <unsigned int, 0, UINT_MAX> profile_id_hash;
    1211              : 
    1212              : static hash_map<profile_id_hash, cgraph_node *> *cgraph_node_map = 0;
    1213              : 
    1214              : /* Returns true if node graph is initialized. This
    1215              :    is used to test if profile_id has been created
    1216              :    for cgraph_nodes.  */
    1217              : 
    1218              : bool
    1219         3967 : coverage_node_map_initialized_p (void)
    1220              : {
    1221         3967 :   return cgraph_node_map != 0;
    1222              : }
    1223              : 
    1224              : /* Initialize map from PROFILE_ID to CGRAPH_NODE.
    1225              :    When LOCAL is true, the PROFILE_IDs are computed.  when it is false we assume
    1226              :    that the PROFILE_IDs was already assigned.  */
    1227              : 
    1228              : void
    1229          647 : init_node_map (bool local)
    1230              : {
    1231          647 :   struct cgraph_node *n;
    1232          647 :   cgraph_node_map = new hash_map<profile_id_hash, cgraph_node *>;
    1233              : 
    1234         3599 :   FOR_EACH_DEFINED_FUNCTION (n)
    1235         2952 :     if (n->has_gimple_body_p () || n->thunk)
    1236              :       {
    1237         2731 :         cgraph_node **val;
    1238         2731 :         dump_user_location_t loc
    1239         2731 :           = dump_user_location_t::from_function_decl (n->decl);
    1240         2731 :         if (local)
    1241              :           {
    1242         2565 :             n->profile_id = coverage_compute_profile_id (n);
    1243         2565 :             while ((val = cgraph_node_map->get (n->profile_id))
    1244         2565 :                    || !n->profile_id)
    1245              :               {
    1246            0 :                 if (dump_enabled_p ())
    1247            0 :                   dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc,
    1248              :                                    "Local profile-id %i conflict"
    1249              :                                    " with nodes %s %s\n",
    1250              :                                    n->profile_id,
    1251              :                                    n->dump_name (),
    1252              :                                    (*val)->dump_name ());
    1253            0 :                 n->profile_id = (n->profile_id + 1) & 0x7fffffff;
    1254              :               }
    1255              :           }
    1256          166 :         else if (!n->profile_id)
    1257              :           {
    1258           46 :             if (dump_enabled_p ())
    1259           45 :               dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc,
    1260              :                                "Node %s has no profile-id"
    1261              :                                " (profile feedback missing?)\n",
    1262              :                                n->dump_name ());
    1263           46 :             continue;
    1264              :           }
    1265          120 :         else if ((val = cgraph_node_map->get (n->profile_id)))
    1266              :           {
    1267            0 :             if (dump_enabled_p ())
    1268            0 :               dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc,
    1269              :                                "Node %s has IP profile-id %i conflict. "
    1270              :                                "Giving up.\n",
    1271              :                                n->dump_name (), n->profile_id);
    1272            0 :             *val = NULL;
    1273            0 :             continue;
    1274              :           }
    1275         2685 :         cgraph_node_map->put (n->profile_id, n);
    1276              :       }
    1277          647 : }
    1278              : 
    1279              : /* Delete the CGRAPH_NODE_MAP.  */
    1280              : 
    1281              : void
    1282          647 : del_node_map (void)
    1283              : {
    1284         1294 :   delete cgraph_node_map;
    1285          647 : }
    1286              : 
    1287              : /* Return cgraph node for function with pid */
    1288              : 
    1289              : struct cgraph_node*
    1290           71 : find_func_by_profile_id (int profile_id)
    1291              : {
    1292           71 :   cgraph_node **val = cgraph_node_map->get (profile_id);
    1293           71 :   if (val)
    1294           69 :     return *val;
    1295              :   else
    1296              :     return NULL;
    1297              : }
    1298              : 
    1299              : /* Do transformation
    1300              : 
    1301              :   if (actual_callee_address == address_of_most_common_function/method)
    1302              :     do direct call
    1303              :   else
    1304              :     old call
    1305              :  */
    1306              : 
    1307              : gcall *
    1308        31564 : gimple_ic (gcall *icall_stmt, struct cgraph_node *direct_call,
    1309              :            profile_probability prob)
    1310              : {
    1311        31564 :   gcall *dcall_stmt;
    1312        31564 :   gassign *load_stmt;
    1313        31564 :   gcond *cond_stmt;
    1314        31564 :   tree tmp0, tmp1, tmp;
    1315        31564 :   basic_block cond_bb, dcall_bb, icall_bb, join_bb = NULL;
    1316        31564 :   edge e_cd, e_ci, e_di, e_dj = NULL, e_ij;
    1317        31564 :   gimple_stmt_iterator gsi;
    1318        31564 :   int lp_nr, dflags;
    1319        31564 :   edge e_eh, e;
    1320        31564 :   edge_iterator ei;
    1321              : 
    1322        31564 :   cond_bb = gimple_bb (icall_stmt);
    1323        31564 :   gsi = gsi_for_stmt (icall_stmt);
    1324              : 
    1325        31564 :   tmp0 = make_temp_ssa_name (ptr_type_node, NULL, "PROF");
    1326        31564 :   tmp1 = make_temp_ssa_name (ptr_type_node, NULL, "PROF");
    1327        31564 :   tmp = unshare_expr (gimple_call_fn (icall_stmt));
    1328        31564 :   load_stmt = gimple_build_assign (tmp0, tmp);
    1329        31564 :   gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT);
    1330              : 
    1331        31564 :   tmp = fold_convert (ptr_type_node, build_addr (direct_call->decl));
    1332        31564 :   load_stmt = gimple_build_assign (tmp1, tmp);
    1333        31564 :   gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT);
    1334              : 
    1335        31564 :   cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmp0, NULL_TREE, NULL_TREE);
    1336        31564 :   gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
    1337              : 
    1338        63128 :   if (TREE_CODE (gimple_vdef (icall_stmt)) == SSA_NAME)
    1339              :     {
    1340         5184 :       unlink_stmt_vdef (icall_stmt);
    1341        10368 :       release_ssa_name (gimple_vdef (icall_stmt));
    1342              :     }
    1343        31564 :   gimple_set_vdef (icall_stmt, NULL_TREE);
    1344        31564 :   gimple_set_vuse (icall_stmt, NULL_TREE);
    1345        31564 :   update_stmt (icall_stmt);
    1346        31564 :   dcall_stmt = as_a <gcall *> (gimple_copy (icall_stmt));
    1347        31564 :   gimple_call_set_fndecl (dcall_stmt, direct_call->decl);
    1348        31564 :   dflags = flags_from_decl_or_type (direct_call->decl);
    1349        31564 :   if ((dflags & ECF_NORETURN) != 0
    1350        31564 :       && should_remove_lhs_p (gimple_call_lhs (dcall_stmt)))
    1351            3 :     gimple_call_set_lhs (dcall_stmt, NULL_TREE);
    1352        31564 :   gsi_insert_before (&gsi, dcall_stmt, GSI_SAME_STMT);
    1353              : 
    1354              :   /* Fix CFG. */
    1355              :   /* Edge e_cd connects cond_bb to dcall_bb, etc; note the first letters. */
    1356        31564 :   e_cd = split_block (cond_bb, cond_stmt);
    1357        31564 :   dcall_bb = e_cd->dest;
    1358        31564 :   dcall_bb->count = cond_bb->count.apply_probability (prob);
    1359              : 
    1360        31564 :   e_di = split_block (dcall_bb, dcall_stmt);
    1361        31564 :   icall_bb = e_di->dest;
    1362        31564 :   icall_bb->count = cond_bb->count - dcall_bb->count;
    1363              : 
    1364              :   /* Do not disturb existing EH edges from the indirect call.  */
    1365        31564 :   if (!stmt_ends_bb_p (icall_stmt))
    1366        24099 :     e_ij = split_block (icall_bb, icall_stmt);
    1367              :   else
    1368              :     {
    1369         7465 :       e_ij = find_fallthru_edge (icall_bb->succs);
    1370              :       /* The indirect call might be noreturn.  */
    1371         7465 :       if (e_ij != NULL)
    1372              :         {
    1373         7465 :           e_ij->probability = profile_probability::always ();
    1374         7465 :           e_ij = single_pred_edge (split_edge (e_ij));
    1375              :         }
    1376              :     }
    1377        31564 :   if (e_ij != NULL)
    1378              :     {
    1379        31564 :       join_bb = e_ij->dest;
    1380        31564 :       join_bb->count = cond_bb->count;
    1381              :     }
    1382              : 
    1383        31564 :   e_cd->flags = (e_cd->flags & ~EDGE_FALLTHRU) | EDGE_TRUE_VALUE;
    1384        31564 :   e_cd->probability = prob;
    1385              : 
    1386        31564 :   e_ci = make_edge (cond_bb, icall_bb, EDGE_FALSE_VALUE);
    1387        31564 :   e_ci->probability = prob.invert ();
    1388              : 
    1389        31564 :   remove_edge (e_di);
    1390              : 
    1391        31564 :   if (e_ij != NULL)
    1392              :     {
    1393        31564 :       if ((dflags & ECF_NORETURN) == 0)
    1394              :         {
    1395        31544 :           e_dj = make_edge (dcall_bb, join_bb, EDGE_FALLTHRU);
    1396        31544 :           e_dj->probability = profile_probability::always ();
    1397              :         }
    1398        31564 :       e_ij->probability = profile_probability::always ();
    1399              :     }
    1400              : 
    1401              :   /* Insert PHI node for the call result if necessary.  */
    1402        31564 :   if (gimple_call_lhs (icall_stmt)
    1403        15611 :       && TREE_CODE (gimple_call_lhs (icall_stmt)) == SSA_NAME
    1404        45029 :       && (dflags & ECF_NORETURN) == 0)
    1405              :     {
    1406        13462 :       tree result = gimple_call_lhs (icall_stmt);
    1407        13462 :       gphi *phi = create_phi_node (result, join_bb);
    1408        13462 :       gimple_call_set_lhs (icall_stmt,
    1409              :                            duplicate_ssa_name (result, icall_stmt));
    1410        13462 :       add_phi_arg (phi, gimple_call_lhs (icall_stmt), e_ij, UNKNOWN_LOCATION);
    1411        13462 :       gimple_call_set_lhs (dcall_stmt,
    1412              :                            duplicate_ssa_name (result, dcall_stmt));
    1413        13462 :       add_phi_arg (phi, gimple_call_lhs (dcall_stmt), e_dj, UNKNOWN_LOCATION);
    1414              :     }
    1415              : 
    1416              :   /* Build an EH edge for the direct call if necessary.  */
    1417        31564 :   lp_nr = lookup_stmt_eh_lp (icall_stmt);
    1418        31564 :   if (lp_nr > 0 && stmt_could_throw_p (cfun, dcall_stmt))
    1419              :     {
    1420          913 :       add_stmt_to_eh_lp (dcall_stmt, lp_nr);
    1421              :     }
    1422              : 
    1423        70597 :   FOR_EACH_EDGE (e_eh, ei, icall_bb->succs)
    1424        39033 :     if (e_eh->flags & (EDGE_EH | EDGE_ABNORMAL))
    1425              :       {
    1426         7469 :         e = make_edge (dcall_bb, e_eh->dest, e_eh->flags);
    1427         7469 :         e->probability = e_eh->probability;
    1428         7469 :         for (gphi_iterator psi = gsi_start_phis (e_eh->dest);
    1429        13751 :              !gsi_end_p (psi); gsi_next (&psi))
    1430              :           {
    1431         6282 :             gphi *phi = psi.phi ();
    1432         6282 :             SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e),
    1433              :                      PHI_ARG_DEF_FROM_EDGE (phi, e_eh));
    1434              :           }
    1435              :        }
    1436        31564 :   if (!stmt_could_throw_p (cfun, dcall_stmt))
    1437        27830 :     gimple_purge_dead_eh_edges (dcall_bb);
    1438        31564 :   return dcall_stmt;
    1439              : }
    1440              : 
    1441              : /* Dump info about indirect call profile.  */
    1442              : 
    1443              : static void
    1444           32 : dump_ic_profile (gimple_stmt_iterator *gsi)
    1445              : {
    1446           32 :   gcall *stmt;
    1447           32 :   histogram_value histogram;
    1448           32 :   gcov_type val, count, all;
    1449           32 :   struct cgraph_node *direct_call;
    1450              : 
    1451           32 :   stmt = dyn_cast <gcall *> (gsi_stmt (*gsi));
    1452           25 :   if (!stmt)
    1453           32 :     return;
    1454              : 
    1455           25 :   if (gimple_call_fndecl (stmt) != NULL_TREE)
    1456              :     return;
    1457              : 
    1458           10 :   if (gimple_call_internal_p (stmt))
    1459              :     return;
    1460              : 
    1461           10 :   histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_INDIR_CALL);
    1462           10 :   if (!histogram)
    1463              :     return;
    1464              : 
    1465           10 :   count = 0;
    1466           10 :   all = histogram->hvalue.counters[0];
    1467              : 
    1468           22 :   for (unsigned j = 0; j < GCOV_TOPN_MAXIMUM_TRACKED_VALUES; j++)
    1469              :     {
    1470           22 :       if (!get_nth_most_common_value (NULL, "indirect call", histogram, &val,
    1471              :                                       &count, &all, j))
    1472              :         return;
    1473           12 :       if (!count)
    1474            0 :         continue;
    1475              : 
    1476           12 :       direct_call = find_func_by_profile_id ((int) val);
    1477              : 
    1478           12 :       if (direct_call == NULL)
    1479            1 :         dump_printf_loc (
    1480            1 :           MSG_MISSED_OPTIMIZATION, stmt,
    1481              :           "Indirect call -> direct call from other "
    1482              :           "module %T=> %i (will resolve by ipa-profile only with LTO)\n",
    1483              :           gimple_call_fn (stmt), (int) val);
    1484              :       else
    1485           11 :         dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt,
    1486              :                          "Indirect call -> direct call "
    1487              :                          "%T => %T (will resolve by ipa-profile)\n",
    1488              :                          gimple_call_fn (stmt), direct_call->decl);
    1489           12 :       dump_printf_loc (MSG_NOTE, stmt,
    1490              :                        "hist->count %" PRId64 " hist->all %" PRId64 "\n",
    1491              :                        count, all);
    1492              :     }
    1493              : }
    1494              : 
    1495              : /* Return true if the stringop CALL shall be profiled.  SIZE_ARG be
    1496              :    set to the argument index for the size of the string operation.  */
    1497              : 
    1498              : static bool
    1499          434 : interesting_stringop_to_profile_p (gcall *call, int *size_arg)
    1500              : {
    1501          434 :   enum built_in_function fcode;
    1502              : 
    1503          434 :   fcode = DECL_FUNCTION_CODE (gimple_call_fndecl (call));
    1504          434 :   switch (fcode)
    1505              :     {
    1506           64 :      case BUILT_IN_MEMCPY:
    1507           64 :      case BUILT_IN_MEMPCPY:
    1508           64 :      case BUILT_IN_MEMMOVE:
    1509           64 :        *size_arg = 2;
    1510           64 :        return validate_gimple_arglist (call, POINTER_TYPE, POINTER_TYPE,
    1511           64 :                                        INTEGER_TYPE, VOID_TYPE);
    1512           29 :      case BUILT_IN_MEMSET:
    1513           29 :        *size_arg = 2;
    1514           29 :        return validate_gimple_arglist (call, POINTER_TYPE, INTEGER_TYPE,
    1515           29 :                                       INTEGER_TYPE, VOID_TYPE);
    1516            0 :      case BUILT_IN_BZERO:
    1517            0 :        *size_arg = 1;
    1518            0 :        return validate_gimple_arglist (call, POINTER_TYPE, INTEGER_TYPE,
    1519            0 :                                        VOID_TYPE);
    1520              :      default:
    1521              :        return false;
    1522              :     }
    1523              : }
    1524              : 
    1525              : /* Convert stringop (..., vcall_size)
    1526              :    into
    1527              :    if (vcall_size == icall_size)
    1528              :      stringop (..., icall_size);
    1529              :    else
    1530              :      stringop (..., vcall_size);
    1531              :    assuming we'll propagate a true constant into ICALL_SIZE later.  */
    1532              : 
    1533              : static void
    1534           11 : gimple_stringop_fixed_value (gcall *vcall_stmt, tree icall_size, profile_probability prob,
    1535              :                              gcov_type count, gcov_type all)
    1536              : {
    1537           11 :   gassign *tmp_stmt;
    1538           11 :   gcond *cond_stmt;
    1539           11 :   gcall *icall_stmt;
    1540           11 :   tree tmp0, tmp1, vcall_size, optype;
    1541           11 :   basic_block cond_bb, icall_bb, vcall_bb, join_bb;
    1542           11 :   edge e_ci, e_cv, e_iv, e_ij, e_vj;
    1543           11 :   gimple_stmt_iterator gsi;
    1544           11 :   int size_arg;
    1545              : 
    1546           11 :   if (!interesting_stringop_to_profile_p (vcall_stmt, &size_arg))
    1547            0 :     gcc_unreachable ();
    1548              : 
    1549           11 :   cond_bb = gimple_bb (vcall_stmt);
    1550           11 :   gsi = gsi_for_stmt (vcall_stmt);
    1551              : 
    1552           11 :   vcall_size = gimple_call_arg (vcall_stmt, size_arg);
    1553           11 :   optype = TREE_TYPE (vcall_size);
    1554              : 
    1555           11 :   tmp0 = make_temp_ssa_name (optype, NULL, "PROF");
    1556           11 :   tmp1 = make_temp_ssa_name (optype, NULL, "PROF");
    1557           11 :   tmp_stmt = gimple_build_assign (tmp0, fold_convert (optype, icall_size));
    1558           11 :   gsi_insert_before (&gsi, tmp_stmt, GSI_SAME_STMT);
    1559              : 
    1560           11 :   tmp_stmt = gimple_build_assign (tmp1, vcall_size);
    1561           11 :   gsi_insert_before (&gsi, tmp_stmt, GSI_SAME_STMT);
    1562              : 
    1563           11 :   cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmp0, NULL_TREE, NULL_TREE);
    1564           11 :   gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
    1565              : 
    1566           22 :   if (TREE_CODE (gimple_vdef (vcall_stmt)) == SSA_NAME)
    1567              :     {
    1568           11 :       unlink_stmt_vdef (vcall_stmt);
    1569           22 :       release_ssa_name (gimple_vdef (vcall_stmt));
    1570              :     }
    1571           11 :   gimple_set_vdef (vcall_stmt, NULL);
    1572           11 :   gimple_set_vuse (vcall_stmt, NULL);
    1573           11 :   update_stmt (vcall_stmt);
    1574           11 :   icall_stmt = as_a <gcall *> (gimple_copy (vcall_stmt));
    1575           11 :   gimple_call_set_arg (icall_stmt, size_arg,
    1576              :                        fold_convert (optype, icall_size));
    1577           11 :   gsi_insert_before (&gsi, icall_stmt, GSI_SAME_STMT);
    1578              : 
    1579              :   /* Fix CFG. */
    1580              :   /* Edge e_ci connects cond_bb to icall_bb, etc. */
    1581           11 :   e_ci = split_block (cond_bb, cond_stmt);
    1582           11 :   icall_bb = e_ci->dest;
    1583           11 :   icall_bb->count = profile_count::from_gcov_type (count);
    1584              : 
    1585           11 :   e_iv = split_block (icall_bb, icall_stmt);
    1586           11 :   vcall_bb = e_iv->dest;
    1587           11 :   vcall_bb->count = profile_count::from_gcov_type (all - count);
    1588              : 
    1589           11 :   e_vj = split_block (vcall_bb, vcall_stmt);
    1590           11 :   join_bb = e_vj->dest;
    1591           11 :   join_bb->count = profile_count::from_gcov_type (all);
    1592              : 
    1593           11 :   e_ci->flags = (e_ci->flags & ~EDGE_FALLTHRU) | EDGE_TRUE_VALUE;
    1594           11 :   e_ci->probability = prob;
    1595              : 
    1596           11 :   e_cv = make_edge (cond_bb, vcall_bb, EDGE_FALSE_VALUE);
    1597           11 :   e_cv->probability = prob.invert ();
    1598              : 
    1599           11 :   remove_edge (e_iv);
    1600              : 
    1601           11 :   e_ij = make_edge (icall_bb, join_bb, EDGE_FALLTHRU);
    1602           11 :   e_ij->probability = profile_probability::always ();
    1603              : 
    1604           11 :   e_vj->probability = profile_probability::always ();
    1605              : 
    1606              :   /* Insert PHI node for the call result if necessary.  */
    1607           11 :   if (gimple_call_lhs (vcall_stmt)
    1608           11 :       && TREE_CODE (gimple_call_lhs (vcall_stmt)) == SSA_NAME)
    1609              :     {
    1610            0 :       tree result = gimple_call_lhs (vcall_stmt);
    1611            0 :       gphi *phi = create_phi_node (result, join_bb);
    1612            0 :       gimple_call_set_lhs (vcall_stmt,
    1613              :                            duplicate_ssa_name (result, vcall_stmt));
    1614            0 :       add_phi_arg (phi, gimple_call_lhs (vcall_stmt), e_vj, UNKNOWN_LOCATION);
    1615            0 :       gimple_call_set_lhs (icall_stmt,
    1616              :                            duplicate_ssa_name (result, icall_stmt));
    1617            0 :       add_phi_arg (phi, gimple_call_lhs (icall_stmt), e_ij, UNKNOWN_LOCATION);
    1618              :     }
    1619              : 
    1620              :   /* Because these are all string op builtins, they're all nothrow.  */
    1621           11 :   gcc_assert (!stmt_could_throw_p (cfun, vcall_stmt));
    1622           11 :   gcc_assert (!stmt_could_throw_p (cfun, icall_stmt));
    1623           11 : }
    1624              : 
    1625              : /* Find values inside STMT for that we want to measure histograms for
    1626              :    division/modulo optimization.  */
    1627              : 
    1628              : static bool
    1629           63 : gimple_stringops_transform (gimple_stmt_iterator *gsi)
    1630              : {
    1631           63 :   gcall *stmt;
    1632           63 :   tree blck_size;
    1633           63 :   enum built_in_function fcode;
    1634           63 :   histogram_value histogram;
    1635           63 :   gcov_type count, all, val;
    1636           63 :   tree dest, src;
    1637           63 :   unsigned int dest_align, src_align;
    1638           63 :   profile_probability prob;
    1639           63 :   tree tree_val;
    1640           63 :   int size_arg;
    1641              : 
    1642          113 :   stmt = dyn_cast <gcall *> (gsi_stmt (*gsi));
    1643           61 :   if (!stmt)
    1644              :     return false;
    1645              : 
    1646           61 :   if (!gimple_call_builtin_p (gsi_stmt (*gsi), BUILT_IN_NORMAL))
    1647              :     return false;
    1648              : 
    1649           21 :   if (!interesting_stringop_to_profile_p (stmt, &size_arg))
    1650              :     return false;
    1651              : 
    1652           21 :   blck_size = gimple_call_arg (stmt, size_arg);
    1653           21 :   if (TREE_CODE (blck_size) == INTEGER_CST)
    1654              :     return false;
    1655              : 
    1656           21 :   histogram = gimple_histogram_value_of_type (cfun, stmt,
    1657              :                                               HIST_TYPE_TOPN_VALUES);
    1658           21 :   if (!histogram)
    1659              :     return false;
    1660              : 
    1661           21 :   if (!get_nth_most_common_value (stmt, "stringops", histogram, &val, &count,
    1662              :                                   &all))
    1663              :     return false;
    1664              : 
    1665           18 :   gimple_remove_histogram_value (cfun, stmt, histogram);
    1666              : 
    1667              :   /* We require that count is at least half of all.  */
    1668           18 :   if (2 * count < all || optimize_bb_for_size_p (gimple_bb (stmt)))
    1669            2 :     return false;
    1670           16 :   if (check_counter (stmt, "value", &count, &all, gimple_bb (stmt)->count))
    1671              :     return false;
    1672           16 :   if (all > 0)
    1673           16 :     prob = profile_probability::probability_in_gcov_type (count, all);
    1674              :   else
    1675            0 :     prob = profile_probability::never ();
    1676              : 
    1677           16 :   dest = gimple_call_arg (stmt, 0);
    1678           16 :   dest_align = get_pointer_alignment (dest);
    1679           16 :   fcode = DECL_FUNCTION_CODE (gimple_call_fndecl (stmt));
    1680           16 :   switch (fcode)
    1681              :     {
    1682           12 :     case BUILT_IN_MEMCPY:
    1683           12 :     case BUILT_IN_MEMPCPY:
    1684           12 :     case BUILT_IN_MEMMOVE:
    1685           12 :       src = gimple_call_arg (stmt, 1);
    1686           12 :       src_align = get_pointer_alignment (src);
    1687           12 :       if (!can_move_by_pieces (val, MIN (dest_align, src_align)))
    1688              :         return false;
    1689              :       break;
    1690            4 :     case BUILT_IN_MEMSET:
    1691            8 :       if (!can_store_by_pieces (val, builtin_memset_read_str,
    1692            4 :                                 gimple_call_arg (stmt, 1),
    1693              :                                 dest_align, true))
    1694              :         return false;
    1695              :       break;
    1696            0 :     case BUILT_IN_BZERO:
    1697            0 :       if (!can_store_by_pieces (val, builtin_memset_read_str,
    1698            0 :                                 integer_zero_node,
    1699              :                                 dest_align, true))
    1700              :         return false;
    1701              :       break;
    1702            0 :     default:
    1703            0 :       gcc_unreachable ();
    1704              :     }
    1705              : 
    1706           11 :   if (sizeof (gcov_type) == sizeof (HOST_WIDE_INT))
    1707           11 :     tree_val = build_int_cst (get_gcov_type (), val);
    1708              :   else
    1709              :     {
    1710              :       HOST_WIDE_INT a[2];
    1711              :       a[0] = (unsigned HOST_WIDE_INT) val;
    1712              :       a[1] = val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1;
    1713              : 
    1714              :       tree_val = wide_int_to_tree (get_gcov_type (), wide_int::from_array (a, 2,
    1715              :         TYPE_PRECISION (get_gcov_type ()), false));
    1716              :     }
    1717              : 
    1718           11 :   if (dump_enabled_p ())
    1719           10 :     dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt,
    1720              :                      "Transformation done: single value %i stringop for %s\n",
    1721           10 :                      (int)val, built_in_names[(int)fcode]);
    1722              : 
    1723           11 :   gimple_stringop_fixed_value (stmt, tree_val, prob, count, all);
    1724              : 
    1725           11 :   return true;
    1726              : }
    1727              : 
    1728              : void
    1729       176520 : stringop_block_profile (gimple *stmt, unsigned int *expected_align,
    1730              :                         HOST_WIDE_INT *expected_size)
    1731              : {
    1732       176520 :   histogram_value histogram;
    1733       176520 :   histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_AVERAGE);
    1734              : 
    1735       176520 :   if (!histogram)
    1736       176500 :     *expected_size = -1;
    1737           20 :   else if (!histogram->hvalue.counters[1])
    1738              :     {
    1739            2 :       *expected_size = -1;
    1740            2 :       gimple_remove_histogram_value (cfun, stmt, histogram);
    1741              :     }
    1742              :   else
    1743              :     {
    1744           18 :       gcov_type size;
    1745           18 :       size = ((histogram->hvalue.counters[0]
    1746           18 :               + histogram->hvalue.counters[1] / 2)
    1747              :                / histogram->hvalue.counters[1]);
    1748              :       /* Even if we can hold bigger value in SIZE, INT_MAX
    1749              :          is safe "infinity" for code generation strategies.  */
    1750           18 :       if (size > INT_MAX)
    1751              :         size = INT_MAX;
    1752           18 :       *expected_size = size;
    1753           18 :       gimple_remove_histogram_value (cfun, stmt, histogram);
    1754              :     }
    1755              : 
    1756       176520 :   histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_IOR);
    1757              : 
    1758       176520 :   if (!histogram)
    1759       176500 :     *expected_align = 0;
    1760           20 :   else if (!histogram->hvalue.counters[0])
    1761              :     {
    1762            2 :       gimple_remove_histogram_value (cfun, stmt, histogram);
    1763            2 :       *expected_align = 0;
    1764              :     }
    1765              :   else
    1766              :     {
    1767              :       gcov_type count;
    1768              :       unsigned int alignment;
    1769              : 
    1770              :       count = histogram->hvalue.counters[0];
    1771              :       alignment = 1;
    1772          105 :       while (!(count & alignment)
    1773          105 :              && (alignment <= UINT_MAX / 2 / BITS_PER_UNIT))
    1774           87 :         alignment <<= 1;
    1775           18 :       *expected_align = alignment * BITS_PER_UNIT;
    1776           18 :       gimple_remove_histogram_value (cfun, stmt, histogram);
    1777              :     }
    1778       176520 : }
    1779              : 
    1780              : 
    1781              : /* Find values inside STMT for that we want to measure histograms for
    1782              :    division/modulo optimization.  */
    1783              : 
    1784              : static void
    1785         7176 : gimple_divmod_values_to_profile (gimple *stmt, histogram_values *values)
    1786              : {
    1787         7176 :   tree lhs, divisor, op0, type;
    1788         7176 :   histogram_value hist;
    1789              : 
    1790         7176 :   if (gimple_code (stmt) != GIMPLE_ASSIGN)
    1791              :     return;
    1792              : 
    1793         3167 :   lhs = gimple_assign_lhs (stmt);
    1794         3167 :   type = TREE_TYPE (lhs);
    1795         3167 :   if (!INTEGRAL_TYPE_P (type))
    1796              :     return;
    1797              : 
    1798         2203 :   switch (gimple_assign_rhs_code (stmt))
    1799              :     {
    1800           70 :     case TRUNC_DIV_EXPR:
    1801           70 :     case TRUNC_MOD_EXPR:
    1802           70 :       divisor = gimple_assign_rhs2 (stmt);
    1803           70 :       op0 = gimple_assign_rhs1 (stmt);
    1804              : 
    1805           70 :       if (TREE_CODE (divisor) == SSA_NAME)
    1806              :         /* Check for the case where the divisor is the same value most
    1807              :            of the time.  */
    1808           41 :         values->safe_push (gimple_alloc_histogram_value (cfun,
    1809              :                                                          HIST_TYPE_TOPN_VALUES,
    1810              :                                                          stmt, divisor));
    1811              : 
    1812              :       /* For mod, check whether it is not often a noop (or replaceable by
    1813              :          a few subtractions).  */
    1814           70 :       if (gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR
    1815           48 :           && TYPE_UNSIGNED (type)
    1816           93 :           && TREE_CODE (divisor) == SSA_NAME)
    1817              :         {
    1818           19 :           tree val;
    1819              :           /* Check for a special case where the divisor is power of 2.  */
    1820           19 :           values->safe_push (gimple_alloc_histogram_value (cfun,
    1821              :                                                            HIST_TYPE_POW2,
    1822              :                                                            stmt, divisor));
    1823           19 :           val = build2 (TRUNC_DIV_EXPR, type, op0, divisor);
    1824           19 :           hist = gimple_alloc_histogram_value (cfun, HIST_TYPE_INTERVAL,
    1825              :                                                stmt, val);
    1826           19 :           hist->hdata.intvl.int_start = 0;
    1827           19 :           hist->hdata.intvl.steps = 2;
    1828           19 :           values->safe_push (hist);
    1829              :         }
    1830              :       return;
    1831              : 
    1832              :     default:
    1833              :       return;
    1834              :     }
    1835              : }
    1836              : 
    1837              : /* Find calls inside STMT for that we want to measure histograms for
    1838              :    indirect/virtual call optimization. */
    1839              : 
    1840              : static void
    1841         7176 : gimple_indirect_call_to_profile (gimple *stmt, histogram_values *values)
    1842              : {
    1843         7176 :   tree callee;
    1844              : 
    1845         7176 :   if (gimple_code (stmt) != GIMPLE_CALL
    1846         1394 :       || gimple_call_internal_p (stmt)
    1847         8522 :       || gimple_call_fndecl (stmt) != NULL_TREE)
    1848         7085 :     return;
    1849              : 
    1850           91 :   callee = gimple_call_fn (stmt);
    1851           91 :   histogram_value v = gimple_alloc_histogram_value (cfun, HIST_TYPE_INDIR_CALL,
    1852           91 :                                                     stmt, callee);
    1853           91 :   values->safe_push (v);
    1854              : 
    1855           91 :   return;
    1856              : }
    1857              : 
    1858              : /* Find values inside STMT for that we want to measure histograms for
    1859              :    string operations.  */
    1860              : 
    1861              : static void
    1862         7176 : gimple_stringops_values_to_profile (gimple *gs, histogram_values *values)
    1863              : {
    1864         7176 :   gcall *stmt;
    1865         7176 :   tree blck_size;
    1866         7176 :   tree dest;
    1867         7176 :   int size_arg;
    1868              : 
    1869         7176 :   stmt = dyn_cast <gcall *> (gs);
    1870         1394 :   if (!stmt)
    1871         7115 :     return;
    1872              : 
    1873         1394 :   if (!gimple_call_builtin_p (gs, BUILT_IN_NORMAL))
    1874              :     return;
    1875              : 
    1876          402 :   if (!interesting_stringop_to_profile_p (stmt, &size_arg))
    1877              :     return;
    1878              : 
    1879           61 :   dest = gimple_call_arg (stmt, 0);
    1880           61 :   blck_size = gimple_call_arg (stmt, size_arg);
    1881              : 
    1882           61 :   if (TREE_CODE (blck_size) != INTEGER_CST)
    1883              :     {
    1884           50 :       values->safe_push (gimple_alloc_histogram_value (cfun,
    1885              :                                                        HIST_TYPE_TOPN_VALUES,
    1886              :                                                        stmt, blck_size));
    1887           50 :       values->safe_push (gimple_alloc_histogram_value (cfun, HIST_TYPE_AVERAGE,
    1888              :                                                        stmt, blck_size));
    1889              :     }
    1890              : 
    1891           61 :   if (TREE_CODE (blck_size) != INTEGER_CST)
    1892           50 :     values->safe_push (gimple_alloc_histogram_value (cfun, HIST_TYPE_IOR,
    1893              :                                                      stmt, dest));
    1894              : }
    1895              : 
    1896              : /* Find values inside STMT for that we want to measure histograms and adds
    1897              :    them to list VALUES.  */
    1898              : 
    1899              : static void
    1900         7176 : gimple_values_to_profile (gimple *stmt, histogram_values *values)
    1901              : {
    1902         7176 :   gimple_divmod_values_to_profile (stmt, values);
    1903         7176 :   gimple_stringops_values_to_profile (stmt, values);
    1904         7176 :   gimple_indirect_call_to_profile (stmt, values);
    1905         7176 : }
    1906              : 
    1907              : void
    1908          978 : gimple_find_values_to_profile (histogram_values *values)
    1909              : {
    1910          978 :   basic_block bb;
    1911          978 :   gimple_stmt_iterator gsi;
    1912          978 :   unsigned i;
    1913          978 :   histogram_value hist = NULL;
    1914          978 :   values->create (0);
    1915              : 
    1916         5193 :   FOR_EACH_BB_FN (bb, cfun)
    1917        15606 :     for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    1918         7176 :       gimple_values_to_profile (gsi_stmt (gsi), values);
    1919              : 
    1920          978 :   values->safe_push (gimple_alloc_histogram_value (cfun,
    1921              :                                                    HIST_TYPE_TIME_PROFILE));
    1922              : 
    1923         2276 :   FOR_EACH_VEC_ELT (*values, i, hist)
    1924              :     {
    1925         1298 :       switch (hist->type)
    1926              :         {
    1927           19 :         case HIST_TYPE_INTERVAL:
    1928           19 :           hist->n_counters = hist->hdata.intvl.steps + 2;
    1929           19 :           break;
    1930              : 
    1931           19 :         case HIST_TYPE_POW2:
    1932           19 :           hist->n_counters = 2;
    1933           19 :           break;
    1934              : 
    1935          182 :         case HIST_TYPE_TOPN_VALUES:
    1936          182 :         case HIST_TYPE_INDIR_CALL:
    1937          182 :           hist->n_counters = GCOV_TOPN_MEM_COUNTERS;
    1938          182 :           break;
    1939              : 
    1940          978 :         case HIST_TYPE_TIME_PROFILE:
    1941          978 :           hist->n_counters = 1;
    1942          978 :           break;
    1943              : 
    1944           50 :         case HIST_TYPE_AVERAGE:
    1945           50 :           hist->n_counters = 2;
    1946           50 :           break;
    1947              : 
    1948           50 :         case HIST_TYPE_IOR:
    1949           50 :           hist->n_counters = 1;
    1950           50 :           break;
    1951              : 
    1952            0 :         default:
    1953            0 :           gcc_unreachable ();
    1954              :         }
    1955         1298 :       if (dump_file && hist->hvalue.stmt != NULL)
    1956              :         {
    1957          140 :           fprintf (dump_file, "Stmt ");
    1958          140 :           print_gimple_stmt (dump_file, hist->hvalue.stmt, 0, TDF_SLIM);
    1959          140 :           dump_histogram_value (dump_file, hist);
    1960              :         }
    1961              :     }
    1962          978 : }
        

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.