LCOV - code coverage report
Current view: top level - gcc/rtl-ssa - accesses.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 65.3 % 900 588
Test Date: 2025-09-20 13:40:47 Functions: 52.8 % 89 47
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : // Implementation of access-related functions for RTL SSA           -*- C++ -*-
       2                 :             : // Copyright (C) 2020-2025 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                 :             : #define INCLUDE_ALGORITHM
      21                 :             : #define INCLUDE_FUNCTIONAL
      22                 :             : #define INCLUDE_ARRAY
      23                 :             : #include "config.h"
      24                 :             : #include "system.h"
      25                 :             : #include "coretypes.h"
      26                 :             : #include "backend.h"
      27                 :             : #include "rtl.h"
      28                 :             : #include "df.h"
      29                 :             : #include "rtl-ssa.h"
      30                 :             : #include "rtl-ssa/internals.h"
      31                 :             : #include "rtl-ssa/internals.inl"
      32                 :             : 
      33                 :             : using namespace rtl_ssa;
      34                 :             : 
      35                 :             : // This clobber belongs to a clobber_group but m_group appears to be
      36                 :             : // out of date.  Update it and return the new (correct) value.
      37                 :             : clobber_group *
      38                 :        1761 : clobber_info::recompute_group ()
      39                 :             : {
      40                 :        1761 :   using splay_tree = clobber_info::splay_tree;
      41                 :             : 
      42                 :             :   // Splay this clobber to the root of the tree while searching for a node
      43                 :             :   // that has the correct group.  The root always has the correct group,
      44                 :             :   // so the search always breaks early and does not install this clobber
      45                 :             :   // as the root.
      46                 :        1761 :   clobber_info *cursor = m_parent;
      47                 :        4257 :   auto find_group = [](clobber_info *node, unsigned int)
      48                 :             :     {
      49                 :        2496 :       return node->m_group->has_been_superceded () ? nullptr : node->m_group;
      50                 :             :     };
      51                 :        1761 :   clobber_group *group = splay_tree::splay_and_search (this, nullptr,
      52                 :             :                                                        find_group);
      53                 :        1761 :   gcc_checking_assert (m_parent);
      54                 :             : 
      55                 :             :   // If the previous splay operation did anything, this clobber is now an
      56                 :             :   // ancestor of CURSOR, and all the nodes inbetween have a stale group.
      57                 :             :   // Since we have visited the nodes, we might as well update them too.
      58                 :             :   //
      59                 :             :   // If the previous splay operation did nothing, start the update from
      60                 :             :   // this clobber instead.  In that case we change at most two clobbers:
      61                 :             :   // this clobber and possibly its parent.
      62                 :        1761 :   if (cursor == m_parent)
      63                 :        1733 :     cursor = this;
      64                 :             : 
      65                 :             :   // Walk up the tree from CURSOR updating clobbers that need it.
      66                 :             :   // This walk always includes this clobber.
      67                 :        4220 :   while (cursor->m_group != group)
      68                 :             :     {
      69                 :        2459 :       cursor->m_group = group;
      70                 :        2459 :       cursor = cursor->m_parent;
      71                 :             :     }
      72                 :             : 
      73                 :        1761 :   gcc_checking_assert (m_group == group);
      74                 :        1761 :   return group;
      75                 :             : }
      76                 :             : 
      77                 :             : // See the comment above the declaration.
      78                 :             : void
      79                 :           0 : resource_info::print_identifier (pretty_printer *pp) const
      80                 :             : {
      81                 :           0 :   if (is_mem ())
      82                 :           0 :     pp_string (pp, "mem");
      83                 :             :   else
      84                 :             :     {
      85                 :           0 :       char tmp[3 * sizeof (regno) + 2];
      86                 :           0 :       snprintf (tmp, sizeof (tmp), "r%d", regno);
      87                 :           0 :       pp_string (pp, tmp);
      88                 :             :     }
      89                 :           0 : }
      90                 :             : 
      91                 :             : // See the comment above the declaration.
      92                 :             : void
      93                 :           0 : resource_info::print_context (pretty_printer *pp) const
      94                 :             : {
      95                 :           0 :   if (HARD_REGISTER_NUM_P (regno))
      96                 :             :     {
      97                 :           0 :       if (const char *name = reg_names[regno])
      98                 :             :         {
      99                 :           0 :           pp_space (pp);
     100                 :           0 :           pp_left_paren (pp);
     101                 :           0 :           pp_string (pp, name);
     102                 :           0 :           if (mode != E_BLKmode)
     103                 :             :             {
     104                 :           0 :               pp_colon (pp);
     105                 :           0 :               pp_string (pp, GET_MODE_NAME (mode));
     106                 :             :             }
     107                 :           0 :           pp_right_paren (pp);
     108                 :             :         }
     109                 :             :     }
     110                 :           0 :   else if (is_reg ())
     111                 :             :     {
     112                 :           0 :       pp_space (pp);
     113                 :           0 :       pp_left_paren (pp);
     114                 :           0 :       if (mode != E_BLKmode)
     115                 :             :         {
     116                 :           0 :           pp_string (pp, GET_MODE_NAME (mode));
     117                 :           0 :           pp_space (pp);
     118                 :             :         }
     119                 :           0 :       pp_string (pp, "pseudo");
     120                 :           0 :       pp_right_paren (pp);
     121                 :             :     }
     122                 :           0 : }
     123                 :             : 
     124                 :             : // See the comment above the declaration.
     125                 :             : void
     126                 :           0 : resource_info::print (pretty_printer *pp) const
     127                 :             : {
     128                 :           0 :   print_identifier (pp);
     129                 :           0 :   print_context (pp);
     130                 :           0 : }
     131                 :             : 
     132                 :             : // Some properties can naturally be described using adjectives that attach
     133                 :             : // to nouns like "use" or "definition".  Print such adjectives to PP.
     134                 :             : void
     135                 :           0 : access_info::print_prefix_flags (pretty_printer *pp) const
     136                 :             : {
     137                 :           0 :   if (m_is_temp)
     138                 :           0 :     pp_string (pp, "temporary ");
     139                 :           0 :   if (m_has_been_superceded)
     140                 :           0 :     pp_string (pp, "superceded ");
     141                 :           0 : }
     142                 :             : 
     143                 :             : // Print properties not handled by print_prefix_flags to PP, putting
     144                 :             : // each property on a new line indented by two extra spaces.
     145                 :             : void
     146                 :           0 : access_info::print_properties_on_new_lines (pretty_printer *pp) const
     147                 :             : {
     148                 :           0 :   if (m_is_pre_post_modify)
     149                 :             :     {
     150                 :           0 :       pp_newline_and_indent (pp, 2);
     151                 :           0 :       pp_string (pp, "set by a pre/post-modify");
     152                 :           0 :       pp_indentation (pp) -= 2;
     153                 :             :     }
     154                 :           0 :   if (m_includes_address_uses)
     155                 :             :     {
     156                 :           0 :       pp_newline_and_indent (pp, 2);
     157                 :           0 :       pp_string (pp, "appears inside an address");
     158                 :           0 :       pp_indentation (pp) -= 2;
     159                 :             :     }
     160                 :           0 :   if (m_includes_read_writes)
     161                 :             :     {
     162                 :           0 :       pp_newline_and_indent (pp, 2);
     163                 :           0 :       pp_string (pp, "appears in a read/write context");
     164                 :           0 :       pp_indentation (pp) -= 2;
     165                 :             :     }
     166                 :           0 :   if (m_includes_subregs)
     167                 :             :     {
     168                 :           0 :       pp_newline_and_indent (pp, 2);
     169                 :           0 :       pp_string (pp, "appears inside a subreg");
     170                 :           0 :       pp_indentation (pp) -= 2;
     171                 :             :     }
     172                 :           0 : }
     173                 :             : 
     174                 :             : // Return true if there are no known issues with the integrity of the
     175                 :             : // link information.
     176                 :             : inline bool
     177                 :  1549911696 : use_info::check_integrity ()
     178                 :             : {
     179                 :  4652147412 :   auto subsequence_id = [](use_info *use)
     180                 :             :     {
     181                 :  1551117858 :       if (use->is_in_nondebug_insn ())
     182                 :             :         return 1;
     183                 :   639248032 :       if (use->is_in_debug_insn ())
     184                 :   311584274 :         return 2;
     185                 :             :       return 3;
     186                 :             :     };
     187                 :             : 
     188                 :  1549911696 :   use_info *prev = prev_use ();
     189                 :  1549911696 :   use_info *next = next_use ();
     190                 :             : 
     191                 :  2629587513 :   if (prev && subsequence_id (prev) > subsequence_id (this))
     192                 :             :     return false;
     193                 :  2195066909 :   if (next && subsequence_id (next) < subsequence_id (this))
     194                 :             :     return false;
     195                 :  1549911696 :   if (m_is_last_nondebug_insn_use != calculate_is_last_nondebug_insn_use ())
     196                 :             :     return false;
     197                 :             : 
     198                 :  1549911696 :   if (!prev && last_use ()->next_use ())
     199                 :             :     return false;
     200                 :  1549911696 :   if (!next)
     201                 :   964653768 :     if (use_info *use = last_nondebug_insn_use ())
     202                 :   880383908 :       if (!use->m_is_last_nondebug_insn_use)
     203                 :           0 :         return false;
     204                 :             : 
     205                 :             :   return true;
     206                 :             : }
     207                 :             : 
     208                 :             : // See the comment above the declaration.
     209                 :             : void
     210                 :           0 : use_info::print_location (pretty_printer *pp) const
     211                 :             : {
     212                 :           0 :   if (is_in_phi ())
     213                 :           0 :     pp_access (pp, phi (), PP_ACCESS_INCLUDE_LOCATION);
     214                 :             :   else
     215                 :           0 :     insn ()->print_identifier_and_location (pp);
     216                 :           0 : }
     217                 :             : 
     218                 :             : // See the comment above the declaration.
     219                 :             : void
     220                 :           0 : use_info::print_def (pretty_printer *pp) const
     221                 :             : {
     222                 :           0 :   if (const set_info *set = def ())
     223                 :           0 :     pp_access (pp, set, 0);
     224                 :             :   else
     225                 :             :     {
     226                 :           0 :       pp_string (pp, "undefined ");
     227                 :           0 :       resource ().print (pp);
     228                 :             :     }
     229                 :           0 : }
     230                 :             : 
     231                 :             : // See the comment above the declaration.
     232                 :             : void
     233                 :           0 : use_info::print (pretty_printer *pp, unsigned int flags) const
     234                 :             : {
     235                 :           0 :   print_prefix_flags (pp);
     236                 :             : 
     237                 :           0 :   const set_info *set = def ();
     238                 :           0 :   if (set && set->mode () != mode ())
     239                 :             :     {
     240                 :           0 :       pp_string (pp, GET_MODE_NAME (mode ()));
     241                 :           0 :       pp_space (pp);
     242                 :             :     }
     243                 :             : 
     244                 :           0 :   pp_string (pp, "use of ");
     245                 :           0 :   print_def (pp);
     246                 :           0 :   if (flags & PP_ACCESS_INCLUDE_LOCATION)
     247                 :             :     {
     248                 :           0 :       pp_string (pp, " by ");
     249                 :           0 :       print_location (pp);
     250                 :             :     }
     251                 :           0 :   if (set && (flags & PP_ACCESS_INCLUDE_LINKS))
     252                 :             :     {
     253                 :           0 :       pp_newline_and_indent (pp, 2);
     254                 :           0 :       pp_string (pp, "defined in ");
     255                 :           0 :       set->insn ()->print_location (pp);
     256                 :           0 :       pp_indentation (pp) -= 2;
     257                 :             :     }
     258                 :           0 :   if (flags & PP_ACCESS_INCLUDE_PROPERTIES)
     259                 :           0 :     print_properties_on_new_lines (pp);
     260                 :           0 : }
     261                 :             : 
     262                 :             : // See the comment above the declaration.
     263                 :             : void
     264                 :           0 : def_info::print_identifier (pretty_printer *pp) const
     265                 :             : {
     266                 :           0 :   resource ().print_identifier (pp);
     267                 :           0 :   pp_colon (pp);
     268                 :           0 :   insn ()->print_identifier (pp);
     269                 :           0 :   resource ().print_context (pp);
     270                 :           0 : }
     271                 :             : 
     272                 :             : // See the comment above the declaration.
     273                 :             : void
     274                 :           0 : def_info::print_location (pretty_printer *pp) const
     275                 :             : {
     276                 :           0 :   insn ()->print_identifier_and_location (pp);
     277                 :           0 : }
     278                 :             : 
     279                 :             : // See the comment above the declaration.
     280                 :             : void
     281                 :           0 : clobber_info::print (pretty_printer *pp, unsigned int flags) const
     282                 :             : {
     283                 :           0 :   print_prefix_flags (pp);
     284                 :           0 :   if (is_call_clobber ())
     285                 :           0 :     pp_string (pp, "call ");
     286                 :           0 :   pp_string (pp, "clobber ");
     287                 :           0 :   print_identifier (pp);
     288                 :           0 :   if (flags & PP_ACCESS_INCLUDE_LOCATION)
     289                 :             :     {
     290                 :           0 :       pp_string (pp, " in ");
     291                 :           0 :       insn ()->print_location (pp);
     292                 :             :     }
     293                 :           0 :   if (flags & PP_ACCESS_INCLUDE_PROPERTIES)
     294                 :           0 :     print_properties_on_new_lines (pp);
     295                 :           0 : }
     296                 :             : 
     297                 :             : // See the comment above the declaration.
     298                 :             : void
     299                 :           0 : set_info::print_uses_on_new_lines (pretty_printer *pp) const
     300                 :             : {
     301                 :           0 :   for (const use_info *use : all_uses ())
     302                 :             :     {
     303                 :           0 :       pp_newline_and_indent (pp, 2);
     304                 :           0 :       if (use->is_live_out_use ())
     305                 :             :         {
     306                 :           0 :           pp_string (pp, "live out from ");
     307                 :           0 :           use->insn ()->print_location (pp);
     308                 :             :         }
     309                 :             :       else
     310                 :             :         {
     311                 :           0 :           pp_string (pp, "used by ");
     312                 :           0 :           use->print_location (pp);
     313                 :             :         }
     314                 :           0 :       pp_indentation (pp) -= 2;
     315                 :             :     }
     316                 :           0 :   if (m_use_tree)
     317                 :             :     {
     318                 :           0 :       pp_newline_and_indent (pp, 2);
     319                 :           0 :       pp_string (pp, "splay tree:");
     320                 :           0 :       pp_newline_and_indent (pp, 2);
     321                 :           0 :       auto print_use = [](pretty_printer *pp,
     322                 :             :                           splay_tree_node<use_info *> *node)
     323                 :             :         {
     324                 :           0 :           pp_string (pp, "use by ");
     325                 :           0 :           node->value ()->print_location (pp);
     326                 :           0 :         };
     327                 :           0 :       m_use_tree.print (pp, m_use_tree.root (), print_use);
     328                 :           0 :       pp_indentation (pp) -= 4;
     329                 :             :     }
     330                 :           0 : }
     331                 :             : 
     332                 :             : // See the comment above the declaration.
     333                 :             : void
     334                 :           0 : set_info::print (pretty_printer *pp, unsigned int flags) const
     335                 :             : {
     336                 :           0 :   print_prefix_flags (pp);
     337                 :           0 :   pp_string (pp, "set ");
     338                 :           0 :   print_identifier (pp);
     339                 :           0 :   if (flags & PP_ACCESS_INCLUDE_LOCATION)
     340                 :             :     {
     341                 :           0 :       pp_string (pp, " in ");
     342                 :           0 :       insn ()->print_location (pp);
     343                 :             :     }
     344                 :           0 :   if (flags & PP_ACCESS_INCLUDE_PROPERTIES)
     345                 :           0 :     print_properties_on_new_lines (pp);
     346                 :           0 :   if (flags & PP_ACCESS_INCLUDE_LINKS)
     347                 :           0 :     print_uses_on_new_lines (pp);
     348                 :           0 : }
     349                 :             : 
     350                 :             : // See the comment above the declaration.
     351                 :             : void
     352                 :           0 : phi_info::print (pretty_printer *pp, unsigned int flags) const
     353                 :             : {
     354                 :           0 :   print_prefix_flags (pp);
     355                 :           0 :   pp_string (pp, "phi node ");
     356                 :           0 :   print_identifier (pp);
     357                 :           0 :   if (flags & PP_ACCESS_INCLUDE_LOCATION)
     358                 :             :     {
     359                 :           0 :       pp_string (pp, " in ");
     360                 :           0 :       insn ()->print_location (pp);
     361                 :             :     }
     362                 :             : 
     363                 :           0 :   if (flags & PP_ACCESS_INCLUDE_PROPERTIES)
     364                 :           0 :     print_properties_on_new_lines (pp);
     365                 :             : 
     366                 :           0 :   if (flags & PP_ACCESS_INCLUDE_LINKS)
     367                 :             :     {
     368                 :           0 :       basic_block cfg_bb = bb ()->cfg_bb ();
     369                 :           0 :       pp_newline_and_indent (pp, 2);
     370                 :           0 :       pp_string (pp, "inputs:");
     371                 :           0 :       unsigned int i = 0;
     372                 :           0 :       for (const use_info *input : inputs ())
     373                 :             :         {
     374                 :           0 :           basic_block pred_cfg_bb = EDGE_PRED (cfg_bb, i)->src;
     375                 :           0 :           pp_newline_and_indent (pp, 2);
     376                 :           0 :           pp_string (pp, "bb");
     377                 :           0 :           pp_decimal_int (pp, pred_cfg_bb->index);
     378                 :           0 :           pp_colon (pp);
     379                 :           0 :           pp_space (pp);
     380                 :           0 :           input->print_def (pp);
     381                 :           0 :           pp_indentation (pp) -= 2;
     382                 :           0 :           i += 1;
     383                 :             :         }
     384                 :           0 :       pp_indentation (pp) -= 2;
     385                 :             : 
     386                 :           0 :       print_uses_on_new_lines (pp);
     387                 :             :     }
     388                 :           0 : }
     389                 :             : 
     390                 :             : // See the comment above the declaration.
     391                 :             : void
     392                 :           0 : set_node::print (pretty_printer *pp) const
     393                 :             : {
     394                 :           0 :   pp_access (pp, first_def ());
     395                 :           0 : }
     396                 :             : 
     397                 :             : // See the comment above the declaration.
     398                 :             : clobber_info *
     399                 :           8 : clobber_group::prev_clobber (insn_info *insn) const
     400                 :             : {
     401                 :           8 :   int comparison = lookup_clobber (insn);
     402                 :           8 :   if (comparison <= 0)
     403                 :          16 :     return dyn_cast<clobber_info *> (m_clobber_tree.root ()->prev_def ());
     404                 :           0 :   return m_clobber_tree.root ();
     405                 :             : }
     406                 :             : 
     407                 :             : // See the comment above the declaration.
     408                 :             : clobber_info *
     409                 :           8 : clobber_group::next_clobber (insn_info *insn) const
     410                 :             : {
     411                 :           8 :   int comparison = lookup_clobber (insn);
     412                 :           8 :   if (comparison >= 0)
     413                 :          16 :     return dyn_cast<clobber_info *> (m_clobber_tree.root ()->next_def ());
     414                 :           0 :   return m_clobber_tree.root ();
     415                 :             : }
     416                 :             : 
     417                 :             : // See the comment above the declaration.
     418                 :             : void
     419                 :           0 : clobber_group::print (pretty_printer *pp) const
     420                 :             : {
     421                 :           0 :   auto print_clobber = [](pretty_printer *pp, const def_info *clobber)
     422                 :             :     {
     423                 :           0 :       pp_access (pp, clobber);
     424                 :             :     };
     425                 :           0 :   pp_string (pp, "grouped clobber");
     426                 :           0 :   for (const def_info *clobber : clobbers ())
     427                 :             :     {
     428                 :           0 :       pp_newline_and_indent (pp, 2);
     429                 :           0 :       print_clobber (pp, clobber);
     430                 :           0 :       pp_indentation (pp) -= 2;
     431                 :             :     }
     432                 :           0 :   pp_newline_and_indent (pp, 2);
     433                 :           0 :   pp_string (pp, "splay tree");
     434                 :           0 :   pp_newline_and_indent (pp, 2);
     435                 :           0 :   m_clobber_tree.print (pp, print_clobber);
     436                 :           0 :   pp_indentation (pp) -= 4;
     437                 :           0 : }
     438                 :             : 
     439                 :             : // A wrapper around rtl_ssa::lookup_clobber that ensures that the root
     440                 :             : // of the splay tree always has the correct group.
     441                 :             : int
     442                 :      323415 : clobber_group::lookup_clobber (insn_info *insn) const
     443                 :             : {
     444                 :      323415 :   auto &tree = const_cast<clobber_tree &> (m_clobber_tree);
     445                 :      323415 :   int result = rtl_ssa::lookup_clobber (tree, insn);
     446                 :      323415 :   tree->update_group (const_cast<clobber_group *> (this));
     447                 :      323415 :   return result;
     448                 :             : }
     449                 :             : 
     450                 :             : // See the comment above the declaration.
     451                 :             : def_info *
     452                 :      181772 : def_lookup::prev_def (insn_info *insn) const
     453                 :             : {
     454                 :      181772 :   if (mux && comparison == 0)
     455                 :           8 :     if (auto *node = mux.dyn_cast<def_node *> ())
     456                 :           8 :       if (auto *group = dyn_cast<clobber_group *> (node))
     457                 :           8 :         if (clobber_info *clobber = group->prev_clobber (insn))
     458                 :             :           return clobber;
     459                 :             : 
     460                 :      181764 :   return last_def_of_prev_group ();
     461                 :             : }
     462                 :             : 
     463                 :             : // See the comment above the declaration.
     464                 :             : def_info *
     465                 :      181772 : def_lookup::next_def (insn_info *insn) const
     466                 :             : {
     467                 :      181772 :   if (mux && comparison == 0)
     468                 :           8 :     if (auto *node = mux.dyn_cast<def_node *> ())
     469                 :           8 :       if (auto *group = dyn_cast<clobber_group *> (node))
     470                 :           8 :         if (clobber_info *clobber = group->next_clobber (insn))
     471                 :             :           return clobber;
     472                 :             : 
     473                 :      181764 :   return first_def_of_next_group ();
     474                 :             : }
     475                 :             : 
     476                 :             : // Return a clobber_group for CLOBBER, creating one if CLOBBER doesn't
     477                 :             : // already belong to a group.
     478                 :             : clobber_group *
     479                 :    87239246 : function_info::need_clobber_group (clobber_info *clobber)
     480                 :             : {
     481                 :    87239246 :   if (clobber->is_in_group ())
     482                 :    68444133 :     return clobber->group ();
     483                 :    18795113 :   return allocate<clobber_group> (clobber);
     484                 :             : }
     485                 :             : 
     486                 :             : // Return a def_node for inserting DEF into the associated resource's
     487                 :             : // splay tree.  Use a clobber_group if DEF is a clobber and a set_node
     488                 :             : // otherwise.
     489                 :             : def_node *
     490                 :    20473188 : function_info::need_def_node (def_info *def)
     491                 :             : {
     492                 :    20473188 :   if (auto *clobber = dyn_cast<clobber_info *> (def))
     493                 :     4235526 :     return need_clobber_group (clobber);
     494                 :    16237662 :   return allocate<set_node> (as_a<set_info *> (def));
     495                 :             : }
     496                 :             : 
     497                 :             : // LAST is the last thing to define LAST->resource (), and is where any
     498                 :             : // splay tree root for LAST->resource () is stored.  Require such a splay tree
     499                 :             : // to exist, creating a new one if necessary.  Return the root of the tree.
     500                 :             : //
     501                 :             : // The caller must call LAST->set_splay_root after it has finished with
     502                 :             : // the splay tree.
     503                 :             : def_splay_tree
     504                 :     2572414 : function_info::need_def_splay_tree (def_info *last)
     505                 :             : {
     506                 :     2572414 :   if (def_node *root = last->splay_root ())
     507                 :     2032328 :     return root;
     508                 :             : 
     509                 :             :   // Use a left-spine rooted at the last node.
     510                 :      540086 :   def_node *root = need_def_node (last);
     511                 :      540086 :   def_node *parent = root;
     512                 :    36520883 :   while (def_info *prev = first_def (parent)->prev_def ())
     513                 :             :     {
     514                 :    19752830 :       def_node *node = need_def_node (prev);
     515                 :    19752830 :       def_splay_tree::insert_child (parent, 0, node);
     516                 :    19752830 :       parent = node;
     517                 :    19752830 :     }
     518                 :      540086 :   return root;
     519                 :             : }
     520                 :             : 
     521                 :             : // Search TREE for either:
     522                 :             : //
     523                 :             : // - a set_info at INSN or
     524                 :             : // - a clobber_group whose range includes INSN
     525                 :             : //
     526                 :             : // If such a node exists, install it as the root of TREE and return 0.
     527                 :             : // Otherwise arbitrarily choose between:
     528                 :             : //
     529                 :             : // (1) Installing the closest preceding node as the root and returning 1.
     530                 :             : // (2) Installing the closest following node as the root and returning -1.
     531                 :             : //
     532                 :             : // Note that this routine should not be used to check whether INSN
     533                 :             : // itself defines a resource; that can be checked more cheaply using
     534                 :             : // find_access_index.
     535                 :             : int
     536                 :     2695950 : rtl_ssa::lookup_def (def_splay_tree &tree, insn_info *insn)
     537                 :             : {
     538                 :    30830353 :   auto go_left = [&](def_node *node)
     539                 :             :     {
     540                 :    47785061 :       return *insn < *first_def (node)->insn ();
     541                 :     2695950 :     };
     542                 :     8930939 :   auto go_right = [&](def_node *node)
     543                 :             :     {
     544                 :    12469978 :       return *insn > *last_def (node)->insn ();
     545                 :     2695950 :     };
     546                 :     2695950 :   return tree.lookup (go_left, go_right);
     547                 :             : }
     548                 :             : 
     549                 :             : // Search TREE for a clobber in INSN.  If such a clobber exists, install
     550                 :             : // it as the root of TREE and return 0.  Otherwise arbitrarily choose between:
     551                 :             : //
     552                 :             : // (1) Installing the closest preceding clobber as the root and returning 1.
     553                 :             : // (2) Installing the closest following clobber as the root and returning -1.
     554                 :             : int
     555                 :      323415 : rtl_ssa::lookup_clobber (clobber_tree &tree, insn_info *insn)
     556                 :             : {
     557                 :     1555659 :   auto compare = [&](clobber_info *clobber)
     558                 :             :     {
     559                 :     1232244 :       return insn->compare_with (clobber->insn ());
     560                 :      323415 :     };
     561                 :      323415 :   return tree.lookup (compare);
     562                 :             : }
     563                 :             : 
     564                 :             : // Search for a definition of RESOURCE at INSN and return the result of
     565                 :             : // the search as a def_lookup.  See the comment above the class for more
     566                 :             : // details.
     567                 :             : def_lookup
     568                 :     2364264 : function_info::find_def (resource_info resource, insn_info *insn)
     569                 :             : {
     570                 :     2364264 :   def_info *first = m_defs[resource.regno + 1];
     571                 :     2364264 :   if (!first)
     572                 :             :     // There are no nodes.  The comparison result is pretty meaningless
     573                 :             :     // in this case.
     574                 :         710 :     return { nullptr, -1 };
     575                 :             : 
     576                 :             :   // See whether the first node matches.
     577                 :     2363554 :   auto first_result = clobber_group_or_single_def (first);
     578                 :     2363554 :   if (*insn <= *last_def (first_result)->insn ())
     579                 :             :     {
     580                 :      192326 :       int comparison = (*insn >= *first->insn () ? 0 : -1);
     581                 :      192326 :       return { first_result, comparison };
     582                 :             :     }
     583                 :             : 
     584                 :             :   // See whether the last node matches.
     585                 :     2171228 :   def_info *last = first->last_def ();
     586                 :     2171228 :   auto last_result = clobber_group_or_single_def (last);
     587                 :     3299388 :   if (*insn >= *first_def (last_result)->insn ())
     588                 :             :     {
     589                 :      411012 :       int comparison = (*insn <= *last->insn () ? 0 : 1);
     590                 :      411012 :       return { last_result, comparison };
     591                 :             :     }
     592                 :             : 
     593                 :             :   // Resort to using a splay tree to search for the result.
     594                 :     1760216 :   def_splay_tree tree = need_def_splay_tree (last);
     595                 :     1760216 :   int comparison = lookup_def (tree, insn);
     596                 :     1760216 :   last->set_splay_root (tree.root ());
     597                 :     1760216 :   return { tree.root (), comparison };
     598                 :             : }
     599                 :             : 
     600                 :             : // Add DEF to the function's list of definitions of DEF->resource (),
     601                 :             : // inserting DEF immediately before BEFORE.  DEF is not currently in the list.
     602                 :             : void
     603                 :      369617 : function_info::insert_def_before (def_info *def, def_info *before)
     604                 :             : {
     605                 :      739234 :   gcc_checking_assert (!def->has_def_links ()
     606                 :             :                        && *before->insn () > *def->insn ());
     607                 :             : 
     608                 :      369617 :   def->copy_prev_from (before);
     609                 :      369617 :   if (def_info *prev = def->prev_def ())
     610                 :             :     {
     611                 :      299325 :       gcc_checking_assert (*prev->insn () < *def->insn ());
     612                 :      299325 :       prev->set_next_def (def);
     613                 :             :     }
     614                 :             :   else
     615                 :       70292 :     m_defs[def->regno () + 1] = def;
     616                 :             : 
     617                 :      369617 :   def->set_next_def (before);
     618                 :      369617 :   before->set_prev_def (def);
     619                 :      369617 : }
     620                 :             : 
     621                 :             : // Add DEF to the function's list of definitions of DEF->resource (),
     622                 :             : // inserting DEF immediately after AFTER.  DEF is not currently in the list.
     623                 :             : void
     624                 :   102432215 : function_info::insert_def_after (def_info *def, def_info *after)
     625                 :             : {
     626                 :   204864430 :   gcc_checking_assert (!def->has_def_links ()
     627                 :             :                        && *after->insn () < *def->insn ());
     628                 :             : 
     629                 :   102432215 :   def->copy_next_from (after);
     630                 :   102432215 :   if (def_info *next = def->next_def ())
     631                 :             :     {
     632                 :      512873 :       gcc_checking_assert (*next->insn () > *def->insn ());
     633                 :      512873 :       next->set_prev_def (def);
     634                 :             :     }
     635                 :             :   else
     636                 :   101919342 :     m_defs[def->regno () + 1]->set_last_def (def);
     637                 :             : 
     638                 :   102432215 :   def->set_prev_def (after);
     639                 :   102432215 :   after->set_next_def (def);
     640                 :   102432215 : }
     641                 :             : 
     642                 :             : // Remove DEF from the function's list of definitions of DEF->resource ().
     643                 :             : void
     644                 :    12646371 : function_info::remove_def_from_list (def_info *def)
     645                 :             : {
     646                 :    12646371 :   def_info *prev = def->prev_def ();
     647                 :    12646371 :   def_info *next = def->next_def ();
     648                 :             : 
     649                 :    12646371 :   if (next)
     650                 :     6314283 :     next->copy_prev_from (def);
     651                 :             :   else
     652                 :     6332088 :     m_defs[def->regno () + 1]->set_last_def (prev);
     653                 :             : 
     654                 :    12646371 :   if (prev)
     655                 :    12496399 :     prev->copy_next_from (def);
     656                 :             :   else
     657                 :      149972 :     m_defs[def->regno () + 1] = next;
     658                 :             : 
     659                 :    12646371 :   def->clear_def_links ();
     660                 :    12646371 : }
     661                 :             : 
     662                 :             : // Add CLOBBER to GROUP and insert it into the function's list of
     663                 :             : // accesses to CLOBBER->resource ().  CLOBBER is not currently part
     664                 :             : // of an active group and is not currently in the list.
     665                 :             : void
     666                 :      323399 : function_info::add_clobber (clobber_info *clobber, clobber_group *group)
     667                 :             : {
     668                 :             :   // Search for either the previous or next clobber in the group.
     669                 :             :   // The result is less than zero if CLOBBER should come before NEIGHBOR
     670                 :             :   // or greater than zero if CLOBBER should come after NEIGHBOR.
     671                 :      323399 :   int comparison = group->lookup_clobber (clobber->insn ());
     672                 :      323399 :   gcc_checking_assert (comparison != 0);
     673                 :      323399 :   clobber_info *neighbor = group->m_clobber_tree.root ();
     674                 :             : 
     675                 :             :   // If CLOBBER comes before NEIGHBOR, insert CLOBBER to NEIGHBOR's left,
     676                 :             :   // otherwise insert CLOBBER to NEIGHBOR's right.
     677                 :      323399 :   clobber_info::splay_tree::insert_child (neighbor, comparison > 0, clobber);
     678                 :      323399 :   clobber->set_group (group);
     679                 :             : 
     680                 :             :   // Insert the clobber into the function-wide list and update the
     681                 :             :   // bounds of the group.
     682                 :      323399 :   if (comparison > 0)
     683                 :             :     {
     684                 :       24074 :       insert_def_after (clobber, neighbor);
     685                 :       24074 :       if (neighbor == group->last_clobber ())
     686                 :           0 :         group->set_last_clobber (clobber);
     687                 :             :     }
     688                 :             :   else
     689                 :             :     {
     690                 :      299325 :       insert_def_before (clobber, neighbor);
     691                 :      299325 :       if (neighbor == group->first_clobber ())
     692                 :           0 :         group->set_first_clobber (clobber);
     693                 :             :     }
     694                 :      323399 : }
     695                 :             : 
     696                 :             : // Remove CLOBBER from GROUP, given that GROUP contains other clobbers too.
     697                 :             : // Also remove CLOBBER from the function's list of accesses to
     698                 :             : // CLOBBER->resource ().
     699                 :             : void
     700                 :      805445 : function_info::remove_clobber (clobber_info *clobber, clobber_group *group)
     701                 :             : {
     702                 :      805445 :   if (clobber == group->first_clobber ())
     703                 :             :     {
     704                 :      563004 :       auto *new_first = as_a<clobber_info *> (clobber->next_def ());
     705                 :      281502 :       group->set_first_clobber (new_first);
     706                 :      281502 :       new_first->update_group (group);
     707                 :             :     }
     708                 :      523943 :   else if (clobber == group->last_clobber ())
     709                 :             :     {
     710                 :      325614 :       auto *new_last = as_a<clobber_info *> (clobber->prev_def ());
     711                 :      162807 :       group->set_last_clobber (new_last);
     712                 :      162807 :       new_last->update_group (group);
     713                 :             :     }
     714                 :             : 
     715                 :      805445 :   clobber_info *replacement = clobber_info::splay_tree::remove_node (clobber);
     716                 :      805445 :   if (clobber == group->m_clobber_tree.root ())
     717                 :             :     {
     718                 :      346698 :       group->m_clobber_tree = replacement;
     719                 :      346698 :       replacement->update_group (group);
     720                 :             :     }
     721                 :      805445 :   clobber->set_group (nullptr);
     722                 :             : 
     723                 :      805445 :   remove_def_from_list (clobber);
     724                 :      805445 : }
     725                 :             : 
     726                 :             : // Add CLOBBER immediately before the first clobber in GROUP, given that
     727                 :             : // CLOBBER is not currently part of any group.
     728                 :             : void
     729                 :      224657 : function_info::prepend_clobber_to_group (clobber_info *clobber,
     730                 :             :                                          clobber_group *group)
     731                 :             : {
     732                 :      224657 :   clobber_info *next = group->first_clobber ();
     733                 :      224657 :   clobber_info::splay_tree::insert_child (next, 0, clobber);
     734                 :      224657 :   group->set_first_clobber (clobber);
     735                 :      224657 :   clobber->set_group (group);
     736                 :      224657 : }
     737                 :             : 
     738                 :             : // Add CLOBBER immediately after the last clobber in GROUP, given that
     739                 :             : // CLOBBER is not currently part of any group.
     740                 :             : void
     741                 :    82779535 : function_info::append_clobber_to_group (clobber_info *clobber,
     742                 :             :                                         clobber_group *group)
     743                 :             : {
     744                 :    82779535 :   clobber_info *prev = group->last_clobber ();
     745                 :    82779535 :   clobber_info::splay_tree::insert_child (prev, 1, clobber);
     746                 :    82779535 :   group->set_last_clobber (clobber);
     747                 :    82779535 :   clobber->set_group (group);
     748                 :    82779535 : }
     749                 :             : 
     750                 :             : // Put CLOBBER1 and CLOBBER2 into the same clobber_group, given that
     751                 :             : // CLOBBER1 occurs immediately before CLOBBER2 and that the two clobbers
     752                 :             : // are not currently in the same group.  LAST is the last definition of
     753                 :             : // the associated resource, and is where any splay tree is stored.
     754                 :             : void
     755                 :        1838 : function_info::merge_clobber_groups (clobber_info *clobber1,
     756                 :             :                                      clobber_info *clobber2,
     757                 :             :                                      def_info *last)
     758                 :             : {
     759                 :        1838 :   if (clobber1->is_in_group () && clobber2->is_in_group ())
     760                 :             :     {
     761                 :         701 :       clobber_group *group1 = clobber1->group ();
     762                 :         701 :       clobber_group *group2 = clobber2->group ();
     763                 :         701 :       gcc_checking_assert (clobber1 == group1->last_clobber ()
     764                 :             :                            && clobber2 == group2->first_clobber ());
     765                 :             : 
     766                 :         701 :       if (def_splay_tree tree = last->splay_root ())
     767                 :             :         {
     768                 :             :           // Remove GROUP2 from the splay tree.
     769                 :         205 :           int comparison = lookup_def (tree, clobber2->insn ());
     770                 :         205 :           gcc_checking_assert (comparison == 0);
     771                 :         205 :           tree.remove_root ();
     772                 :         205 :           last->set_splay_root (tree.root ());
     773                 :             :         }
     774                 :             : 
     775                 :             :       // Splice the trees together.
     776                 :         701 :       group1->m_clobber_tree.splice_next_tree (group2->m_clobber_tree);
     777                 :             : 
     778                 :             :       // Bring the two extremes of GROUP2 under GROUP1.  Any other
     779                 :             :       // clobbers in the group are updated lazily on demand.
     780                 :         701 :       clobber2->set_group (group1);
     781                 :         701 :       group2->last_clobber ()->set_group (group1);
     782                 :         701 :       group1->set_last_clobber (group2->last_clobber ());
     783                 :             : 
     784                 :             :       // Record that GROUP2 is no more.
     785                 :         701 :       group2->set_first_clobber (nullptr);
     786                 :         701 :       group2->set_last_clobber (nullptr);
     787                 :         701 :       group2->m_clobber_tree = nullptr;
     788                 :             :     }
     789                 :             :   else
     790                 :             :     {
     791                 :             :       // In this case there can be no active splay tree.
     792                 :        1137 :       gcc_assert (!last->splay_root ());
     793                 :        1137 :       if (clobber2->is_in_group ())
     794                 :         472 :         prepend_clobber_to_group (clobber1, clobber2->group ());
     795                 :             :       else
     796                 :         665 :         append_clobber_to_group (clobber2, need_clobber_group (clobber1));
     797                 :             :     }
     798                 :        1838 : }
     799                 :             : 
     800                 :             : // GROUP spans INSN, and INSN now sets the resource that GROUP clobbers.
     801                 :             : // Split GROUP around INSN, to form two new groups.  The first of the
     802                 :             : // returned groups comes before INSN and the second comes after INSN.
     803                 :             : //
     804                 :             : // The caller is responsible for updating the def_splay_tree and chaining
     805                 :             : // the defs together.
     806                 :             : std::array<clobber_group *, 2>
     807                 :           0 : function_info::split_clobber_group (clobber_group *group, insn_info *insn)
     808                 :             : {
     809                 :             :   // Search for either the previous or next clobber in the group.
     810                 :             :   // The result is less than zero if CLOBBER should come before NEIGHBOR
     811                 :             :   // or greater than zero if CLOBBER should come after NEIGHBOR.
     812                 :           0 :   clobber_tree &tree1 = group->m_clobber_tree;
     813                 :           0 :   int comparison = lookup_clobber (tree1, insn);
     814                 :           0 :   gcc_checking_assert (comparison != 0);
     815                 :           0 :   clobber_info *neighbor = tree1.root ();
     816                 :             : 
     817                 :           0 :   clobber_tree tree2;
     818                 :           0 :   clobber_info *prev;
     819                 :           0 :   clobber_info *next;
     820                 :           0 :   if (comparison > 0)
     821                 :             :     {
     822                 :             :       // NEIGHBOR is the last clobber in what will become the first group.
     823                 :           0 :       tree2 = tree1.split_after_root ();
     824                 :           0 :       prev = neighbor;
     825                 :           0 :       next = as_a<clobber_info *> (prev->next_def ());
     826                 :             :     }
     827                 :             :   else
     828                 :             :     {
     829                 :             :       // NEIGHBOR is the first clobber in what will become the second group.
     830                 :           0 :       tree2 = neighbor;
     831                 :           0 :       tree1 = tree2.split_before_root ();
     832                 :           0 :       next = neighbor;
     833                 :           0 :       prev = as_a<clobber_info *> (next->prev_def ());
     834                 :             :     }
     835                 :             : 
     836                 :             :   // Create a new group for each side of the split.  We need to invalidate
     837                 :             :   // the old group so that clobber_info::group can tell whether a lazy
     838                 :             :   // update is needed.
     839                 :           0 :   clobber_info *first_clobber = group->first_clobber ();
     840                 :           0 :   clobber_info *last_clobber = group->last_clobber ();
     841                 :           0 :   auto *group1 = allocate<clobber_group> (first_clobber, prev, tree1.root ());
     842                 :           0 :   auto *group2 = allocate<clobber_group> (next, last_clobber, tree2.root ());
     843                 :             : 
     844                 :             :   // Invalidate the old group.
     845                 :           0 :   group->set_last_clobber (nullptr);
     846                 :             : 
     847                 :           0 :   return { group1, group2 };
     848                 :             : }
     849                 :             : 
     850                 :             : // Add DEF to the end of the function's list of definitions of
     851                 :             : // DEF->resource ().  There is known to be no associated splay tree yet.
     852                 :             : void
     853                 :   511464416 : function_info::append_def (def_info *def)
     854                 :             : {
     855                 :   511464416 :   gcc_checking_assert (!def->has_def_links ());
     856                 :   511464416 :   def_info **head = &m_defs[def->regno () + 1];
     857                 :   511464416 :   def_info *first = *head;
     858                 :   511464416 :   if (!first)
     859                 :             :     {
     860                 :             :       // This is the only definition of the resource.
     861                 :   161156754 :       def->set_last_def (def);
     862                 :   161156754 :       *head = def;
     863                 :   161156754 :       return;
     864                 :             :     }
     865                 :             : 
     866                 :   350307662 :   def_info *prev = first->last_def ();
     867                 :   350307662 :   gcc_checking_assert (!prev->splay_root ());
     868                 :             : 
     869                 :             :   // Maintain the invariant that two clobbers must not appear in
     870                 :             :   // neighboring nodes of the splay tree.
     871                 :   350307662 :   auto *clobber = dyn_cast<clobber_info *> (def);
     872                 :   350307662 :   auto *prev_clobber = dyn_cast<clobber_info *> (prev);
     873                 :   350307662 :   if (clobber && prev_clobber)
     874                 :    82620527 :     append_clobber_to_group (clobber, need_clobber_group (prev_clobber));
     875                 :             : 
     876                 :   350307662 :   prev->set_next_def (def);
     877                 :   350307662 :   def->set_prev_def (prev);
     878                 :   350307662 :   first->set_last_def (def);
     879                 :             : }
     880                 :             : 
     881                 :             : // Add DEF to the function's list of definitions of DEF->resource ().
     882                 :             : // Also insert it into the associated splay tree, if there is one.
     883                 :             : // DEF is not currently part of the list and is not in the splay tree.
     884                 :             : void
     885                 :   102816125 : function_info::add_def (def_info *def)
     886                 :             : {
     887                 :   205632250 :   gcc_checking_assert (!def->has_def_links ()
     888                 :             :                        && !def->m_is_temp
     889                 :             :                        && !def->m_has_been_superceded);
     890                 :   102816125 :   def_info **head = &m_defs[def->regno () + 1];
     891                 :   102816125 :   def_info *first = *head;
     892                 :   102816125 :   if (!first)
     893                 :             :     {
     894                 :             :       // This is the only definition of the resource.
     895                 :       14293 :       def->set_last_def (def);
     896                 :       14293 :       *head = def;
     897                 :       14293 :       return;
     898                 :             :     }
     899                 :             : 
     900                 :   102801832 :   def_info *last = first->last_def ();
     901                 :   102801832 :   insn_info *insn = def->insn ();
     902                 :             : 
     903                 :   102801832 :   int comparison;
     904                 :   102801832 :   def_node *neighbor = nullptr;
     905                 :   102801832 :   def_info *prev = nullptr;
     906                 :   102801832 :   def_info *next = nullptr;
     907                 :   102801832 :   if (*insn > *last->insn ())
     908                 :             :     {
     909                 :             :       // This definition comes after all other definitions.
     910                 :   101919342 :       comparison = 1;
     911                 :   101919342 :       if (def_splay_tree tree = last->splay_root ())
     912                 :             :         {
     913                 :       15841 :           tree.splay_max_node ();
     914                 :       15841 :           last->set_splay_root (tree.root ());
     915                 :       15841 :           neighbor = tree.root ();
     916                 :             :         }
     917                 :   101919342 :       prev = last;
     918                 :             :     }
     919                 :      882490 :   else if (*insn < *first->insn ())
     920                 :             :     {
     921                 :             :       // This definition comes before all other definitions.
     922                 :       70292 :       comparison = -1;
     923                 :       70292 :       if (def_splay_tree tree = last->splay_root ())
     924                 :             :         {
     925                 :       14890 :           tree.splay_min_node ();
     926                 :       14890 :           last->set_splay_root (tree.root ());
     927                 :       14890 :           neighbor = tree.root ();
     928                 :             :         }
     929                 :       70292 :       next = first;
     930                 :             :     }
     931                 :             :   else
     932                 :             :     {
     933                 :             :       // Search the splay tree for an insertion point.
     934                 :      812198 :       def_splay_tree tree = need_def_splay_tree (last);
     935                 :      812198 :       comparison = lookup_def (tree, insn);
     936                 :      812198 :       last->set_splay_root (tree.root ());
     937                 :      812198 :       neighbor = tree.root ();
     938                 :             : 
     939                 :             :       // Deal with cases in which we found an overlapping live range.
     940                 :      812198 :       if (comparison == 0)
     941                 :             :         {
     942                 :      323399 :           auto *group = as_a<clobber_group *> (tree.root ());
     943                 :      323399 :           if (auto *clobber = dyn_cast<clobber_info *> (def))
     944                 :             :             {
     945                 :      323399 :               add_clobber (clobber, group);
     946                 :      323399 :               return;
     947                 :             :             }
     948                 :           0 :           auto new_groups = split_clobber_group (group, insn);
     949                 :             : 
     950                 :             :           // Insert the two new groups immediately after GROUP.
     951                 :           0 :           def_splay_tree::insert_child (group, 1, new_groups[1]);
     952                 :           0 :           def_splay_tree::insert_child (group, 1, new_groups[0]);
     953                 :             : 
     954                 :             :           // Remove GROUP.
     955                 :           0 :           tree.remove_root ();
     956                 :           0 :           last->set_splay_root (tree.root ());
     957                 :             : 
     958                 :           0 :           prev = new_groups[0]->last_clobber ();
     959                 :           0 :           next = new_groups[1]->first_clobber ();
     960                 :             : 
     961                 :             :           // DEF comes after the first group.  (new_groups[1] and -1 would
     962                 :             :           // also work.)
     963                 :           0 :           neighbor = new_groups[0];
     964                 :           0 :           comparison = 1;
     965                 :             :         }
     966                 :             :       // COMPARISON is < 0 if DEF comes before NEIGHBOR or > 0 if DEF comes
     967                 :             :       // after NEIGHBOR.
     968                 :      488799 :       else if (comparison < 0)
     969                 :             :         {
     970                 :      244895 :           next = first_def (neighbor);
     971                 :      733694 :           prev = next->prev_def ();
     972                 :             :         }
     973                 :             :       else
     974                 :             :         {
     975                 :      243904 :           prev = last_def (neighbor);
     976                 :      732703 :           next = prev->next_def ();
     977                 :             :         }
     978                 :             :     }
     979                 :             : 
     980                 :             :   // See if we should merge CLOBBER with a neighboring clobber.
     981                 :   102478433 :   auto *clobber = dyn_cast<clobber_info *> (def);
     982                 :   102478433 :   auto *prev_clobber = safe_dyn_cast<clobber_info *> (prev);
     983                 :   102478433 :   auto *next_clobber = safe_dyn_cast<clobber_info *> (next);
     984                 :             :   // We shouldn't have consecutive clobber_groups.
     985                 :   102478433 :   gcc_checking_assert (!(clobber && prev_clobber && next_clobber));
     986                 :   102478433 :   if (clobber && prev_clobber)
     987                 :      158343 :     append_clobber_to_group (clobber, need_clobber_group (prev_clobber));
     988                 :   102320090 :   else if (clobber && next_clobber)
     989                 :      224185 :     prepend_clobber_to_group (clobber, need_clobber_group (next_clobber));
     990                 :   102095905 :   else if (neighbor)
     991                 :             :     {
     992                 :             :       // If DEF comes before NEIGHBOR, insert DEF to NEIGHBOR's left,
     993                 :             :       // otherwise insert DEF to NEIGHBOR's right.
     994                 :      180272 :       def_node *node = need_def_node (def);
     995                 :      180272 :       def_splay_tree::insert_child (neighbor, comparison >= 0, node);
     996                 :             :     }
     997                 :   102478433 :   if (prev)
     998                 :   102408141 :     insert_def_after (def, prev);
     999                 :             :   else
    1000                 :       70292 :     insert_def_before (def, next);
    1001                 :             : }
    1002                 :             : 
    1003                 :             : // Remove DEF from the function's list of definitions of DEF->resource ().
    1004                 :             : // Also remove DEF from the associated splay tree, if there is one.
    1005                 :             : void
    1006                 :    14320791 : function_info::remove_def (def_info *def)
    1007                 :             : {
    1008                 :    14320791 :   def_info **head = &m_defs[def->regno () + 1];
    1009                 :    14320791 :   def_info *first = *head;
    1010                 :    14320791 :   gcc_checking_assert (first);
    1011                 :    14320791 :   if (first->is_last_def ())
    1012                 :             :     {
    1013                 :             :       // DEF is the only definition of the resource.
    1014                 :     1674420 :       gcc_checking_assert (first == def);
    1015                 :     1674420 :       *head = nullptr;
    1016                 :     1674420 :       def->clear_def_links ();
    1017                 :     1674420 :       return;
    1018                 :             :     }
    1019                 :             : 
    1020                 :             :   // If CLOBBER belongs to a clobber_group that contains other clobbers
    1021                 :             :   // too, then we need to update the clobber_group and the list, but any
    1022                 :             :   // splay tree that contains the clobber_group is unaffected.
    1023                 :    12646371 :   if (auto *clobber = dyn_cast<clobber_info *> (def))
    1024                 :     1073134 :     if (clobber->is_in_group ())
    1025                 :             :       {
    1026                 :      924299 :         clobber_group *group = clobber->group ();
    1027                 :      924299 :         if (group->first_clobber () != group->last_clobber ())
    1028                 :             :           {
    1029                 :      805445 :             remove_clobber (clobber, group);
    1030                 :      805445 :             return;
    1031                 :             :           }
    1032                 :             :       }
    1033                 :             : 
    1034                 :             :   // If we've created a splay tree for this resource, remove the entry
    1035                 :             :   // for DEF.
    1036                 :    11840926 :   def_info *last = first->last_def ();
    1037                 :    11840926 :   if (def_splay_tree tree = last->splay_root ())
    1038                 :             :     {
    1039                 :      123331 :       int comparison = lookup_def (tree, def->insn ());
    1040                 :      123331 :       gcc_checking_assert (comparison == 0);
    1041                 :      123331 :       tree.remove_root ();
    1042                 :      123331 :       last->set_splay_root (tree.root ());
    1043                 :             :     }
    1044                 :             : 
    1045                 :             :   // If the definition came between two clobbers, merge them into a single
    1046                 :             :   // group.
    1047                 :    11840926 :   auto *prev_clobber = safe_dyn_cast<clobber_info *> (def->prev_def ());
    1048                 :    11840926 :   auto *next_clobber = safe_dyn_cast<clobber_info *> (def->next_def ());
    1049                 :    11840926 :   if (prev_clobber && next_clobber)
    1050                 :        1838 :     merge_clobber_groups (prev_clobber, next_clobber, last);
    1051                 :             : 
    1052                 :    11840926 :   remove_def_from_list (def);
    1053                 :             : }
    1054                 :             : 
    1055                 :             : // Require DEF to have a splay tree that contains all non-phi uses.
    1056                 :             : void
    1057                 :     9246519 : function_info::need_use_splay_tree (set_info *def)
    1058                 :             : {
    1059                 :     9246519 :   if (!def->m_use_tree)
    1060                 :    40760782 :     for (use_info *use : def->all_insn_uses ())
    1061                 :             :       {
    1062                 :    36631818 :         auto *use_node = allocate<splay_tree_node<use_info *>> (use);
    1063                 :    36631818 :         def->m_use_tree.insert_max_node (use_node);
    1064                 :             :       }
    1065                 :     9246519 : }
    1066                 :             : 
    1067                 :             : // Compare two instructions by their position in a use splay tree.  Return >0
    1068                 :             : // if INSN1 comes after INSN2, <0 if INSN1 comes before INSN2, or 0 if they are
    1069                 :             : // the same instruction.
    1070                 :             : static inline int
    1071                 :   972838336 : compare_use_insns (insn_info *insn1, insn_info *insn2)
    1072                 :             : {
    1073                 :             :   // Debug instructions go after nondebug instructions.
    1074                 :   972838336 :   int diff = insn1->is_debug_insn () - insn2->is_debug_insn ();
    1075                 :   972838336 :   if (diff != 0)
    1076                 :             :     return diff;
    1077                 :   895121982 :   return insn1->compare_with (insn2);
    1078                 :             : }
    1079                 :             : 
    1080                 :             : // Search TREE for a use in INSN.  If such a use exists, install it as
    1081                 :             : // the root of TREE and return 0.  Otherwise arbitrarily choose between:
    1082                 :             : //
    1083                 :             : // (1) Installing the closest preceding use as the root and returning 1.
    1084                 :             : // (2) Installing the closest following use as the root and returning -1.
    1085                 :             : int
    1086                 :    11006291 : rtl_ssa::lookup_use (splay_tree<use_info *> &tree, insn_info *insn)
    1087                 :             : {
    1088                 :    74142493 :   auto compare = [&](splay_tree_node<use_info *> *node)
    1089                 :             :     {
    1090                 :    63136202 :       return compare_use_insns (insn, node->value ()->insn ());
    1091                 :    11006291 :     };
    1092                 :    11006291 :   return tree.lookup (compare);
    1093                 :             : }
    1094                 :             : 
    1095                 :             : // See the comment above the declaration.
    1096                 :             : use_lookup
    1097                 :    92696080 : function_info::find_use (set_info *def, insn_info *insn)
    1098                 :             : {
    1099                 :    92696080 :   gcc_assert (!insn->is_debug_insn ());
    1100                 :    92696080 :   use_info *first = def->first_nondebug_insn_use ();
    1101                 :    53303122 :   if (!first)
    1102                 :             :     // There are no uses.  The comparison result is pretty meaningless
    1103                 :             :     // in this case.
    1104                 :    39392958 :     return { nullptr, -1 };
    1105                 :             : 
    1106                 :             :   // See whether the first use matches.
    1107                 :    53303122 :   if (*insn <= *first->insn ())
    1108                 :             :     {
    1109                 :     7845219 :       int comparison = (insn == first->insn () ? 0 : -1);
    1110                 :     7845219 :       return { first, comparison };
    1111                 :             :     }
    1112                 :             : 
    1113                 :             :   // See whether the last use matches.
    1114                 :    45457903 :   use_info *last = def->last_nondebug_insn_use ();
    1115                 :    45457903 :   if (*insn >= *last->insn ())
    1116                 :             :     {
    1117                 :    43647070 :       int comparison = (insn == last->insn () ? 0 : 1);
    1118                 :    43647070 :       return { last, comparison };
    1119                 :             :     }
    1120                 :             : 
    1121                 :             :   // Resort to using a splay tree to search for the result.
    1122                 :     1810833 :   need_use_splay_tree (def);
    1123                 :     1810833 :   int comparison = lookup_use (def->m_use_tree, insn);
    1124                 :     1810833 :   return { def->m_use_tree.root ()->value (), comparison };
    1125                 :             : }
    1126                 :             : 
    1127                 :             : // Add USE to USE->def ()'s list of uses. inserting USE immediately before
    1128                 :             : // BEFORE.  USE is not currently in the list.
    1129                 :             : //
    1130                 :             : // This routine should not be used for inserting phi uses.
    1131                 :             : void
    1132                 :    21603955 : function_info::insert_use_before (use_info *use, use_info *before)
    1133                 :             : {
    1134                 :    43207910 :   gcc_checking_assert (!use->has_use_links () && use->is_in_any_insn ());
    1135                 :             : 
    1136                 :    21603955 :   set_info *def = use->def ();
    1137                 :             : 
    1138                 :    21603955 :   use->copy_prev_from (before);
    1139                 :    21603955 :   use->set_next_use (before);
    1140                 :             : 
    1141                 :    21603955 :   if (use_info *prev = use->prev_use ())
    1142                 :     2457984 :     prev->set_next_use (use);
    1143                 :             :   else
    1144                 :    19192639 :     use->def ()->set_first_use (use);
    1145                 :             : 
    1146                 :    21603955 :   before->set_prev_use (use);
    1147                 :    21603955 :   if (use->is_in_nondebug_insn () && before->is_in_debug_insn_or_phi ())
    1148                 :    36876184 :     def->last_use ()->set_last_nondebug_insn_use (use);
    1149                 :             : 
    1150                 :    21603955 :   gcc_checking_assert (use->check_integrity () && before->check_integrity ());
    1151                 :    21603955 : }
    1152                 :             : 
    1153                 :             : // Add USE to USE->def ()'s list of uses. inserting USE immediately after
    1154                 :             : // AFTER.  USE is not currently in the list.
    1155                 :             : //
    1156                 :             : // This routine should not be used for inserting phi uses.
    1157                 :             : void
    1158                 :   448982813 : function_info::insert_use_after (use_info *use, use_info *after)
    1159                 :             : {
    1160                 :   448982813 :   set_info *def = use->def ();
    1161                 :   897965626 :   gcc_checking_assert (after->is_in_any_insn ()
    1162                 :             :                        && !use->has_use_links ()
    1163                 :             :                        && use->is_in_any_insn ());
    1164                 :             : 
    1165                 :   448982813 :   use->set_prev_use (after);
    1166                 :   448982813 :   use->copy_next_from (after);
    1167                 :             : 
    1168                 :   448982813 :   after->set_next_use (use);
    1169                 :             : 
    1170                 :   448982813 :   if (use_info *next = use->next_use ())
    1171                 :             :     {
    1172                 :             :       // The last node doesn't change, but we might need to update its
    1173                 :             :       // last_nondebug_insn_use record.
    1174                 :    87953482 :       if (use->is_in_nondebug_insn () && next->is_in_debug_insn_or_phi ())
    1175                 :   168414970 :         def->last_use ()->set_last_nondebug_insn_use (use);
    1176                 :    87953482 :       next->set_prev_use (use);
    1177                 :             :     }
    1178                 :             :   else
    1179                 :             :     {
    1180                 :             :       // USE is now the last node.
    1181                 :   361029331 :       if (use->is_in_nondebug_insn ())
    1182                 :   311266339 :         use->set_last_nondebug_insn_use (use);
    1183                 :   361029331 :       def->first_use ()->set_last_use (use);
    1184                 :             :     }
    1185                 :             : 
    1186                 :   448982813 :   gcc_checking_assert (use->check_integrity () && after->check_integrity ());
    1187                 :   448982813 : }
    1188                 :             : 
    1189                 :             : // If USE has a known definition, add USE to that definition's list of uses.
    1190                 :             : // Also update the associated splay tree, if any.
    1191                 :             : void
    1192                 :  1106351639 : function_info::add_use (use_info *use)
    1193                 :             : {
    1194                 :  2212703278 :   gcc_checking_assert (!use->has_use_links ()
    1195                 :             :                        && !use->m_is_temp
    1196                 :             :                        && !use->m_has_been_superceded);
    1197                 :             : 
    1198                 :  1106351639 :   set_info *def = use->def ();
    1199                 :  1106351639 :   if (!def)
    1200                 :  1098915953 :     return;
    1201                 :             : 
    1202                 :  1044218885 :   use_info *first = def->first_use ();
    1203                 :  1044218885 :   if (!first)
    1204                 :             :     {
    1205                 :             :       // This is the only use of the definition.
    1206                 :   447659896 :       use->set_last_use (use);
    1207                 :   447659896 :       if (use->is_in_nondebug_insn ())
    1208                 :   391939265 :         use->set_last_nondebug_insn_use (use);
    1209                 :             : 
    1210                 :   447659896 :       def->set_first_use (use);
    1211                 :             : 
    1212                 :   447659896 :       gcc_checking_assert (use->check_integrity ());
    1213                 :             :       return;
    1214                 :             :     }
    1215                 :             : 
    1216                 :   596558989 :   if (use->is_in_phi ())
    1217                 :             :     {
    1218                 :             :       // Add USE at the end of the list, as the new first phi.
    1219                 :   125972221 :       use_info *last = first->last_use ();
    1220                 :             : 
    1221                 :   125972221 :       use->set_prev_use (last);
    1222                 :   125972221 :       use->copy_next_from (last);
    1223                 :             : 
    1224                 :   125972221 :       last->set_next_use (use);
    1225                 :   125972221 :       first->set_last_use (use);
    1226                 :             : 
    1227                 :   125972221 :       gcc_checking_assert (use->check_integrity ());
    1228                 :             :       return;
    1229                 :             :     }
    1230                 :             : 
    1231                 :             :   // If there is currently no splay tree for this definition, see if can
    1232                 :             :   // get away with a pure list-based update.
    1233                 :   470586768 :   insn_info *insn = use->insn ();
    1234                 :   935435005 :   auto quick_path = [&]()
    1235                 :             :     {
    1236                 :             :       // Check if USE should come before all current uses.
    1237                 :   464848237 :       if (first->is_in_phi () || compare_use_insns (insn, first->insn ()) < 0)
    1238                 :             :         {
    1239                 :    19016641 :           insert_use_before (use, first);
    1240                 :    19016641 :           return true;
    1241                 :             :         }
    1242                 :             : 
    1243                 :             :       // Check if USE should come after all current uses in the same
    1244                 :             :       // subsequence (i.e. the list of nondebug insn uses or the list
    1245                 :             :       // of debug insn uses).
    1246                 :   445831596 :       use_info *last = first->last_use ();
    1247                 :   445831596 :       if (use->is_in_debug_insn ())
    1248                 :             :         {
    1249                 :    50250882 :           if (last->is_in_phi ())
    1250                 :             :             return false;
    1251                 :             :         }
    1252                 :             :       else
    1253                 :   395580714 :         last = last->last_nondebug_insn_use ();
    1254                 :             : 
    1255                 :   445127182 :       if (compare_use_insns (insn, last->insn ()) > 0)
    1256                 :             :         {
    1257                 :   444134441 :           insert_use_after (use, last);
    1258                 :   444134441 :           return true;
    1259                 :             :         }
    1260                 :             : 
    1261                 :             :       return false;
    1262                 :   470586768 :     };
    1263                 :   470586768 :   if (!def->m_use_tree && quick_path ())
    1264                 :             :     return;
    1265                 :             : 
    1266                 :             :   // Search the splay tree for an insertion point.  COMPARISON is less
    1267                 :             :   // than zero if USE should come before NEIGHBOR, or greater than zero
    1268                 :             :   // if USE should come after NEIGHBOR.
    1269                 :     7435686 :   need_use_splay_tree (def);
    1270                 :     7435686 :   int comparison = lookup_use (def->m_use_tree, insn);
    1271                 :     7435686 :   gcc_checking_assert (comparison != 0);
    1272                 :     7435686 :   use_info *neighbor = def->m_use_tree.root ()->value ();
    1273                 :             : 
    1274                 :             :   // If USE comes before NEIGHBOR, insert USE to NEIGHBOR's left,
    1275                 :             :   // otherwise insert USE to NEIGHBOR's right.
    1276                 :     7435686 :   auto *use_node = allocate<splay_tree_node<use_info *>> (use);
    1277                 :     7435686 :   def->m_use_tree.insert_relative (comparison, use_node);
    1278                 :     7435686 :   if (comparison > 0)
    1279                 :     4848372 :     insert_use_after (use, neighbor);
    1280                 :             :   else
    1281                 :     2587314 :     insert_use_before (use, neighbor);
    1282                 :             : }
    1283                 :             : 
    1284                 :             : void
    1285                 :           0 : function_info::reparent_use (use_info *use, set_info *new_def)
    1286                 :             : {
    1287                 :           0 :   remove_use (use);
    1288                 :           0 :   use->set_def (new_def);
    1289                 :           0 :   add_use (use);
    1290                 :           0 : }
    1291                 :             : 
    1292                 :             : // If USE has a known definition, remove USE from that definition's list
    1293                 :             : // of uses.  Also remove if it from the associated splay tree, if any.
    1294                 :             : void
    1295                 :    45243504 : function_info::remove_use (use_info *use)
    1296                 :             : {
    1297                 :    45243504 :   set_info *def = use->def ();
    1298                 :    45243504 :   if (!def)
    1299                 :             :     return;
    1300                 :             : 
    1301                 :             :   // Remove USE from the splay tree.
    1302                 :    45168888 :   if (def->m_use_tree && use->is_in_any_insn ())
    1303                 :             :     {
    1304                 :     1759772 :       int comparison = lookup_use (def->m_use_tree, use->insn ());
    1305                 :     1759772 :       gcc_checking_assert (comparison == 0);
    1306                 :     1759772 :       def->m_use_tree.remove_root ();
    1307                 :             :     }
    1308                 :             : 
    1309                 :    45168888 :   use_info *prev = use->prev_use ();
    1310                 :    45168888 :   use_info *next = use->next_use ();
    1311                 :             : 
    1312                 :    45168888 :   use_info *first = def->first_use ();
    1313                 :    45168888 :   use_info *last = first->last_use ();
    1314                 :    45168888 :   if (last->last_nondebug_insn_use () == use)
    1315                 :    16848958 :     last->set_last_nondebug_insn_use (prev);
    1316                 :             : 
    1317                 :    45168888 :   if (next)
    1318                 :    14946872 :     next->copy_prev_from (use);
    1319                 :             :   else
    1320                 :    30222016 :     first->set_last_use (prev);
    1321                 :             : 
    1322                 :    45168888 :   if (prev)
    1323                 :    20159171 :     prev->copy_next_from (use);
    1324                 :             :   else
    1325                 :    50019434 :     def->set_first_use (next);
    1326                 :             : 
    1327                 :    45168888 :   use->clear_use_links ();
    1328                 :    45168888 :   gcc_checking_assert ((!prev || prev->check_integrity ())
    1329                 :             :                        && (!next || next->check_integrity ()));
    1330                 :             : }
    1331                 :             : 
    1332                 :             : // Allocate a temporary clobber_info for register REGNO in insn INSN,
    1333                 :             : // including it in the region of the obstack governed by WATERMARK.
    1334                 :             : // Return a new def_array that contains OLD_DEFS and the new clobber.
    1335                 :             : //
    1336                 :             : // OLD_DEFS is known not to define REGNO.
    1337                 :             : def_array
    1338                 :     2031145 : function_info::insert_temp_clobber (obstack_watermark &watermark,
    1339                 :             :                                     insn_info *insn, unsigned int regno,
    1340                 :             :                                     def_array old_defs)
    1341                 :             : {
    1342                 :     2031145 :   gcc_checking_assert (watermark == &m_temp_obstack);
    1343                 :     2031145 :   auto *clobber = allocate_temp<clobber_info> (insn, regno);
    1344                 :     2031145 :   clobber->m_is_temp = true;
    1345                 :     2031145 :   return insert_access (watermark, clobber, old_defs);
    1346                 :             : }
    1347                 :             : 
    1348                 :             : // See the comment above the declaration.
    1349                 :             : bool
    1350                 :     4650418 : function_info::remains_available_at_insn (const set_info *set,
    1351                 :             :                                           insn_info *insn)
    1352                 :             : {
    1353                 :     4650418 :   auto *ebb = set->ebb ();
    1354                 :     4650418 :   gcc_checking_assert (ebb == insn->ebb ());
    1355                 :             : 
    1356                 :     4650418 :   def_info *next_def = set->next_def ();
    1357                 :     4334524 :   if (next_def && *next_def->insn () < *insn)
    1358                 :             :     return false;
    1359                 :             : 
    1360                 :     3988866 :   if (HARD_REGISTER_NUM_P (set->regno ())
    1361                 :     3988866 :       && TEST_HARD_REG_BIT (m_clobbered_by_calls, set->regno ()))
    1362                 :      294421 :     for (ebb_call_clobbers_info *call_group : ebb->call_clobbers ())
    1363                 :             :       {
    1364                 :       55541 :         if (!call_group->clobbers (set->resource ()))
    1365                 :        1189 :           continue;
    1366                 :             : 
    1367                 :       54352 :         insn_info *call_insn = next_call_clobbers (*call_group, insn);
    1368                 :       54352 :         if (call_insn && *call_insn < *insn)
    1369                 :      661552 :           return false;
    1370                 :             :       }
    1371                 :             : 
    1372                 :             :   return true;
    1373                 :             : }
    1374                 :             : 
    1375                 :             : // See the comment above the declaration.
    1376                 :             : bool
    1377                 :      457748 : function_info::remains_available_on_exit (const set_info *set, bb_info *bb)
    1378                 :             : {
    1379                 :      457748 :   if (HARD_REGISTER_NUM_P (set->regno ())
    1380                 :      457748 :       && TEST_HARD_REG_BIT (m_clobbered_by_calls, set->regno ()))
    1381                 :             :     {
    1382                 :       39506 :       insn_info *search_insn = (set->bb () == bb
    1383                 :       39506 :                                 ? set->insn ()
    1384                 :        3143 :                                 : bb->head_insn ());
    1385                 :       49967 :       for (ebb_call_clobbers_info *call_group : bb->ebb ()->call_clobbers ())
    1386                 :             :         {
    1387                 :       13326 :           if (!call_group->clobbers (set->resource ()))
    1388                 :           5 :             continue;
    1389                 :             : 
    1390                 :       13321 :           insn_info *insn = next_call_clobbers (*call_group, search_insn);
    1391                 :       13321 :           if (insn && insn->bb () == bb)
    1392                 :       95069 :             return false;
    1393                 :             :         }
    1394                 :             :     }
    1395                 :             : 
    1396                 :      454883 :   return (set->is_last_def ()
    1397                 :      888356 :           || *set->next_def ()->insn () > *bb->end_insn ());
    1398                 :             : }
    1399                 :             : 
    1400                 :             : // A subroutine of make_uses_available.  Try to make USE's definition
    1401                 :             : // available at the head of BB.  WILL_BE_DEBUG_USE is true if the
    1402                 :             : // definition will be used only in debug instructions.
    1403                 :             : //
    1404                 :             : // On success:
    1405                 :             : //
    1406                 :             : // - If the use would have the same def () as USE, return USE.
    1407                 :             : //
    1408                 :             : // - If BB already has a degenerate phi for the same definition,
    1409                 :             : //   return a temporary use of that phi.
    1410                 :             : //
    1411                 :             : // - Otherwise, the use would need a new degenerate phi.  Allocate a
    1412                 :             : //   temporary phi and return a temporary use of it.
    1413                 :             : //
    1414                 :             : // Return null on failure.
    1415                 :             : use_info *
    1416                 :    19598527 : function_info::make_use_available (use_info *use, bb_info *bb,
    1417                 :             :                                    bool will_be_debug_use)
    1418                 :             : {
    1419                 :    19598527 :   set_info *def = use->def ();
    1420                 :    19598527 :   if (!def)
    1421                 :             :     return use;
    1422                 :             : 
    1423                 :    19559502 :   if (is_single_dominating_def (def))
    1424                 :             :     return use;
    1425                 :             : 
    1426                 :     7838637 :   if (def->ebb () == bb->ebb ())
    1427                 :             :     {
    1428                 :     4650418 :       if (remains_available_at_insn (def, bb->head_insn ()))
    1429                 :             :         return use;
    1430                 :             :       return nullptr;
    1431                 :             :     }
    1432                 :             : 
    1433                 :     3188219 :   basic_block cfg_bb = bb->cfg_bb ();
    1434                 :     3188219 :   bb_info *use_bb = use->bb ();
    1435                 :     3188219 :   if (single_pred_p (cfg_bb)
    1436                 :     1975881 :       && single_pred (cfg_bb) == use_bb->cfg_bb ()
    1437                 :     3645967 :       && remains_available_on_exit (def, use_bb))
    1438                 :             :     {
    1439                 :      362679 :       if (will_be_debug_use)
    1440                 :             :         return use;
    1441                 :             : 
    1442                 :      320010 :       resource_info resource = use->resource ();
    1443                 :      320010 :       set_info *ultimate_def = look_through_degenerate_phi (def);
    1444                 :             : 
    1445                 :             :       // See if there is already a (degenerate) phi for DEF.
    1446                 :      320010 :       insn_info *phi_insn = bb->ebb ()->phi_insn ();
    1447                 :      320010 :       phi_info *phi;
    1448                 :      320010 :       def_lookup dl = find_def (resource, phi_insn);
    1449                 :      320010 :       if (set_info *set = dl.matching_set ())
    1450                 :             :         {
    1451                 :             :           // There is an existing phi.
    1452                 :      138238 :           phi = as_a<phi_info *> (set);
    1453                 :      138238 :           gcc_checking_assert (phi->input_value (0) == ultimate_def);
    1454                 :             :         }
    1455                 :             :       else
    1456                 :             :         {
    1457                 :             :           // Create a temporary placeholder phi.  This will become
    1458                 :             :           // permanent if the change is later committed.
    1459                 :      181772 :           phi = allocate_temp<phi_info> (phi_insn, resource, 0);
    1460                 :      181772 :           auto *input = allocate_temp<use_info> (phi, resource, ultimate_def);
    1461                 :      181772 :           input->m_is_temp = true;
    1462                 :      181772 :           phi->m_is_temp = true;
    1463                 :      181772 :           phi->make_degenerate (input);
    1464                 :      181772 :           if (def_info *prev = dl.prev_def (phi_insn))
    1465                 :      181772 :             phi->set_prev_def (prev);
    1466                 :      181772 :           if (def_info *next = dl.next_def (phi_insn))
    1467                 :      156882 :             phi->set_next_def (next);
    1468                 :             :         }
    1469                 :             : 
    1470                 :             :       // Create a temporary use of the phi at the head of the first
    1471                 :             :       // block, since we know for sure that it's available there.
    1472                 :      320010 :       insn_info *use_insn = bb->ebb ()->first_bb ()->head_insn ();
    1473                 :      320010 :       auto *new_use = allocate_temp<use_info> (use_insn, resource, phi);
    1474                 :      320010 :       new_use->m_is_temp = true;
    1475                 :      320010 :       return new_use;
    1476                 :             :     }
    1477                 :             :   return nullptr;
    1478                 :             : }
    1479                 :             : 
    1480                 :             : // See the comment above the declaration.
    1481                 :             : use_array
    1482                 :    12384504 : function_info::make_uses_available (obstack_watermark &watermark,
    1483                 :             :                                     use_array uses, bb_info *bb,
    1484                 :             :                                     bool will_be_debug_uses)
    1485                 :             : {
    1486                 :    12384504 :   unsigned int num_uses = uses.size ();
    1487                 :    12384504 :   if (num_uses == 0)
    1488                 :      386301 :     return uses;
    1489                 :             : 
    1490                 :    11998203 :   auto **new_uses = XOBNEWVEC (watermark, access_info *, num_uses);
    1491                 :    28109638 :   for (unsigned int i = 0; i < num_uses; ++i)
    1492                 :             :     {
    1493                 :    19598527 :       use_info *use = make_use_available (uses[i], bb, will_be_debug_uses);
    1494                 :    19598527 :       if (!use)
    1495                 :     3487092 :         return use_array (access_array::invalid ());
    1496                 :    16111435 :       new_uses[i] = use;
    1497                 :             :     }
    1498                 :     8511111 :   return use_array (new_uses, num_uses);
    1499                 :             : }
    1500                 :             : 
    1501                 :             : set_info *
    1502                 :           0 : function_info::create_set (obstack_watermark &watermark,
    1503                 :             :                            insn_info *insn,
    1504                 :             :                            resource_info resource)
    1505                 :             : {
    1506                 :           0 :   auto set = change_alloc<set_info> (watermark, insn, resource);
    1507                 :           0 :   set->m_is_temp = true;
    1508                 :           0 :   return set;
    1509                 :             : }
    1510                 :             : 
    1511                 :             : use_info *
    1512                 :           0 : function_info::create_use (obstack_watermark &watermark,
    1513                 :             :                            insn_info *insn,
    1514                 :             :                            set_info *set)
    1515                 :             : {
    1516                 :           0 :   auto use = change_alloc<use_info> (watermark, insn, set->resource (), set);
    1517                 :           0 :   use->m_is_temp = true;
    1518                 :           0 :   return use;
    1519                 :             : }
    1520                 :             : 
    1521                 :             : // Return true if ACCESS1 can represent ACCESS2 and if ACCESS2 can
    1522                 :             : // represent ACCESS1.
    1523                 :             : static bool
    1524                 :    10103680 : can_merge_accesses (access_info *access1, access_info *access2)
    1525                 :             : {
    1526                 :    10103680 :   if (access1 == access2)
    1527                 :             :     return true;
    1528                 :             : 
    1529                 :    10103680 :   auto *use1 = dyn_cast<use_info *> (access1);
    1530                 :    10103680 :   auto *use2 = dyn_cast<use_info *> (access2);
    1531                 :    10103680 :   return use1 && use2 && use1->def () == use2->def ();
    1532                 :             : }
    1533                 :             : 
    1534                 :             : // See the comment above the declaration.
    1535                 :             : access_array
    1536                 :    64721690 : rtl_ssa::merge_access_arrays_base (obstack_watermark &watermark,
    1537                 :             :                                    access_array accesses1,
    1538                 :             :                                    access_array accesses2)
    1539                 :             : {
    1540                 :    64721690 :   if (accesses1.empty ())
    1541                 :     2220561 :     return accesses2;
    1542                 :    62501129 :   if (accesses2.empty ())
    1543                 :    17745922 :     return accesses1;
    1544                 :             : 
    1545                 :    44755207 :   auto i1 = accesses1.begin ();
    1546                 :    44755207 :   auto end1 = accesses1.end ();
    1547                 :    44755207 :   auto i2 = accesses2.begin ();
    1548                 :    44755207 :   auto end2 = accesses2.end ();
    1549                 :             : 
    1550                 :    44755207 :   access_array_builder builder (watermark);
    1551                 :    44755207 :   builder.reserve (accesses1.size () + accesses2.size ());
    1552                 :             : 
    1553                 :   166652351 :   while (i1 != end1 && i2 != end2)
    1554                 :             :     {
    1555                 :    79624128 :       access_info *access1 = *i1;
    1556                 :    79624128 :       access_info *access2 = *i2;
    1557                 :             : 
    1558                 :    79624128 :       unsigned int regno1 = access1->regno ();
    1559                 :    79624128 :       unsigned int regno2 = access2->regno ();
    1560                 :    79624128 :       if (regno1 == regno2)
    1561                 :             :         {
    1562                 :    10103680 :           if (!can_merge_accesses (access1, access2))
    1563                 :     2482191 :             return access_array::invalid ();
    1564                 :             : 
    1565                 :     7621489 :           builder.quick_push (access1);
    1566                 :     7621489 :           ++i1;
    1567                 :     7621489 :           ++i2;
    1568                 :             :         }
    1569                 :    69520448 :       else if (regno1 < regno2)
    1570                 :             :         {
    1571                 :    39344229 :           builder.quick_push (access1);
    1572                 :    39344229 :           ++i1;
    1573                 :             :         }
    1574                 :             :       else
    1575                 :             :         {
    1576                 :    30176219 :           builder.quick_push (access2);
    1577                 :    30176219 :           ++i2;
    1578                 :             :         }
    1579                 :             :     }
    1580                 :    70025571 :   for (; i1 != end1; ++i1)
    1581                 :    27752555 :     builder.quick_push (*i1);
    1582                 :    64182930 :   for (; i2 != end2; ++i2)
    1583                 :    21909914 :     builder.quick_push (*i2);
    1584                 :             : 
    1585                 :    42273016 :   return builder.finish ();
    1586                 :    44755207 : }
    1587                 :             : 
    1588                 :             : // See the comment above the declaration.
    1589                 :             : access_array
    1590                 :     2031145 : rtl_ssa::insert_access_base (obstack_watermark &watermark,
    1591                 :             :                              access_info *access1, access_array accesses2)
    1592                 :             : {
    1593                 :     2031145 :   access_array_builder builder (watermark);
    1594                 :     2031145 :   builder.reserve (1 + accesses2.size ());
    1595                 :             : 
    1596                 :     2031145 :   unsigned int regno1 = access1->regno ();
    1597                 :     2031145 :   auto i2 = accesses2.begin ();
    1598                 :     2031145 :   auto end2 = accesses2.end ();
    1599                 :     5707968 :   while (i2 != end2)
    1600                 :             :     {
    1601                 :     2033265 :       access_info *access2 = *i2;
    1602                 :             : 
    1603                 :     2033265 :       unsigned int regno2 = access2->regno ();
    1604                 :     2033265 :       if (regno1 == regno2)
    1605                 :             :         {
    1606                 :           0 :           if (!can_merge_accesses (access1, access2))
    1607                 :           0 :             return access_array::invalid ();
    1608                 :             : 
    1609                 :           0 :           builder.quick_push (access1);
    1610                 :           0 :           access1 = nullptr;
    1611                 :           0 :           ++i2;
    1612                 :           0 :           break;
    1613                 :             :         }
    1614                 :     2033265 :       else if (regno1 < regno2)
    1615                 :             :         {
    1616                 :      387587 :           builder.quick_push (access1);
    1617                 :      387587 :           access1 = nullptr;
    1618                 :      387587 :           break;
    1619                 :             :         }
    1620                 :             :       else
    1621                 :             :         {
    1622                 :     1645678 :           builder.quick_push (access2);
    1623                 :     1645678 :           ++i2;
    1624                 :             :         }
    1625                 :             :     }
    1626                 :      387587 :   if (access1)
    1627                 :     1643558 :     builder.quick_push (access1);
    1628                 :     2418734 :   for (; i2 != end2; ++i2)
    1629                 :      387589 :     builder.quick_push (*i2);
    1630                 :             : 
    1631                 :     2031145 :   return builder.finish ();
    1632                 :     2031145 : }
    1633                 :             : 
    1634                 :             : // See the comment above the declaration.
    1635                 :             : use_array
    1636                 :    31411591 : rtl_ssa::remove_uses_of_def (obstack_watermark &watermark, use_array uses,
    1637                 :             :                              def_info *def)
    1638                 :             : {
    1639                 :    31411591 :   access_array_builder uses_builder (watermark);
    1640                 :    31411591 :   uses_builder.reserve (uses.size ());
    1641                 :    85050147 :   for (use_info *use : uses)
    1642                 :    53638556 :     if (use->def () != def)
    1643                 :    22226965 :       uses_builder.quick_push (use);
    1644                 :    31411591 :   return use_array (uses_builder.finish ());
    1645                 :    31411591 : }
    1646                 :             : 
    1647                 :             : // See the comment above the declaration.
    1648                 :             : access_array
    1649                 :    54802241 : rtl_ssa::remove_note_accesses_base (obstack_watermark &watermark,
    1650                 :             :                                     access_array accesses)
    1651                 :             : {
    1652                 :    57689799 :   auto predicate = [](access_info *a) {
    1653                 :     2887558 :     return !a->only_occurs_in_notes ();
    1654                 :             :   };
    1655                 :             : 
    1656                 :   124523927 :   for (access_info *access : accesses)
    1657                 :    70750403 :     if (access->only_occurs_in_notes ())
    1658                 :     1028717 :       return filter_accesses (watermark, accesses, predicate);
    1659                 :             : 
    1660                 :    53773524 :   return accesses;
    1661                 :             : }
    1662                 :             : 
    1663                 :             : // See the comment above the declaration.
    1664                 :             : bool
    1665                 :     8554198 : rtl_ssa::accesses_reference_same_resource (access_array accesses1,
    1666                 :             :                                            access_array accesses2)
    1667                 :             : {
    1668                 :     8554198 :   auto i1 = accesses1.begin ();
    1669                 :     8554198 :   auto end1 = accesses1.end ();
    1670                 :     8554198 :   auto i2 = accesses2.begin ();
    1671                 :     8554198 :   auto end2 = accesses2.end ();
    1672                 :             : 
    1673                 :    27067104 :   while (i1 != end1 && i2 != end2)
    1674                 :             :     {
    1675                 :    10584196 :       access_info *access1 = *i1;
    1676                 :    10584196 :       access_info *access2 = *i2;
    1677                 :             : 
    1678                 :    10584196 :       unsigned int regno1 = access1->regno ();
    1679                 :    10584196 :       unsigned int regno2 = access2->regno ();
    1680                 :    10584196 :       if (regno1 == regno2)
    1681                 :             :         return true;
    1682                 :             : 
    1683                 :     9958708 :       if (regno1 < regno2)
    1684                 :     4875146 :         ++i1;
    1685                 :             :       else
    1686                 :     5083562 :         ++i2;
    1687                 :             :     }
    1688                 :             :   return false;
    1689                 :             : }
    1690                 :             : 
    1691                 :             : // See the comment above the declaration.
    1692                 :             : bool
    1693                 :     8554198 : rtl_ssa::insn_clobbers_resources (insn_info *insn, access_array accesses)
    1694                 :             : {
    1695                 :     8554198 :   if (accesses_reference_same_resource (insn->defs (), accesses))
    1696                 :             :     return true;
    1697                 :             : 
    1698                 :     7928710 :   if (insn->is_call () && accesses_include_hard_registers (accesses))
    1699                 :             :     {
    1700                 :         732 :       function_abi abi = insn_callee_abi (insn->rtl ());
    1701                 :         769 :       for (const access_info *access : accesses)
    1702                 :             :         {
    1703                 :         732 :           if (!HARD_REGISTER_NUM_P (access->regno ()))
    1704                 :             :             break;
    1705                 :         732 :           if (abi.clobbers_reg_p (access->mode (), access->regno ()))
    1706                 :         695 :             return true;
    1707                 :             :         }
    1708                 :             :     }
    1709                 :             : 
    1710                 :             :   return false;
    1711                 :             : }
    1712                 :             : 
    1713                 :             : // Print RESOURCE to PP.
    1714                 :             : void
    1715                 :           0 : rtl_ssa::pp_resource (pretty_printer *pp, resource_info resource)
    1716                 :             : {
    1717                 :           0 :   resource.print (pp);
    1718                 :           0 : }
    1719                 :             : 
    1720                 :             : // Print ACCESS to PP.  FLAGS is a bitmask of PP_ACCESS_* flags.
    1721                 :             : void
    1722                 :           0 : rtl_ssa::pp_access (pretty_printer *pp, const access_info *access,
    1723                 :             :                     unsigned int flags)
    1724                 :             : {
    1725                 :           0 :   if (!access)
    1726                 :           0 :     pp_string (pp, "<null>");
    1727                 :           0 :   else if (auto *phi = dyn_cast<const phi_info *> (access))
    1728                 :           0 :     phi->print (pp, flags);
    1729                 :           0 :   else if (auto *set = dyn_cast<const set_info *> (access))
    1730                 :           0 :     set->print (pp, flags);
    1731                 :           0 :   else if (auto *clobber = dyn_cast<const clobber_info *> (access))
    1732                 :           0 :     clobber->print (pp, flags);
    1733                 :           0 :   else if (auto *use = dyn_cast<const use_info *> (access))
    1734                 :           0 :     use->print (pp, flags);
    1735                 :             :   else
    1736                 :             :     pp_string (pp, "??? Unknown access");
    1737                 :           0 : }
    1738                 :             : 
    1739                 :             : // Print ACCESSES to PP.  FLAGS is a bitmask of PP_ACCESS_* flags.
    1740                 :             : void
    1741                 :           0 : rtl_ssa::pp_accesses (pretty_printer *pp, access_array accesses,
    1742                 :             :                       unsigned int flags)
    1743                 :             : {
    1744                 :           0 :   if (accesses.empty ())
    1745                 :           0 :     pp_string (pp, "none");
    1746                 :             :   else
    1747                 :             :     {
    1748                 :           0 :       bool is_first = true;
    1749                 :           0 :       for (access_info *access : accesses)
    1750                 :             :         {
    1751                 :           0 :           if (is_first)
    1752                 :             :             is_first = false;
    1753                 :             :           else
    1754                 :           0 :             pp_newline_and_indent (pp, 0);
    1755                 :           0 :           pp_access (pp, access, flags);
    1756                 :             :         }
    1757                 :             :     }
    1758                 :           0 : }
    1759                 :             : 
    1760                 :             : // Print NODE to PP.
    1761                 :             : void
    1762                 :           0 : rtl_ssa::pp_def_node (pretty_printer *pp, const def_node *node)
    1763                 :             : {
    1764                 :           0 :   if (!node)
    1765                 :           0 :     pp_string (pp, "<null>");
    1766                 :           0 :   else if (auto *group = dyn_cast<const clobber_group *> (node))
    1767                 :           0 :     group->print (pp);
    1768                 :           0 :   else if (auto *set = dyn_cast<const set_node *> (node))
    1769                 :           0 :     set->print (pp);
    1770                 :             :   else
    1771                 :           0 :     pp_string (pp, "??? Unknown def node");
    1772                 :           0 : }
    1773                 :             : 
    1774                 :             : // Print MUX to PP.
    1775                 :             : void
    1776                 :           0 : rtl_ssa::pp_def_mux (pretty_printer *pp, def_mux mux)
    1777                 :             : {
    1778                 :           0 :   if (auto *node = mux.dyn_cast<def_node *> ())
    1779                 :           0 :     pp_def_node (pp, node);
    1780                 :             :   else
    1781                 :           0 :     pp_access (pp, mux.as_a<def_info *> ());
    1782                 :           0 : }
    1783                 :             : 
    1784                 :             : // Print DL to PP.
    1785                 :             : void
    1786                 :           0 : rtl_ssa::pp_def_lookup (pretty_printer *pp, def_lookup dl)
    1787                 :             : {
    1788                 :           0 :   pp_string (pp, "comparison result of ");
    1789                 :           0 :   pp_decimal_int (pp, dl.comparison);
    1790                 :           0 :   pp_string (pp, " for ");
    1791                 :           0 :   pp_newline_and_indent (pp, 0);
    1792                 :           0 :   pp_def_mux (pp, dl.mux);
    1793                 :           0 : }
    1794                 :             : 
    1795                 :             : // Print TREE to PP.
    1796                 :             : void
    1797                 :           0 : rtl_ssa::pp_def_splay_tree (pretty_printer *pp, def_splay_tree tree)
    1798                 :             : {
    1799                 :           0 :   tree.print (pp, pp_def_node);
    1800                 :           0 : }
    1801                 :             : 
    1802                 :             : // Dump RESOURCE to FILE.
    1803                 :             : void
    1804                 :           0 : dump (FILE *file, resource_info resource)
    1805                 :             : {
    1806                 :           0 :   dump_using (file, pp_resource, resource);
    1807                 :           0 : }
    1808                 :             : 
    1809                 :             : // Dump ACCESS to FILE.  FLAGS is a bitmask of PP_ACCESS_* flags.
    1810                 :             : void
    1811                 :           0 : dump (FILE *file, const access_info *access, unsigned int flags)
    1812                 :             : {
    1813                 :           0 :   dump_using (file, pp_access, access, flags);
    1814                 :           0 : }
    1815                 :             : 
    1816                 :             : // Dump ACCESSES to FILE.  FLAGS is a bitmask of PP_ACCESS_* flags.
    1817                 :             : void
    1818                 :           0 : dump (FILE *file, access_array accesses, unsigned int flags)
    1819                 :             : {
    1820                 :           0 :   dump_using (file, pp_accesses, accesses, flags);
    1821                 :           0 : }
    1822                 :             : 
    1823                 :             : // Print NODE to FILE.
    1824                 :             : void
    1825                 :           0 : dump (FILE *file, const def_node *node)
    1826                 :             : {
    1827                 :           0 :   dump_using (file, pp_def_node, node);
    1828                 :           0 : }
    1829                 :             : 
    1830                 :             : // Print MUX to FILE.
    1831                 :             : void
    1832                 :           0 : dump (FILE *file, def_mux mux)
    1833                 :             : {
    1834                 :           0 :   dump_using (file, pp_def_mux, mux);
    1835                 :           0 : }
    1836                 :             : 
    1837                 :             : // Print RESULT to FILE.
    1838                 :             : void
    1839                 :           0 : dump (FILE *file, def_lookup result)
    1840                 :             : {
    1841                 :           0 :   dump_using (file, pp_def_lookup, result);
    1842                 :           0 : }
    1843                 :             : 
    1844                 :             : // Print TREE to FILE.
    1845                 :             : void
    1846                 :           0 : dump (FILE *file, def_splay_tree tree)
    1847                 :             : {
    1848                 :           0 :   dump_using (file, pp_def_splay_tree, tree);
    1849                 :           0 : }
    1850                 :             : 
    1851                 :             : // Debug interfaces to the dump routines above.
    1852                 :           0 : void debug (const resource_info &x) { dump (stderr, x); }
    1853                 :           0 : void debug (const access_info *x) { dump (stderr, x); }
    1854                 :           0 : void debug (const access_array &x) { dump (stderr, x); }
    1855                 :           0 : void debug (const def_node *x) { dump (stderr, x); }
    1856                 :           0 : void debug (const def_mux &x) { dump (stderr, x); }
    1857                 :           0 : void debug (const def_lookup &x) { dump (stderr, x); }
    1858                 :           0 : void debug (const def_splay_tree &x) { dump (stderr, x); }
        

Generated by: LCOV version 2.1-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.