LCOV - code coverage report
Current view: top level - gcc - tree-ssa-ter.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 89.5 % 287 257
Test Date: 2024-04-13 14:00:49 Functions: 94.1 % 17 16
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Routines for performing Temporary Expression Replacement (TER) in SSA trees.
       2                 :             :    Copyright (C) 2003-2024 Free Software Foundation, Inc.
       3                 :             :    Contributed by Andrew MacLeod  <amacleod@redhat.com>
       4                 :             : 
       5                 :             : This file is part of GCC.
       6                 :             : 
       7                 :             : GCC is free software; you can redistribute it and/or modify
       8                 :             : it under the terms of the GNU General Public License as published by
       9                 :             : the Free Software Foundation; either version 3, or (at your option)
      10                 :             : any later version.
      11                 :             : 
      12                 :             : GCC is distributed in the hope that it will be useful,
      13                 :             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      14                 :             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15                 :             : GNU General Public License for more details.
      16                 :             : 
      17                 :             : You should have received a copy of the GNU General Public License
      18                 :             : along with GCC; see the file COPYING3.  If not see
      19                 :             : <http://www.gnu.org/licenses/>.  */
      20                 :             : 
      21                 :             : 
      22                 :             : #include "config.h"
      23                 :             : #include "system.h"
      24                 :             : #include "coretypes.h"
      25                 :             : #include "backend.h"
      26                 :             : #include "tree.h"
      27                 :             : #include "gimple.h"
      28                 :             : #include "ssa.h"
      29                 :             : #include "gimple-pretty-print.h"
      30                 :             : #include "gimple-iterator.h"
      31                 :             : #include "dumpfile.h"
      32                 :             : #include "tree-ssa-live.h"
      33                 :             : #include "tree-ssa-ter.h"
      34                 :             : #include "tree-outof-ssa.h"
      35                 :             : #include "gimple-walk.h"
      36                 :             : 
      37                 :             : 
      38                 :             : /* Temporary Expression Replacement (TER)
      39                 :             : 
      40                 :             :    Replace SSA version variables during out-of-ssa with their defining
      41                 :             :    expression if there is only one use of the variable.
      42                 :             : 
      43                 :             :    This pass is required in order for the RTL expansion pass to see larger
      44                 :             :    chunks of code.  This allows it to make better choices on RTL pattern
      45                 :             :    selection.  When expand is rewritten and merged with out-of-ssa, and
      46                 :             :    understands SSA, this should be eliminated.
      47                 :             : 
      48                 :             :    A pass is made through the function, one block at a time.  No cross block
      49                 :             :    information is tracked.
      50                 :             : 
      51                 :             :    Variables which only have one use, and whose defining stmt is considered
      52                 :             :    a replaceable expression (see ssa_is_replaceable_p) are tracked to see whether
      53                 :             :    they can be replaced at their use location.
      54                 :             : 
      55                 :             :    n_12 = C * 10
      56                 :             :    a_2 = b_5 + 6
      57                 :             :    v_9 = a_2 * n_12
      58                 :             : 
      59                 :             :    if there are the only use of n_12 and a_2, TER will substitute in their
      60                 :             :    expressions in v_9, and end up with:
      61                 :             : 
      62                 :             :    v_9 = (b_5 + 6) * (C * 10)
      63                 :             : 
      64                 :             :    which will then have the ssa_name assigned to regular variables, and the
      65                 :             :    resulting code which will be passed to the expander looks something like:
      66                 :             : 
      67                 :             :    v = (b + 6) * (C * 10)
      68                 :             : 
      69                 :             : 
      70                 :             :    This requires ensuring that none of the variables used by the expression
      71                 :             :    change between the def point and where it is used.  Furthermore, if any
      72                 :             :    of the ssa_names used in this expression are themselves replaceable, we
      73                 :             :    have to ensure none of that expressions' arguments change either.
      74                 :             :    Although SSA_NAMES themselves don't change, this pass is performed after
      75                 :             :    coalescing has coalesced different SSA_NAMES together, so there could be a
      76                 :             :    definition of an SSA_NAME which is coalesced with a use that causes a
      77                 :             :    problem, i.e.,
      78                 :             : 
      79                 :             :    PHI b_5 = <b_8(2), b_14(1)>
      80                 :             :    <...>
      81                 :             :    a_2 = b_5 + 6
      82                 :             :    b_8 = c_4 + 4
      83                 :             :    v_9 = a_2 * n_12
      84                 :             :    <...>
      85                 :             : 
      86                 :             :    If b_5, b_8 and b_14 are all coalesced together...
      87                 :             :    The expression b_5 + 6 CANNOT replace the use in the statement defining v_9
      88                 :             :    because b_8 is in fact killing the value of b_5 since they share a partition
      89                 :             :    and will be assigned the same memory or register location.
      90                 :             : 
      91                 :             :    TER implements this but stepping through the instructions in a block and
      92                 :             :    tracking potential expressions for replacement, and the partitions they are
      93                 :             :    dependent on.  Expressions are represented by the SSA_NAME_VERSION of the
      94                 :             :    DEF on the LHS of a GIMPLE_ASSIGN and the expression is the RHS.
      95                 :             : 
      96                 :             :    When a stmt is determined to be a possible replacement expression, the
      97                 :             :    following steps are taken:
      98                 :             : 
      99                 :             :    EXPR_DECL_UID bitmap is allocated and set to the base variable UID of the
     100                 :             :    def and any uses in the expression.  non-NULL means the expression is being
     101                 :             :    tracked.  The UID's themselves are used to prevent TER substitution into
     102                 :             :    accumulating sequences, i.e.,
     103                 :             : 
     104                 :             :    x = x + y
     105                 :             :    x = x + z
     106                 :             :    x = x + w
     107                 :             :    etc.
     108                 :             :    this can result in very large expressions which don't accomplish anything
     109                 :             :    see PR tree-optimization/17549.
     110                 :             : 
     111                 :             :    PARTITION_DEPENDENCIES is another bitmap array, and it has a bit set for any
     112                 :             :    partition which is used in the expression.  This is primarily used to remove
     113                 :             :    an expression from the partition kill lists when a decision is made whether
     114                 :             :    to replace it or not.  This is indexed by ssa version number as well, and
     115                 :             :    indicates a partition number.  virtual operands are not tracked individually,
     116                 :             :    but they are summarized by an artificial partition called VIRTUAL_PARTITION.
     117                 :             :    This means a MAY or MUST def will kill *ALL* expressions that are dependent
     118                 :             :    on a virtual operand.
     119                 :             :    Note that the EXPR_DECL_UID and this bitmap represent very similar
     120                 :             :    information, but the info in one is not easy to obtain from the other.
     121                 :             : 
     122                 :             :    KILL_LIST is yet another bitmap array, this time it is indexed by partition
     123                 :             :    number, and represents a list of active expressions which will no
     124                 :             :    longer be valid if a definition into this partition takes place.
     125                 :             : 
     126                 :             :    PARTITION_IN_USE is simply a bitmap which is used to track which partitions
     127                 :             :    currently have something in their kill list.  This is used at the end of
     128                 :             :    a block to clear out the KILL_LIST bitmaps at the end of each block.
     129                 :             : 
     130                 :             :    NEW_REPLACEABLE_DEPENDENCIES is used as a temporary place to store
     131                 :             :    dependencies which will be reused by the current definition. All the uses
     132                 :             :    on an expression are processed before anything else is done. If a use is
     133                 :             :    determined to be a replaceable expression AND the current stmt is also going
     134                 :             :    to be replaceable, all the dependencies of this replaceable use will be
     135                 :             :    picked up by the current stmt's expression. Rather than recreate them, they
     136                 :             :    are simply copied here and then copied into the new expression when it is
     137                 :             :    processed.
     138                 :             : 
     139                 :             :    a_2 = b_5 + 6
     140                 :             :    v_8 = a_2 + c_4
     141                 :             : 
     142                 :             :    a_2's expression 'b_5 + 6' is determined to be replaceable at the use
     143                 :             :    location. It is dependent on the partition 'b_5' is in. This is cached into
     144                 :             :    the NEW_REPLACEABLE_DEPENDENCIES bitmap, and when v_8 is examined for
     145                 :             :    replaceability, it is a candidate, and it is dependent on the partition
     146                 :             :    b_5 is in *NOT* a_2, as well as c_4's partition.
     147                 :             : 
     148                 :             :    if v_8 is also replaceable:
     149                 :             : 
     150                 :             :    x_9 = v_8 * 5
     151                 :             : 
     152                 :             :    x_9 is dependent on partitions b_5, and c_4
     153                 :             : 
     154                 :             :    if a statement is found which has either of those partitions written to
     155                 :             :    before x_9 is used, then x_9 itself is NOT replaceable.  */
     156                 :             : 
     157                 :             : 
     158                 :             : /* Temporary Expression Replacement (TER) table information.  */
     159                 :             : 
     160                 :             : struct temp_expr_table
     161                 :             : {
     162                 :             :   var_map map;
     163                 :             :   bitmap *partition_dependencies;       /* Partitions expr is dependent on.  */
     164                 :             :   bitmap replaceable_expressions;       /* Replacement expression table.  */
     165                 :             :   bitmap *expr_decl_uids;               /* Base uids of exprs.  */
     166                 :             :   bitmap *kill_list;                    /* Expr's killed by a partition.  */
     167                 :             :   int virtual_partition;                /* Pseudo partition for virtual ops.  */
     168                 :             :   bitmap partition_in_use;              /* Partitions with kill entries.  */
     169                 :             :   bitmap new_replaceable_dependencies;  /* Holding place for pending dep's.  */
     170                 :             :   int *num_in_part;                     /* # of ssa_names in a partition.  */
     171                 :             :   int *call_cnt;                        /* Call count at definition.  */
     172                 :             :   int *reg_vars_cnt;                    /* Number of register variable
     173                 :             :                                            definitions encountered.  */
     174                 :             : };
     175                 :             : 
     176                 :             : /* Used to indicate a dependency on VDEFs.  */
     177                 :             : #define VIRTUAL_PARTITION(table)        (table->virtual_partition)
     178                 :             : 
     179                 :             : /* A place for the many, many bitmaps we create.  */
     180                 :             : static bitmap_obstack ter_bitmap_obstack;
     181                 :             : 
     182                 :             : extern void debug_ter (FILE *, temp_expr_table *);
     183                 :             : 
     184                 :             : 
     185                 :             : /* Create a new TER table for MAP.  */
     186                 :             : 
     187                 :             : static temp_expr_table *
     188                 :      974641 : new_temp_expr_table (var_map map)
     189                 :             : {
     190                 :      974641 :   temp_expr_table *t = XNEW (struct temp_expr_table);
     191                 :      974641 :   t->map = map;
     192                 :             : 
     193                 :     1949282 :   t->partition_dependencies = XCNEWVEC (bitmap, num_ssa_names + 1);
     194                 :     1949282 :   t->expr_decl_uids = XCNEWVEC (bitmap, num_ssa_names + 1);
     195                 :      974641 :   t->kill_list = XCNEWVEC (bitmap, num_var_partitions (map) + 1);
     196                 :             : 
     197                 :      974641 :   t->partition_in_use = BITMAP_ALLOC (&ter_bitmap_obstack);
     198                 :             : 
     199                 :      974641 :   t->virtual_partition = num_var_partitions (map);
     200                 :      974641 :   t->new_replaceable_dependencies = BITMAP_ALLOC (&ter_bitmap_obstack);
     201                 :             : 
     202                 :      974641 :   t->replaceable_expressions = NULL;
     203                 :      974641 :   t->num_in_part = XCNEWVEC (int, num_var_partitions (map));
     204                 :             : 
     205                 :      974641 :   unsigned x;
     206                 :      974641 :   tree name;
     207                 :             : 
     208                 :    51403863 :   FOR_EACH_SSA_NAME (x, name, cfun)
     209                 :             :     {
     210                 :    32403525 :       int p;
     211                 :    32403525 :       p = var_to_partition (map, name);
     212                 :    32403525 :       if (p != NO_PARTITION)
     213                 :    20424929 :         t->num_in_part[p]++;
     214                 :             :     }
     215                 :      974641 :   t->call_cnt = XCNEWVEC (int, num_ssa_names + 1);
     216                 :     1949282 :   t->reg_vars_cnt = XCNEWVEC (int, num_ssa_names + 1);
     217                 :             : 
     218                 :      974641 :   return t;
     219                 :             : }
     220                 :             : 
     221                 :             : 
     222                 :             : /* Free TER table T.  If there are valid replacements, return the expression
     223                 :             :    vector.  */
     224                 :             : 
     225                 :             : static bitmap
     226                 :      974641 : free_temp_expr_table (temp_expr_table *t)
     227                 :             : {
     228                 :      974641 :   bitmap ret = NULL;
     229                 :             : 
     230                 :      974641 :   if (flag_checking)
     231                 :             :     {
     232                 :    18810436 :       for (unsigned x = 0; x <= num_var_partitions (t->map); x++)
     233                 :    17835817 :         gcc_assert (!t->kill_list[x]);
     234                 :   104756238 :       for (unsigned x = 0; x < num_ssa_names; x++)
     235                 :             :         {
     236                 :    51403500 :           gcc_assert (t->expr_decl_uids[x] == NULL);
     237                 :    51403500 :           gcc_assert (t->partition_dependencies[x] == NULL);
     238                 :             :         }
     239                 :             :     }
     240                 :             : 
     241                 :      974641 :   BITMAP_FREE (t->partition_in_use);
     242                 :      974641 :   BITMAP_FREE (t->new_replaceable_dependencies);
     243                 :             : 
     244                 :      974641 :   free (t->expr_decl_uids);
     245                 :      974641 :   free (t->kill_list);
     246                 :      974641 :   free (t->partition_dependencies);
     247                 :      974641 :   free (t->num_in_part);
     248                 :      974641 :   free (t->call_cnt);
     249                 :      974641 :   free (t->reg_vars_cnt);
     250                 :             : 
     251                 :      974641 :   if (t->replaceable_expressions)
     252                 :             :     ret = t->replaceable_expressions;
     253                 :             : 
     254                 :      974641 :   free (t);
     255                 :      974641 :   return ret;
     256                 :             : }
     257                 :             : 
     258                 :             : 
     259                 :             : /* Return TRUE if VERSION is to be replaced by an expression in TAB.  */
     260                 :             : 
     261                 :             : static inline bool
     262                 :     8580327 : version_to_be_replaced_p (temp_expr_table *tab, int version)
     263                 :             : {
     264                 :     8580327 :   if (!tab->replaceable_expressions)
     265                 :             :     return false;
     266                 :     7855509 :   return bitmap_bit_p (tab->replaceable_expressions, version);
     267                 :             : }
     268                 :             : 
     269                 :             : 
     270                 :             : /* Add partition P to the list if partitions VERSION is dependent on.  TAB is
     271                 :             :    the expression table */
     272                 :             : 
     273                 :             : static inline void
     274                 :     3852501 : make_dependent_on_partition (temp_expr_table *tab, int version, int p)
     275                 :             : {
     276                 :     3852501 :   if (!tab->partition_dependencies[version])
     277                 :     3315997 :     tab->partition_dependencies[version] = BITMAP_ALLOC (&ter_bitmap_obstack);
     278                 :             : 
     279                 :     3852501 :   bitmap_set_bit (tab->partition_dependencies[version], p);
     280                 :     3852501 : }
     281                 :             : 
     282                 :             : 
     283                 :             : /* Add VER to the kill list for P.  TAB is the expression table */
     284                 :             : 
     285                 :             : static inline void
     286                 :     5680038 : add_to_partition_kill_list (temp_expr_table *tab, int p, int ver)
     287                 :             : {
     288                 :     5680038 :   if (!tab->kill_list[p])
     289                 :             :     {
     290                 :     4821695 :       tab->kill_list[p] = BITMAP_ALLOC (&ter_bitmap_obstack);
     291                 :     4821695 :       bitmap_set_bit (tab->partition_in_use, p);
     292                 :             :     }
     293                 :     5680038 :   bitmap_set_bit (tab->kill_list[p], ver);
     294                 :     5680038 : }
     295                 :             : 
     296                 :             : 
     297                 :             : /* Remove VER from the partition kill list for P.  TAB is the expression
     298                 :             :    table.  */
     299                 :             : 
     300                 :             : static inline void
     301                 :     5569585 : remove_from_partition_kill_list (temp_expr_table *tab, int p, int version)
     302                 :             : {
     303                 :     5569585 :   gcc_checking_assert (tab->kill_list[p]);
     304                 :     5569585 :   bitmap_clear_bit (tab->kill_list[p], version);
     305                 :     5569585 :   if (bitmap_empty_p (tab->kill_list[p]))
     306                 :             :     {
     307                 :     4821695 :       bitmap_clear_bit (tab->partition_in_use, p);
     308                 :     4821695 :       BITMAP_FREE (tab->kill_list[p]);
     309                 :             :     }
     310                 :     5569585 : }
     311                 :             : 
     312                 :             : 
     313                 :             : /* Add a dependency between the def of ssa VERSION and VAR.  If VAR is
     314                 :             :    replaceable by an expression, add a dependence each of the elements of the
     315                 :             :    expression.  These are contained in the new_replaceable list.  TAB is the
     316                 :             :    expression table.  */
     317                 :             : 
     318                 :             : static void
     319                 :     8580327 : add_dependence (temp_expr_table *tab, int version, tree var)
     320                 :             : {
     321                 :     8580327 :   int i;
     322                 :     8580327 :   bitmap_iterator bi;
     323                 :     8580327 :   unsigned x;
     324                 :             : 
     325                 :     8580327 :   i = SSA_NAME_VERSION (var);
     326                 :    16435836 :   if (version_to_be_replaced_p (tab, i))
     327                 :             :     {
     328                 :     3286644 :       if (!bitmap_empty_p (tab->new_replaceable_dependencies))
     329                 :             :         {
     330                 :             :           /* Version will now be killed by a write to any partition the
     331                 :             :              substituted expression would have been killed by.  */
     332                 :     3354964 :           EXECUTE_IF_SET_IN_BITMAP (tab->new_replaceable_dependencies, 0, x, bi)
     333                 :     1827537 :             add_to_partition_kill_list (tab, x, version);
     334                 :             : 
     335                 :             :           /* Rather than set partition_dependencies and in_use lists bit by
     336                 :             :              bit, simply OR in the new_replaceable_dependencies bits.  */
     337                 :     1527427 :           if (!tab->partition_dependencies[version])
     338                 :     1496666 :             tab->partition_dependencies[version] =
     339                 :     1496666 :               BITMAP_ALLOC (&ter_bitmap_obstack);
     340                 :     1527427 :           bitmap_ior_into (tab->partition_dependencies[version],
     341                 :     1527427 :                            tab->new_replaceable_dependencies);
     342                 :     1527427 :           bitmap_ior_into (tab->partition_in_use,
     343                 :     1527427 :                            tab->new_replaceable_dependencies);
     344                 :             :           /* It is only necessary to add these once.  */
     345                 :     1527427 :           bitmap_clear (tab->new_replaceable_dependencies);
     346                 :             :         }
     347                 :             :     }
     348                 :             :   else
     349                 :             :     {
     350                 :     5293683 :       i = var_to_partition (tab->map, var);
     351                 :     5293683 :       gcc_checking_assert (i != NO_PARTITION);
     352                 :     5293683 :       gcc_checking_assert (tab->num_in_part[i] != 0);
     353                 :             :       /* Only dependencies on ssa_names which are coalesced with something need
     354                 :             :          to be tracked.  Partitions with containing only a single SSA_NAME
     355                 :             :          *cannot* have their value changed.  */
     356                 :     5293683 :       if (tab->num_in_part[i] > 1)
     357                 :             :         {
     358                 :     1208555 :           add_to_partition_kill_list (tab, i, version);
     359                 :     1208555 :           make_dependent_on_partition (tab, version, i);
     360                 :             :         }
     361                 :             :     }
     362                 :     8580327 : }
     363                 :             : 
     364                 :             : 
     365                 :             : /* This function will remove the expression for VERSION from replacement
     366                 :             :    consideration in table TAB.  If FREE_EXPR is true, then remove the
     367                 :             :    expression from consideration as well by freeing the decl uid bitmap.  */
     368                 :             : 
     369                 :             : static void
     370                 :     8254428 : finished_with_expr (temp_expr_table *tab, int version, bool free_expr)
     371                 :             : {
     372                 :     8254428 :   unsigned i;
     373                 :     8254428 :   bitmap_iterator bi;
     374                 :             : 
     375                 :             :   /* Remove this expression from its dependent lists.  The partition dependence
     376                 :             :      list is retained and transferred later to whomever uses this version.  */
     377                 :     8254428 :   if (tab->partition_dependencies[version])
     378                 :             :     {
     379                 :    10382248 :       EXECUTE_IF_SET_IN_BITMAP (tab->partition_dependencies[version], 0, i, bi)
     380                 :     5569585 :         remove_from_partition_kill_list (tab, i, version);
     381                 :     4812663 :       BITMAP_FREE (tab->partition_dependencies[version]);
     382                 :             :     }
     383                 :     8254428 :   if (free_expr)
     384                 :     4967784 :     BITMAP_FREE (tab->expr_decl_uids[version]);
     385                 :     8254428 : }
     386                 :             : 
     387                 :             : 
     388                 :             : /* Return TRUE if expression STMT is suitable for replacement.
     389                 :             :    In addition to ssa_is_replaceable_p, require the same bb, and for -O0
     390                 :             :    same locus and same BLOCK), Considers memory loads as replaceable if aliasing
     391                 :             :    is available.  */
     392                 :             : 
     393                 :             : static inline bool
     394                 :    38630505 : ter_is_replaceable_p (gimple *stmt)
     395                 :             : {
     396                 :             : 
     397                 :    38630505 :   if (ssa_is_replaceable_p (stmt))
     398                 :             :     {
     399                 :    16937536 :       use_operand_p use_p;
     400                 :    16937536 :       tree def;
     401                 :    16937536 :       gimple *use_stmt;
     402                 :    16937536 :       location_t locus1, locus2;
     403                 :    16937536 :       tree block1, block2;
     404                 :             : 
     405                 :             :       /* Only consider definitions which have a single use.  ssa_is_replaceable_p
     406                 :             :          already performed this check, but the use stmt pointer is required for
     407                 :             :          further checks.  */
     408                 :    16937536 :       def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
     409                 :    16937536 :       if (!single_imm_use (def, &use_p, &use_stmt))
     410                 :             :           return false;
     411                 :             : 
     412                 :             :       /* If the use isn't in this block, it wont be replaced either.  */
     413                 :    16937536 :       if (gimple_bb (use_stmt) != gimple_bb (stmt))
     414                 :             :         return false;
     415                 :             : 
     416                 :    16513814 :       locus1 = gimple_location (stmt);
     417                 :    16513814 :       block1 = LOCATION_BLOCK (locus1);
     418                 :    16513814 :       locus1 = LOCATION_LOCUS (locus1);
     419                 :             : 
     420                 :    16513814 :       if (gphi *phi = dyn_cast <gphi *> (use_stmt))
     421                 :           0 :         locus2 = gimple_phi_arg_location (phi,
     422                 :           0 :                                           PHI_ARG_INDEX_FROM_USE (use_p));
     423                 :             :       else
     424                 :    16513814 :         locus2 = gimple_location (use_stmt);
     425                 :    16513814 :       block2 = LOCATION_BLOCK (locus2);
     426                 :    16513814 :       locus2 = LOCATION_LOCUS (locus2);
     427                 :             : 
     428                 :    16513814 :       if ((!optimize || optimize_debug)
     429                 :       18158 :           && ((locus1 != UNKNOWN_LOCATION && locus1 != locus2)
     430                 :       13200 :               || (block1 != NULL_TREE && block1 != block2)))
     431                 :             :         return false;
     432                 :             : 
     433                 :             :       return true;
     434                 :             :     }
     435                 :             :   return false;
     436                 :             : }
     437                 :             : 
     438                 :             : 
     439                 :             : /* Create an expression entry for a replaceable expression.  */
     440                 :             : 
     441                 :             : static void
     442                 :     8254428 : process_replaceable (temp_expr_table *tab, gimple *stmt, int call_cnt,
     443                 :             :                      int reg_vars_cnt)
     444                 :             : {
     445                 :     8254428 :   tree var, def, basevar;
     446                 :     8254428 :   int version;
     447                 :     8254428 :   ssa_op_iter iter;
     448                 :     8254428 :   bitmap def_vars, use_vars;
     449                 :             : 
     450                 :     8254428 :   gcc_checking_assert (ter_is_replaceable_p (stmt));
     451                 :             : 
     452                 :     8254428 :   def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
     453                 :     8254428 :   version = SSA_NAME_VERSION (def);
     454                 :     8254428 :   def_vars = BITMAP_ALLOC (&ter_bitmap_obstack);
     455                 :             : 
     456                 :     8254428 :   basevar = SSA_NAME_VAR (def);
     457                 :      670431 :   if (basevar)
     458                 :      670431 :     bitmap_set_bit (def_vars, DECL_UID (basevar));
     459                 :             : 
     460                 :             :   /* Add this expression to the dependency list for each use partition.  */
     461                 :    16834755 :   FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE)
     462                 :             :     {
     463                 :     8580327 :       int var_version = SSA_NAME_VERSION (var);
     464                 :             : 
     465                 :     8580327 :       use_vars = tab->expr_decl_uids[var_version];
     466                 :     8580327 :       add_dependence (tab, version, var);
     467                 :     8580327 :       if (use_vars)
     468                 :             :         {
     469                 :     3286644 :           bitmap_ior_into (def_vars, use_vars);
     470                 :     3286644 :           BITMAP_FREE (tab->expr_decl_uids[var_version]);
     471                 :             :         }
     472                 :     5293683 :       else if (SSA_NAME_VAR (var))
     473                 :     2853680 :         bitmap_set_bit (def_vars, DECL_UID (SSA_NAME_VAR (var)));
     474                 :             :     }
     475                 :     8254428 :   tab->expr_decl_uids[version] = def_vars;
     476                 :             : 
     477                 :             :   /* If there are VUSES, add a dependence on virtual defs.  */
     478                 :    16508856 :   if (gimple_vuse (stmt))
     479                 :             :     {
     480                 :     2643946 :       make_dependent_on_partition (tab, version, VIRTUAL_PARTITION (tab));
     481                 :     2643946 :       add_to_partition_kill_list (tab, VIRTUAL_PARTITION (tab), version);
     482                 :             :     }
     483                 :             : 
     484                 :     8254428 :   tab->call_cnt[version] = call_cnt;
     485                 :     8254428 :   tab->reg_vars_cnt[version] = reg_vars_cnt;
     486                 :     8254428 : }
     487                 :             : 
     488                 :             : 
     489                 :             : /* This function removes any expression in TAB which is dependent on PARTITION
     490                 :             :    from consideration, making it not replaceable.  */
     491                 :             : 
     492                 :             : static inline void
     493                 :    10725557 : kill_expr (temp_expr_table *tab, int partition)
     494                 :             : {
     495                 :    10725557 :   unsigned version;
     496                 :             : 
     497                 :             :   /* Mark every active expr dependent on this var as not replaceable.
     498                 :             :      finished_with_expr can modify the bitmap, so we can't execute over it.  */
     499                 :    10934168 :   while (tab->kill_list[partition])
     500                 :             :     {
     501                 :      208611 :       version = bitmap_first_set_bit (tab->kill_list[partition]);
     502                 :      208611 :       finished_with_expr (tab, version, true);
     503                 :             :     }
     504                 :             : 
     505                 :    10725557 :   gcc_checking_assert (!tab->kill_list[partition]);
     506                 :    10725557 : }
     507                 :             : 
     508                 :             : 
     509                 :             : /* This function kills all expressions in TAB which are dependent on virtual
     510                 :             :    partitions.  */
     511                 :             : 
     512                 :             : static inline void
     513                 :    10704868 : kill_virtual_exprs (temp_expr_table *tab)
     514                 :             : {
     515                 :    10704868 :   kill_expr (tab, VIRTUAL_PARTITION (tab));
     516                 :    10704868 : }
     517                 :             : 
     518                 :             : 
     519                 :             : /* Mark the expression associated with VAR as replaceable, and enter
     520                 :             :    the defining stmt into the partition_dependencies table TAB.  If
     521                 :             :    MORE_REPLACING is true, accumulate the pending partition dependencies.  */
     522                 :             : 
     523                 :             : static void
     524                 :     7832021 : mark_replaceable (temp_expr_table *tab, tree var, bool more_replacing)
     525                 :             : {
     526                 :     7832021 :   int version = SSA_NAME_VERSION (var);
     527                 :             : 
     528                 :             :   /* Move the dependence list to the pending listpending.  */
     529                 :     7832021 :   if (more_replacing && tab->partition_dependencies[version])
     530                 :     1725644 :     bitmap_ior_into (tab->new_replaceable_dependencies,
     531                 :             :                      tab->partition_dependencies[version]);
     532                 :             : 
     533                 :     7832021 :   finished_with_expr (tab, version, !more_replacing);
     534                 :             : 
     535                 :             :   /* Set the replaceable expression.
     536                 :             :      The bitmap for this "escapes" from this file so it's allocated
     537                 :             :      on the default obstack.  */
     538                 :     7832021 :   if (!tab->replaceable_expressions)
     539                 :      630126 :     tab->replaceable_expressions = BITMAP_ALLOC (NULL);
     540                 :     7832021 :   bitmap_set_bit (tab->replaceable_expressions, version);
     541                 :     7832021 : }
     542                 :             : 
     543                 :             : 
     544                 :             : /* Helper function for find_ssaname_in_stores.  Called via walk_tree to
     545                 :             :    find a SSA_NAME DATA somewhere in *TP.  */
     546                 :             : 
     547                 :             : static tree
     548                 :       28052 : find_ssaname (tree *tp, int *walk_subtrees, void *data)
     549                 :             : {
     550                 :       28052 :   tree var = (tree) data;
     551                 :       28052 :   if (*tp == var)
     552                 :             :     return var;
     553                 :       28005 :   else if (IS_TYPE_OR_DECL_P (*tp))
     554                 :       22206 :     *walk_subtrees = 0;
     555                 :             :   return NULL_TREE;
     556                 :             : }
     557                 :             : 
     558                 :             : /* Helper function for find_replaceable_in_bb.  Return true if SSA_NAME DATA
     559                 :             :    is used somewhere in T, which is a store in the statement.  Called via
     560                 :             :    walk_stmt_load_store_addr_ops.  */
     561                 :             : 
     562                 :             : static bool
     563                 :       23199 : find_ssaname_in_store (gimple *, tree, tree t, void *data)
     564                 :             : {
     565                 :       23199 :   return walk_tree (&t, find_ssaname, data, NULL) != NULL_TREE;
     566                 :             : }
     567                 :             : 
     568                 :             : /* This function processes basic block BB, and looks for variables which can
     569                 :             :    be replaced by their expressions.  Results are stored in the table TAB.  */
     570                 :             : 
     571                 :             : static void
     572                 :     8221157 : find_replaceable_in_bb (temp_expr_table *tab, basic_block bb)
     573                 :             : {
     574                 :     8221157 :   gimple_stmt_iterator bsi;
     575                 :     8221157 :   gimple *stmt;
     576                 :     8221157 :   tree def, use, fndecl;
     577                 :     8221157 :   int partition;
     578                 :     8221157 :   var_map map = tab->map;
     579                 :     8221157 :   ssa_op_iter iter;
     580                 :     8221157 :   bool stmt_replaceable;
     581                 :     8221157 :   int cur_call_cnt = 0;
     582                 :     8221157 :   int cur_reg_vars_cnt = 0;
     583                 :             : 
     584                 :    82896409 :   for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
     585                 :             :     {
     586                 :    66454095 :       stmt = gsi_stmt (bsi);
     587                 :             : 
     588                 :    66454095 :       if (is_gimple_debug (stmt))
     589                 :    36078018 :         continue;
     590                 :             : 
     591                 :    30376077 :       stmt_replaceable = ter_is_replaceable_p (stmt);
     592                 :             : 
     593                 :             :       /* Determine if this stmt finishes an existing expression.  */
     594                 :    57337586 :       FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
     595                 :             :         {
     596                 :    26961509 :           unsigned ver = SSA_NAME_VERSION (use);
     597                 :             : 
     598                 :             :           /* If this use is a potential replacement variable, process it.  */
     599                 :    26961509 :           if (tab->expr_decl_uids[ver])
     600                 :             :             {
     601                 :     8045817 :               bool same_root_var = false;
     602                 :     8045817 :               ssa_op_iter iter2;
     603                 :     8045817 :               bitmap vars = tab->expr_decl_uids[ver];
     604                 :             : 
     605                 :             :               /* See if the root variables are the same.  If they are, we
     606                 :             :                  do not want to do the replacement to avoid problems with
     607                 :             :                  code size, see PR tree-optimization/17549.  */
     608                 :     8045817 :               if (!bitmap_empty_p (vars))
     609                 :     6745628 :                 FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter2, SSA_OP_DEF)
     610                 :             :                   {
     611                 :     2726620 :                     if (SSA_NAME_VAR (def)
     612                 :      616786 :                         && bitmap_bit_p (vars, DECL_UID (SSA_NAME_VAR (def))))
     613                 :             :                       {
     614                 :             :                         same_root_var = true;
     615                 :             :                         break;
     616                 :             :                       }
     617                 :             :                   }
     618                 :             : 
     619                 :             :               /* If the stmt does a memory store and the replacement
     620                 :             :                  is a load aliasing it avoid creating overlapping
     621                 :             :                  assignments which we cannot expand correctly.  */
     622                 :    14874580 :               if (gimple_vdef (stmt))
     623                 :             :                 {
     624                 :     1966962 :                   gimple *def_stmt = SSA_NAME_DEF_STMT (use);
     625                 :     1967250 :                   while (is_gimple_assign (def_stmt)
     626                 :     1967250 :                          && gimple_assign_rhs_code (def_stmt) == SSA_NAME)
     627                 :         288 :                     def_stmt
     628                 :         288 :                       = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def_stmt));
     629                 :    10012779 :                   if (gimple_vuse (def_stmt)
     630                 :      642456 :                       && gimple_assign_single_p (def_stmt)
     631                 :     2609171 :                       && stmt_may_clobber_ref_p (stmt,
     632                 :             :                                                  gimple_assign_rhs1 (def_stmt)))
     633                 :             :                     {
     634                 :             :                       /* For calls, it is not a problem if USE is among
     635                 :             :                          call's arguments or say OBJ_TYPE_REF argument,
     636                 :             :                          all those necessarily need to be evaluated before
     637                 :             :                          the call that may clobber the memory.  But if
     638                 :             :                          LHS of the call refers to USE, expansion might
     639                 :             :                          evaluate it after the call, prevent TER in that
     640                 :             :                          case.
     641                 :             :                          For inline asm, allow TER of loads into input
     642                 :             :                          arguments, but disallow TER for USEs that occur
     643                 :             :                          somewhere in outputs.  */
     644                 :      372150 :                       if (is_gimple_call (stmt)
     645                 :      372150 :                           || gimple_code (stmt) == GIMPLE_ASM)
     646                 :             :                         {
     647                 :      309051 :                           if (walk_stmt_load_store_ops (stmt, use, NULL,
     648                 :             :                                                         find_ssaname_in_store))
     649                 :       63146 :                             same_root_var = true;
     650                 :             :                         }
     651                 :             :                       else
     652                 :             :                         same_root_var = true;
     653                 :             :                     }
     654                 :             :                 }
     655                 :             : 
     656                 :             :               /* Mark expression as replaceable unless stmt is volatile, or the
     657                 :             :                  def variable has the same root variable as something in the
     658                 :             :                  substitution list, or the def and use span a call such that
     659                 :             :                  we'll expand lifetimes across a call.  We also don't want to
     660                 :             :                  replace across these expressions that may call libcalls that
     661                 :             :                  clobber the register involved.  See PR 70184.  Neither
     662                 :             :                  do we want to move possibly trapping expressions across
     663                 :             :                  a call.  See PRs 102129 and 33593.  */
     664                 :    14822258 :               if (gimple_has_volatile_ops (stmt) || same_root_var
     665                 :     7881420 :                   || (tab->call_cnt[ver] != cur_call_cnt
     666                 :       80925 :                       && (SINGLE_SSA_USE_OPERAND (SSA_NAME_DEF_STMT (use),
     667                 :             :                                                   SSA_OP_USE)
     668                 :             :                             == NULL_USE_OPERAND_P
     669                 :       33948 :                           || gimple_could_trap_p (SSA_NAME_DEF_STMT (use))))
     670                 :    14660797 :                   || tab->reg_vars_cnt[ver] != cur_reg_vars_cnt)
     671                 :      213796 :                 finished_with_expr (tab, ver, true);
     672                 :             :               else
     673                 :     7832021 :                 mark_replaceable (tab, use, stmt_replaceable);
     674                 :             :             }
     675                 :             :         }
     676                 :             : 
     677                 :             :       /* Next, see if this stmt kills off an active expression.  */
     678                 :    45995705 :       FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
     679                 :             :         {
     680                 :    15619628 :           partition = var_to_partition (map, def);
     681                 :    15619628 :           if (partition != NO_PARTITION && tab->kill_list[partition])
     682                 :       20689 :             kill_expr (tab, partition);
     683                 :             :         }
     684                 :             : 
     685                 :             :       /* Increment counter if this is a non BUILT_IN call. We allow
     686                 :             :          replacement over BUILT_IN calls since many will expand to inline
     687                 :             :          insns instead of a true call.  */
     688                 :    30376077 :       if (is_gimple_call (stmt)
     689                 :    35016107 :           && !((fndecl = gimple_call_fndecl (stmt))
     690                 :     4640030 :                && fndecl_built_in_p (fndecl)))
     691                 :     3553808 :         cur_call_cnt++;
     692                 :             : 
     693                 :             :       /* Increment counter if this statement sets a local
     694                 :             :          register variable.  */
     695                 :    30376077 :       if (gimple_assign_single_p (stmt)
     696                 :    30376077 :           && (VAR_P (gimple_assign_lhs (stmt))
     697                 :     1616245 :           && DECL_HARD_REGISTER (gimple_assign_lhs (stmt))))
     698                 :         998 :         cur_reg_vars_cnt++;
     699                 :             : 
     700                 :             :       /* Now see if we are creating a new expression or not.  */
     701                 :    30376077 :       if (stmt_replaceable)
     702                 :     8254428 :         process_replaceable (tab, stmt, cur_call_cnt, cur_reg_vars_cnt);
     703                 :             : 
     704                 :             :       /* Free any unused dependency lists.  */
     705                 :    30376077 :       bitmap_clear (tab->new_replaceable_dependencies);
     706                 :             : 
     707                 :             :       /* A V_{MAY,MUST}_DEF kills any expression using a virtual operand,
     708                 :             :          including the current stmt.  */
     709                 :   123099410 :       if (gimple_vdef (stmt))
     710                 :    10704868 :         kill_virtual_exprs (tab);
     711                 :             :     }
     712                 :     8221157 : }
     713                 :             : 
     714                 :             : 
     715                 :             : /* This function is the driver routine for replacement of temporary expressions
     716                 :             :    in the SSA->normal phase, operating on MAP.  If there are replaceable
     717                 :             :    expressions, a table is returned which maps SSA versions to the
     718                 :             :    expressions they should be replaced with.  A NULL_TREE indicates no
     719                 :             :    replacement should take place.  If there are no replacements at all,
     720                 :             :    NULL is returned by the function, otherwise an expression vector indexed
     721                 :             :    by SSA_NAME version numbers.  */
     722                 :             : 
     723                 :             : bitmap
     724                 :      974641 : find_replaceable_exprs (var_map map)
     725                 :             : {
     726                 :      974641 :   basic_block bb;
     727                 :      974641 :   temp_expr_table *table;
     728                 :      974641 :   bitmap ret;
     729                 :             : 
     730                 :      974641 :   bitmap_obstack_initialize (&ter_bitmap_obstack);
     731                 :      974641 :   table = new_temp_expr_table (map);
     732                 :     9195798 :   FOR_EACH_BB_FN (bb, cfun)
     733                 :             :     {
     734                 :     8221157 :       find_replaceable_in_bb (table, bb);
     735                 :     8221157 :       gcc_checking_assert (bitmap_empty_p (table->partition_in_use));
     736                 :             :     }
     737                 :      974641 :   ret = free_temp_expr_table (table);
     738                 :      974641 :   bitmap_obstack_release (&ter_bitmap_obstack);
     739                 :      974641 :   return ret;
     740                 :             : }
     741                 :             : 
     742                 :             : /* Dump TER expression table EXPR to file F.  */
     743                 :             : 
     744                 :             : void
     745                 :          11 : dump_replaceable_exprs (FILE *f, bitmap expr)
     746                 :             : {
     747                 :          11 :   tree var;
     748                 :          11 :   unsigned x;
     749                 :             : 
     750                 :          11 :   fprintf (f, "\nReplacing Expressions\n");
     751                 :         369 :   for (x = 0; x < num_ssa_names; x++)
     752                 :         168 :     if (bitmap_bit_p (expr, x))
     753                 :             :       {
     754                 :          38 :         var = ssa_name (x);
     755                 :          38 :         print_generic_expr (f, var, TDF_SLIM);
     756                 :          38 :         fprintf (f, " replace with --> ");
     757                 :          38 :         print_gimple_stmt (f, SSA_NAME_DEF_STMT (var), 0, TDF_SLIM);
     758                 :          38 :         fprintf (f, "\n");
     759                 :             :       }
     760                 :          11 :   fprintf (f, "\n");
     761                 :          11 : }
     762                 :             : 
     763                 :             : 
     764                 :             : /* Dump the status of the various tables in the expression table.  This is used
     765                 :             :    exclusively to debug TER.  F is the place to send debug info and T is the
     766                 :             :    table being debugged.  */
     767                 :             : 
     768                 :             : DEBUG_FUNCTION void
     769                 :           0 : debug_ter (FILE *f, temp_expr_table *t)
     770                 :             : {
     771                 :           0 :   unsigned x, y;
     772                 :           0 :   bitmap_iterator bi;
     773                 :             : 
     774                 :           0 :   fprintf (f, "\nDumping current state of TER\n virtual partition = %d\n",
     775                 :             :            VIRTUAL_PARTITION (t));
     776                 :           0 :   if (t->replaceable_expressions)
     777                 :           0 :     dump_replaceable_exprs (f, t->replaceable_expressions);
     778                 :           0 :   fprintf (f, "Currently tracking the following expressions:\n");
     779                 :             : 
     780                 :           0 :   for (x = 1; x < num_ssa_names; x++)
     781                 :           0 :     if (t->expr_decl_uids[x])
     782                 :             :       {
     783                 :           0 :         print_generic_expr (f, ssa_name (x), TDF_SLIM);
     784                 :           0 :         fprintf (f, " dep-parts : ");
     785                 :           0 :         if (t->partition_dependencies[x]
     786                 :           0 :             && !bitmap_empty_p (t->partition_dependencies[x]))
     787                 :             :           {
     788                 :           0 :             EXECUTE_IF_SET_IN_BITMAP (t->partition_dependencies[x], 0, y, bi)
     789                 :           0 :               fprintf (f, "P%d ",y);
     790                 :             :           }
     791                 :           0 :         fprintf (f, "   basedecls: ");
     792                 :           0 :         EXECUTE_IF_SET_IN_BITMAP (t->expr_decl_uids[x], 0, y, bi)
     793                 :           0 :           fprintf (f, "%d ",y);
     794                 :           0 :         fprintf (f, "   call_cnt : %d",t->call_cnt[x]);
     795                 :           0 :         fprintf (f, "\n");
     796                 :             :       }
     797                 :             : 
     798                 :           0 :   bitmap_print (f, t->partition_in_use, "Partitions in use ",
     799                 :             :                 "\npartition KILL lists:\n");
     800                 :             : 
     801                 :           0 :   for (x = 0; x <= num_var_partitions (t->map); x++)
     802                 :           0 :     if (t->kill_list[x])
     803                 :             :       {
     804                 :           0 :         fprintf (f, "Partition %d : ", x);
     805                 :           0 :         EXECUTE_IF_SET_IN_BITMAP (t->kill_list[x], 0, y, bi)
     806                 :           0 :           fprintf (f, "_%d ",y);
     807                 :             :       }
     808                 :             : 
     809                 :           0 :   fprintf (f, "\n----------\n");
     810                 :           0 : }
        

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.