LCOV - code coverage report
Current view: top level - gcc/rtl-ssa - internals.inl (source / functions) Coverage Total Hit
Test: gcc.info Lines: 95.1 % 286 272
Test Date: 2026-08-22 16:33:35 Functions: 72.2 % 54 39
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   1971155133 : inline access_info::access_info (resource_info resource, access_kind kind)
      24   1971155133 :   : m_regno (resource.regno),
      25   1971155133 :     m_mode (resource.mode),
      26   1971155133 :     m_kind (kind),
      27              :     m_is_artificial (false),
      28   1971155133 :     m_is_set_with_nondebug_insn_uses (false),
      29   1971155133 :     m_is_pre_post_modify (false),
      30   1971155133 :     m_is_call_clobber (false),
      31   1971155133 :     m_is_live_out_use (false),
      32   1971155133 :     m_includes_address_uses (false),
      33   1971155133 :     m_includes_read_writes (false),
      34   1971155133 :     m_includes_subregs (false),
      35   1971155133 :     m_includes_multiregs (false),
      36   1971155133 :     m_only_occurs_in_notes (false),
      37   1971155133 :     m_is_last_nondebug_insn_use (false),
      38    730646335 :     m_is_in_debug_insn_or_phi (false),
      39   1971155133 :     m_has_been_superceded (false),
      40   1971155133 :     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   1240508798 : inline use_info::use_info (insn_or_phi location, resource_info resource,
      47              :                            set_info *definition)
      48              :   : access_info (resource, access_kind::USE),
      49   1240508798 :     m_insn_or_phi (location),
      50   1240508798 :     m_last_use_or_prev_use (nullptr),
      51   1240508798 :     m_last_nondebug_insn_use_or_next_use (nullptr),
      52   1240508798 :     m_def (definition)
      53              : {
      54   1240508798 :   if (m_insn_or_phi.is_second ())
      55              :     {
      56    196062665 :       m_is_in_debug_insn_or_phi = true;
      57    196062665 :       m_is_artificial = true;
      58              :     }
      59              :   else
      60              :     {
      61   1044446133 :       insn_info *insn = m_insn_or_phi.known_first ();
      62   1044446133 :       m_is_in_debug_insn_or_phi = insn->is_debug_insn ();
      63   1044446133 :       m_is_artificial = insn->is_artificial ();
      64              :     }
      65   1240508798 : }
      66              : 
      67              : // Return the correct (uncached) value of m_is_last_nondebug_insn_use.
      68              : inline bool
      69   3204917287 : use_info::calculate_is_last_nondebug_insn_use () const
      70              : {
      71   3204917287 :   use_info *next = next_use ();
      72   3204917287 :   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    780927191 : use_info::record_reference (rtx_obj_reference ref, bool is_first)
      81              : {
      82    780927191 :   if (is_first)
      83              :     {
      84    703420700 :       m_includes_address_uses = ref.in_address ();
      85    703420700 :       m_includes_read_writes = ref.is_write ();
      86    703420700 :       m_includes_subregs = ref.in_subreg ();
      87    703420700 :       m_includes_multiregs = ref.is_multireg ();
      88    703420700 :       m_only_occurs_in_notes = ref.in_note ();
      89              :     }
      90              :   else
      91              :     {
      92     77506491 :       m_includes_address_uses |= ref.in_address ();
      93     77506491 :       m_includes_read_writes |= ref.is_write ();
      94     77506491 :       m_includes_subregs |= ref.in_subreg ();
      95     77506491 :       m_includes_multiregs |= ref.is_multireg ();
      96     77506491 :       m_only_occurs_in_notes &= ref.in_note ();
      97              :     }
      98    780927191 : }
      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     41176619 : use_info::copy_prev_from (use_info *other)
     111              : {
     112     41176619 :   m_last_use_or_prev_use = other->m_last_use_or_prev_use;
     113              : }
     114              : 
     115              : // Copy the overloaded next link from OTHER.
     116              : inline void
     117    693633761 : use_info::copy_next_from (use_info *other)
     118              : {
     119    693633761 :   m_last_nondebug_insn_use_or_next_use
     120    693633761 :     = other->m_last_nondebug_insn_use_or_next_use;
     121    693633761 :   m_is_last_nondebug_insn_use = calculate_is_last_nondebug_insn_use ();
     122              : }
     123              : 
     124              : // Record that this use is the first in the list and that the last use is LAST.
     125              : inline void
     126   1141483885 : use_info::set_last_use (use_info *last_use)
     127              : {
     128   1141483885 :   m_last_use_or_prev_use.set_first (last_use);
     129              : }
     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    793628479 : use_info::set_prev_use (use_info *prev_use)
     135              : {
     136    793628479 :   m_last_use_or_prev_use.set_second (prev_use);
     137              : }
     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    957020692 : use_info::set_last_nondebug_insn_use (use_info *use)
     145              : {
     146    957020692 :   m_last_nondebug_insn_use_or_next_use.set_first (use);
     147    957020692 :   m_is_last_nondebug_insn_use = (use == this);
     148              : }
     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    698424784 : use_info::set_next_use (use_info *next_use)
     154              : {
     155    698424784 :   m_last_nondebug_insn_use_or_next_use.set_second (next_use);
     156    698424784 :   m_is_last_nondebug_insn_use = calculate_is_last_nondebug_insn_use ();
     157    698424784 : }
     158              : 
     159              : // Clear any information relating to the position of the use in its
     160              : // definition's list.
     161              : inline void
     162     49270785 : use_info::clear_use_links ()
     163              : {
     164     49270785 :   m_last_use_or_prev_use = nullptr;
     165     49270785 :   m_last_nondebug_insn_use_or_next_use = nullptr;
     166     49270785 :   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   1845889709 : use_info::has_use_links ()
     173              : {
     174   1845889709 :   return (m_last_use_or_prev_use
     175   1845889709 :           || m_last_nondebug_insn_use_or_next_use
     176   3691779418 :           || m_is_last_nondebug_insn_use);
     177              : }
     178              : 
     179              : // Construct a definition of RESOURCE in INSN, giving it kind KIND.
     180    730646335 : inline def_info::def_info (insn_info *insn, resource_info resource,
     181              :                            access_kind kind)
     182              :   : access_info (resource, kind),
     183    730646335 :     m_insn (insn),
     184    730646335 :     m_last_def_or_prev_def (nullptr),
     185    730646335 :     m_splay_root_or_next_def (nullptr)
     186              : {
     187    730646335 :   m_is_artificial = insn->is_artificial ();
     188    730646335 : }
     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    490370857 : def_info::record_reference (rtx_obj_reference ref, bool is_first)
     196              : {
     197     15199722 :   if (is_first)
     198              :     {
     199    475171135 :       m_is_pre_post_modify = ref.is_pre_post_modify ();
     200    475171135 :       m_includes_read_writes = ref.is_read ();
     201    475171135 :       m_includes_subregs = ref.in_subreg ();
     202    475171135 :       m_includes_multiregs = ref.is_multireg ();
     203              :     }
     204              :   else
     205              :     {
     206     15199722 :       m_is_pre_post_modify |= ref.is_pre_post_modify ();
     207     15199722 :       m_includes_read_writes |= ref.is_read ();
     208     15199722 :       m_includes_subregs |= ref.in_subreg ();
     209     15199722 :       m_includes_multiregs |= ref.is_multireg ();
     210              :     }
     211     15199722 : }
     212              : 
     213              : // Return the last definition in the list.  Only valid when is_first ()
     214              : // is true.
     215              : inline def_info *
     216    634271266 : def_info::last_def () const
     217              : {
     218    634271266 :   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    570301832 : def_info::splay_root () const
     226              : {
     227    570301832 :   return m_splay_root_or_next_def.known_first ();
     228              : }
     229              : 
     230              : // Copy the overloaded prev link from OTHER.
     231              : inline void
     232      7591004 : def_info::copy_prev_from (def_info *other)
     233              : {
     234      7591004 :   m_last_def_or_prev_def
     235      7591004 :     = other->m_last_def_or_prev_def;
     236              : }
     237              : 
     238              : // Copy the overloaded next link from OTHER.
     239              : inline void
     240    143163726 : def_info::copy_next_from (def_info *other)
     241              : {
     242    143163726 :   m_splay_root_or_next_def = other->m_splay_root_or_next_def;
     243              : }
     244              : 
     245              : // Record that this definition is the first in the list and that the last
     246              : // definition is LAST.
     247              : inline void
     248    735703443 : def_info::set_last_def (def_info *last_def)
     249              : {
     250    735703443 :   m_last_def_or_prev_def.set_first (last_def);
     251              : }
     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    555583557 : def_info::set_prev_def (def_info *prev_def)
     257              : {
     258    555096259 :   m_last_def_or_prev_def.set_second (prev_def);
     259              : }
     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      2744346 : def_info::set_splay_root (def_node *root)
     265              : {
     266      2744346 :   m_splay_root_or_next_def = root;
     267              : }
     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    555399492 : def_info::set_next_def (def_info *next_def)
     273              : {
     274    555071080 :   m_splay_root_or_next_def = next_def;
     275              : }
     276              : 
     277              : // Clear the prev and next links
     278              : inline void
     279     16133732 : def_info::clear_def_links ()
     280              : {
     281      1689051 :   m_last_def_or_prev_def = nullptr;
     282      1689051 :   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    858598190 : def_info::has_def_links ()
     289              : {
     290    858598190 :   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    147531317 : inline clobber_info::clobber_info (insn_info *insn, unsigned int regno)
     295              :   : def_info (insn, { E_BLKmode, regno }, access_kind::CLOBBER),
     296    147531317 :     m_children (),
     297    147531317 :     m_parent (nullptr),
     298    147531317 :     m_group (nullptr)
     299              : {
     300    147531317 : }
     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      1173399 : clobber_info::update_group (clobber_group *group)
     306              : {
     307      1173399 :   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    583115018 : inline set_info::set_info (insn_info *insn, resource_info resource,
     314              :                            access_kind kind)
     315              :   : def_info (insn, resource, kind),
     316    830310391 :     m_first_use (nullptr)
     317              : {
     318              : }
     319              : 
     320              : // Cconstruct a set_info for a store to RESOURCE in INSN.
     321    454630856 : inline set_info::set_info (insn_info *insn, resource_info resource)
     322    454630856 :   : set_info (insn, resource, access_kind::SET)
     323              : {
     324              : }
     325              : 
     326              : // Record that USE is the first use of this definition.
     327              : inline void
     328    584230438 : set_info::set_first_use (use_info *first_use)
     329              : {
     330    584230438 :   m_first_use = first_use;
     331    557650907 :   m_is_set_with_nondebug_insn_uses
     332    672832978 :     = (first_use && first_use->is_in_nondebug_insn ());
     333              : }
     334              : 
     335              : // Construct a phi for RESOURCE in INSN, giving it identifier UID.
     336    128484162 : inline phi_info::phi_info (insn_info *insn, resource_info resource,
     337              :                            unsigned int uid)
     338              :   : set_info (insn, resource, access_kind::PHI),
     339    128484162 :     m_uid (uid),
     340    128484162 :     m_num_inputs (0),
     341    128484162 :     m_prev_phi (nullptr),
     342      7463059 :     m_next_phi (nullptr)
     343              : {
     344              : }
     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      2145679 : phi_info::make_degenerate (use_info *input)
     350              : {
     351      2145679 :   m_num_inputs = 1;
     352      2145679 :   m_single_input = input;
     353              : }
     354              : 
     355              : // Set the inputs of the phi to INPUTS.
     356              : inline void
     357    128303460 : phi_info::set_inputs (use_array inputs)
     358              : {
     359    128303460 :   m_num_inputs = inputs.size ();
     360    128303460 :   if (inputs.size () == 1)
     361     88738923 :     m_single_input = inputs[0];
     362              :   else
     363     39564537 :     m_inputs = access_array (inputs).begin ();
     364    128303460 : }
     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     37547868 : inline def_node::def_node (clobber_or_set first_def)
     369     37547868 :   : m_clobber_or_set (first_def),
     370     37547868 :     m_children ()
     371              : {
     372              : }
     373              : 
     374              : // Construct a new group of clobber_infos that initially contains just CLOBBER.
     375     20706068 : inline clobber_group::clobber_group (clobber_info *clobber)
     376     20706068 :   : def_node (clobber),
     377     20706068 :     m_last_clobber (clobber),
     378     20706068 :     m_clobber_tree (clobber)
     379              : {
     380     20706068 :   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              :                                      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         1744 : inline insn_info::order_node::order_node (int uid)
     399              :   : insn_note (kind),
     400         1744 :     m_children (),
     401         1744 :     m_parent (nullptr)
     402              : {
     403         1744 :   m_data32 = uid;
     404              : }
     405              : 
     406              : // Construct a note for instruction INSN, giving it abi_id () value ABI_ID.
     407     30492540 : inline insn_call_clobbers_note::insn_call_clobbers_note (unsigned int abi_id,
     408              :                                                          insn_info *insn)
     409              :   : insn_note (kind),
     410     30492540 :     m_children (),
     411     30492540 :     m_insn (insn)
     412              : {
     413     30492540 :   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   1020749296 : inline insn_info::insn_info (bb_info *bb, rtx_insn *rtl, int cost_or_uid)
     420   1020725870 :   : m_prev_sametype_or_last_debug_insn (nullptr),
     421   1020749296 :     m_next_nondebug_or_debug_insn (nullptr),
     422   1020749296 :     m_bb (bb),
     423   1020749296 :     m_rtl (rtl),
     424   1020749296 :     m_accesses (nullptr),
     425   1020749296 :     m_num_uses (0),
     426   1020749296 :     m_num_defs (0),
     427   1020725870 :     m_is_debug_insn (rtl && DEBUG_INSN_P (rtl)),
     428   1020749296 :     m_can_be_optimized (false),
     429   1020749296 :     m_is_asm (false),
     430   1020749296 :     m_has_pre_post_modify (false),
     431   1020749296 :     m_has_volatile_refs (false),
     432   1020749296 :     m_is_temp (false),
     433   1020749296 :     m_spare (0),
     434   1020749296 :     m_point (0),
     435   1020749296 :     m_cost_or_uid (cost_or_uid),
     436   1020749296 :     m_first_note (nullptr)
     437              : {
     438   1020725870 : }
     439              : 
     440              : // Copy any insn properties from PROPERTIES that are also stored in an
     441              : // insn_info.
     442              : inline void
     443    806457350 : insn_info::set_properties (const rtx_properties &properties)
     444              : {
     445    806457350 :   m_is_asm = properties.has_asm;
     446    806457350 :   m_has_pre_post_modify = properties.has_pre_post_modify;
     447    806457350 :   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    806457350 :   m_can_be_optimized = (NONDEBUG_INSN_P (m_rtl)
     451    806457350 :                         & (GET_CODE (PATTERN (m_rtl)) != USE)
     452    806457350 :                         & (GET_CODE (PATTERN (m_rtl)) != CLOBBER));
     453    806457350 : }
     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    960988497 : insn_info::set_accesses (access_info **accesses,
     459              :                          unsigned int num_defs, unsigned int num_uses)
     460              : {
     461    960988497 :   m_accesses = accesses;
     462    960988497 :   m_num_defs = num_defs;
     463    960988497 :   gcc_assert (num_defs == m_num_defs);
     464    960988497 :   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     18517973 : insn_info::copy_accesses (access_array defs, access_array uses)
     471              : {
     472     18517973 :   gcc_assert (defs.size () + uses.size () <= m_num_defs + m_num_uses);
     473     18517973 :   memcpy (m_accesses, defs.begin (), defs.size_bytes ());
     474     18517973 :   memcpy (m_accesses + defs.size (), uses.begin (), uses.size_bytes ());
     475     18517973 :   m_num_defs = defs.size ();
     476     18517973 :   gcc_assert (m_num_defs == defs.size ());
     477     18517973 :   m_num_uses = uses.size ();
     478     18517973 : }
     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      2265398 : insn_info::get_order_node () const
     484              : {
     485              :   // The order_node always comes first.
     486      2265398 :   if (insn_note *note = first_note ())
     487      2243185 :     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         1536 : insn_info::get_known_order_node () const
     494              : {
     495              :   // The order_node always comes first.
     496          768 :   return first_note ()->as_a<insn_info::order_node *> ();
     497              : }
     498              : 
     499              : // Copy the overloaded prev link from OTHER.
     500              : inline void
     501        43932 : insn_info::copy_prev_from (insn_info *other)
     502              : {
     503        43932 :   m_prev_sametype_or_last_debug_insn
     504        43932 :     = other->m_prev_sametype_or_last_debug_insn;
     505              : }
     506              : 
     507              : // Copy the overloaded next link from OTHER.
     508              : inline void
     509   1013741826 : insn_info::copy_next_from (insn_info *other)
     510              : {
     511   1013741826 :   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   1556743682 : insn_info::set_prev_sametype_insn (insn_info *prev)
     521              : {
     522   1556743682 :   m_prev_sametype_or_last_debug_insn.set_first (prev);
     523              : }
     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    371954464 : insn_info::set_last_debug_insn (insn_info *last)
     529              : {
     530    371954464 :   m_prev_sametype_or_last_debug_insn.set_second (last);
     531              : }
     532              : 
     533              : // Record that the next instruction of any kind is NEXT.
     534              : inline void
     535   1015982006 : insn_info::set_next_any_insn (insn_info *next)
     536              : {
     537   1015982006 :   if (next && next->is_debug_insn ())
     538    372400019 :     m_next_nondebug_or_debug_insn.set_second (next);
     539              :   else
     540    643581987 :     m_next_nondebug_or_debug_insn.set_first (next);
     541   1015982006 : }
     542              : 
     543              : // Clear the list links and point number for this instruction.
     544              : inline void
     545      2263606 : insn_info::clear_insn_links ()
     546              : {
     547      2263606 :   m_prev_sametype_or_last_debug_insn = nullptr;
     548      2263606 :   m_next_nondebug_or_debug_insn = nullptr;
     549      2263606 :   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   2034467696 : insn_info::has_insn_links ()
     556              : {
     557   1013741826 :   return (m_prev_sametype_or_last_debug_insn
     558   2034467696 :           || m_next_nondebug_or_debug_insn
     559   4068935392 :           || m_point);
     560              : }
     561              : 
     562              : // Construct a representation of basic block CFG_BB.
     563     89117269 : inline bb_info::bb_info (basic_block cfg_bb)
     564     89117269 :   : m_prev_bb (nullptr),
     565     89117269 :     m_next_bb (nullptr),
     566     89117269 :     m_cfg_bb (cfg_bb),
     567     89117269 :     m_ebb (nullptr),
     568     89117269 :     m_head_insn (nullptr),
     569     89117269 :     m_end_insn (nullptr)
     570              : {
     571              : }
     572              : 
     573              : // Construct a tree of call clobbers for the given ABI.
     574     17906259 : inline ebb_call_clobbers_info::
     575              : ebb_call_clobbers_info (const predefined_function_abi *abi)
     576     17906259 :   : m_next (nullptr),
     577     17906259 :     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     54847634 : inline ebb_info::ebb_info (bb_info *first_bb, bb_info *last_bb)
     584     54847634 :   : m_first_phi (nullptr),
     585     54847634 :     m_phi_insn (nullptr),
     586     54847634 :     m_first_bb (first_bb),
     587     54847634 :     m_last_bb (last_bb),
     588     54847634 :     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    672341099 : function_info::build_info::record_reg_def (def_info *def)
     596              : {
     597    672341099 :   unsigned int regno = def->regno ();
     598    672341099 :   auto *prev_dominating_def = safe_as_a<def_info *> (last_access[regno + 1]);
     599    672341099 :   if (!prev_dominating_def)
     600              :     // Indicate that DEF is the first dominating definition of REGNO.
     601    192434436 :     def_stack.safe_push (def);
     602    479906663 :   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    223883436 :     def_stack.safe_push (prev_dominating_def);
     606    672341099 :   last_access[regno + 1] = def;
     607    672341099 : }
     608              : 
     609              : // Set the contents of last_access for memory to DEF.
     610              : inline void
     611     56014759 : function_info::build_info::record_mem_def (def_info *def)
     612              : {
     613     56014759 :   last_access[0] = def;
     614              : }
     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   1117996191 : function_info::build_info::current_reg_value (unsigned int regno) const
     620              : {
     621   1117996191 :   return safe_dyn_cast<set_info *> (last_access[regno + 1]);
     622              : }
     623              : 
     624              : // Return the current value of memory.
     625              : inline set_info *
     626     99334796 : function_info::build_info::current_mem_value () const
     627              : {
     628     99334796 :   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   3239855138 : 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   3239855138 :   void *addr = obstack_alloc (&m_obstack, sizeof (T));
     642   3239855138 :   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     10447080 : 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     10447080 :   void *addr = obstack_alloc (&m_temp_obstack, sizeof (T));
     656     10447080 :   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   1020725870 : function_info::append_insn (insn_info *insn)
     662              : {
     663   1020725870 :   gcc_checking_assert (!insn->has_insn_links ());
     664   1020725870 :   if (insn_info *after = m_last_insn)
     665   1013694974 :     add_insn_after (insn, after);
     666              :   else
     667              :     // The first instruction is for the entry block and is always a nondebug
     668              :     // insn
     669      7030896 :     m_first_insn = m_last_insn = m_last_nondebug_insn = insn;
     670   1020725870 : }
     671              : 
     672              : // Start building a new list of uses and definitions for an instruction.
     673              : inline void
     674    958476064 : function_info::start_insn_accesses ()
     675              : {
     676   1909921232 :   gcc_checking_assert (m_temp_defs.is_empty ()
     677              :                        && m_temp_uses.is_empty ());
     678    958476064 : }
     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    320473065 : combine_modes (machine_mode mode1, machine_mode mode2)
     685              : {
     686    320473065 :   if (mode1 == E_BLKmode)
     687              :     return mode2;
     688              : 
     689    136284429 :   if (mode2 == E_BLKmode)
     690              :     return mode1;
     691              : 
     692    136283925 :   if (!ordered_p (GET_MODE_SIZE (mode1), GET_MODE_SIZE (mode2)))
     693              :     return BLKmode;
     694              : 
     695    136283925 :   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.