xref: /dflybsd-src/contrib/gcc-4.7/gcc/lists.c (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
1*e4b17023SJohn Marino /* List management for the GCC expander.
2*e4b17023SJohn Marino    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3*e4b17023SJohn Marino    1999, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4*e4b17023SJohn Marino    Free Software Foundation, Inc.
5*e4b17023SJohn Marino 
6*e4b17023SJohn Marino This file is part of GCC.
7*e4b17023SJohn Marino 
8*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
9*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
10*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
11*e4b17023SJohn Marino version.
12*e4b17023SJohn Marino 
13*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
15*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16*e4b17023SJohn Marino for more details.
17*e4b17023SJohn Marino 
18*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19*e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
20*e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
21*e4b17023SJohn Marino 
22*e4b17023SJohn Marino #include "config.h"
23*e4b17023SJohn Marino #include "system.h"
24*e4b17023SJohn Marino #include "coretypes.h"
25*e4b17023SJohn Marino #include "tm.h"
26*e4b17023SJohn Marino #include "diagnostic-core.h"
27*e4b17023SJohn Marino #include "rtl.h"
28*e4b17023SJohn Marino #include "ggc.h"
29*e4b17023SJohn Marino 
30*e4b17023SJohn Marino static void free_list (rtx *, rtx *);
31*e4b17023SJohn Marino 
32*e4b17023SJohn Marino /* Functions for maintaining cache-able lists of EXPR_LIST and INSN_LISTs.  */
33*e4b17023SJohn Marino 
34*e4b17023SJohn Marino /* An INSN_LIST containing all INSN_LISTs allocated but currently unused.  */
35*e4b17023SJohn Marino static GTY ((deletable)) rtx unused_insn_list;
36*e4b17023SJohn Marino 
37*e4b17023SJohn Marino /* An EXPR_LIST containing all EXPR_LISTs allocated but currently unused.  */
38*e4b17023SJohn Marino static GTY ((deletable)) rtx unused_expr_list;
39*e4b17023SJohn Marino 
40*e4b17023SJohn Marino /* This function will free an entire list of either EXPR_LIST, INSN_LIST
41*e4b17023SJohn Marino    or DEPS_LIST nodes.  This is to be used only on lists that consist
42*e4b17023SJohn Marino    exclusively of nodes of one type only.  This is only called by
43*e4b17023SJohn Marino    free_EXPR_LIST_list, free_INSN_LIST_list and free_DEPS_LIST_list.  */
44*e4b17023SJohn Marino static void
free_list(rtx * listp,rtx * unused_listp)45*e4b17023SJohn Marino free_list (rtx *listp, rtx *unused_listp)
46*e4b17023SJohn Marino {
47*e4b17023SJohn Marino   rtx link, prev_link;
48*e4b17023SJohn Marino 
49*e4b17023SJohn Marino   prev_link = *listp;
50*e4b17023SJohn Marino   link = XEXP (prev_link, 1);
51*e4b17023SJohn Marino 
52*e4b17023SJohn Marino   gcc_assert (unused_listp != &unused_insn_list
53*e4b17023SJohn Marino 	      || GET_CODE (prev_link) == INSN_LIST);
54*e4b17023SJohn Marino 
55*e4b17023SJohn Marino   while (link)
56*e4b17023SJohn Marino     {
57*e4b17023SJohn Marino       gcc_assert (unused_listp != &unused_insn_list
58*e4b17023SJohn Marino 		  || GET_CODE (prev_link) == INSN_LIST);
59*e4b17023SJohn Marino 
60*e4b17023SJohn Marino       prev_link = link;
61*e4b17023SJohn Marino       link = XEXP (link, 1);
62*e4b17023SJohn Marino     }
63*e4b17023SJohn Marino 
64*e4b17023SJohn Marino   XEXP (prev_link, 1) = *unused_listp;
65*e4b17023SJohn Marino   *unused_listp = *listp;
66*e4b17023SJohn Marino   *listp = 0;
67*e4b17023SJohn Marino }
68*e4b17023SJohn Marino 
69*e4b17023SJohn Marino /* Find corresponding to ELEM node in the list pointed to by LISTP.
70*e4b17023SJohn Marino    This node must exist in the list.  Returns pointer to that node.  */
71*e4b17023SJohn Marino static rtx *
find_list_elem(rtx elem,rtx * listp)72*e4b17023SJohn Marino find_list_elem (rtx elem, rtx *listp)
73*e4b17023SJohn Marino {
74*e4b17023SJohn Marino   while (XEXP (*listp, 0) != elem)
75*e4b17023SJohn Marino     listp = &XEXP (*listp, 1);
76*e4b17023SJohn Marino   return listp;
77*e4b17023SJohn Marino }
78*e4b17023SJohn Marino 
79*e4b17023SJohn Marino /* Remove the node pointed to by LISTP from the list.  */
80*e4b17023SJohn Marino static void
remove_list_node(rtx * listp)81*e4b17023SJohn Marino remove_list_node (rtx *listp)
82*e4b17023SJohn Marino {
83*e4b17023SJohn Marino   rtx node;
84*e4b17023SJohn Marino 
85*e4b17023SJohn Marino   node = *listp;
86*e4b17023SJohn Marino   *listp = XEXP (node, 1);
87*e4b17023SJohn Marino   XEXP (node, 1) = 0;
88*e4b17023SJohn Marino }
89*e4b17023SJohn Marino 
90*e4b17023SJohn Marino /* Removes corresponding to ELEM node from the list pointed to by LISTP.
91*e4b17023SJohn Marino    Returns that node.  */
92*e4b17023SJohn Marino rtx
remove_list_elem(rtx elem,rtx * listp)93*e4b17023SJohn Marino remove_list_elem (rtx elem, rtx *listp)
94*e4b17023SJohn Marino {
95*e4b17023SJohn Marino   rtx node;
96*e4b17023SJohn Marino 
97*e4b17023SJohn Marino   listp = find_list_elem (elem, listp);
98*e4b17023SJohn Marino   node = *listp;
99*e4b17023SJohn Marino   remove_list_node (listp);
100*e4b17023SJohn Marino   return node;
101*e4b17023SJohn Marino }
102*e4b17023SJohn Marino 
103*e4b17023SJohn Marino /* This call is used in place of a gen_rtx_INSN_LIST. If there is a cached
104*e4b17023SJohn Marino    node available, we'll use it, otherwise a call to gen_rtx_INSN_LIST
105*e4b17023SJohn Marino    is made.  */
106*e4b17023SJohn Marino rtx
alloc_INSN_LIST(rtx val,rtx next)107*e4b17023SJohn Marino alloc_INSN_LIST (rtx val, rtx next)
108*e4b17023SJohn Marino {
109*e4b17023SJohn Marino   rtx r;
110*e4b17023SJohn Marino 
111*e4b17023SJohn Marino   if (unused_insn_list)
112*e4b17023SJohn Marino     {
113*e4b17023SJohn Marino       r = unused_insn_list;
114*e4b17023SJohn Marino       unused_insn_list = XEXP (r, 1);
115*e4b17023SJohn Marino       XEXP (r, 0) = val;
116*e4b17023SJohn Marino       XEXP (r, 1) = next;
117*e4b17023SJohn Marino       PUT_REG_NOTE_KIND (r, VOIDmode);
118*e4b17023SJohn Marino 
119*e4b17023SJohn Marino       gcc_assert (GET_CODE (r) == INSN_LIST);
120*e4b17023SJohn Marino     }
121*e4b17023SJohn Marino   else
122*e4b17023SJohn Marino     r = gen_rtx_INSN_LIST (VOIDmode, val, next);
123*e4b17023SJohn Marino 
124*e4b17023SJohn Marino   return r;
125*e4b17023SJohn Marino }
126*e4b17023SJohn Marino 
127*e4b17023SJohn Marino /* This call is used in place of a gen_rtx_EXPR_LIST. If there is a cached
128*e4b17023SJohn Marino    node available, we'll use it, otherwise a call to gen_rtx_EXPR_LIST
129*e4b17023SJohn Marino    is made.  */
130*e4b17023SJohn Marino rtx
alloc_EXPR_LIST(int kind,rtx val,rtx next)131*e4b17023SJohn Marino alloc_EXPR_LIST (int kind, rtx val, rtx next)
132*e4b17023SJohn Marino {
133*e4b17023SJohn Marino   rtx r;
134*e4b17023SJohn Marino 
135*e4b17023SJohn Marino   if (unused_expr_list)
136*e4b17023SJohn Marino     {
137*e4b17023SJohn Marino       r = unused_expr_list;
138*e4b17023SJohn Marino       unused_expr_list = XEXP (r, 1);
139*e4b17023SJohn Marino       XEXP (r, 0) = val;
140*e4b17023SJohn Marino       XEXP (r, 1) = next;
141*e4b17023SJohn Marino       PUT_REG_NOTE_KIND (r, kind);
142*e4b17023SJohn Marino     }
143*e4b17023SJohn Marino   else
144*e4b17023SJohn Marino     r = gen_rtx_EXPR_LIST ((enum machine_mode) kind, val, next);
145*e4b17023SJohn Marino 
146*e4b17023SJohn Marino   return r;
147*e4b17023SJohn Marino }
148*e4b17023SJohn Marino 
149*e4b17023SJohn Marino /* This function will free up an entire list of EXPR_LIST nodes.  */
150*e4b17023SJohn Marino void
free_EXPR_LIST_list(rtx * listp)151*e4b17023SJohn Marino free_EXPR_LIST_list (rtx *listp)
152*e4b17023SJohn Marino {
153*e4b17023SJohn Marino   if (*listp == 0)
154*e4b17023SJohn Marino     return;
155*e4b17023SJohn Marino   free_list (listp, &unused_expr_list);
156*e4b17023SJohn Marino }
157*e4b17023SJohn Marino 
158*e4b17023SJohn Marino /* This function will free up an entire list of INSN_LIST nodes.  */
159*e4b17023SJohn Marino void
free_INSN_LIST_list(rtx * listp)160*e4b17023SJohn Marino free_INSN_LIST_list (rtx *listp)
161*e4b17023SJohn Marino {
162*e4b17023SJohn Marino   if (*listp == 0)
163*e4b17023SJohn Marino     return;
164*e4b17023SJohn Marino   free_list (listp, &unused_insn_list);
165*e4b17023SJohn Marino }
166*e4b17023SJohn Marino 
167*e4b17023SJohn Marino /* Make a copy of the INSN_LIST list LINK and return it.  */
168*e4b17023SJohn Marino rtx
copy_INSN_LIST(rtx link)169*e4b17023SJohn Marino copy_INSN_LIST (rtx link)
170*e4b17023SJohn Marino {
171*e4b17023SJohn Marino   rtx new_queue;
172*e4b17023SJohn Marino   rtx *pqueue = &new_queue;
173*e4b17023SJohn Marino 
174*e4b17023SJohn Marino   for (; link; link = XEXP (link, 1))
175*e4b17023SJohn Marino     {
176*e4b17023SJohn Marino       rtx x = XEXP (link, 0);
177*e4b17023SJohn Marino       rtx newlink = alloc_INSN_LIST (x, NULL);
178*e4b17023SJohn Marino       *pqueue = newlink;
179*e4b17023SJohn Marino       pqueue = &XEXP (newlink, 1);
180*e4b17023SJohn Marino     }
181*e4b17023SJohn Marino   *pqueue = NULL_RTX;
182*e4b17023SJohn Marino   return new_queue;
183*e4b17023SJohn Marino }
184*e4b17023SJohn Marino 
185*e4b17023SJohn Marino /* Duplicate the INSN_LIST elements of COPY and prepend them to OLD.  */
186*e4b17023SJohn Marino rtx
concat_INSN_LIST(rtx copy,rtx old)187*e4b17023SJohn Marino concat_INSN_LIST (rtx copy, rtx old)
188*e4b17023SJohn Marino {
189*e4b17023SJohn Marino   rtx new_rtx = old;
190*e4b17023SJohn Marino   for (; copy ; copy = XEXP (copy, 1))
191*e4b17023SJohn Marino     {
192*e4b17023SJohn Marino       new_rtx = alloc_INSN_LIST (XEXP (copy, 0), new_rtx);
193*e4b17023SJohn Marino       PUT_REG_NOTE_KIND (new_rtx, REG_NOTE_KIND (copy));
194*e4b17023SJohn Marino     }
195*e4b17023SJohn Marino   return new_rtx;
196*e4b17023SJohn Marino }
197*e4b17023SJohn Marino 
198*e4b17023SJohn Marino /* This function will free up an individual EXPR_LIST node.  */
199*e4b17023SJohn Marino void
free_EXPR_LIST_node(rtx ptr)200*e4b17023SJohn Marino free_EXPR_LIST_node (rtx ptr)
201*e4b17023SJohn Marino {
202*e4b17023SJohn Marino   XEXP (ptr, 1) = unused_expr_list;
203*e4b17023SJohn Marino   unused_expr_list = ptr;
204*e4b17023SJohn Marino }
205*e4b17023SJohn Marino 
206*e4b17023SJohn Marino /* This function will free up an individual INSN_LIST node.  */
207*e4b17023SJohn Marino void
free_INSN_LIST_node(rtx ptr)208*e4b17023SJohn Marino free_INSN_LIST_node (rtx ptr)
209*e4b17023SJohn Marino {
210*e4b17023SJohn Marino   gcc_assert (GET_CODE (ptr) == INSN_LIST);
211*e4b17023SJohn Marino   XEXP (ptr, 1) = unused_insn_list;
212*e4b17023SJohn Marino   unused_insn_list = ptr;
213*e4b17023SJohn Marino }
214*e4b17023SJohn Marino 
215*e4b17023SJohn Marino /* Remove and free corresponding to ELEM node in the INSN_LIST pointed to
216*e4b17023SJohn Marino    by LISTP.  */
217*e4b17023SJohn Marino void
remove_free_INSN_LIST_elem(rtx elem,rtx * listp)218*e4b17023SJohn Marino remove_free_INSN_LIST_elem (rtx elem, rtx *listp)
219*e4b17023SJohn Marino {
220*e4b17023SJohn Marino   free_INSN_LIST_node (remove_list_elem (elem, listp));
221*e4b17023SJohn Marino }
222*e4b17023SJohn Marino 
223*e4b17023SJohn Marino /* Remove and free the first node in the INSN_LIST pointed to by LISTP.  */
224*e4b17023SJohn Marino rtx
remove_free_INSN_LIST_node(rtx * listp)225*e4b17023SJohn Marino remove_free_INSN_LIST_node (rtx *listp)
226*e4b17023SJohn Marino {
227*e4b17023SJohn Marino   rtx node = *listp;
228*e4b17023SJohn Marino   rtx elem = XEXP (node, 0);
229*e4b17023SJohn Marino 
230*e4b17023SJohn Marino   remove_list_node (listp);
231*e4b17023SJohn Marino   free_INSN_LIST_node (node);
232*e4b17023SJohn Marino 
233*e4b17023SJohn Marino   return elem;
234*e4b17023SJohn Marino }
235*e4b17023SJohn Marino 
236*e4b17023SJohn Marino /* Remove and free the first node in the EXPR_LIST pointed to by LISTP.  */
237*e4b17023SJohn Marino rtx
remove_free_EXPR_LIST_node(rtx * listp)238*e4b17023SJohn Marino remove_free_EXPR_LIST_node (rtx *listp)
239*e4b17023SJohn Marino {
240*e4b17023SJohn Marino   rtx node = *listp;
241*e4b17023SJohn Marino   rtx elem = XEXP (node, 0);
242*e4b17023SJohn Marino 
243*e4b17023SJohn Marino   remove_list_node (listp);
244*e4b17023SJohn Marino   free_EXPR_LIST_node (node);
245*e4b17023SJohn Marino 
246*e4b17023SJohn Marino   return elem;
247*e4b17023SJohn Marino }
248*e4b17023SJohn Marino 
249*e4b17023SJohn Marino #include "gt-lists.h"
250