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-07-11 15:47:05 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   1953940023 : inline access_info::access_info (resource_info resource, access_kind kind)
      24   1953940023 :   : m_regno (resource.regno),
      25   1953940023 :     m_mode (resource.mode),
      26   1953940023 :     m_kind (kind),
      27              :     m_is_artificial (false),
      28   1953940023 :     m_is_set_with_nondebug_insn_uses (false),
      29   1953940023 :     m_is_pre_post_modify (false),
      30   1953940023 :     m_is_call_clobber (false),
      31   1953940023 :     m_is_live_out_use (false),
      32   1953940023 :     m_includes_address_uses (false),
      33   1953940023 :     m_includes_read_writes (false),
      34   1953940023 :     m_includes_subregs (false),
      35   1953940023 :     m_includes_multiregs (false),
      36   1953940023 :     m_only_occurs_in_notes (false),
      37   1953940023 :     m_is_last_nondebug_insn_use (false),
      38    725402284 :     m_is_in_debug_insn_or_phi (false),
      39   1953940023 :     m_has_been_superceded (false),
      40   1953940023 :     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   1228537739 : inline use_info::use_info (insn_or_phi location, resource_info resource,
      47   1228537739 :                            set_info *definition)
      48              :   : access_info (resource, access_kind::USE),
      49   1228537739 :     m_insn_or_phi (location),
      50   1228537739 :     m_last_use_or_prev_use (nullptr),
      51   1228537739 :     m_last_nondebug_insn_use_or_next_use (nullptr),
      52   1228537739 :     m_def (definition)
      53              : {
      54   1228537739 :   if (m_insn_or_phi.is_second ())
      55              :     {
      56    193986805 :       m_is_in_debug_insn_or_phi = true;
      57    193986805 :       m_is_artificial = true;
      58              :     }
      59              :   else
      60              :     {
      61   1034550934 :       insn_info *insn = m_insn_or_phi.known_first ();
      62   1034550934 :       m_is_in_debug_insn_or_phi = insn->is_debug_insn ();
      63   1034550934 :       m_is_artificial = insn->is_artificial ();
      64              :     }
      65   1228537739 : }
      66              : 
      67              : // Return the correct (uncached) value of m_is_last_nondebug_insn_use.
      68              : inline bool
      69   3171481424 : use_info::calculate_is_last_nondebug_insn_use () const
      70              : {
      71   3171481424 :   use_info *next = next_use ();
      72   3171481424 :   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    773805152 : use_info::record_reference (rtx_obj_reference ref, bool is_first)
      81              : {
      82    773805152 :   if (is_first)
      83              :     {
      84    696634080 :       m_includes_address_uses = ref.in_address ();
      85    696634080 :       m_includes_read_writes = ref.is_write ();
      86    696634080 :       m_includes_subregs = ref.in_subreg ();
      87    696634080 :       m_includes_multiregs = ref.is_multireg ();
      88    696634080 :       m_only_occurs_in_notes = ref.in_note ();
      89              :     }
      90              :   else
      91              :     {
      92     77171072 :       m_includes_address_uses |= ref.in_address ();
      93     77171072 :       m_includes_read_writes |= ref.is_write ();
      94     77171072 :       m_includes_subregs |= ref.in_subreg ();
      95     77171072 :       m_includes_multiregs |= ref.is_multireg ();
      96     77171072 :       m_only_occurs_in_notes &= ref.in_note ();
      97              :     }
      98    773805152 : }
      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     40676174 : use_info::copy_prev_from (use_info *other)
     111              : {
     112     24485752 :   m_last_use_or_prev_use = other->m_last_use_or_prev_use;
     113     16190422 : }
     114              : 
     115              : // Copy the overloaded next link from OTHER.
     116              : inline void
     117    685999201 : use_info::copy_next_from (use_info *other)
     118              : {
     119    685999201 :   m_last_nondebug_insn_use_or_next_use
     120    685999201 :     = other->m_last_nondebug_insn_use_or_next_use;
     121    663593801 :   m_is_last_nondebug_insn_use = calculate_is_last_nondebug_insn_use ();
     122     22405400 : }
     123              : 
     124              : // Record that this use is the first in the list and that the last use is LAST.
     125              : inline void
     126   1130817863 : use_info::set_last_use (use_info *last_use)
     127              : {
     128   1130817863 :   m_last_use_or_prev_use.set_first (last_use);
     129    448035247 : }
     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    784780346 : use_info::set_prev_use (use_info *prev_use)
     135              : {
     136    784780346 :   m_last_use_or_prev_use.set_second (prev_use);
     137     96700793 : }
     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    948829948 : use_info::set_last_nondebug_insn_use (use_info *use)
     145              : {
     146    948829948 :   m_last_nondebug_insn_use_or_next_use.set_first (use);
     147    948829948 :   m_is_last_nondebug_insn_use = (use == this);
     148    948829948 : }
     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    690782759 : use_info::set_next_use (use_info *next_use)
     154              : {
     155    690782759 :   m_last_nondebug_insn_use_or_next_use.set_second (next_use);
     156    690782759 :   m_is_last_nondebug_insn_use = calculate_is_last_nondebug_insn_use ();
     157    690782759 : }
     158              : 
     159              : // Clear any information relating to the position of the use in its
     160              : // definition's list.
     161              : inline void
     162     48751701 : use_info::clear_use_links ()
     163              : {
     164     48751701 :   m_last_use_or_prev_use = nullptr;
     165     48751701 :   m_last_nondebug_insn_use_or_next_use = nullptr;
     166     48751701 :   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   1827037686 : use_info::has_use_links ()
     173              : {
     174   1827037686 :   return (m_last_use_or_prev_use
     175   1827037686 :           || m_last_nondebug_insn_use_or_next_use
     176   3654075372 :           || m_is_last_nondebug_insn_use);
     177              : }
     178              : 
     179              : // Construct a definition of RESOURCE in INSN, giving it kind KIND.
     180    725402284 : inline def_info::def_info (insn_info *insn, resource_info resource,
     181    725402284 :                            access_kind kind)
     182              :   : access_info (resource, kind),
     183    725402284 :     m_insn (insn),
     184    725402284 :     m_last_def_or_prev_def (nullptr),
     185    725402284 :     m_splay_root_or_next_def (nullptr)
     186              : {
     187    725402284 :   m_is_artificial = insn->is_artificial ();
     188    725402284 : }
     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    486486560 : def_info::record_reference (rtx_obj_reference ref, bool is_first)
     196              : {
     197    486486560 :   if (is_first)
     198              :     {
     199    471294204 :       m_is_pre_post_modify = ref.is_pre_post_modify ();
     200    471294204 :       m_includes_read_writes = ref.is_read ();
     201    471294204 :       m_includes_subregs = ref.in_subreg ();
     202    471294204 :       m_includes_multiregs = ref.is_multireg ();
     203              :     }
     204              :   else
     205              :     {
     206     15192356 :       m_is_pre_post_modify |= ref.is_pre_post_modify ();
     207     15192356 :       m_includes_read_writes |= ref.is_read ();
     208     15192356 :       m_includes_subregs |= ref.in_subreg ();
     209     15192356 :       m_includes_multiregs |= ref.is_multireg ();
     210              :     }
     211    486486560 : }
     212              : 
     213              : // Return the last definition in the list.  Only valid when is_first ()
     214              : // is true.
     215              : inline def_info *
     216    629998227 : def_info::last_def () const
     217              : {
     218    629998227 :   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    566170554 : def_info::splay_root () const
     226              : {
     227    566170554 :   return m_splay_root_or_next_def.known_first ();
     228              : }
     229              : 
     230              : // Copy the overloaded prev link from OTHER.
     231              : inline void
     232      7474480 : def_info::copy_prev_from (def_info *other)
     233              : {
     234      7474480 :   m_last_def_or_prev_def
     235       382438 :     = other->m_last_def_or_prev_def;
     236      7092042 : }
     237              : 
     238              : // Copy the overloaded next link from OTHER.
     239              : inline void
     240    141954124 : def_info::copy_next_from (def_info *other)
     241              : {
     242    127800998 :   m_splay_root_or_next_def = other->m_splay_root_or_next_def;
     243     14153126 : }
     244              : 
     245              : // Record that this definition is the first in the list and that the last
     246              : // definition is LAST.
     247              : inline void
     248    730424480 : def_info::set_last_def (def_info *last_def)
     249              : {
     250    730424480 :   m_last_def_or_prev_def.set_first (last_def);
     251    557264644 : }
     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    551563762 : def_info::set_prev_def (def_info *prev_def)
     257              : {
     258    551563762 :   m_last_def_or_prev_def.set_second (prev_def);
     259       651673 : }
     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      2700358 : def_info::set_splay_root (def_node *root)
     265              : {
     266      2700358 :   m_splay_root_or_next_def = root;
     267        98850 : }
     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    551382488 : def_info::set_next_def (def_info *next_def)
     273              : {
     274    551066401 :   m_splay_root_or_next_def = next_def;
     275       470399 : }
     276              : 
     277              : // Clear the prev and next links
     278              : inline void
     279     15969935 : def_info::clear_def_links ()
     280              : {
     281      1670695 :   m_last_def_or_prev_def = nullptr;
     282      1670695 :   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    852255361 : def_info::has_def_links ()
     289              : {
     290    852255361 :   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    146957138 : inline clobber_info::clobber_info (insn_info *insn, unsigned int regno)
     295              :   : def_info (insn, { E_BLKmode, regno }, access_kind::CLOBBER),
     296    146957138 :     m_children (),
     297    146957138 :     m_parent (nullptr),
     298    146957138 :     m_group (nullptr)
     299              : {
     300    146957138 : }
     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      1135852 : clobber_info::update_group (clobber_group *group)
     306              : {
     307      1135852 :   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    578445146 : inline set_info::set_info (insn_info *insn, resource_info resource,
     314    578445146 :                            access_kind kind)
     315              :   : def_info (insn, resource, kind),
     316   1156890292 :     m_first_use (nullptr)
     317              : {
     318              : }
     319              : 
     320              : // Cconstruct a set_info for a store to RESOURCE in INSN.
     321    451012238 : inline set_info::set_info (insn_info *insn, resource_info resource)
     322    451012238 :   : set_info (insn, resource, access_kind::SET)
     323              : {
     324    451012238 : }
     325              : 
     326              : // Record that USE is the first use of this definition.
     327              : inline void
     328    579492423 : set_info::set_first_use (use_info *first_use)
     329              : {
     330    579492423 :   m_first_use = first_use;
     331    553146122 :   m_is_set_with_nondebug_insn_uses
     332    667479190 :     = (first_use && first_use->is_in_nondebug_insn ());
     333     48128847 : }
     334              : 
     335              : // Construct a phi for RESOURCE in INSN, giving it identifier UID.
     336    127432908 : inline phi_info::phi_info (insn_info *insn, resource_info resource,
     337    127432908 :                            unsigned int uid)
     338              :   : set_info (insn, resource, access_kind::PHI),
     339    127432908 :     m_uid (uid),
     340    127432908 :     m_num_inputs (0),
     341    127432908 :     m_prev_phi (nullptr),
     342    127432908 :     m_next_phi (nullptr)
     343              : {
     344    127432908 : }
     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      2141134 : phi_info::make_degenerate (use_info *input)
     350              : {
     351      2141134 :   m_num_inputs = 1;
     352      2141134 :   m_single_input = input;
     353      1961666 : }
     354              : 
     355              : // Set the inputs of the phi to INPUTS.
     356              : inline void
     357    127253440 : phi_info::set_inputs (use_array inputs)
     358              : {
     359    127253440 :   m_num_inputs = inputs.size ();
     360    127253440 :   if (inputs.size () == 1)
     361     88224952 :     m_single_input = inputs[0];
     362              :   else
     363     39028488 :     m_inputs = access_array (inputs).begin ();
     364    127253440 : }
     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     37074845 : inline def_node::def_node (clobber_or_set first_def)
     369     37074845 :   : m_clobber_or_set (first_def),
     370     37074845 :     m_children ()
     371              : {
     372              : }
     373              : 
     374              : // Construct a new group of clobber_infos that initially contains just CLOBBER.
     375     20535397 : inline clobber_group::clobber_group (clobber_info *clobber)
     376     20535397 :   : def_node (clobber),
     377     20535397 :     m_last_clobber (clobber),
     378     20535397 :     m_clobber_tree (clobber)
     379              : {
     380     20535397 :   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         1783 : inline insn_info::order_node::order_node (int uid)
     399              :   : insn_note (kind),
     400         1783 :     m_children (),
     401         1783 :     m_parent (nullptr)
     402              : {
     403         1783 :   m_data32 = uid;
     404              : }
     405              : 
     406              : // Construct a note for instruction INSN, giving it abi_id () value ABI_ID.
     407     30289691 : inline insn_call_clobbers_note::insn_call_clobbers_note (unsigned int abi_id,
     408     30289691 :                                                          insn_info *insn)
     409              :   : insn_note (kind),
     410     30289691 :     m_children (),
     411     30289691 :     m_insn (insn)
     412              : {
     413     30289691 :   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   1003541413 : inline insn_info::insn_info (bb_info *bb, rtx_insn *rtl, int cost_or_uid)
     420   1003516843 :   : m_prev_sametype_or_last_debug_insn (nullptr),
     421   1003541413 :     m_next_nondebug_or_debug_insn (nullptr),
     422   1003541413 :     m_bb (bb),
     423   1003541413 :     m_rtl (rtl),
     424   1003541413 :     m_accesses (nullptr),
     425   1003541413 :     m_num_uses (0),
     426   1003541413 :     m_num_defs (0),
     427   1003516843 :     m_is_debug_insn (rtl && DEBUG_INSN_P (rtl)),
     428   1003541413 :     m_can_be_optimized (false),
     429   1003541413 :     m_is_asm (false),
     430   1003541413 :     m_has_pre_post_modify (false),
     431   1003541413 :     m_has_volatile_refs (false),
     432   1003541413 :     m_is_temp (false),
     433   1003541413 :     m_spare (0),
     434   1003541413 :     m_point (0),
     435   1003541413 :     m_cost_or_uid (cost_or_uid),
     436   1003541413 :     m_first_note (nullptr)
     437              : {
     438   1003516843 : }
     439              : 
     440              : // Copy any insn properties from PROPERTIES that are also stored in an
     441              : // insn_info.
     442              : inline void
     443    790771031 : insn_info::set_properties (const rtx_properties &properties)
     444              : {
     445    790771031 :   m_is_asm = properties.has_asm;
     446    790771031 :   m_has_pre_post_modify = properties.has_pre_post_modify;
     447    790771031 :   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    790771031 :   m_can_be_optimized = (NONDEBUG_INSN_P (m_rtl)
     451    790771031 :                         & (GET_CODE (PATTERN (m_rtl)) != USE)
     452    790771031 :                         & (GET_CODE (PATTERN (m_rtl)) != CLOBBER));
     453    790771031 : }
     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    944179977 : insn_info::set_accesses (access_info **accesses,
     459              :                          unsigned int num_defs, unsigned int num_uses)
     460              : {
     461    944179977 :   m_accesses = accesses;
     462    944179977 :   m_num_defs = num_defs;
     463    944179977 :   gcc_assert (num_defs == m_num_defs);
     464    944179977 :   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     18345695 : insn_info::copy_accesses (access_array defs, access_array uses)
     471              : {
     472     18345695 :   gcc_assert (defs.size () + uses.size () <= m_num_defs + m_num_uses);
     473     18345695 :   memcpy (m_accesses, defs.begin (), defs.size_bytes ());
     474     18345695 :   memcpy (m_accesses + defs.size (), uses.begin (), uses.size_bytes ());
     475     18345695 :   m_num_defs = defs.size ();
     476     18345695 :   gcc_assert (m_num_defs == defs.size ());
     477     18345695 :   m_num_uses = uses.size ();
     478     18345695 : }
     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      2238616 : insn_info::get_order_node () const
     484              : {
     485              :   // The order_node always comes first.
     486      2238616 :   if (insn_note *note = first_note ())
     487      2215281 :     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         1708 : insn_info::get_known_order_node () const
     494              : {
     495              :   // The order_node always comes first.
     496          854 :   return first_note ()->as_a<insn_info::order_node *> ();
     497              : }
     498              : 
     499              : // Copy the overloaded prev link from OTHER.
     500              : inline void
     501        46116 : insn_info::copy_prev_from (insn_info *other)
     502              : {
     503        46116 :   m_prev_sametype_or_last_debug_insn
     504        46116 :     = other->m_prev_sametype_or_last_debug_insn;
     505              : }
     506              : 
     507              : // Copy the overloaded next link from OTHER.
     508              : inline void
     509    996569800 : insn_info::copy_next_from (insn_info *other)
     510              : {
     511    996569800 :   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   1535801934 : insn_info::set_prev_sametype_insn (insn_info *prev)
     521              : {
     522   1535801934 :   m_prev_sametype_or_last_debug_insn.set_first (prev);
     523    896934188 : }
     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    359920854 : insn_info::set_last_debug_insn (insn_info *last)
     529              : {
     530    359920854 :   m_prev_sametype_or_last_debug_insn.set_second (last);
     531    359920854 : }
     532              : 
     533              : // Record that the next instruction of any kind is NEXT.
     534              : inline void
     535    998781996 : insn_info::set_next_any_insn (insn_info *next)
     536              : {
     537    998781996 :   if (next && next->is_debug_insn ())
     538    360363588 :     m_next_nondebug_or_debug_insn.set_second (next);
     539              :   else
     540    638418408 :     m_next_nondebug_or_debug_insn.set_first (next);
     541    998781996 : }
     542              : 
     543              : // Clear the list links and point number for this instruction.
     544              : inline void
     545      2236766 : insn_info::clear_insn_links ()
     546              : {
     547      2236766 :   m_prev_sametype_or_last_debug_insn = nullptr;
     548      2236766 :   m_next_nondebug_or_debug_insn = nullptr;
     549      2236766 :   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   2000086643 : insn_info::has_insn_links ()
     556              : {
     557    996569800 :   return (m_prev_sametype_or_last_debug_insn
     558   2000086643 :           || m_next_nondebug_or_debug_insn
     559   4000173286 :           || m_point);
     560              : }
     561              : 
     562              : // Construct a representation of basic block CFG_BB.
     563     88466817 : inline bb_info::bb_info (basic_block cfg_bb)
     564     88466817 :   : m_prev_bb (nullptr),
     565     88466817 :     m_next_bb (nullptr),
     566     88466817 :     m_cfg_bb (cfg_bb),
     567     88466817 :     m_ebb (nullptr),
     568     88466817 :     m_head_insn (nullptr),
     569     88466817 :     m_end_insn (nullptr)
     570              : {
     571              : }
     572              : 
     573              : // Construct a tree of call clobbers for the given ABI.
     574     17776827 : inline ebb_call_clobbers_info::
     575     17776827 : ebb_call_clobbers_info (const predefined_function_abi *abi)
     576     17776827 :   : m_next (nullptr),
     577     17776827 :     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     54445376 : inline ebb_info::ebb_info (bb_info *first_bb, bb_info *last_bb)
     584     54445376 :   : m_first_phi (nullptr),
     585     54445376 :     m_phi_insn (nullptr),
     586     54445376 :     m_first_bb (first_bb),
     587     54445376 :     m_last_bb (last_bb),
     588     54445376 :     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    667526481 : function_info::build_info::record_reg_def (def_info *def)
     596              : {
     597    667526481 :   unsigned int regno = def->regno ();
     598    667526481 :   auto *prev_dominating_def = safe_as_a<def_info *> (last_access[regno + 1]);
     599    667526481 :   if (!prev_dominating_def)
     600              :     // Indicate that DEF is the first dominating definition of REGNO.
     601    190818705 :     def_stack.safe_push (def);
     602    476707776 :   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    222028082 :     def_stack.safe_push (prev_dominating_def);
     606    667526481 :   last_access[regno + 1] = def;
     607    667526481 : }
     608              : 
     609              : // Set the contents of last_access for memory to DEF.
     610              : inline void
     611     55592203 : function_info::build_info::record_mem_def (def_info *def)
     612              : {
     613     55592203 :   last_access[0] = def;
     614      1332045 : }
     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   1107156583 : function_info::build_info::current_reg_value (unsigned int regno) const
     620              : {
     621   1107156583 :   return safe_dyn_cast<set_info *> (last_access[regno + 1]);
     622              : }
     623              : 
     624              : // Return the current value of memory.
     625              : inline set_info *
     626     98630673 : function_info::build_info::current_mem_value () const
     627              : {
     628     98630673 :   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   3202737880 : 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   3202737880 :   void *addr = obstack_alloc (&m_obstack, sizeof (T));
     642   3202737880 :   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     10348597 : 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     10348597 :   void *addr = obstack_alloc (&m_temp_obstack, sizeof (T));
     656     10348597 :   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   1003516843 : function_info::append_insn (insn_info *insn)
     662              : {
     663   1003516843 :   gcc_checking_assert (!insn->has_insn_links ());
     664   1003516843 :   if (insn_info *after = m_last_insn)
     665    996520660 :     add_insn_after (insn, after);
     666              :   else
     667              :     // The first instruction is for the entry block and is always a nondebug
     668              :     // insn
     669      6996183 :     m_first_insn = m_last_insn = m_last_nondebug_insn = insn;
     670   1003516843 : }
     671              : 
     672              : // Start building a new list of uses and definitions for an instruction.
     673              : inline void
     674    941704848 : function_info::start_insn_accesses ()
     675              : {
     676   1876413513 :   gcc_checking_assert (m_temp_defs.is_empty ()
     677              :                        && m_temp_uses.is_empty ());
     678    941704848 : }
     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    317519983 : combine_modes (machine_mode mode1, machine_mode mode2)
     685              : {
     686    317519983 :   if (mode1 == E_BLKmode)
     687              :     return mode2;
     688              : 
     689    134878200 :   if (mode2 == E_BLKmode)
     690              :     return mode1;
     691              : 
     692    134877688 :   if (!ordered_p (GET_MODE_SIZE (mode1), GET_MODE_SIZE (mode2)))
     693              :     return BLKmode;
     694              : 
     695    134877688 :   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.