LCOV - code coverage report
Current view: top level - gcc - gcse-common.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 93.3 % 89 83
Test Date: 2025-09-20 13:40:47 Functions: 100.0 % 3 3
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Shared code for before and after reload gcse implementations.
       2                 :             :    Copyright (C) 1997-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                 :             :    It is expected that more hunks of gcse.cc and postreload-gcse.cc should
      21                 :             :    migrate into this file.  */
      22                 :             : 
      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 "gcse-common.h"
      30                 :             : #include "regs.h"
      31                 :             : #include "function-abi.h"
      32                 :             : 
      33                 :             : /* Record all of the canonicalized MEMs of record_last_mem_set_info's insn.
      34                 :             :    Note we store a pair of elements in the list, so they have to be
      35                 :             :    taken off pairwise.  */
      36                 :             : 
      37                 :             : void
      38                 :     7277834 : canon_list_insert (rtx dest, const_rtx x ATTRIBUTE_UNUSED, void *data)
      39                 :             : {
      40                 :     7277834 :   rtx dest_addr;
      41                 :     7277834 :   int bb;
      42                 :     7277834 :   modify_pair pair;
      43                 :             : 
      44                 :     7277834 :   while (GET_CODE (dest) == SUBREG
      45                 :     7277834 :       || GET_CODE (dest) == ZERO_EXTRACT
      46                 :    14555668 :       || GET_CODE (dest) == STRICT_LOW_PART)
      47                 :           0 :     dest = XEXP (dest, 0);
      48                 :             : 
      49                 :             :   /* If DEST is not a MEM, then it will not conflict with a load.  Note
      50                 :             :      that function calls are assumed to clobber memory, but are handled
      51                 :             :      elsewhere.  */
      52                 :             : 
      53                 :     7277834 :   if (! MEM_P (dest))
      54                 :      284077 :     return;
      55                 :             : 
      56                 :     6993757 :   dest_addr = get_addr (XEXP (dest, 0));
      57                 :     6993757 :   dest_addr = canon_rtx (dest_addr);
      58                 :     6993757 :   rtx_insn *insn = ((struct gcse_note_stores_info *)data)->insn;
      59                 :     6993757 :   bb = BLOCK_FOR_INSN (insn)->index;
      60                 :             : 
      61                 :     6993757 :   pair.dest = dest;
      62                 :     6993757 :   pair.dest_addr = dest_addr;
      63                 :     6993757 :   vec<modify_pair> *canon_mem_list
      64                 :             :     = ((struct gcse_note_stores_info *)data)->canon_mem_list;
      65                 :     6993757 :   canon_mem_list[bb].safe_push (pair);
      66                 :             : }
      67                 :             : 
      68                 :             : /* Record memory modification information for INSN.  We do not actually care
      69                 :             :    about the memory location(s) that are set, or even how they are set (consider
      70                 :             :    a CALL_INSN).  We merely need to record which insns modify memory.  */
      71                 :             : 
      72                 :             : void
      73                 :    10922070 : record_last_mem_set_info_common (rtx_insn *insn,
      74                 :             :                                  vec<rtx_insn *> *modify_mem_list,
      75                 :             :                                  vec<modify_pair> *canon_modify_mem_list,
      76                 :             :                                  bitmap modify_mem_list_set,
      77                 :             :                                  bitmap blocks_with_calls)
      78                 :             : 
      79                 :             : {
      80                 :    10922070 :   int bb;
      81                 :             : 
      82                 :    10922070 :   bb = BLOCK_FOR_INSN (insn)->index;
      83                 :    10922070 :   modify_mem_list[bb].safe_push (insn);
      84                 :    10922070 :   bitmap_set_bit (modify_mem_list_set, bb);
      85                 :             : 
      86                 :    10922070 :   if (CALL_P (insn))
      87                 :     3929219 :     bitmap_set_bit (blocks_with_calls, bb);
      88                 :             :   else
      89                 :             :     {
      90                 :     6992851 :       struct gcse_note_stores_info data;
      91                 :     6992851 :       data.insn = insn;
      92                 :     6992851 :       data.canon_mem_list = canon_modify_mem_list;
      93                 :     6992851 :       note_stores (insn, canon_list_insert, (void*) &data);
      94                 :             :     }
      95                 :    10922070 : }
      96                 :             : 
      97                 :             : 
      98                 :             : /* For each block, compute whether X is transparent.  X is either an
      99                 :             :    expression or an assignment [though we don't care which, for this context
     100                 :             :    an assignment is treated as an expression].  For each block where an
     101                 :             :    element of X is modified, reset the INDX bit in BMAP.
     102                 :             : 
     103                 :             :    BLOCKS_WITH_CALLS indicates which blocks contain CALL_INSNs which kill
     104                 :             :    memory.
     105                 :             : 
     106                 :             :    MODIFY_MEM_LIST_SET indicates which blocks have memory stores which might
     107                 :             :    kill a particular memory location.
     108                 :             : 
     109                 :             :    CANON_MODIFY_MEM_LIST is the canonicalized list of memory locations modified
     110                 :             :    for each block.  */
     111                 :             : 
     112                 :             : void
     113                 :    20081621 : compute_transp (const_rtx x, int indx, sbitmap *bmap,
     114                 :             :                 bitmap blocks_with_calls,
     115                 :             :                 bitmap modify_mem_list_set,
     116                 :             :                 vec<modify_pair> *canon_modify_mem_list)
     117                 :             : {
     118                 :    34936694 :   int i, j;
     119                 :    34936694 :   enum rtx_code code;
     120                 :    34936694 :   const char *fmt;
     121                 :             : 
     122                 :             :   /* repeat is used to turn tail-recursion into iteration since GCC
     123                 :             :      can't do it when there's no return value.  */
     124                 :    34936694 :  repeat:
     125                 :             : 
     126                 :    34936694 :   if (x == 0)
     127                 :             :     return;
     128                 :             : 
     129                 :    34936694 :   code = GET_CODE (x);
     130                 :    34936694 :   switch (code)
     131                 :             :     {
     132                 :    11903403 :     case REG:
     133                 :    11903403 :       {
     134                 :    11903403 :         df_ref def;
     135                 :    11903403 :         for (def = DF_REG_DEF_CHAIN (REGNO (x));
     136                 :    77810074 :              def;
     137                 :    65906671 :              def = DF_REF_NEXT_REG (def))
     138                 :    65906671 :           bitmap_clear_bit (bmap[DF_REF_BB (def)->index], indx);
     139                 :             : 
     140                 :             :         /* Check for hard registers that are partially clobbered (but not
     141                 :             :            fully clobbered) by calls.  Such partial clobbers do not have
     142                 :             :            an associated definition or use in the DF representation,
     143                 :             :            but they do prevent the register from being transparent.
     144                 :             : 
     145                 :             :            ??? The check here is fairly crude.  We could instead maintain
     146                 :             :            separate blocks_with_calls bitmaps for each ABI.  */
     147                 :    11903403 :         if (HARD_REGISTER_P (x))
     148                 :    23293341 :           for (unsigned int i = 0; i < NUM_ABI_IDS; ++i)
     149                 :             :             {
     150                 :    20705192 :               const predefined_function_abi &abi = function_abis[i];
     151                 :    20705192 :               if (abi.initialized_p ()
     152                 :    23316496 :                   && overlaps_hard_reg_set_p (abi.only_partial_reg_clobbers (),
     153                 :     2611304 :                                               GET_MODE (x), REGNO (x)))
     154                 :             :                 {
     155                 :           0 :                   bitmap_iterator bi;
     156                 :           0 :                   unsigned bb_index;
     157                 :           0 :                   EXECUTE_IF_SET_IN_BITMAP (blocks_with_calls, 0, bb_index, bi)
     158                 :           0 :                     bitmap_clear_bit (bmap[bb_index], indx);
     159                 :           0 :                   break;
     160                 :             :                 }
     161                 :             :             }
     162                 :             :       }
     163                 :             : 
     164                 :             :       return;
     165                 :             : 
     166                 :     4708922 :     case MEM:
     167                 :     4708922 :       if (! MEM_READONLY_P (x))
     168                 :             :         {
     169                 :     4343107 :           bitmap_iterator bi;
     170                 :     4343107 :           unsigned bb_index;
     171                 :     4343107 :           rtx x_addr;
     172                 :             : 
     173                 :     4343107 :           x_addr = get_addr (XEXP (x, 0));
     174                 :     4343107 :           x_addr = canon_rtx (x_addr);
     175                 :             : 
     176                 :             :           /* First handle all the blocks with calls.  We don't need to
     177                 :             :              do any list walking for them.  */
     178                 :   159967922 :           EXECUTE_IF_SET_IN_BITMAP (blocks_with_calls, 0, bb_index, bi)
     179                 :             :             {
     180                 :   155624815 :               bitmap_clear_bit (bmap[bb_index], indx);
     181                 :             :             }
     182                 :             : 
     183                 :             :           /* Now iterate over the blocks which have memory modifications
     184                 :             :              but which do not have any calls.  */
     185                 :   102508650 :           EXECUTE_IF_AND_COMPL_IN_BITMAP (modify_mem_list_set,
     186                 :             :                                           blocks_with_calls,
     187                 :             :                                           0, bb_index, bi)
     188                 :             :             {
     189                 :    98165543 :               vec<modify_pair> list
     190                 :    98165543 :                 = canon_modify_mem_list[bb_index];
     191                 :    98165543 :               modify_pair *pair;
     192                 :    98165543 :               unsigned ix;
     193                 :             : 
     194                 :   437517843 :               FOR_EACH_VEC_ELT_REVERSE (list, ix, pair)
     195                 :             :                 {
     196                 :   180447862 :                   rtx dest = pair->dest;
     197                 :   180447862 :                   rtx dest_addr = pair->dest_addr;
     198                 :             : 
     199                 :   180447862 :                   if (canon_true_dependence (dest, GET_MODE (dest),
     200                 :             :                                              dest_addr, x, x_addr))
     201                 :             :                     {
     202                 :    37426648 :                       bitmap_clear_bit (bmap[bb_index], indx);
     203                 :    37426648 :                       break;
     204                 :             :                     }
     205                 :             :                 }
     206                 :             :             }
     207                 :             :         }
     208                 :             : 
     209                 :     4708922 :       x = XEXP (x, 0);
     210                 :     4708922 :       goto repeat;
     211                 :             : 
     212                 :             :     case PC:
     213                 :             :     case CONST:
     214                 :             :     CASE_CONST_ANY:
     215                 :             :     case SYMBOL_REF:
     216                 :             :     case LABEL_REF:
     217                 :             :     case ADDR_VEC:
     218                 :             :     case ADDR_DIFF_VEC:
     219                 :             :       return;
     220                 :             : 
     221                 :    10385721 :     default:
     222                 :    10385721 :       break;
     223                 :             :     }
     224                 :             : 
     225                 :    19851219 :   for (i = GET_RTX_LENGTH (code) - 1, fmt = GET_RTX_FORMAT (code); i >= 0; i--)
     226                 :             :     {
     227                 :    19611649 :       if (fmt[i] == 'e')
     228                 :             :         {
     229                 :             :           /* If we are about to do the last recursive call
     230                 :             :              needed at this level, change it into iteration.
     231                 :             :              This function is called enough to be worth it.  */
     232                 :    19039270 :           if (i == 0)
     233                 :             :             {
     234                 :    10146151 :               x = XEXP (x, i);
     235                 :    10146151 :               goto repeat;
     236                 :             :             }
     237                 :             : 
     238                 :     8893119 :           compute_transp (XEXP (x, i), indx, bmap, blocks_with_calls,
     239                 :             :                           modify_mem_list_set, canon_modify_mem_list);
     240                 :             :         }
     241                 :      572379 :       else if (fmt[i] == 'E')
     242                 :     1058745 :         for (j = 0; j < XVECLEN (x, i); j++)
     243                 :      819175 :           compute_transp (XVECEXP (x, i, j), indx, bmap, blocks_with_calls,
     244                 :             :                           modify_mem_list_set, canon_modify_mem_list);
     245                 :             :     }
     246                 :             : }
        

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.