LCOV - code coverage report
Current view: top level - gcc/rtl-ssa - access-utils.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 100.0 % 148 148
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 46 46
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // Access-related utilities for RTL SSA                             -*- C++ -*-
       2              : // Copyright (C) 2020-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              : namespace rtl_ssa {
      21              : 
      22              : // Return a referene to the whole of register REGNO.
      23              : inline resource_info
      24     29937056 : full_register (unsigned int regno)
      25              : {
      26     29937056 :   return { GET_MODE (regno_reg_rtx[regno]), regno };
      27              : }
      28              : 
      29              : // Return true if sorted array ACCESSES includes an access to hard registers.
      30              : inline bool
      31         5260 : accesses_include_hard_registers (const access_array &accesses)
      32              : {
      33         5260 :   return accesses.size () && HARD_REGISTER_NUM_P (accesses.front ()->regno ());
      34              : }
      35              : 
      36              : // Return true if ACCESSES includes a reference to a non-fixed hard register.
      37              : inline bool
      38     54636846 : accesses_include_nonfixed_hard_registers (access_array accesses)
      39              : {
      40     66614906 :   for (access_info *access : accesses)
      41              :     {
      42     56890665 :       if (!HARD_REGISTER_NUM_P (access->regno ()))
      43              :         break;
      44     19496980 :       if (!fixed_regs[access->regno ()])
      45              :         return true;
      46              :     }
      47              :   return false;
      48              : }
      49              : 
      50              : // Return true if sorted array ACCESSES includes an access to memory.
      51              : inline bool
      52              : accesses_include_memory (const access_array &accesses)
      53              : {
      54              :   return accesses.size () && accesses.back ()->is_mem ();
      55              : }
      56              : 
      57              : // If sorted array ACCESSES includes an access to memory, return the access,
      58              : // otherwise return null.
      59              : template<typename T>
      60              : inline auto
      61    120860870 : memory_access (T accesses) -> decltype (accesses[0])
      62              : {
      63    233129241 :   if (accesses.size () && accesses.back ()->is_mem ())
      64              :     return accesses.back ();
      65              :   return nullptr;
      66              : }
      67              : 
      68              : // If ACCESSES has a memory access, drop it.  Otherwise, return ACCESSES
      69              : // unchanged.
      70              : template<typename T>
      71              : inline T
      72              : drop_memory_access (T accesses)
      73              : {
      74              :   if (!memory_access (accesses))
      75              :     return accesses;
      76              : 
      77              :   access_array arr (accesses);
      78              :   return T (arr.begin (), accesses.size () - 1);
      79              : }
      80              : 
      81              : // Filter ACCESSES to return an access_array of only those accesses that
      82              : // satisfy PREDICATE.  Alocate the new array above WATERMARK.
      83              : template<typename T, typename FilterPredicate>
      84              : inline T
      85       955420 : filter_accesses (obstack_watermark &watermark,
      86              :                  T accesses,
      87              :                  FilterPredicate predicate)
      88              : {
      89       955420 :   access_array_builder builder (watermark);
      90       955420 :   builder.reserve (accesses.size ());
      91      3628976 :   for (auto access : accesses)
      92      2673556 :     if (predicate (access))
      93      1206211 :       builder.quick_push (access);
      94       955420 :   return T (builder.finish ());
      95       955420 : }
      96              : 
      97              : // Given an array of ACCESSES, remove any access with regno REGNO.
      98              : // Allocate the new access array above WM.
      99              : template<typename T>
     100              : inline T
     101              : remove_regno_access (obstack_watermark &watermark,
     102              :                      T accesses, unsigned int regno)
     103              : {
     104              :   using Access = decltype (accesses[0]);
     105              :   auto pred = [regno](Access a) { return a->regno () != regno; };
     106              :   return filter_accesses (watermark, accesses, pred);
     107              : }
     108              : 
     109              : // As above, but additionally check that we actually did remove an access.
     110              : template<typename T>
     111              : inline T
     112              : check_remove_regno_access (obstack_watermark &watermark,
     113              :                            T accesses, unsigned regno)
     114              : {
     115              :   auto orig_size = accesses.size ();
     116              :   auto result = remove_regno_access (watermark, accesses, regno);
     117              :   gcc_assert (result.size () < orig_size);
     118              :   return result;
     119              : }
     120              : 
     121              : // If sorted array ACCESSES includes a reference to REGNO, return the
     122              : // access, otherwise return null.
     123              : template<typename T>
     124              : inline auto
     125     36530490 : find_access (T accesses, unsigned int regno) -> decltype (accesses[0])
     126              : {
     127     36530490 :   unsigned int start = 0;
     128     36530490 :   unsigned int end = accesses.size ();
     129     83628989 :   while (start < end)
     130              :     {
     131     45131839 :       unsigned int mid = (start + end) / 2;
     132     90263678 :       unsigned int found = accesses[mid]->regno ();
     133     45131839 :       if (found == regno)
     134              :         return accesses[mid];
     135     10568009 :       if (found < regno)
     136      3554924 :         start = mid + 1;
     137              :       else
     138              :         end = mid;
     139              :     }
     140              :   return nullptr;
     141              : }
     142              : 
     143              : // If sorted array ACCESSES includes a reference to REGNO, return the
     144              : // index of the access, otherwise return -1.
     145              : inline int
     146      6525093 : find_access_index (access_array accesses, unsigned int regno)
     147              : {
     148      6525093 :   unsigned int start = 0;
     149      6525093 :   unsigned int end = accesses.size ();
     150     13224622 :   while (start < end)
     151              :     {
     152      6699529 :       unsigned int mid = (start + end) / 2;
     153      6699529 :       unsigned int found = accesses[mid]->regno ();
     154      6699529 :       if (found == regno)
     155      6525093 :         return mid;
     156       174436 :       if (found < regno)
     157          537 :         start = mid + 1;
     158              :       else
     159              :         end = mid;
     160              :     }
     161              :   return -1;
     162              : }
     163              : 
     164              : // If ACCESS is a set whose result is used by at least one instruction,
     165              : // return the access as a set_info, otherwise return null.
     166              : inline const set_info *
     167    146626420 : set_with_nondebug_insn_uses (const access_info *access)
     168              : {
     169    146626420 :   if (access->is_set_with_nondebug_insn_uses ())
     170              :     // No need for as_a; this test is just as definitive.
     171    101010562 :     return static_cast<const set_info *> (access);
     172              :   return nullptr;
     173              : }
     174              : 
     175              : // A non-const version of the above.
     176              : inline set_info *
     177              : set_with_nondebug_insn_uses (access_info *access)
     178              : {
     179              :   if (access->is_set_with_nondebug_insn_uses ())
     180              :     return static_cast<set_info *> (access);
     181              :   return nullptr;
     182              : }
     183              : 
     184              : // ACCESS is known to be associated with an instruction rather than
     185              : // a phi node.  Return which instruction that is.
     186              : inline insn_info *
     187    181763426 : access_insn (const access_info *access)
     188              : {
     189              :   // In release builds this function reduces to a single pointer reference.
     190    181763426 :   if (auto *def = dyn_cast<const def_info *> (access))
     191     93152247 :     return def->insn ();
     192     88611179 :   return as_a<const use_info *> (access)->insn ();
     193              : }
     194              : 
     195              : // If ACCESS records a use, return the value that it uses.  If ACCESS records
     196              : // a set, return that set.  If ACCESS records a clobber, return null.
     197              : inline const set_info *
     198              : access_value (const access_info *access)
     199              : {
     200              :   if (!access)
     201              :     return nullptr;
     202              : 
     203              :   if (auto *use = dyn_cast<const use_info *> (access))
     204              :     return use->def ();
     205              : 
     206              :   return dyn_cast<const set_info *> (access);
     207              : }
     208              : 
     209              : // A non-const version of the above.
     210              : inline set_info *
     211              : access_value (access_info *access)
     212              : {
     213              :   auto *const_access = const_cast<const access_info *> (access);
     214              :   return const_cast<set_info *> (access_value (const_access));
     215              : }
     216              : 
     217              : // If ACCESS is a degenerate phi, return the set_info that defines its input,
     218              : // otherwise return ACCESS itself.
     219              : template<typename T>
     220              : inline const T *
     221    231076108 : look_through_degenerate_phi (const T *access)
     222              : {
     223     36366806 :   if (auto *phi = dyn_cast<const phi_info *> (access))
     224     36366806 :     if (phi->is_degenerate ())
     225     18381338 :       return phi->input_value (0);
     226              :   return access;
     227              : }
     228              : 
     229              : // A non-const version of the above.
     230              : template<typename T>
     231              : inline T *
     232    231076108 : look_through_degenerate_phi (T *access)
     233              : {
     234    231076108 :   auto *const_access = const_cast<const T *> (access);
     235    231076108 :   return const_cast<T *> (look_through_degenerate_phi (const_access));
     236              : }
     237              : 
     238              : // If CLOBBER is in a group, return the first clobber in the group,
     239              : // otherwise return CLOBBER itself.
     240              : inline clobber_info *
     241     11480507 : first_clobber_in_group (clobber_info *clobber)
     242              : {
     243     11480507 :   if (clobber->is_in_group ())
     244     11413674 :     return clobber->group ()->first_clobber ();
     245              :   return clobber;
     246              : }
     247              : 
     248              : // If CLOBBER is in a group, return the last clobber in the group,
     249              : // otherwise return CLOBBER itself.
     250              : inline clobber_info *
     251     12066684 : last_clobber_in_group (clobber_info *clobber)
     252              : {
     253     12066684 :   if (clobber->is_in_group ())
     254     12062835 :     return clobber->group ()->last_clobber ();
     255              :   return clobber;
     256              : }
     257              : 
     258              : // If DEF is a clobber in a group, return the containing group,
     259              : // otherwise return DEF.
     260              : inline def_mux
     261      4426477 : clobber_group_or_single_def (def_info *def)
     262              : {
     263      4426477 :   if (auto *clobber = dyn_cast<clobber_info *> (def))
     264      2498164 :     if (clobber->is_in_group ())
     265      2283673 :       return clobber->group ();
     266      2142804 :   return def;
     267              : }
     268              : 
     269              : // Return the first definition associated with NODE.  If NODE holds
     270              : // a single set, the result is that set.  If NODE holds a clobber_group,
     271              : // the result is the first clobber in the group.
     272              : inline def_info *
     273     49763748 : first_def (def_node *node)
     274              : {
     275     86896914 :   return node->first_def ();
     276              : }
     277              : 
     278              : // Likewise for something that is either a node or a single definition.
     279              : inline def_info *
     280      2116254 : first_def (def_mux mux)
     281              : {
     282      3180158 :   return mux.first_def ();
     283              : }
     284              : 
     285              : // Return the last definition associated with NODE.  If NODE holds
     286              : // a single set, the result is that set.  If NODE holds a clobber_group,
     287              : // the result is the last clobber in the group.
     288              : inline def_info *
     289      6533733 : last_def (def_node *node)
     290              : {
     291      6533733 :   if (auto *group = dyn_cast<clobber_group *> (node))
     292      3206437 :     return group->last_clobber ();
     293      3327296 :   return node->first_def ();
     294              : }
     295              : 
     296              : // Likewise for something that is either a node or a single definition.
     297              : inline def_info *
     298      2310223 : last_def (def_mux mux)
     299              : {
     300      2310223 :   return mux.last_def ();
     301              : }
     302              : 
     303              : // If INSN's definitions contain a single set, return that set, otherwise
     304              : // return null.
     305              : inline set_info *
     306    191349989 : single_set_info (insn_info *insn)
     307              : {
     308    191349989 :   set_info *set = nullptr;
     309    414083860 :   for (auto def : insn->defs ())
     310    456944134 :     if (auto this_set = dyn_cast<set_info *> (def))
     311              :       {
     312    187649976 :         if (set)
     313     11476392 :           return nullptr;
     314              :         set = this_set;
     315              :       }
     316    179873597 :   return set;
     317              : }
     318              : 
     319              : int lookup_use (splay_tree<use_info *> &, insn_info *);
     320              : int lookup_def (def_splay_tree &, insn_info *);
     321              : int lookup_clobber (clobber_tree &, insn_info *);
     322              : int lookup_call_clobbers (insn_call_clobbers_tree &, insn_info *);
     323              : 
     324              : // Search backwards from immediately before INSN for the first "relevant"
     325              : // instruction recorded in TREE.  IGNORE is an object that provides the same
     326              : // interface as ignore_nothing; it defines which insns are "relevant"
     327              : // and which should be ignored.
     328              : //
     329              : // Return null if no such relevant instruction exists.
     330              : template<typename IgnorePredicates>
     331              : insn_info *
     332     14672543 : prev_call_clobbers (insn_call_clobbers_tree &tree, insn_info *insn,
     333              :                     IgnorePredicates ignore)
     334              : {
     335     14672543 :   if (!tree)
     336              :     return nullptr;
     337              : 
     338     14672543 :   int comparison = lookup_call_clobbers (tree, insn);
     339     17211466 :   while (comparison <= 0 || ignore.should_ignore_insn (tree->insn ()))
     340              :     {
     341      9839886 :       if (!tree.splay_prev_node ())
     342              :         return nullptr;
     343              : 
     344              :       comparison = 1;
     345              :     }
     346              :   return tree->insn ();
     347              : }
     348              : 
     349              : // Search forwards from immediately after INSN for the first "relevant"
     350              : // instruction recorded in TREE.  IGNORE is an object that provides the
     351              : // same interface as ignore_nothing; it defines which insns are "relevant"
     352              : // and which should be ignored.
     353              : //
     354              : // Return null if no such relevant instruction exists.
     355              : template<typename IgnorePredicates>
     356              : insn_info *
     357     35127291 : next_call_clobbers (insn_call_clobbers_tree &tree, insn_info *insn,
     358              :                     IgnorePredicates ignore)
     359              : {
     360     35127291 :   if (!tree)
     361              :     return nullptr;
     362              : 
     363     35127291 :   int comparison = lookup_call_clobbers (tree, insn);
     364     45446185 :   while (comparison >= 0 || ignore.should_ignore_insn (tree->insn ()))
     365              :     {
     366     23772449 :       if (!tree.splay_next_node ())
     367              :         return nullptr;
     368              : 
     369              :       comparison = -1;
     370              :     }
     371        63002 :   return tree->insn ();
     372              : }
     373              : 
     374              : // Search forwards from immediately after INSN for the first instruction
     375              : // recorded in TREE.  Return null if no such instruction exists.
     376              : inline insn_info *
     377        71822 : next_call_clobbers (insn_call_clobbers_tree &tree, insn_info *insn)
     378              : {
     379        71822 :   return next_call_clobbers (tree, insn, ignore_nothing ());
     380              : }
     381              : 
     382              : // If ACCESS is a set, return the first "relevant" use of ACCESS by a
     383              : // nondebug insn.  IGNORE is an object that provides the same interface
     384              : // as ignore_nothing; it defines which accesses and insns are "relevant"
     385              : // and which should be ignored.
     386              : //
     387              : // Return null if ACCESS is not a set or if no such relevant use exists.
     388              : template<typename IgnorePredicates>
     389              : inline use_info *
     390     94692469 : first_nondebug_insn_use (const access_info *access, IgnorePredicates ignore)
     391              : {
     392     60663417 :   if (const set_info *set = set_with_nondebug_insn_uses (access))
     393              :     {
     394              :       // Written this way to emphasize to the compiler that first_use
     395              :       // must be nonnull in this situation.
     396     60663417 :       use_info *use = set->first_use ();
     397              :       do
     398              :         {
     399     63747581 :           if (!ignore.should_ignore_insn (use->insn ()))
     400              :             return use;
     401      4517171 :           use = use->next_nondebug_insn_use ();
     402              :         }
     403      4517171 :       while (use);
     404              :     }
     405              :   return nullptr;
     406              : }
     407              : 
     408              : // If ACCESS is a set, return the last "relevant" use of ACCESS by a
     409              : // nondebug insn.  IGNORE is an object that provides the same interface
     410              : // as ignore_nothing; it defines which accesses and insns are "relevant"
     411              : // and which should be ignored.
     412              : //
     413              : // Return null if ACCESS is not a set or if no such relevant use exists.
     414              : template<typename IgnorePredicates>
     415              : inline use_info *
     416     51933951 : last_nondebug_insn_use (const access_info *access, IgnorePredicates ignore)
     417              : {
     418     40347145 :   if (const set_info *set = set_with_nondebug_insn_uses (access))
     419              :     {
     420              :       // Written this way to emphasize to the compiler that
     421              :       // last_nondebug_insn_use must be nonnull in this situation.
     422     40347145 :       use_info *use = set->last_nondebug_insn_use ();
     423              :       do
     424              :         {
     425     46826653 :           if (!ignore.should_ignore_insn (use->insn ()))
     426              :             return use;
     427     14539228 :           use = use->prev_use ();
     428              :         }
     429     14539228 :       while (use);
     430              :     }
     431              :   return nullptr;
     432              : }
     433              : 
     434              : // If DEF is null, return null.
     435              : //
     436              : // Otherwise, search backwards for an access to DEF->resource (), starting at
     437              : // the end of DEF's live range.  Ignore clobbers if IGNORE_CLOBBERS_SETTING
     438              : // is YES, otherwise treat them like any other access.  Also ignore any
     439              : // accesses and insns that IGNORE says should be ignored, where IGNORE
     440              : // is an object that provides the same interface as ignore_nothing.
     441              : //
     442              : // Thus if DEF is a set that is used by nondebug insns, the first access
     443              : // that the function considers is the last such use of the set.  Otherwise,
     444              : // the first access that the function considers is DEF itself.
     445              : //
     446              : // Return the access found, or null if there is no access that meets
     447              : // the criteria.
     448              : //
     449              : // Note that this function does not consider separately-recorded call clobbers,
     450              : // although such clobbers are only relevant if IGNORE_CLOBBERS_SETTING is NO.
     451              : template<typename IgnorePredicates>
     452              : access_info *
     453     79390496 : last_access (def_info *def, ignore_clobbers ignore_clobbers_setting,
     454              :              IgnorePredicates ignore)
     455              : {
     456     79390496 :   while (def)
     457              :     {
     458     66160310 :       auto *clobber = dyn_cast<clobber_info *> (def);
     459     66160310 :       if (clobber && ignore_clobbers_setting == ignore_clobbers::YES)
     460     11480507 :         def = first_clobber_in_group (clobber);
     461     22674758 :       else if (!ignore.should_ignore_def (def))
     462              :         {
     463     51933951 :           if (use_info *use = last_nondebug_insn_use (def, ignore))
     464              :             return use;
     465     28403137 :           if (!ignore.should_ignore_insn (def->insn ()))
     466              :             return def;
     467              :         }
     468     95658886 :       def = def->prev_def ();
     469              :     }
     470              :   return nullptr;
     471              : }
     472              : 
     473              : // Search backwards for an access to DEF->resource (), starting
     474              : // immediately before the point at which DEF occurs.  Ignore clobbers
     475              : // if IGNORE_CLOBBERS_SETTING is YES, otherwise treat them like any other
     476              : // access.  Also ignore any accesses and insns that IGNORE says should be
     477              : // ignored, where IGNORE is an object that provides the same interface as
     478              : // ignore_nothing.
     479              : //
     480              : // Thus if DEF->insn () uses DEF->resource (), that use is the first access
     481              : // that the function considers, since an instruction's uses occur strictly
     482              : // before its definitions.
     483              : //
     484              : // Note that this function does not consider separately-recorded call clobbers,
     485              : // although such clobbers are only relevant if IGNORE_CLOBBERS_SETTING is NO.
     486              : template<typename IgnorePredicates>
     487              : inline access_info *
     488     78199925 : prev_access (def_info *def, ignore_clobbers ignore_clobbers_setting,
     489              :              IgnorePredicates ignore)
     490              : {
     491     78199925 :   return last_access (def->prev_def (), ignore_clobbers_setting, ignore);
     492              : }
     493              : 
     494              : // If DEF is null, return null.
     495              : //
     496              : // Otherwise, search forwards for an access to DEF->resource (),
     497              : // starting at DEF itself.  Ignore clobbers if IGNORE_CLOBBERS_SETTING
     498              : // is YES, otherwise treat them like any other access.  Also ignore any
     499              : // accesses and insns that IGNORE says should be ignored, where IGNORE
     500              : // is an object that provides the same interface as ignore_nothing.
     501              : //
     502              : // Return the definition found, or null if there is no access that meets
     503              : // the criteria.
     504              : //
     505              : // Note that this function does not consider separately-recorded call clobbers,
     506              : // although such clobbers are only relevant if IGNORE_CLOBBERS_SETTING is NO.
     507              : template<typename IgnorePredicates>
     508              : access_info *
     509    184782916 : first_access (def_info *def, ignore_clobbers ignore_clobbers_setting,
     510              :               IgnorePredicates ignore)
     511              : {
     512    184782916 :   while (def)
     513              :     {
     514    103642489 :       auto *clobber = dyn_cast<clobber_info *> (def);
     515    103642489 :       if (clobber && ignore_clobbers_setting == ignore_clobbers::YES)
     516     12066684 :         def = last_clobber_in_group (clobber);
     517     37478392 :       else if (!ignore.should_ignore_def (def))
     518              :         {
     519     89133640 :           if (!ignore.should_ignore_insn (def->insn ()))
     520              :             return def;
     521     16492544 :           if (use_info *use = first_nondebug_insn_use (def, ignore))
     522              :             return use;
     523              :         }
     524    204831507 :       def = def->next_def ();
     525              :     }
     526              :   return nullptr;
     527              : }
     528              : 
     529              : // Search forwards for the next access to DEF->resource (),
     530              : // starting immediately after DEF's instruction.  Ignore clobbers if
     531              : // IGNORE_CLOBBERS_SETTING is YES, otherwise treat them like any other access.
     532              : // Also ignore any accesses and insns that IGNORE says should be ignored,
     533              : // where IGNORE is an object that provides the same interface as
     534              : // ignore_nothing.
     535              : //
     536              : // Thus if DEF is a set with uses by nondebug insns, the first access that the
     537              : // function considers is the first such use of the set.  Otherwise, the first
     538              : // access that the function considers is the definition after DEF.
     539              : //
     540              : // Return the access found, or null if there is no access that meets the
     541              : // criteria.
     542              : //
     543              : // Note that this function does not consider separately-recorded call clobbers,
     544              : // although such clobbers are only relevant if IGNORE_CLOBBERS_SETTING is NO.
     545              : template<typename IgnorePredicates>
     546              : access_info *
     547     78199925 : next_access (def_info *def, ignore_clobbers ignore_clobbers_setting,
     548              :              IgnorePredicates ignore)
     549              : {
     550     24903767 :   if (!ignore.should_ignore_def (def))
     551     78199925 :     if (use_info *use = first_nondebug_insn_use (def, ignore))
     552              :       return use;
     553              : 
     554     29922317 :   return first_access (def->next_def (), ignore_clobbers_setting, ignore);
     555              : }
     556              : 
     557              : // Return true if ACCESS1 should before ACCESS2 in an access_array.
     558              : inline bool
     559   1063912337 : compare_access_infos (const access_info *access1, const access_info *access2)
     560              : {
     561   1063912337 :   gcc_checking_assert (access1 == access2
     562              :                        || access1->regno () != access2->regno ());
     563   1063912337 :   return access1->regno () < access2->regno ();
     564              : }
     565              : 
     566              : // Sort [BEGIN, END) into ascending regno order.  The sequence must have
     567              : // at most one access to a given a regno.
     568              : inline void
     569    781850985 : sort_accesses (access_info **begin, access_info **end)
     570              : {
     571    781850985 :   auto count = end - begin;
     572    781850985 :   if (count <= 1)
     573              :     return;
     574              : 
     575    286160921 :   if (count == 2)
     576              :     {
     577    181025974 :       gcc_checking_assert (begin[0]->regno () != begin[1]->regno ());
     578    181025974 :       if (begin[0]->regno () > begin[1]->regno ())
     579    126813800 :         std::swap (begin[0], begin[1]);
     580    181025974 :       return;
     581              :     }
     582              : 
     583    105134947 :   std::sort (begin, end, compare_access_infos);
     584              : }
     585              : 
     586              : // Sort the accesses in CONTAINER, which contains pointers to access_infos.
     587              : template<typename T>
     588              : inline void
     589    781850985 : sort_accesses (T &container)
     590              : {
     591   1563701970 :   return sort_accesses (container.begin (), container.end ());
     592              : }
     593              : 
     594              : // The underlying non-template implementation of merge_access_arrays.
     595              : access_array merge_access_arrays_base (obstack_watermark &, access_array,
     596              :                                        access_array);
     597              : // Merge access arrays ACCESSES1 and ACCESSES2, including the allocation
     598              : // in the area governed by WATERMARK.  Return an invalid access_array if
     599              : // ACCESSES1 and ACCESSES2 contain conflicting accesses to the same resource.
     600              : //
     601              : // T can be an access_array, a def_array or a use_array.
     602              : template<typename T>
     603              : inline T
     604     64737750 : merge_access_arrays (obstack_watermark &watermark, T accesses1, T accesses2)
     605              : {
     606     64737750 :   return T (merge_access_arrays_base (watermark, accesses1, accesses2));
     607              : }
     608              : 
     609              : // The underlying non-template implementation of insert_access.
     610              : access_array insert_access_base (obstack_watermark &, access_info *,
     611              :                                  access_array);
     612              : 
     613              : // Return a new access_array that contains the result of inserting ACCESS1
     614              : // into sorted access array ACCESSES2.  Allocate the returned array in the
     615              : // area governed by WATERMARK.  Return an invalid access_array if ACCESSES2
     616              : // contains a conflicting access to the same resource as ACCESS1.
     617              : //
     618              : // T can be an access_array, a def_array or a use_array.
     619              : template<typename T>
     620              : inline T
     621      1966660 : insert_access (obstack_watermark &watermark,
     622              :                typename T::value_type access1, T accesses2)
     623              : {
     624      1966660 :   return T (insert_access_base (watermark, access1, accesses2));
     625              : }
     626              : 
     627              : // Return a copy of USES that drops any use of DEF.
     628              : use_array remove_uses_of_def (obstack_watermark &, use_array uses,
     629              :                               def_info *def);
     630              : 
     631              : // The underlying non-template implementation of remove_note_accesses.
     632              : access_array remove_note_accesses_base (obstack_watermark &, access_array);
     633              : 
     634              : // If ACCESSES contains accesses that only occur in notes, return a new
     635              : // array without such accesses, allocating it in the area governed by
     636              : // WATERMARK.  Return ACCESSES itself otherwise.
     637              : //
     638              : // T can be an access_array, a def_array or a use_array.
     639              : template<typename T>
     640              : inline T
     641     55215446 : remove_note_accesses (obstack_watermark &watermark, T accesses)
     642              : {
     643     55215446 :   return T (remove_note_accesses_base (watermark, accesses));
     644              : }
     645              : 
     646              : // Return true if ACCESSES1 and ACCESSES2 have at least one resource in common.
     647              : bool accesses_reference_same_resource (access_array accesses1,
     648              :                                        access_array accesses2);
     649              : 
     650              : // Return true if INSN clobbers the value of any resources in ACCESSES.
     651              : bool insn_clobbers_resources (insn_info *insn, access_array accesses);
     652              : 
     653              : }
        

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.