LCOV - code coverage report
Current view: top level - gcc - lists.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 88.5 % 96 85
Test Date: 2026-02-28 14:20:25 Functions: 93.3 % 15 14
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* List management for the GCC expander.
       2              :    Copyright (C) 1987-2026 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              : #include "config.h"
      21              : #include "system.h"
      22              : #include "coretypes.h"
      23              : #include "tm.h"
      24              : #include "rtl.h"
      25              : 
      26              : static void free_list (rtx *, rtx *);
      27              : 
      28              : /* Functions for maintaining cache-able lists of EXPR_LIST and INSN_LISTs.  */
      29              : 
      30              : /* An INSN_LIST containing all INSN_LISTs allocated but currently unused.  */
      31              : static GTY ((deletable)) rtx unused_insn_list;
      32              : 
      33              : /* An EXPR_LIST containing all EXPR_LISTs allocated but currently unused.  */
      34              : static GTY ((deletable)) rtx unused_expr_list;
      35              : 
      36              : /* This function will free an entire list of either EXPR_LIST, INSN_LIST
      37              :    or DEPS_LIST nodes.  This is to be used only on lists that consist
      38              :    exclusively of nodes of one type only.  This is only called by
      39              :    free_EXPR_LIST_list, free_INSN_LIST_list and free_DEPS_LIST_list.  */
      40              : static void
      41    839595292 : free_list (rtx *listp, rtx *unused_listp)
      42              : {
      43    839595292 :   rtx link, prev_link;
      44              : 
      45    839595292 :   prev_link = *listp;
      46    839595292 :   link = XEXP (prev_link, 1);
      47              : 
      48    839595292 :   gcc_assert (unused_listp != &unused_insn_list
      49              :               || GET_CODE (prev_link) == INSN_LIST);
      50              : 
      51   1031604161 :   while (link)
      52              :     {
      53    192008869 :       gcc_assert (unused_listp != &unused_insn_list
      54              :                   || GET_CODE (prev_link) == INSN_LIST);
      55              : 
      56    192008869 :       prev_link = link;
      57    192008869 :       link = XEXP (link, 1);
      58              :     }
      59              : 
      60    839595292 :   XEXP (prev_link, 1) = *unused_listp;
      61    839595292 :   *unused_listp = *listp;
      62    839595292 :   *listp = 0;
      63    839595292 : }
      64              : 
      65              : /* Find corresponding to ELEM node in the list pointed to by LISTP.
      66              :    This node must exist in the list.  Returns pointer to that node.  */
      67              : static rtx *
      68       138267 : find_list_elem (rtx elem, rtx *listp)
      69              : {
      70       203959 :   while (XEXP (*listp, 0) != elem)
      71        65692 :     listp = &XEXP (*listp, 1);
      72       138267 :   return listp;
      73              : }
      74              : 
      75              : /* Remove the node pointed to by LISTP from the list.  */
      76              : static void
      77       152574 : remove_list_node (rtx *listp)
      78              : {
      79       152574 :   rtx node;
      80              : 
      81       152574 :   node = *listp;
      82       152574 :   *listp = XEXP (node, 1);
      83       152574 :   XEXP (node, 1) = 0;
      84            0 : }
      85              : 
      86              : /* Removes corresponding to ELEM node from the list pointed to by LISTP.
      87              :    Returns that node.  */
      88              : rtx
      89       138267 : remove_list_elem (rtx elem, rtx *listp)
      90              : {
      91       138267 :   rtx node;
      92              : 
      93       138267 :   listp = find_list_elem (elem, listp);
      94       138267 :   node = *listp;
      95       138267 :   remove_list_node (listp);
      96       138267 :   return node;
      97              : }
      98              : 
      99              : /* This call is used in place of a gen_rtx_INSN_LIST. If there is a cached
     100              :    node available, we'll use it, otherwise a call to gen_rtx_INSN_LIST
     101              :    is made.  */
     102              : rtx_insn_list *
     103   1011795548 : alloc_INSN_LIST (rtx val, rtx next)
     104              : {
     105   1011795548 :   rtx_insn_list *r;
     106              : 
     107   1011795548 :   if (unused_insn_list)
     108              :     {
     109    960255230 :       r = as_a <rtx_insn_list *> (unused_insn_list);
     110    960255230 :       unused_insn_list = r->next ();
     111    960255230 :       XEXP (r, 0) = val;
     112    960255230 :       XEXP (r, 1) = next;
     113    960255230 :       PUT_REG_NOTE_KIND (r, VOIDmode);
     114              : 
     115    960255230 :       gcc_assert (GET_CODE (r) == INSN_LIST);
     116              :     }
     117              :   else
     118     51540318 :     r = gen_rtx_INSN_LIST (VOIDmode, val, next);
     119              : 
     120   1011795548 :   return r;
     121              : }
     122              : 
     123              : /* This call is used in place of a gen_rtx_EXPR_LIST. If there is a cached
     124              :    node available, we'll use it, otherwise a call to gen_rtx_EXPR_LIST
     125              :    is made.  */
     126              : rtx_expr_list *
     127    805873250 : alloc_EXPR_LIST (int kind, rtx val, rtx next)
     128              : {
     129    805873250 :   rtx_expr_list *r;
     130              : 
     131    805873250 :   if (unused_expr_list)
     132              :     {
     133    619380522 :       r = as_a <rtx_expr_list *> (unused_expr_list);
     134    619380522 :       unused_expr_list = XEXP (r, 1);
     135    619380522 :       XEXP (r, 0) = val;
     136    619380522 :       XEXP (r, 1) = next;
     137    619380522 :       PUT_REG_NOTE_KIND (r, kind);
     138              :     }
     139              :   else
     140    186492728 :     r = gen_rtx_EXPR_LIST ((machine_mode) kind, val, next);
     141              : 
     142    805873250 :   return r;
     143              : }
     144              : 
     145              : /* This function will free up an entire list of EXPR_LIST nodes.  */
     146              : void
     147     61059139 : free_EXPR_LIST_list (rtx_expr_list **listp)
     148              : {
     149     61059139 :   if (*listp == 0)
     150              :     return;
     151     14732765 :   free_list ((rtx *)listp, &unused_expr_list);
     152              : }
     153              : 
     154              : /* This function will free up an entire list of INSN_LIST nodes.  */
     155              : void
     156   1831845994 : free_INSN_LIST_list (rtx_insn_list **listp)
     157              : {
     158   1831845994 :   if (*listp == 0)
     159              :     return;
     160    824862527 :   free_list ((rtx *)listp, &unused_insn_list);
     161              : }
     162              : 
     163              : /* Make a copy of the INSN_LIST list LINK and return it.  */
     164              : rtx_insn_list *
     165            0 : copy_INSN_LIST (rtx_insn_list *link)
     166              : {
     167            0 :   rtx_insn_list *new_queue;
     168            0 :   rtx_insn_list **pqueue = &new_queue;
     169              : 
     170            0 :   for (; link; link = link->next ())
     171              :     {
     172            0 :       rtx_insn *x = link->insn ();
     173            0 :       rtx_insn_list *newlink = alloc_INSN_LIST (x, NULL);
     174            0 :       *pqueue = newlink;
     175            0 :       pqueue = (rtx_insn_list **)&XEXP (newlink, 1);
     176              :     }
     177            0 :   *pqueue = NULL;
     178            0 :   return new_queue;
     179              : }
     180              : 
     181              : /* Duplicate the INSN_LIST elements of COPY and prepend them to OLD.  */
     182              : rtx_insn_list *
     183        85110 : concat_INSN_LIST (rtx_insn_list *copy, rtx_insn_list *old)
     184              : {
     185        85110 :   rtx_insn_list *new_rtx = old;
     186       124374 :   for (; copy ; copy = copy->next ())
     187              :     {
     188        39264 :       new_rtx = alloc_INSN_LIST (copy->insn (), new_rtx);
     189        39264 :       PUT_REG_NOTE_KIND (new_rtx, REG_NOTE_KIND (copy));
     190              :     }
     191        85110 :   return new_rtx;
     192              : }
     193              : 
     194              : /* This function will free up an individual EXPR_LIST node.  */
     195              : void
     196    580988194 : free_EXPR_LIST_node (rtx ptr)
     197              : {
     198    580988194 :   XEXP (ptr, 1) = unused_expr_list;
     199    580988194 :   unused_expr_list = ptr;
     200    580988194 : }
     201              : 
     202              : /* This function will free up an individual INSN_LIST node.  */
     203              : void
     204       151901 : free_INSN_LIST_node (rtx ptr)
     205              : {
     206       151901 :   gcc_assert (GET_CODE (ptr) == INSN_LIST);
     207       151901 :   XEXP (ptr, 1) = unused_insn_list;
     208       151901 :   unused_insn_list = ptr;
     209       151901 : }
     210              : 
     211              : /* Remove and free corresponding to ELEM node in the INSN_LIST pointed to
     212              :    by LISTP.  */
     213              : void
     214       138267 : remove_free_INSN_LIST_elem (rtx_insn *elem, rtx_insn_list **listp)
     215              : {
     216       138267 :   free_INSN_LIST_node (remove_list_elem (elem, (rtx *)listp));
     217       138267 : }
     218              : 
     219              : /* Remove and free the first node in the INSN_LIST pointed to by LISTP.  */
     220              : rtx_insn *
     221        13629 : remove_free_INSN_LIST_node (rtx_insn_list **listp)
     222              : {
     223        13629 :   rtx_insn_list *node = *listp;
     224        13629 :   rtx_insn *elem = node->insn ();
     225              : 
     226        13629 :   remove_list_node ((rtx *)listp);
     227        13629 :   free_INSN_LIST_node (node);
     228              : 
     229        13629 :   return elem;
     230              : }
     231              : 
     232              : /* Remove and free the first node in the EXPR_LIST pointed to by LISTP.  */
     233              : rtx
     234          678 : remove_free_EXPR_LIST_node (rtx_expr_list **listp)
     235              : {
     236          678 :   rtx_expr_list *node = *listp;
     237          678 :   rtx elem = XEXP (node, 0);
     238              : 
     239          678 :   remove_list_node ((rtx *)listp);
     240          678 :   free_EXPR_LIST_node (node);
     241              : 
     242          678 :   return elem;
     243              : }
     244              : 
     245              : #include "gt-lists.h"
        

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