LCOV - code coverage report
Current view: top level - gcc/rtl-ssa - internals.inl (source / functions) Coverage Total Hit
Test: gcc.info Lines: 95.2 % 311 296
Test Date: 2026-02-28 14:20:25 Functions: 73.2 % 56 41
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // Implementation of private inline member functions 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              : // Construct a new access with the given resource () and kind () values.
      23   1655665517 : inline access_info::access_info (resource_info resource, access_kind kind)
      24   1655665517 :   : m_regno (resource.regno),
      25   1655665517 :     m_mode (resource.mode),
      26   1655665517 :     m_kind (kind),
      27              :     m_is_artificial (false),
      28   1655665517 :     m_is_set_with_nondebug_insn_uses (false),
      29   1655665517 :     m_is_pre_post_modify (false),
      30   1655665517 :     m_is_call_clobber (false),
      31   1655665517 :     m_is_live_out_use (false),
      32   1655665517 :     m_includes_address_uses (false),
      33   1655665517 :     m_includes_read_writes (false),
      34   1655665517 :     m_includes_subregs (false),
      35   1655665517 :     m_includes_multiregs (false),
      36   1655665517 :     m_only_occurs_in_notes (false),
      37   1655665517 :     m_is_last_nondebug_insn_use (false),
      38    609138728 :     m_is_in_debug_insn_or_phi (false),
      39   1655665517 :     m_has_been_superceded (false),
      40   1655665517 :     m_is_temp (false)
      41              : {
      42              : }
      43              : 
      44              : // Construct a use of RESOURCE in LOCATION.  The resource's value is provided
      45              : // by DEF, or is completely undefined if DEF is null.
      46   1046526789 : inline use_info::use_info (insn_or_phi location, resource_info resource,
      47   1046526789 :                            set_info *definition)
      48              :   : access_info (resource, access_kind::USE),
      49   1046526789 :     m_insn_or_phi (location),
      50   1046526789 :     m_last_use_or_prev_use (nullptr),
      51   1046526789 :     m_last_nondebug_insn_use_or_next_use (nullptr),
      52   1046526789 :     m_def (definition)
      53              : {
      54   1046526789 :   if (m_insn_or_phi.is_second ())
      55              :     {
      56    157947155 :       m_is_in_debug_insn_or_phi = true;
      57    157947155 :       m_is_artificial = true;
      58              :     }
      59              :   else
      60              :     {
      61    888579634 :       insn_info *insn = m_insn_or_phi.known_first ();
      62    888579634 :       m_is_in_debug_insn_or_phi = insn->is_debug_insn ();
      63    888579634 :       m_is_artificial = insn->is_artificial ();
      64              :     }
      65   1046526789 : }
      66              : 
      67              : // Return the correct (uncached) value of m_is_last_nondebug_insn_use.
      68              : inline bool
      69   2739227814 : use_info::calculate_is_last_nondebug_insn_use () const
      70              : {
      71   2739227814 :   use_info *next = next_use ();
      72   2739227814 :   return is_in_nondebug_insn () && (!next || next->is_in_debug_insn_or_phi ());
      73              : }
      74              : 
      75              : // Accumulate any properties about REF that are also stored in use_infos.
      76              : // IS_FIRST is true if REF is the first access to resource () that we have
      77              : // recorded in this way, false if we have already recorded previous
      78              : // references.
      79              : inline void
      80    648056568 : use_info::record_reference (rtx_obj_reference ref, bool is_first)
      81              : {
      82    648056568 :   if (is_first)
      83              :     {
      84    585471003 :       m_includes_address_uses = ref.in_address ();
      85    585471003 :       m_includes_read_writes = ref.is_write ();
      86    585471003 :       m_includes_subregs = ref.in_subreg ();
      87    585471003 :       m_includes_multiregs = ref.is_multireg ();
      88    585471003 :       m_only_occurs_in_notes = ref.in_note ();
      89              :     }
      90              :   else
      91              :     {
      92     62585565 :       m_includes_address_uses |= ref.in_address ();
      93     62585565 :       m_includes_read_writes |= ref.is_write ();
      94     62585565 :       m_includes_subregs |= ref.in_subreg ();
      95     62585565 :       m_includes_multiregs |= ref.is_multireg ();
      96     62585565 :       m_only_occurs_in_notes &= ref.in_note ();
      97              :     }
      98    648056568 : }
      99              : 
     100              : // Change the value of insn () to INSN.
     101              : inline void
     102              : use_info::set_insn (insn_info *insn)
     103              : {
     104              :   m_insn_or_phi = insn;
     105              :   m_is_artificial = insn->is_artificial ();
     106              : }
     107              : 
     108              : // Copy the overloaded prev link from OTHER.
     109              : inline void
     110     36334415 : use_info::copy_prev_from (use_info *other)
     111              : {
     112     21080603 :   m_last_use_or_prev_use = other->m_last_use_or_prev_use;
     113     15253812 : }
     114              : 
     115              : // Copy the overloaded next link from OTHER.
     116              : inline void
     117    594804089 : use_info::copy_next_from (use_info *other)
     118              : {
     119    594804089 :   m_last_nondebug_insn_use_or_next_use
     120    594804089 :     = other->m_last_nondebug_insn_use_or_next_use;
     121    574593317 :   m_is_last_nondebug_insn_use = calculate_is_last_nondebug_insn_use ();
     122     20210772 : }
     123              : 
     124              : // Record that this use is the first in the list and that the last use is LAST.
     125              : inline void
     126    962425748 : use_info::set_last_use (use_info *last_use)
     127              : {
     128    962425748 :   m_last_use_or_prev_use.set_first (last_use);
     129    396338201 : }
     130              : 
     131              : // Record that this use is not the first in the list and that the previous
     132              : // use is PREV.
     133              : inline void
     134    680395433 : use_info::set_prev_use (use_info *prev_use)
     135              : {
     136    680395433 :   m_last_use_or_prev_use.set_second (prev_use);
     137     84721513 : }
     138              : 
     139              : // Record that this use is the last use in the list.  If USE is nonnull,
     140              : // record that USE is the last use in the list by a nondebug instruction,
     141              : // otherwise record that there are no uses by nondebug instructions
     142              : // in the list.
     143              : inline void
     144    819214810 : use_info::set_last_nondebug_insn_use (use_info *use)
     145              : {
     146    819214810 :   m_last_nondebug_insn_use_or_next_use.set_first (use);
     147    819214810 :   m_is_last_nondebug_insn_use = (use == this);
     148    819214810 : }
     149              : 
     150              : // Record that this use is not the last in the list and that the next
     151              : // use is NEXT_USE.
     152              : inline void
     153    598315826 : use_info::set_next_use (use_info *next_use)
     154              : {
     155    598315826 :   m_last_nondebug_insn_use_or_next_use.set_second (next_use);
     156    598315826 :   m_is_last_nondebug_insn_use = calculate_is_last_nondebug_insn_use ();
     157    598315826 : }
     158              : 
     159              : // Clear any information relating to the position of the use in its
     160              : // definition's list.
     161              : inline void
     162     45116245 : use_info::clear_use_links ()
     163              : {
     164     45116245 :   m_last_use_or_prev_use = nullptr;
     165     45116245 :   m_last_nondebug_insn_use_or_next_use = nullptr;
     166     45116245 :   m_is_last_nondebug_insn_use = false;
     167              : }
     168              : 
     169              : // Return true if the use has any links to other uses.  This is mostly
     170              : // for assert checking.
     171              : inline bool
     172   1570522572 : use_info::has_use_links ()
     173              : {
     174   1570522572 :   return (m_last_use_or_prev_use
     175   1570522572 :           || m_last_nondebug_insn_use_or_next_use
     176   3141045144 :           || m_is_last_nondebug_insn_use);
     177              : }
     178              : 
     179              : // Construct a definition of RESOURCE in INSN, giving it kind KIND.
     180    609138728 : inline def_info::def_info (insn_info *insn, resource_info resource,
     181    609138728 :                            access_kind kind)
     182              :   : access_info (resource, kind),
     183    609138728 :     m_insn (insn),
     184    609138728 :     m_last_def_or_prev_def (nullptr),
     185    609138728 :     m_splay_root_or_next_def (nullptr)
     186              : {
     187    609138728 :   m_is_artificial = insn->is_artificial ();
     188    609138728 : }
     189              : 
     190              : // Record any properties about REF that are also stored in def_infos.
     191              : // IS_FIRST is true if REF is the first access to resource () that we have
     192              : // recorded in this way, false if we have already recorded previous
     193              : // references.
     194              : inline void
     195    411845340 : def_info::record_reference (rtx_obj_reference ref, bool is_first)
     196              : {
     197    411845340 :   if (is_first)
     198              :     {
     199    399832282 :       m_is_pre_post_modify = ref.is_pre_post_modify ();
     200    399832282 :       m_includes_read_writes = ref.is_read ();
     201    399832282 :       m_includes_subregs = ref.in_subreg ();
     202    399832282 :       m_includes_multiregs = ref.is_multireg ();
     203              :     }
     204              :   else
     205              :     {
     206     12013058 :       m_is_pre_post_modify |= ref.is_pre_post_modify ();
     207     12013058 :       m_includes_read_writes |= ref.is_read ();
     208     12013058 :       m_includes_subregs |= ref.in_subreg ();
     209     12013058 :       m_includes_multiregs |= ref.is_multireg ();
     210              :     }
     211    411845340 : }
     212              : 
     213              : // Return the last definition in the list.  Only valid when is_first ()
     214              : // is true.
     215              : inline def_info *
     216    517145212 : def_info::last_def () const
     217              : {
     218    517145212 :   return m_last_def_or_prev_def.known_first ();
     219              : }
     220              : 
     221              : // Return the root of the splay tree of definitions of resource (),
     222              : // or null if no splay tree has been created for this resource.
     223              : // Only valid when is_last () is true.
     224              : inline def_node *
     225    461758712 : def_info::splay_root () const
     226              : {
     227    461758712 :   return m_splay_root_or_next_def.known_first ();
     228              : }
     229              : 
     230              : // Copy the overloaded prev link from OTHER.
     231              : inline void
     232      6501352 : def_info::copy_prev_from (def_info *other)
     233              : {
     234      6501352 :   m_last_def_or_prev_def
     235       373912 :     = other->m_last_def_or_prev_def;
     236      6127440 : }
     237              : 
     238              : // Copy the overloaded next link from OTHER.
     239              : inline void
     240    113543897 : def_info::copy_next_from (def_info *other)
     241              : {
     242    101440530 :   m_splay_root_or_next_def = other->m_splay_root_or_next_def;
     243     12103367 : }
     244              : 
     245              : // Record that this definition is the first in the list and that the last
     246              : // definition is LAST.
     247              : inline void
     248    613165084 : def_info::set_last_def (def_info *last_def)
     249              : {
     250    613165084 :   m_last_def_or_prev_def.set_first (last_def);
     251    453834718 : }
     252              : 
     253              : // Record that this definition is not the first in the list and that the
     254              : // previous definition is PREV.
     255              : inline void
     256    449312138 : def_info::set_prev_def (def_info *prev_def)
     257              : {
     258    449312138 :   m_last_def_or_prev_def.set_second (prev_def);
     259       706512 : }
     260              : 
     261              : // Record that this definition is the last in the list and that the root
     262              : // of the splay tree associated with resource () is ROOT.
     263              : inline void
     264      2706446 : def_info::set_splay_root (def_node *root)
     265              : {
     266      2706446 :   m_splay_root_or_next_def = root;
     267       130400 : }
     268              : 
     269              : // Record that this definition is not the last in the list and that the
     270              : // next definition is NEXT.
     271              : inline void
     272    449070480 : def_info::set_next_def (def_info *next_def)
     273              : {
     274    448765364 :   m_splay_root_or_next_def = next_def;
     275       464854 : }
     276              : 
     277              : // Clear the prev and next links
     278              : inline void
     279     13899916 : def_info::clear_def_links ()
     280              : {
     281      1648306 :   m_last_def_or_prev_def = nullptr;
     282      1648306 :   m_splay_root_or_next_def = nullptr;
     283              : }
     284              : 
     285              : // Return true if the definition has any links to other definitions.
     286              : // This is mostly for assert checking.
     287              : inline bool
     288    709750434 : def_info::has_def_links ()
     289              : {
     290    709750434 :   return m_last_def_or_prev_def || m_splay_root_or_next_def;
     291              : }
     292              : 
     293              : // Construct a clobber of register REGNO in insn INSN.
     294    128919431 : inline clobber_info::clobber_info (insn_info *insn, unsigned int regno)
     295              :   : def_info (insn, { E_BLKmode, regno }, access_kind::CLOBBER),
     296    128919431 :     m_children (),
     297    128919431 :     m_parent (nullptr),
     298    128919431 :     m_group (nullptr)
     299              : {
     300    128919431 : }
     301              : 
     302              : // Set the containing group to GROUP, if it isn't already.  The main
     303              : // use of this function is to update the new root of GROUP's splay tree.
     304              : inline void
     305      1135583 : clobber_info::update_group (clobber_group *group)
     306              : {
     307      1135583 :   if (UNLIKELY (m_group != group))
     308            0 :     m_group = group;
     309              : }
     310              : 
     311              : // Cconstruct a set_info for a store to RESOURCE in INSN, giving it
     312              : // kind KIND.
     313    480219297 : inline set_info::set_info (insn_info *insn, resource_info resource,
     314    480219297 :                            access_kind kind)
     315              :   : def_info (insn, resource, kind),
     316    960438594 :     m_first_use (nullptr)
     317              : {
     318              : }
     319              : 
     320              : // Cconstruct a set_info for a store to RESOURCE in INSN.
     321    379184506 : inline set_info::set_info (insn_info *insn, resource_info resource)
     322    379184506 :   : set_info (insn, resource, access_kind::SET)
     323              : {
     324    379184506 : }
     325              : 
     326              : // Record that USE is the first use of this definition.
     327              : inline void
     328    486035681 : set_info::set_first_use (use_info *first_use)
     329              : {
     330    486035681 :   m_first_use = first_use;
     331    461130208 :   m_is_set_with_nondebug_insn_uses
     332    560648811 :     = (first_use && first_use->is_in_nondebug_insn ());
     333     43344170 : }
     334              : 
     335              : // Construct a phi for RESOURCE in INSN, giving it identifier UID.
     336    101034791 : inline phi_info::phi_info (insn_info *insn, resource_info resource,
     337    101034791 :                            unsigned int uid)
     338              :   : set_info (insn, resource, access_kind::PHI),
     339    101034791 :     m_uid (uid),
     340    101034791 :     m_num_inputs (0),
     341    101034791 :     m_prev_phi (nullptr),
     342    101034791 :     m_next_phi (nullptr)
     343              : {
     344    101034791 : }
     345              : 
     346              : // Turn the phi into a degenerate phi, with INPUT representing the
     347              : // value of the resource on all incoming edges.
     348              : inline void
     349      1685593 : phi_info::make_degenerate (use_info *input)
     350              : {
     351      1685593 :   m_num_inputs = 1;
     352      1685593 :   m_single_input = input;
     353      1500247 : }
     354              : 
     355              : // Set the inputs of the phi to INPUTS.
     356              : inline void
     357    100849445 : phi_info::set_inputs (use_array inputs)
     358              : {
     359    100849445 :   m_num_inputs = inputs.size ();
     360    100849445 :   if (inputs.size () == 1)
     361     67981342 :     m_single_input = inputs[0];
     362              :   else
     363     32868103 :     m_inputs = access_array (inputs).begin ();
     364    100849445 : }
     365              : 
     366              : // Construct a definition splay tree node for FIRST_DEF, which is either
     367              : // the first clobber_info in a group or a standalone set_info.
     368     34966315 : inline def_node::def_node (clobber_or_set first_def)
     369     34966315 :   : m_clobber_or_set (first_def),
     370     34966315 :     m_children ()
     371              : {
     372              : }
     373              : 
     374              : // Construct a new group of clobber_infos that initially contains just CLOBBER.
     375     18397922 : inline clobber_group::clobber_group (clobber_info *clobber)
     376     18397922 :   : def_node (clobber),
     377     18397922 :     m_last_clobber (clobber),
     378     18397922 :     m_clobber_tree (clobber)
     379              : {
     380     18397922 :   clobber->m_group = this;
     381              : }
     382              : 
     383              : // Construct a new group of clobber_infos that spans [FIRST_CLOBBER,
     384              : // LAST_CLOBBER].  Set the root of the splay tree to CLOBBER_TREE.
     385            0 : inline clobber_group::clobber_group (clobber_info *first_clobber,
     386              :                                      clobber_info *last_clobber,
     387            0 :                                      clobber_info *clobber_tree)
     388            0 :   : def_node (first_clobber),
     389            0 :     m_last_clobber (last_clobber),
     390            0 :     m_clobber_tree (clobber_tree)
     391              : {
     392            0 :   first_clobber->m_group = this;
     393            0 :   last_clobber->m_group = this;
     394            0 :   clobber_tree->m_group = this;
     395              : }
     396              : 
     397              : // Construct a node for the instruction with uid UID.
     398         1750 : inline insn_info::order_node::order_node (int uid)
     399              :   : insn_note (kind),
     400         1750 :     m_children (),
     401         1750 :     m_parent (nullptr)
     402              : {
     403         1750 :   m_data32 = uid;
     404              : }
     405              : 
     406              : // Construct a note for instruction INSN, giving it abi_id () value ABI_ID.
     407     25278183 : inline insn_call_clobbers_note::insn_call_clobbers_note (unsigned int abi_id,
     408     25278183 :                                                          insn_info *insn)
     409              :   : insn_note (kind),
     410     25278183 :     m_children (),
     411     25278183 :     m_insn (insn)
     412              : {
     413     25278183 :   m_data32 = abi_id;
     414              : }
     415              : 
     416              : // Construct an instruction with the given bb () and rtl () values.
     417              : // If the instruction is real, COST_OR_UID is the value of cost (),
     418              : // otherwise it is the value of uid ().
     419    833733635 : inline insn_info::insn_info (bb_info *bb, rtx_insn *rtl, int cost_or_uid)
     420    833708274 :   : m_prev_sametype_or_last_debug_insn (nullptr),
     421    833733635 :     m_next_nondebug_or_debug_insn (nullptr),
     422    833733635 :     m_bb (bb),
     423    833733635 :     m_rtl (rtl),
     424    833733635 :     m_accesses (nullptr),
     425    833733635 :     m_num_uses (0),
     426    833733635 :     m_num_defs (0),
     427    833708274 :     m_is_debug_insn (rtl && DEBUG_INSN_P (rtl)),
     428    833733635 :     m_can_be_optimized (false),
     429    833733635 :     m_is_asm (false),
     430    833733635 :     m_has_pre_post_modify (false),
     431    833733635 :     m_has_volatile_refs (false),
     432    833733635 :     m_is_temp (false),
     433    833733635 :     m_spare (0),
     434    833733635 :     m_point (0),
     435    833733635 :     m_cost_or_uid (cost_or_uid),
     436    833733635 :     m_first_note (nullptr)
     437              : {
     438    833708274 : }
     439              : 
     440              : // Copy any insn properties from PROPERTIES that are also stored in an
     441              : // insn_info.
     442              : inline void
     443    656745324 : insn_info::set_properties (const rtx_properties &properties)
     444              : {
     445    656745324 :   m_is_asm = properties.has_asm;
     446    656745324 :   m_has_pre_post_modify = properties.has_pre_post_modify;
     447    656745324 :   m_has_volatile_refs = properties.has_volatile_refs;
     448              :   // Not strictly related to the properties we've been given, but it's
     449              :   // a convenient location to do this.
     450    656745324 :   m_can_be_optimized = (NONDEBUG_INSN_P (m_rtl)
     451    656745324 :                         & (GET_CODE (PATTERN (m_rtl)) != USE)
     452    656745324 :                         & (GET_CODE (PATTERN (m_rtl)) != CLOBBER));
     453    656745324 : }
     454              : 
     455              : // Change the list of instruction accesses to ACCESSES, which contains
     456              : // NUM_DEFS definitions followed by NUM_USES uses.
     457              : inline void
     458    783928436 : insn_info::set_accesses (access_info **accesses,
     459              :                          unsigned int num_defs, unsigned int num_uses)
     460              : {
     461    783928436 :   m_accesses = accesses;
     462    783928436 :   m_num_defs = num_defs;
     463    783928436 :   gcc_assert (num_defs == m_num_defs);
     464    783928436 :   m_num_uses = num_uses;
     465              : }
     466              : 
     467              : // Change defs () and uses () to DEFS and USES respectively, given that
     468              : // the existing m_accesses array has enough room for them.
     469              : inline void
     470     18187144 : insn_info::copy_accesses (access_array defs, access_array uses)
     471              : {
     472     18187144 :   gcc_assert (defs.size () + uses.size () <= m_num_defs + m_num_uses);
     473     18187144 :   memcpy (m_accesses, defs.begin (), defs.size_bytes ());
     474     18187144 :   memcpy (m_accesses + defs.size (), uses.begin (), uses.size_bytes ());
     475     18187144 :   m_num_defs = defs.size ();
     476     18187144 :   gcc_assert (m_num_defs == defs.size ());
     477     18187144 :   m_num_uses = uses.size ();
     478     18187144 : }
     479              : 
     480              : // If the instruction has an insn_info::order_node, return the node,
     481              : // otherwise return null.
     482              : inline insn_info::order_node *
     483      2220340 : insn_info::get_order_node () const
     484              : {
     485              :   // The order_node always comes first.
     486      2220340 :   if (insn_note *note = first_note ())
     487      2196193 :     return note->dyn_cast<insn_info::order_node *> ();
     488              :   return nullptr;
     489              : }
     490              : 
     491              : // Like get_order_node (), but the node is known to exist.
     492              : inline insn_info::order_node *
     493         1726 : insn_info::get_known_order_node () const
     494              : {
     495              :   // The order_node always comes first.
     496          863 :   return first_note ()->as_a<insn_info::order_node *> ();
     497              : }
     498              : 
     499              : // Copy the overloaded prev link from OTHER.
     500              : inline void
     501        47772 : insn_info::copy_prev_from (insn_info *other)
     502              : {
     503        47772 :   m_prev_sametype_or_last_debug_insn
     504        47772 :     = other->m_prev_sametype_or_last_debug_insn;
     505              : }
     506              : 
     507              : // Copy the overloaded next link from OTHER.
     508              : inline void
     509    827816034 : insn_info::copy_next_from (insn_info *other)
     510              : {
     511    827816034 :   m_next_nondebug_or_debug_insn = other->m_next_nondebug_or_debug_insn;
     512              : }
     513              : 
     514              : // If this is a nondebug instruction, record that the previous nondebug
     515              : // instruction is PREV.  (There might be intervening debug instructions.)
     516              : //
     517              : // If this is a debug instruction, record that the previous instruction
     518              : // is debug instruction PREV.
     519              : inline void
     520   1282831392 : insn_info::set_prev_sametype_insn (insn_info *prev)
     521              : {
     522   1282831392 :   m_prev_sametype_or_last_debug_insn.set_first (prev);
     523    744368824 : }
     524              : 
     525              : // Only valid for debug instructions.  Record that this instruction starts
     526              : // a subsequence of debug instructions that ends with LAST.
     527              : inline void
     528    291551678 : insn_info::set_last_debug_insn (insn_info *last)
     529              : {
     530    291551678 :   m_prev_sametype_or_last_debug_insn.set_second (last);
     531    291551678 : }
     532              : 
     533              : // Record that the next instruction of any kind is NEXT.
     534              : inline void
     535    830009187 : insn_info::set_next_any_insn (insn_info *next)
     536              : {
     537    830009187 :   if (next && next->is_debug_insn ())
     538    291987455 :     m_next_nondebug_or_debug_insn.set_second (next);
     539              :   else
     540    538021732 :     m_next_nondebug_or_debug_insn.set_first (next);
     541    830009187 : }
     542              : 
     543              : // Clear the list links and point number for this instruction.
     544              : inline void
     545      2218514 : insn_info::clear_insn_links ()
     546              : {
     547      2218514 :   m_prev_sametype_or_last_debug_insn = nullptr;
     548      2218514 :   m_next_nondebug_or_debug_insn = nullptr;
     549      2218514 :   m_point = 0;
     550              : }
     551              : 
     552              : // Return true if the instruction contains any list information.
     553              : // This is used by assert checking.
     554              : inline bool
     555   1661524308 : insn_info::has_insn_links ()
     556              : {
     557    827816034 :   return (m_prev_sametype_or_last_debug_insn
     558   1661524308 :           || m_next_nondebug_or_debug_insn
     559   3323048616 :           || m_point);
     560              : }
     561              : 
     562              : // Construct a representation of basic block CFG_BB.
     563     74730939 : inline bb_info::bb_info (basic_block cfg_bb)
     564     74730939 :   : m_prev_bb (nullptr),
     565     74730939 :     m_next_bb (nullptr),
     566     74730939 :     m_cfg_bb (cfg_bb),
     567     74730939 :     m_ebb (nullptr),
     568     74730939 :     m_head_insn (nullptr),
     569     74730939 :     m_end_insn (nullptr)
     570              : {
     571              : }
     572              : 
     573              : // Construct a tree of call clobbers for the given ABI.
     574     14784682 : inline ebb_call_clobbers_info::
     575     14784682 : ebb_call_clobbers_info (const predefined_function_abi *abi)
     576     14784682 :   : m_next (nullptr),
     577     14784682 :     m_abi (abi)
     578              : {
     579              : }
     580              : 
     581              : // Construct an EBB whose first block is FIRST_BB and whose last block
     582              : // is LAST_BB.
     583     45977392 : inline ebb_info::ebb_info (bb_info *first_bb, bb_info *last_bb)
     584     45977392 :   : m_first_phi (nullptr),
     585     45977392 :     m_phi_insn (nullptr),
     586     45977392 :     m_first_bb (first_bb),
     587     45977392 :     m_last_bb (last_bb),
     588     45977392 :     m_first_call_clobbers (nullptr)
     589              : {
     590              : }
     591              : 
     592              : // Record register definition DEF in last_access, pushing a definition
     593              : // to def_stack where appropriate.
     594              : inline void
     595    560052839 : function_info::build_info::record_reg_def (def_info *def)
     596              : {
     597    560052839 :   unsigned int regno = def->regno ();
     598    560052839 :   auto *prev_dominating_def = safe_as_a<def_info *> (last_access[regno + 1]);
     599    560052839 :   if (!prev_dominating_def)
     600              :     // Indicate that DEF is the first dominating definition of REGNO.
     601    175573689 :     def_stack.safe_push (def);
     602    384479150 :   else if (prev_dominating_def->bb () != def->bb ())
     603              :     // Record that PREV_DOMINATING_DEF was the dominating definition
     604              :     // of REGNO on entry to the current block.
     605    175377236 :     def_stack.safe_push (prev_dominating_def);
     606    560052839 :   last_access[regno + 1] = def;
     607    560052839 : }
     608              : 
     609              : // Set the contents of last_access for memory to DEF.
     610              : inline void
     611     46891339 : function_info::build_info::record_mem_def (def_info *def)
     612              : {
     613     46891339 :   last_access[0] = def;
     614      1072173 : }
     615              : 
     616              : // Return the current value of live register REGNO, or null if the register's
     617              : // value is completedly undefined.
     618              : inline set_info *
     619    938338288 : function_info::build_info::current_reg_value (unsigned int regno) const
     620              : {
     621    938338288 :   return safe_dyn_cast<set_info *> (last_access[regno + 1]);
     622              : }
     623              : 
     624              : // Return the current value of memory.
     625              : inline set_info *
     626     83338745 : function_info::build_info::current_mem_value () const
     627              : {
     628     83338745 :   return as_a<set_info *> (last_access[0]);
     629              : }
     630              : 
     631              : // Allocate a T on the function's main obstack, passing ARGS
     632              : // to its constructor.
     633              : template<typename T, typename... Ts>
     634              : inline T *
     635   2698421091 : function_info::allocate (Ts... args)
     636              : {
     637              :   static_assert (std::is_trivially_destructible<T>::value,
     638              :                  "destructor won't be called");
     639              :   static_assert (alignof (T) <= obstack_alignment,
     640              :                  "too much alignment required");
     641   2698421091 :   void *addr = obstack_alloc (&m_obstack, sizeof (T));
     642   2698421091 :   return new (addr) T (std::forward<Ts> (args)...);
     643              : }
     644              : 
     645              : // Allocate a T on the function's temporary obstack, passing ARGS
     646              : // to its constructor.
     647              : template<typename T, typename... Ts>
     648              : inline T *
     649     10175292 : function_info::allocate_temp (Ts... args)
     650              : {
     651              :   static_assert (std::is_trivially_destructible<T>::value,
     652              :                  "destructor won't be called");
     653              :   static_assert (alignof (T) <= obstack_alignment,
     654              :                  "too much alignment required");
     655     10175292 :   void *addr = obstack_alloc (&m_temp_obstack, sizeof (T));
     656     10175292 :   return new (addr) T (std::forward<Ts> (args)...);
     657              : }
     658              : 
     659              : // Add INSN to the end of the function's list of instructions.
     660              : inline void
     661    833708274 : function_info::append_insn (insn_info *insn)
     662              : {
     663    833708274 :   gcc_checking_assert (!insn->has_insn_links ());
     664    833708274 :   if (insn_info *after = m_last_insn)
     665    827765312 :     add_insn_after (insn, after);
     666              :   else
     667              :     // The first instruction is for the entry block and is always a nondebug
     668              :     // insn
     669      5942962 :     m_first_insn = m_last_insn = m_last_nondebug_insn = insn;
     670    833708274 : }
     671              : 
     672              : // Start building a new list of uses and definitions for an instruction.
     673              : inline void
     674    781471468 : function_info::start_insn_accesses ()
     675              : {
     676   1556999974 :   gcc_checking_assert (m_temp_defs.is_empty ()
     677              :                        && m_temp_uses.is_empty ());
     678    781471468 : }
     679              : 
     680              : // Return a mode that encapsulates two distinct references to a register,
     681              : // one with mode MODE1 and one with mode MODE2.  Treat BLKmode as a
     682              : // "don't know" wildcard.
     683              : inline machine_mode
     684    255768513 : combine_modes (machine_mode mode1, machine_mode mode2)
     685              : {
     686    255768513 :   if (mode1 == E_BLKmode)
     687              :     return mode2;
     688              : 
     689    100897987 :   if (mode2 == E_BLKmode)
     690              :     return mode1;
     691              : 
     692    100897507 :   if (!ordered_p (GET_MODE_SIZE (mode1), GET_MODE_SIZE (mode2)))
     693              :     return BLKmode;
     694              : 
     695    100897507 :   return wider_subreg_mode (mode1, mode2);
     696              : }
     697              : 
     698              : // PRINTER (PP, ARGS...) prints ARGS... to a pretty_printer PP.  Use it
     699              : // to print ARGS... to FILE.
     700              : template<typename Printer, typename... Args>
     701              : inline void
     702            0 : dump_using (FILE *file, Printer printer, Args... args)
     703              : {
     704            0 :   pretty_printer pp;
     705            0 :   printer (&pp, args...);
     706            0 :   pp_newline (&pp);
     707            0 :   fprintf (file, "%s", pp_formatted_text (&pp));
     708            0 : }
     709              : 
     710              : }
        

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.