LCOV - code coverage report
Current view: top level - gcc - gcse-common.c (source / functions) Hit Total Coverage
Test: gcc.info Lines: 76 77 98.7 %
Date: 2020-04-04 11:58:09 Functions: 3 3 100.0 %
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-2020 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.c and postreload-gcse.c 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                 :            : 
      31                 :            : 
      32                 :            : /* Record all of the canonicalized MEMs of record_last_mem_set_info's insn.
      33                 :            :    Note we store a pair of elements in the list, so they have to be
      34                 :            :    taken off pairwise.  */
      35                 :            : 
      36                 :            : void
      37                 :    5476110 : canon_list_insert (rtx dest, const_rtx x ATTRIBUTE_UNUSED, void *data)
      38                 :            : {
      39                 :    5476110 :   rtx dest_addr;
      40                 :    5476110 :   int bb;
      41                 :    5476110 :   modify_pair pair;
      42                 :            : 
      43                 :    5476110 :   while (GET_CODE (dest) == SUBREG
      44                 :    5476110 :       || GET_CODE (dest) == ZERO_EXTRACT
      45                 :   10952200 :       || GET_CODE (dest) == STRICT_LOW_PART)
      46                 :          0 :     dest = XEXP (dest, 0);
      47                 :            : 
      48                 :            :   /* If DEST is not a MEM, then it will not conflict with a load.  Note
      49                 :            :      that function calls are assumed to clobber memory, but are handled
      50                 :            :      elsewhere.  */
      51                 :            : 
      52                 :    5476110 :   if (! MEM_P (dest))
      53                 :     287664 :     return;
      54                 :            : 
      55                 :    5188440 :   dest_addr = get_addr (XEXP (dest, 0));
      56                 :    5188440 :   dest_addr = canon_rtx (dest_addr);
      57                 :    5188440 :   rtx_insn *insn = ((struct gcse_note_stores_info *)data)->insn;
      58                 :    5188440 :   bb = BLOCK_FOR_INSN (insn)->index;
      59                 :            : 
      60                 :    5188440 :   pair.dest = dest;
      61                 :    5188440 :   pair.dest_addr = dest_addr;
      62                 :    5188440 :   vec<modify_pair> *canon_mem_list
      63                 :            :     = ((struct gcse_note_stores_info *)data)->canon_mem_list;
      64                 :    5188440 :   canon_mem_list[bb].safe_push (pair);
      65                 :            : }
      66                 :            : 
      67                 :            : /* Record memory modification information for INSN.  We do not actually care
      68                 :            :    about the memory location(s) that are set, or even how they are set (consider
      69                 :            :    a CALL_INSN).  We merely need to record which insns modify memory.  */
      70                 :            : 
      71                 :            : void
      72                 :    7928650 : record_last_mem_set_info_common (rtx_insn *insn,
      73                 :            :                                  vec<rtx_insn *> *modify_mem_list,
      74                 :            :                                  vec<modify_pair> *canon_modify_mem_list,
      75                 :            :                                  bitmap modify_mem_list_set,
      76                 :            :                                  bitmap blocks_with_calls)
      77                 :            : 
      78                 :            : {
      79                 :    7928650 :   int bb;
      80                 :            : 
      81                 :    7928650 :   bb = BLOCK_FOR_INSN (insn)->index;
      82                 :    7928650 :   modify_mem_list[bb].safe_push (insn);
      83                 :    7928650 :   bitmap_set_bit (modify_mem_list_set, bb);
      84                 :            : 
      85                 :    7928650 :   if (CALL_P (insn))
      86                 :    2741080 :     bitmap_set_bit (blocks_with_calls, bb);
      87                 :            :   else
      88                 :            :     {
      89                 :    5187570 :       struct gcse_note_stores_info data;
      90                 :    5187570 :       data.insn = insn;
      91                 :    5187570 :       data.canon_mem_list = canon_modify_mem_list;
      92                 :    5187570 :       note_stores (insn, canon_list_insert, (void*) &data);
      93                 :            :     }
      94                 :    7928650 : }
      95                 :            : 
      96                 :            : 
      97                 :            : /* For each block, compute whether X is transparent.  X is either an
      98                 :            :    expression or an assignment [though we don't care which, for this context
      99                 :            :    an assignment is treated as an expression].  For each block where an
     100                 :            :    element of X is modified, reset the INDX bit in BMAP. 
     101                 :            : 
     102                 :            :    BLOCKS_WITH_CALLS indicates which blocks contain CALL_INSNs which kill
     103                 :            :    memory.
     104                 :            : 
     105                 :            :    MODIFY_MEM_LIST_SET indicates which blocks have memory stores which might
     106                 :            :    kill a particular memory location.
     107                 :            : 
     108                 :            :    CANON_MODIFY_MEM_LIST is the canonicalized list of memory locations modified
     109                 :            :    for each block.  */
     110                 :            : 
     111                 :            : void
     112                 :   11837400 : compute_transp (const_rtx x, int indx, sbitmap *bmap,
     113                 :            :                 bitmap blocks_with_calls,
     114                 :            :                 bitmap modify_mem_list_set,
     115                 :            :                 vec<modify_pair> *canon_modify_mem_list)
     116                 :            : {
     117                 :   20585900 :   int i, j;
     118                 :   20585900 :   enum rtx_code code;
     119                 :   20585900 :   const char *fmt;
     120                 :            : 
     121                 :            :   /* repeat is used to turn tail-recursion into iteration since GCC
     122                 :            :      can't do it when there's no return value.  */
     123                 :   20585900 :  repeat:
     124                 :            : 
     125                 :   20585900 :   if (x == 0)
     126                 :            :     return;
     127                 :            : 
     128                 :   20585900 :   code = GET_CODE (x);
     129                 :   20585900 :   switch (code)
     130                 :            :     {
     131                 :    7077250 :     case REG:
     132                 :    7077250 :         {
     133                 :    7077250 :           df_ref def;
     134                 :    7077250 :           for (def = DF_REG_DEF_CHAIN (REGNO (x));
     135                 :   56269200 :                def;
     136                 :   49191900 :                def = DF_REF_NEXT_REG (def))
     137                 :   49191900 :             bitmap_clear_bit (bmap[DF_REF_BB (def)->index], indx);
     138                 :            :         }
     139                 :            : 
     140                 :            :       return;
     141                 :            : 
     142                 :    2938500 :     case MEM:
     143                 :    2938500 :       if (! MEM_READONLY_P (x))
     144                 :            :         {
     145                 :    2726700 :           bitmap_iterator bi;
     146                 :    2726700 :           unsigned bb_index;
     147                 :    2726700 :           rtx x_addr;
     148                 :            : 
     149                 :    2726700 :           x_addr = get_addr (XEXP (x, 0));
     150                 :    2726700 :           x_addr = canon_rtx (x_addr);
     151                 :            : 
     152                 :            :           /* First handle all the blocks with calls.  We don't need to
     153                 :            :              do any list walking for them.  */
     154                 :  117726000 :           EXECUTE_IF_SET_IN_BITMAP (blocks_with_calls, 0, bb_index, bi)
     155                 :            :             {
     156                 :  114999000 :               bitmap_clear_bit (bmap[bb_index], indx);
     157                 :            :             }
     158                 :            : 
     159                 :            :           /* Now iterate over the blocks which have memory modifications
     160                 :            :              but which do not have any calls.  */
     161                 :   74764300 :           EXECUTE_IF_AND_COMPL_IN_BITMAP (modify_mem_list_set,
     162                 :            :                                           blocks_with_calls,
     163                 :            :                                           0, bb_index, bi)
     164                 :            :             {
     165                 :   72037600 :               vec<modify_pair> list
     166                 :   72037600 :                 = canon_modify_mem_list[bb_index];
     167                 :   72037600 :               modify_pair *pair;
     168                 :   72037600 :               unsigned ix;
     169                 :            : 
     170                 :  268093000 :               FOR_EACH_VEC_ELT_REVERSE (list, ix, pair)
     171                 :            :                 {
     172                 :  152946000 :                   rtx dest = pair->dest;
     173                 :  152946000 :                   rtx dest_addr = pair->dest_addr;
     174                 :            : 
     175                 :  152946000 :                   if (canon_true_dependence (dest, GET_MODE (dest),
     176                 :            :                                              dest_addr, x, x_addr))
     177                 :            :                     {
     178                 :  100966000 :                       bitmap_clear_bit (bmap[bb_index], indx);
     179                 :            :                       break;
     180                 :            :                     }
     181                 :            :                 }
     182                 :            :             }
     183                 :            :         }
     184                 :            : 
     185                 :    2938500 :       x = XEXP (x, 0);
     186                 :    2938500 :       goto repeat;
     187                 :            : 
     188                 :            :     case PC:
     189                 :            :     case CC0: /*FIXME*/
     190                 :            :     case CONST:
     191                 :            :     CASE_CONST_ANY:
     192                 :            :     case SYMBOL_REF:
     193                 :            :     case LABEL_REF:
     194                 :            :     case ADDR_VEC:
     195                 :            :     case ADDR_DIFF_VEC:
     196                 :            :       return;
     197                 :            : 
     198                 :    5945590 :     default:
     199                 :    5945590 :       break;
     200                 :            :     }
     201                 :            : 
     202                 :   11532500 :   for (i = GET_RTX_LENGTH (code) - 1, fmt = GET_RTX_FORMAT (code); i >= 0; i--)
     203                 :            :     {
     204                 :   11397000 :       if (fmt[i] == 'e')
     205                 :            :         {
     206                 :            :           /* If we are about to do the last recursive call
     207                 :            :              needed at this level, change it into iteration.
     208                 :            :              This function is called enough to be worth it.  */
     209                 :   11083000 :           if (i == 0)
     210                 :            :             {
     211                 :    5810050 :               x = XEXP (x, i);
     212                 :    5810050 :               goto repeat;
     213                 :            :             }
     214                 :            : 
     215                 :    5272940 :           compute_transp (XEXP (x, i), indx, bmap, blocks_with_calls,
     216                 :            :                           modify_mem_list_set, canon_modify_mem_list);
     217                 :            :         }
     218                 :     313983 :       else if (fmt[i] == 'E')
     219                 :     619908 :         for (j = 0; j < XVECLEN (x, i); j++)
     220                 :     484370 :           compute_transp (XVECEXP (x, i, j), indx, bmap, blocks_with_calls,
     221                 :            :                           modify_mem_list_set, canon_modify_mem_list);
     222                 :            :     }
     223                 :            : }

Generated by: LCOV version 1.0

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 --enable-host-shared. GCC test suite is run with the built compiler.