Mark ChangeLog
[official-gcc.git] / gcc / lists.c
blob0f3c471ced1aea247e85c72e0d3f5fb3c05385fc
1 /* List management for the GCC expander.
2 Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "toplev.h"
26 #include "rtl.h"
27 #include "ggc.h"
29 static void free_list (rtx *, rtx *);
30 static void free_DEPS_LIST_node (rtx);
32 /* Functions for maintaining cache-able lists of EXPR_LIST and INSN_LISTs. */
34 /* An INSN_LIST containing all INSN_LISTs allocated but currently unused. */
35 static GTY ((deletable)) rtx unused_insn_list;
37 /* An EXPR_LIST containing all EXPR_LISTs allocated but currently unused. */
38 static GTY ((deletable)) rtx unused_expr_list;
40 /* An DEPS_LIST containing all DEPS_LISTs allocated but currently unused. */
41 static GTY ((deletable)) rtx unused_deps_list;
44 /* This function will free an entire list of either EXPR_LIST, INSN_LIST
45 or DEPS_LIST nodes. This is to be used only on lists that consist
46 exclusively of nodes of one type only. This is only called by
47 free_EXPR_LIST_list, free_INSN_LIST_list and free_DEPS_LIST_list. */
48 static void
49 free_list (rtx *listp, rtx *unused_listp)
51 rtx link, prev_link;
53 prev_link = *listp;
54 link = XEXP (prev_link, 1);
56 gcc_assert ((unused_listp != &unused_insn_list
57 || GET_CODE (prev_link) == INSN_LIST)
58 && (unused_listp != &unused_deps_list
59 || GET_CODE (prev_link) == DEPS_LIST));
61 while (link)
63 gcc_assert ((unused_listp != &unused_insn_list
64 || GET_CODE (prev_link) == INSN_LIST)
65 && (unused_listp != &unused_deps_list
66 || GET_CODE (prev_link) == DEPS_LIST));
68 prev_link = link;
69 link = XEXP (link, 1);
72 XEXP (prev_link, 1) = *unused_listp;
73 *unused_listp = *listp;
74 *listp = 0;
77 /* Find corresponding to ELEM node in the list pointed to by LISTP.
78 This node must exist in the list. Returns pointer to that node. */
79 static rtx *
80 find_list_elem (rtx elem, rtx *listp)
82 while (XEXP (*listp, 0) != elem)
83 listp = &XEXP (*listp, 1);
84 return listp;
87 /* Remove the node pointed to by LISTP from the list. */
88 static void
89 remove_list_node (rtx *listp)
91 rtx node;
93 node = *listp;
94 *listp = XEXP (node, 1);
95 XEXP (node, 1) = 0;
98 /* Removes corresponding to ELEM node from the list pointed to by LISTP.
99 Returns that node. */
101 remove_list_elem (rtx elem, rtx *listp)
103 rtx node;
105 listp = find_list_elem (elem, listp);
106 node = *listp;
107 remove_list_node (listp);
108 return node;
111 /* This call is used in place of a gen_rtx_INSN_LIST. If there is a cached
112 node available, we'll use it, otherwise a call to gen_rtx_INSN_LIST
113 is made. */
115 alloc_INSN_LIST (rtx val, rtx next)
117 rtx r;
119 if (unused_insn_list)
121 r = unused_insn_list;
122 unused_insn_list = XEXP (r, 1);
123 XEXP (r, 0) = val;
124 XEXP (r, 1) = next;
125 PUT_REG_NOTE_KIND (r, VOIDmode);
127 gcc_assert (GET_CODE (r) == INSN_LIST);
129 else
130 r = gen_rtx_INSN_LIST (VOIDmode, val, next);
132 return r;
135 /* This call is used in place of a gen_rtx_EXPR_LIST. If there is a cached
136 node available, we'll use it, otherwise a call to gen_rtx_EXPR_LIST
137 is made. */
139 alloc_EXPR_LIST (int kind, rtx val, rtx next)
141 rtx r;
143 if (unused_expr_list)
145 r = unused_expr_list;
146 unused_expr_list = XEXP (r, 1);
147 XEXP (r, 0) = val;
148 XEXP (r, 1) = next;
149 PUT_REG_NOTE_KIND (r, kind);
151 else
152 r = gen_rtx_EXPR_LIST (kind, val, next);
154 return r;
157 /* This call is used in place of a gen_rtx_DEPS_LIST. If there is a cached
158 node available, we'll use it, otherwise a call to gen_rtx_DEPS_LIST
159 is made. */
161 alloc_DEPS_LIST (rtx val, rtx next, int ds)
163 rtx r;
165 if (unused_deps_list)
167 r = unused_deps_list;
168 unused_deps_list = XEXP (r, 1);
169 XEXP (r, 0) = val;
170 XEXP (r, 1) = next;
171 XINT (r, 2) = ds;
172 PUT_REG_NOTE_KIND (r, VOIDmode);
174 gcc_assert (GET_CODE (r) == DEPS_LIST);
176 else
177 r = gen_rtx_DEPS_LIST (VOIDmode, val, next, ds);
179 return r;
182 /* This function will free up an entire list of EXPR_LIST nodes. */
183 void
184 free_EXPR_LIST_list (rtx *listp)
186 if (*listp == 0)
187 return;
188 free_list (listp, &unused_expr_list);
191 /* This function will free up an entire list of INSN_LIST nodes. */
192 void
193 free_INSN_LIST_list (rtx *listp)
195 if (*listp == 0)
196 return;
197 free_list (listp, &unused_insn_list);
200 /* This function will free up an entire list of DEPS_LIST nodes. */
201 void
202 free_DEPS_LIST_list (rtx *listp)
204 if (*listp == 0)
205 return;
206 free_list (listp, &unused_deps_list);
209 /* This function will free up an individual EXPR_LIST node. */
210 void
211 free_EXPR_LIST_node (rtx ptr)
213 XEXP (ptr, 1) = unused_expr_list;
214 unused_expr_list = ptr;
217 /* This function will free up an individual INSN_LIST node. */
218 void
219 free_INSN_LIST_node (rtx ptr)
221 gcc_assert (GET_CODE (ptr) == INSN_LIST);
222 XEXP (ptr, 1) = unused_insn_list;
223 unused_insn_list = ptr;
226 /* This function will free up an individual DEPS_LIST node. */
227 static void
228 free_DEPS_LIST_node (rtx ptr)
230 gcc_assert (GET_CODE (ptr) == DEPS_LIST);
231 XEXP (ptr, 1) = unused_deps_list;
232 unused_deps_list = ptr;
235 /* Remove and free corresponding to ELEM node in the DEPS_LIST pointed to
236 by LISTP. */
237 void
238 remove_free_DEPS_LIST_elem (rtx elem, rtx *listp)
240 free_DEPS_LIST_node (remove_list_elem (elem, listp));
243 /* Remove and free corresponding to ELEM node in the INSN_LIST pointed to
244 by LISTP. */
245 void
246 remove_free_INSN_LIST_elem (rtx elem, rtx *listp)
248 free_INSN_LIST_node (remove_list_elem (elem, listp));
251 /* Create and return a copy of the DEPS_LIST LIST. */
253 copy_DEPS_LIST_list (rtx list)
255 rtx res = NULL_RTX, *resp = &res;
257 while (list)
259 *resp = alloc_DEPS_LIST (XEXP (list, 0), 0, XINT (list, 2));
260 PUT_REG_NOTE_KIND (*resp, REG_NOTE_KIND (list));
261 resp = &XEXP (*resp, 1);
262 list = XEXP (list, 1);
264 return res;
267 #include "gt-lists.h"