LCOV - code coverage report
Current view: top level - gcc/rtl-ssa - functions.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 86.2 % 123 106
Test Date: 2024-04-20 14:03:02 Functions: 60.0 % 10 6
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : // Implementation of function-related RTL SSA functions             -*- C++ -*-
       2                 :             : // Copyright (C) 2020-2024 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                 :             : #include "config.h"
      23                 :             : #include "system.h"
      24                 :             : #include "coretypes.h"
      25                 :             : #include "backend.h"
      26                 :             : #include "rtl.h"
      27                 :             : #include "df.h"
      28                 :             : #include "rtl-ssa.h"
      29                 :             : #include "rtl-ssa/internals.h"
      30                 :             : #include "rtl-ssa/internals.inl"
      31                 :             : 
      32                 :             : using namespace rtl_ssa;
      33                 :             : 
      34                 :     1975264 : function_info::function_info (function *fn)
      35                 :     3950528 :   : m_fn (fn), m_clobbered_by_calls ()
      36                 :             : {
      37                 :             :   // Force the alignment to be obstack_alignment.  Everything else is normal.
      38                 :     1975264 :   obstack_specify_allocation (&m_obstack, OBSTACK_CHUNK_SIZE,
      39                 :             :                               obstack_alignment, obstack_chunk_alloc,
      40                 :             :                               obstack_chunk_free);
      41                 :     1975264 :   obstack_specify_allocation (&m_temp_obstack, OBSTACK_CHUNK_SIZE,
      42                 :             :                               obstack_alignment, obstack_chunk_alloc,
      43                 :             :                               obstack_chunk_free);
      44                 :             : 
      45                 :             :   // Record the start of the obstacks.
      46                 :     1975264 :   m_obstack_start = XOBNEWVAR (&m_obstack, char, 0);
      47                 :     1975264 :   m_temp_obstack_start = XOBNEWVAR (&m_temp_obstack, char, 0);
      48                 :             : 
      49                 :     1975264 :   init_function_data ();
      50                 :     1975264 :   process_all_blocks ();
      51                 :     1975264 :   simplify_phis ();
      52                 :     1975264 : }
      53                 :             : 
      54                 :     1975264 : function_info::~function_info ()
      55                 :             : {
      56                 :             :   // Anything using the temporary obstack should free it afterwards,
      57                 :             :   // preferably via temp_watermark ().
      58                 :     1975264 :   gcc_assert (XOBNEWVAR (&m_temp_obstack, char, 0) == m_temp_obstack_start);
      59                 :             : 
      60                 :     1975264 :   obstack_free (&m_temp_obstack, nullptr);
      61                 :     1975264 :   obstack_free (&m_obstack, nullptr);
      62                 :     1975264 : }
      63                 :             : 
      64                 :             : // See the comment above the declaration.
      65                 :             : void
      66                 :           0 : function_info::print (pretty_printer *pp) const
      67                 :             : {
      68                 :           0 :   pp_string (pp, "Function: ");
      69                 :           0 :   pp_string (pp, function_name (m_fn));
      70                 :           0 :   for (ebb_info *ebb : ebbs ())
      71                 :             :     {
      72                 :           0 :       pp_newline (pp);
      73                 :           0 :       pp_newline_and_indent (pp, 0);
      74                 :           0 :       pp_ebb (pp, ebb);
      75                 :             :     }
      76                 :           0 : }
      77                 :             : 
      78                 :             : // Initialize all member variables in preparation for (re)building
      79                 :             : // SSA form from scratch.
      80                 :             : void
      81                 :     1975264 : function_info::init_function_data ()
      82                 :             : {
      83                 :     1975264 :   m_next_artificial_uid = -1;
      84                 :     1975264 :   m_next_phi_uid = 0;
      85                 :     1975264 :   m_num_regs = max_reg_num ();
      86                 :     1975264 :   m_defs.safe_grow_cleared (m_num_regs + 1);
      87                 :     1975264 :   m_bbs.safe_grow_cleared (last_basic_block_for_fn (m_fn));
      88                 :     1975264 :   m_first_bb = nullptr;
      89                 :     1975264 :   m_last_bb = nullptr;
      90                 :     1975264 :   m_first_insn = nullptr;
      91                 :     1975264 :   m_last_insn = nullptr;
      92                 :     1975264 :   m_last_nondebug_insn = nullptr;
      93                 :     1975264 :   m_free_phis = nullptr;
      94                 :     1975264 : }
      95                 :             : 
      96                 :             : // The initial phase of the phi simplification process.  The cumulative
      97                 :             : // effect of the initial phase is to set up ASSUMED_VALUES such that,
      98                 :             : // for a phi P with uid ID:
      99                 :             : //
     100                 :             : // - if we think all inputs to P have the same value, ASSUMED_VALUES[ID]
     101                 :             : //   is that value
     102                 :             : //
     103                 :             : // - otherwise, ASSUMED_VALUES[ID] is P.
     104                 :             : //
     105                 :             : // This has already been done for phis with a lower uid than PHI,
     106                 :             : // initially making optimistic assumptions about backedge inputs.
     107                 :             : // Now do the same for PHI.  If this might invalidate any assumptions
     108                 :             : // made for earlier phis, add the uids of those phis to WORKLIST.
     109                 :             : void
     110                 :    25449971 : function_info::simplify_phi_setup (phi_info *phi, set_info **assumed_values,
     111                 :             :                                    bitmap worklist)
     112                 :             : {
     113                 :             :   // If all non-backedge inputs have the same value, set NEW_VALUE
     114                 :             :   // to that value.  Otherwise set NEW_VALUE to PHI, to indicate
     115                 :             :   // that PHI cannot be simplified.
     116                 :    25449971 :   unsigned int phi_uid = phi->uid ();
     117                 :    25449971 :   bool is_first_input = true;
     118                 :    25449971 :   set_info *new_value = nullptr;
     119                 :    25449971 :   machine_mode phi_mode = phi->mode ();
     120                 :    93960058 :   for (use_info *input : phi->inputs ())
     121                 :             :     {
     122                 :    43060116 :       set_info *def = input->def ();
     123                 :             : 
     124                 :    43060116 :       if (auto *input_phi = safe_dyn_cast<phi_info *> (def))
     125                 :             :         {
     126                 :             :           // Ignore backedges for now.
     127                 :    10509830 :           unsigned int input_phi_uid = input_phi->uid ();
     128                 :    10509830 :           if (phi_uid <= input_phi_uid)
     129                 :      933169 :             continue;
     130                 :             : 
     131                 :     9576661 :           def = assumed_values[input_phi_uid];
     132                 :             :         }
     133                 :             : 
     134                 :             :       // Compare this definition with previous ones.
     135                 :    42126947 :       if (is_first_input)
     136                 :             :         {
     137                 :             :           new_value = def;
     138                 :             :           is_first_input = false;
     139                 :             :         }
     140                 :    16676976 :       else if (new_value != def)
     141                 :    15864157 :         new_value = phi;
     142                 :             : 
     143                 :             :       // If the input has a known mode (i.e. not BLKmode), make sure
     144                 :             :       // that the phi's mode is at least as large.
     145                 :    42126947 :       if (def)
     146                 :    42095720 :         phi_mode = combine_modes (phi_mode, def->mode ());
     147                 :             :     }
     148                 :    25449971 :   if (phi->mode () != phi_mode)
     149                 :     8386967 :     phi->set_mode (phi_mode);
     150                 :             : 
     151                 :             :   // Since we use a reverse postorder traversal, no phi can consist
     152                 :             :   // entirely of backedges.
     153                 :    25449971 :   gcc_checking_assert (!is_first_input);
     154                 :    25449971 :   assumed_values[phi_uid] = new_value;
     155                 :             : 
     156                 :             :   // See whether any assumptions for earlier phis are now invalid.
     157                 :    25449971 :   simplify_phi_propagate (phi, assumed_values, nullptr, worklist);
     158                 :    25449971 : }
     159                 :             : 
     160                 :             : // The propagation phase of the phi simplification process, with
     161                 :             : // ASSUMED_VALUES as described above simplify_phi_setup.  Iteratively
     162                 :             : // update the phis that use PHI based on PHI's entry in ASSUMED_VALUES.
     163                 :             : // If CURR_WORKLIST is null, consider only phi uses with a lower uid
     164                 :             : // than PHI, otherwise consider all phi uses.
     165                 :             : //
     166                 :             : // If a phi with a higher uid than PHI needs updating, add its uid to
     167                 :             : // CURR_WORKLIST; if a phi with a lower uid than PHI needs updating,
     168                 :             : // add its uid to NEXT_WORKLIST.
     169                 :             : void
     170                 :    26407611 : function_info::simplify_phi_propagate (phi_info *phi,
     171                 :             :                                        set_info **assumed_values,
     172                 :             :                                        bitmap curr_worklist,
     173                 :             :                                        bitmap next_worklist)
     174                 :             : {
     175                 :             :   // Go through each phi user of PHI to see whether it needs updating.
     176                 :    26407611 :   unsigned int phi_uid = phi->uid ();
     177                 :    26407611 :   machine_mode phi_mode = phi->mode ();
     178                 :    26407611 :   set_info *phi_value = assumed_values[phi_uid];
     179                 :    65250964 :   for (use_info *use : phi->phi_uses ())
     180                 :             :     {
     181                 :    12435742 :       phi_info *user_phi = use->phi ();
     182                 :             : 
     183                 :             :       // Propagate the phi's new mode to all phi users.  Insn uses should
     184                 :             :       // not be updated, since their modes reflect a property of the insns
     185                 :             :       // rather than the phi.
     186                 :    12435742 :       if (use->mode () != phi_mode)
     187                 :     6835390 :         use->set_mode (phi_mode);
     188                 :             : 
     189                 :    12435742 :       if (user_phi == phi)
     190                 :      409921 :         continue;
     191                 :             : 
     192                 :             :       // If this is a phi we should be looking at, see whether it needs
     193                 :             :       // an update.
     194                 :    12025821 :       unsigned int user_phi_uid = user_phi->uid ();
     195                 :    12025821 :       if (user_phi_uid < phi_uid || curr_worklist)
     196                 :             :         {
     197                 :     2449160 :           bool needs_update = false;
     198                 :             : 
     199                 :             :           // Make sure that USER_PHI's mode is at least as big as PHI_MODE.
     200                 :     2449160 :           machine_mode user_phi_mode = user_phi->mode ();
     201                 :     2449160 :           machine_mode new_mode = combine_modes (user_phi_mode, phi_mode);
     202                 :     2449160 :           if (user_phi_mode != new_mode)
     203                 :             :             {
     204                 :           0 :               user_phi->set_mode (new_mode);
     205                 :           0 :               needs_update = true;
     206                 :             :             }
     207                 :             : 
     208                 :             :           // If USER_PHI optimistically assumed an incorrect value,
     209                 :             :           // adjust it now.
     210                 :     2449160 :           if (assumed_values[user_phi_uid] != user_phi
     211                 :     1041828 :               && assumed_values[user_phi_uid] != phi_value)
     212                 :             :             {
     213                 :      957640 :               assumed_values[user_phi_uid] = user_phi;
     214                 :      957640 :               needs_update = true;
     215                 :             :             }
     216                 :             : 
     217                 :     2449160 :           if (needs_update)
     218                 :             :             {
     219                 :      957640 :               if (user_phi_uid < phi_uid)
     220                 :      467608 :                 bitmap_set_bit (next_worklist, user_phi_uid);
     221                 :             :               else
     222                 :      490032 :                 bitmap_set_bit (curr_worklist, user_phi_uid);
     223                 :             :             }
     224                 :             :         }
     225                 :             :     }
     226                 :    26407611 : }
     227                 :             : 
     228                 :             : // Update the modes of all phis so that they are at least as big as
     229                 :             : // all inputs.  Remove any non-degenerate phis whose inputs are all equal.
     230                 :             : void
     231                 :     1975264 : function_info::simplify_phis ()
     232                 :             : {
     233                 :     1975264 :   auto temps = temp_watermark ();
     234                 :             : 
     235                 :             :   // See the comment above simplify_phi_setup for details about this array.
     236                 :     1975264 :   auto *assumed_values = XOBNEWVEC (&m_temp_obstack, set_info *,
     237                 :             :                                     m_next_phi_uid);
     238                 :             : 
     239                 :             :   // An array of all phis, indexed by uid.
     240                 :     1975264 :   auto *phis = XOBNEWVEC (&m_temp_obstack, phi_info *, m_next_phi_uid);
     241                 :             : 
     242                 :             :   // Which phi uids are actually in use.
     243                 :     1975264 :   auto_sbitmap valid_phi_uids (m_next_phi_uid);
     244                 :     1975264 :   bitmap_clear (valid_phi_uids);
     245                 :             : 
     246                 :             :   // Bitmaps used for the main double-queue propagation phase.
     247                 :     1975264 :   auto_bitmap worklist1;
     248                 :     1975264 :   auto_bitmap worklist2;
     249                 :     1975264 :   bitmap curr_worklist = worklist1;
     250                 :     1975264 :   bitmap next_worklist = worklist2;
     251                 :             : 
     252                 :             :   // Perform the set-up phase; see simplify_phi_setup for details.
     253                 :    31214362 :   for (ebb_info *ebb : ebbs ())
     254                 :    40069520 :     for (phi_info *phi : ebb->phis ())
     255                 :             :       {
     256                 :    25449971 :         bitmap_set_bit (valid_phi_uids, phi->uid ());
     257                 :    25449971 :         phis[phi->uid ()] = phi;
     258                 :    25449971 :         simplify_phi_setup (phi, assumed_values, curr_worklist);
     259                 :             :       }
     260                 :             : 
     261                 :             :   // Iteratively process any phis that need updating; see
     262                 :             :   // simplify_phi_propagate for details.  Using a double queue
     263                 :             :   // should reduce the number of times that any given phi node
     264                 :             :   // needs to be revisited.
     265                 :     2088941 :   while (!bitmap_empty_p (curr_worklist))
     266                 :             :     {
     267                 :      957640 :       do
     268                 :             :         {
     269                 :      957640 :           unsigned int uid = bitmap_first_set_bit (curr_worklist);
     270                 :      957640 :           bitmap_clear_bit (curr_worklist, uid);
     271                 :      957640 :           simplify_phi_propagate (phis[uid], assumed_values,
     272                 :             :                                   curr_worklist, next_worklist);
     273                 :             :         }
     274                 :      957640 :       while (!bitmap_empty_p (curr_worklist));
     275                 :             :       std::swap (next_worklist, curr_worklist);
     276                 :             :     }
     277                 :             : 
     278                 :             :   // Make sure that assumed_values is a transitive closure.  This ensures
     279                 :             :   // that each use_info is only updated once.
     280                 :     1975264 :   if (flag_checking)
     281                 :    27427398 :     for (unsigned int i = 0; i < m_next_phi_uid; ++i)
     282                 :    25452178 :       if (bitmap_bit_p (valid_phi_uids, i))
     283                 :    50900707 :         if (auto *new_phi = safe_dyn_cast<phi_info *> (assumed_values[i]))
     284                 :    12701735 :           gcc_assert (assumed_values[new_phi->uid ()] == new_phi);
     285                 :             : 
     286                 :             :   // Update any phis that turned out to be equivalent to a single input.
     287                 :    27427614 :   for (unsigned int i = 0; i < m_next_phi_uid; ++i)
     288                 :    25452350 :     if (bitmap_bit_p (valid_phi_uids, i) && phis[i] != assumed_values[i])
     289                 :    15932326 :       replace_phi (phis[i], assumed_values[i]);
     290                 :     1975264 : }
     291                 :             : 
     292                 :             : // Print a description of FUNCTION to PP.
     293                 :             : void
     294                 :           0 : rtl_ssa::pp_function (pretty_printer *pp, const function_info *function)
     295                 :             : {
     296                 :           0 :   function->print (pp);
     297                 :           0 : }
     298                 :             : 
     299                 :             : // Print a description of FUNCTION to FILE.
     300                 :             : void
     301                 :           0 : dump (FILE *file, const function_info *function)
     302                 :             : {
     303                 :           0 :   dump_using (file, pp_function, function);
     304                 :           0 : }
     305                 :             : 
     306                 :             : // Debug interface to the dump routine above.
     307                 :           0 : void debug (const function_info *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.