11debfc3dSmrg /* List management for the GCC expander.
2*8feb0f0bSmrg Copyright (C) 1987-2020 Free Software Foundation, Inc.
31debfc3dSmrg
41debfc3dSmrg This file is part of GCC.
51debfc3dSmrg
61debfc3dSmrg GCC is free software; you can redistribute it and/or modify it under
71debfc3dSmrg the terms of the GNU General Public License as published by the Free
81debfc3dSmrg Software Foundation; either version 3, or (at your option) any later
91debfc3dSmrg version.
101debfc3dSmrg
111debfc3dSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
121debfc3dSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
131debfc3dSmrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
141debfc3dSmrg for more details.
151debfc3dSmrg
161debfc3dSmrg You should have received a copy of the GNU General Public License
171debfc3dSmrg along with GCC; see the file COPYING3. If not see
181debfc3dSmrg <http://www.gnu.org/licenses/>. */
191debfc3dSmrg
201debfc3dSmrg #include "config.h"
211debfc3dSmrg #include "system.h"
221debfc3dSmrg #include "coretypes.h"
231debfc3dSmrg #include "tm.h"
241debfc3dSmrg #include "rtl.h"
251debfc3dSmrg
261debfc3dSmrg static void free_list (rtx *, rtx *);
271debfc3dSmrg
281debfc3dSmrg /* Functions for maintaining cache-able lists of EXPR_LIST and INSN_LISTs. */
291debfc3dSmrg
301debfc3dSmrg /* An INSN_LIST containing all INSN_LISTs allocated but currently unused. */
311debfc3dSmrg static GTY ((deletable)) rtx unused_insn_list;
321debfc3dSmrg
331debfc3dSmrg /* An EXPR_LIST containing all EXPR_LISTs allocated but currently unused. */
341debfc3dSmrg static GTY ((deletable)) rtx unused_expr_list;
351debfc3dSmrg
361debfc3dSmrg /* This function will free an entire list of either EXPR_LIST, INSN_LIST
371debfc3dSmrg or DEPS_LIST nodes. This is to be used only on lists that consist
381debfc3dSmrg exclusively of nodes of one type only. This is only called by
391debfc3dSmrg free_EXPR_LIST_list, free_INSN_LIST_list and free_DEPS_LIST_list. */
401debfc3dSmrg static void
free_list(rtx * listp,rtx * unused_listp)411debfc3dSmrg free_list (rtx *listp, rtx *unused_listp)
421debfc3dSmrg {
431debfc3dSmrg rtx link, prev_link;
441debfc3dSmrg
451debfc3dSmrg prev_link = *listp;
461debfc3dSmrg link = XEXP (prev_link, 1);
471debfc3dSmrg
481debfc3dSmrg gcc_assert (unused_listp != &unused_insn_list
491debfc3dSmrg || GET_CODE (prev_link) == INSN_LIST);
501debfc3dSmrg
511debfc3dSmrg while (link)
521debfc3dSmrg {
531debfc3dSmrg gcc_assert (unused_listp != &unused_insn_list
541debfc3dSmrg || GET_CODE (prev_link) == INSN_LIST);
551debfc3dSmrg
561debfc3dSmrg prev_link = link;
571debfc3dSmrg link = XEXP (link, 1);
581debfc3dSmrg }
591debfc3dSmrg
601debfc3dSmrg XEXP (prev_link, 1) = *unused_listp;
611debfc3dSmrg *unused_listp = *listp;
621debfc3dSmrg *listp = 0;
631debfc3dSmrg }
641debfc3dSmrg
651debfc3dSmrg /* Find corresponding to ELEM node in the list pointed to by LISTP.
661debfc3dSmrg This node must exist in the list. Returns pointer to that node. */
671debfc3dSmrg static rtx *
find_list_elem(rtx elem,rtx * listp)681debfc3dSmrg find_list_elem (rtx elem, rtx *listp)
691debfc3dSmrg {
701debfc3dSmrg while (XEXP (*listp, 0) != elem)
711debfc3dSmrg listp = &XEXP (*listp, 1);
721debfc3dSmrg return listp;
731debfc3dSmrg }
741debfc3dSmrg
751debfc3dSmrg /* Remove the node pointed to by LISTP from the list. */
761debfc3dSmrg static void
remove_list_node(rtx * listp)771debfc3dSmrg remove_list_node (rtx *listp)
781debfc3dSmrg {
791debfc3dSmrg rtx node;
801debfc3dSmrg
811debfc3dSmrg node = *listp;
821debfc3dSmrg *listp = XEXP (node, 1);
831debfc3dSmrg XEXP (node, 1) = 0;
841debfc3dSmrg }
851debfc3dSmrg
861debfc3dSmrg /* Removes corresponding to ELEM node from the list pointed to by LISTP.
871debfc3dSmrg Returns that node. */
881debfc3dSmrg rtx
remove_list_elem(rtx elem,rtx * listp)891debfc3dSmrg remove_list_elem (rtx elem, rtx *listp)
901debfc3dSmrg {
911debfc3dSmrg rtx node;
921debfc3dSmrg
931debfc3dSmrg listp = find_list_elem (elem, listp);
941debfc3dSmrg node = *listp;
951debfc3dSmrg remove_list_node (listp);
961debfc3dSmrg return node;
971debfc3dSmrg }
981debfc3dSmrg
991debfc3dSmrg /* This call is used in place of a gen_rtx_INSN_LIST. If there is a cached
1001debfc3dSmrg node available, we'll use it, otherwise a call to gen_rtx_INSN_LIST
1011debfc3dSmrg is made. */
1021debfc3dSmrg rtx_insn_list *
alloc_INSN_LIST(rtx val,rtx next)1031debfc3dSmrg alloc_INSN_LIST (rtx val, rtx next)
1041debfc3dSmrg {
1051debfc3dSmrg rtx_insn_list *r;
1061debfc3dSmrg
1071debfc3dSmrg if (unused_insn_list)
1081debfc3dSmrg {
1091debfc3dSmrg r = as_a <rtx_insn_list *> (unused_insn_list);
1101debfc3dSmrg unused_insn_list = r->next ();
1111debfc3dSmrg XEXP (r, 0) = val;
1121debfc3dSmrg XEXP (r, 1) = next;
1131debfc3dSmrg PUT_REG_NOTE_KIND (r, VOIDmode);
1141debfc3dSmrg
1151debfc3dSmrg gcc_assert (GET_CODE (r) == INSN_LIST);
1161debfc3dSmrg }
1171debfc3dSmrg else
1181debfc3dSmrg r = gen_rtx_INSN_LIST (VOIDmode, val, next);
1191debfc3dSmrg
1201debfc3dSmrg return r;
1211debfc3dSmrg }
1221debfc3dSmrg
1231debfc3dSmrg /* This call is used in place of a gen_rtx_EXPR_LIST. If there is a cached
1241debfc3dSmrg node available, we'll use it, otherwise a call to gen_rtx_EXPR_LIST
1251debfc3dSmrg is made. */
1261debfc3dSmrg rtx_expr_list *
alloc_EXPR_LIST(int kind,rtx val,rtx next)1271debfc3dSmrg alloc_EXPR_LIST (int kind, rtx val, rtx next)
1281debfc3dSmrg {
1291debfc3dSmrg rtx_expr_list *r;
1301debfc3dSmrg
1311debfc3dSmrg if (unused_expr_list)
1321debfc3dSmrg {
1331debfc3dSmrg r = as_a <rtx_expr_list *> (unused_expr_list);
1341debfc3dSmrg unused_expr_list = XEXP (r, 1);
1351debfc3dSmrg XEXP (r, 0) = val;
1361debfc3dSmrg XEXP (r, 1) = next;
1371debfc3dSmrg PUT_REG_NOTE_KIND (r, kind);
1381debfc3dSmrg }
1391debfc3dSmrg else
1401debfc3dSmrg r = gen_rtx_EXPR_LIST ((machine_mode) kind, val, next);
1411debfc3dSmrg
1421debfc3dSmrg return r;
1431debfc3dSmrg }
1441debfc3dSmrg
1451debfc3dSmrg /* This function will free up an entire list of EXPR_LIST nodes. */
1461debfc3dSmrg void
free_EXPR_LIST_list(rtx_expr_list ** listp)1471debfc3dSmrg free_EXPR_LIST_list (rtx_expr_list **listp)
1481debfc3dSmrg {
1491debfc3dSmrg if (*listp == 0)
1501debfc3dSmrg return;
1511debfc3dSmrg free_list ((rtx *)listp, &unused_expr_list);
1521debfc3dSmrg }
1531debfc3dSmrg
1541debfc3dSmrg /* This function will free up an entire list of INSN_LIST nodes. */
1551debfc3dSmrg void
free_INSN_LIST_list(rtx_insn_list ** listp)1561debfc3dSmrg free_INSN_LIST_list (rtx_insn_list **listp)
1571debfc3dSmrg {
1581debfc3dSmrg if (*listp == 0)
1591debfc3dSmrg return;
1601debfc3dSmrg free_list ((rtx *)listp, &unused_insn_list);
1611debfc3dSmrg }
1621debfc3dSmrg
1631debfc3dSmrg /* Make a copy of the INSN_LIST list LINK and return it. */
1641debfc3dSmrg rtx_insn_list *
copy_INSN_LIST(rtx_insn_list * link)1651debfc3dSmrg copy_INSN_LIST (rtx_insn_list *link)
1661debfc3dSmrg {
1671debfc3dSmrg rtx_insn_list *new_queue;
1681debfc3dSmrg rtx_insn_list **pqueue = &new_queue;
1691debfc3dSmrg
1701debfc3dSmrg for (; link; link = link->next ())
1711debfc3dSmrg {
1721debfc3dSmrg rtx_insn *x = link->insn ();
1731debfc3dSmrg rtx_insn_list *newlink = alloc_INSN_LIST (x, NULL);
1741debfc3dSmrg *pqueue = newlink;
1751debfc3dSmrg pqueue = (rtx_insn_list **)&XEXP (newlink, 1);
1761debfc3dSmrg }
1771debfc3dSmrg *pqueue = NULL;
1781debfc3dSmrg return new_queue;
1791debfc3dSmrg }
1801debfc3dSmrg
1811debfc3dSmrg /* Duplicate the INSN_LIST elements of COPY and prepend them to OLD. */
1821debfc3dSmrg rtx_insn_list *
concat_INSN_LIST(rtx_insn_list * copy,rtx_insn_list * old)1831debfc3dSmrg concat_INSN_LIST (rtx_insn_list *copy, rtx_insn_list *old)
1841debfc3dSmrg {
1851debfc3dSmrg rtx_insn_list *new_rtx = old;
1861debfc3dSmrg for (; copy ; copy = copy->next ())
1871debfc3dSmrg {
1881debfc3dSmrg new_rtx = alloc_INSN_LIST (copy->insn (), new_rtx);
1891debfc3dSmrg PUT_REG_NOTE_KIND (new_rtx, REG_NOTE_KIND (copy));
1901debfc3dSmrg }
1911debfc3dSmrg return new_rtx;
1921debfc3dSmrg }
1931debfc3dSmrg
1941debfc3dSmrg /* This function will free up an individual EXPR_LIST node. */
1951debfc3dSmrg void
free_EXPR_LIST_node(rtx ptr)1961debfc3dSmrg free_EXPR_LIST_node (rtx ptr)
1971debfc3dSmrg {
1981debfc3dSmrg XEXP (ptr, 1) = unused_expr_list;
1991debfc3dSmrg unused_expr_list = ptr;
2001debfc3dSmrg }
2011debfc3dSmrg
2021debfc3dSmrg /* This function will free up an individual INSN_LIST node. */
2031debfc3dSmrg void
free_INSN_LIST_node(rtx ptr)2041debfc3dSmrg free_INSN_LIST_node (rtx ptr)
2051debfc3dSmrg {
2061debfc3dSmrg gcc_assert (GET_CODE (ptr) == INSN_LIST);
2071debfc3dSmrg XEXP (ptr, 1) = unused_insn_list;
2081debfc3dSmrg unused_insn_list = ptr;
2091debfc3dSmrg }
2101debfc3dSmrg
2111debfc3dSmrg /* Remove and free corresponding to ELEM node in the INSN_LIST pointed to
2121debfc3dSmrg by LISTP. */
2131debfc3dSmrg void
remove_free_INSN_LIST_elem(rtx_insn * elem,rtx_insn_list ** listp)2141debfc3dSmrg remove_free_INSN_LIST_elem (rtx_insn *elem, rtx_insn_list **listp)
2151debfc3dSmrg {
2161debfc3dSmrg free_INSN_LIST_node (remove_list_elem (elem, (rtx *)listp));
2171debfc3dSmrg }
2181debfc3dSmrg
2191debfc3dSmrg /* Remove and free the first node in the INSN_LIST pointed to by LISTP. */
2201debfc3dSmrg rtx_insn *
remove_free_INSN_LIST_node(rtx_insn_list ** listp)2211debfc3dSmrg remove_free_INSN_LIST_node (rtx_insn_list **listp)
2221debfc3dSmrg {
2231debfc3dSmrg rtx_insn_list *node = *listp;
2241debfc3dSmrg rtx_insn *elem = node->insn ();
2251debfc3dSmrg
2261debfc3dSmrg remove_list_node ((rtx *)listp);
2271debfc3dSmrg free_INSN_LIST_node (node);
2281debfc3dSmrg
2291debfc3dSmrg return elem;
2301debfc3dSmrg }
2311debfc3dSmrg
2321debfc3dSmrg /* Remove and free the first node in the EXPR_LIST pointed to by LISTP. */
2331debfc3dSmrg rtx
remove_free_EXPR_LIST_node(rtx_expr_list ** listp)2341debfc3dSmrg remove_free_EXPR_LIST_node (rtx_expr_list **listp)
2351debfc3dSmrg {
2361debfc3dSmrg rtx_expr_list *node = *listp;
2371debfc3dSmrg rtx elem = XEXP (node, 0);
2381debfc3dSmrg
2391debfc3dSmrg remove_list_node ((rtx *)listp);
2401debfc3dSmrg free_EXPR_LIST_node (node);
2411debfc3dSmrg
2421debfc3dSmrg return elem;
2431debfc3dSmrg }
2441debfc3dSmrg
2451debfc3dSmrg #include "gt-lists.h"
246