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 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 2, or (at your option) any later
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
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
24 #include "coretypes.h"
30 static void free_list (rtx
*, rtx
*);
31 static void free_DEPS_LIST_node (rtx
);
33 /* Functions for maintaining cache-able lists of EXPR_LIST and INSN_LISTs. */
35 /* An INSN_LIST containing all INSN_LISTs allocated but currently unused. */
36 static GTY ((deletable
)) rtx unused_insn_list
;
38 /* An EXPR_LIST containing all EXPR_LISTs allocated but currently unused. */
39 static GTY ((deletable
)) rtx unused_expr_list
;
41 /* An DEPS_LIST containing all DEPS_LISTs allocated but currently unused. */
42 static GTY ((deletable
)) rtx unused_deps_list
;
45 /* This function will free an entire list of either EXPR_LIST, INSN_LIST
46 or DEPS_LIST nodes. This is to be used only on lists that consist
47 exclusively of nodes of one type only. This is only called by
48 free_EXPR_LIST_list, free_INSN_LIST_list and free_DEPS_LIST_list. */
50 free_list (rtx
*listp
, rtx
*unused_listp
)
55 link
= XEXP (prev_link
, 1);
57 gcc_assert ((unused_listp
!= &unused_insn_list
58 || GET_CODE (prev_link
) == INSN_LIST
)
59 && (unused_listp
!= &unused_deps_list
60 || GET_CODE (prev_link
) == DEPS_LIST
));
64 gcc_assert ((unused_listp
!= &unused_insn_list
65 || GET_CODE (prev_link
) == INSN_LIST
)
66 && (unused_listp
!= &unused_deps_list
67 || GET_CODE (prev_link
) == DEPS_LIST
));
70 link
= XEXP (link
, 1);
73 XEXP (prev_link
, 1) = *unused_listp
;
74 *unused_listp
= *listp
;
78 /* Find corresponding to ELEM node in the list pointed to by LISTP.
79 This node must exist in the list. Returns pointer to that node. */
81 find_list_elem (rtx elem
, rtx
*listp
)
83 while (XEXP (*listp
, 0) != elem
)
84 listp
= &XEXP (*listp
, 1);
88 /* Remove the node pointed to by LISTP from the list. */
90 remove_list_node (rtx
*listp
)
95 *listp
= XEXP (node
, 1);
99 /* Removes corresponding to ELEM node from the list pointed to by LISTP.
100 Returns that node. */
102 remove_list_elem (rtx elem
, rtx
*listp
)
106 listp
= find_list_elem (elem
, listp
);
108 remove_list_node (listp
);
112 /* This call is used in place of a gen_rtx_INSN_LIST. If there is a cached
113 node available, we'll use it, otherwise a call to gen_rtx_INSN_LIST
116 alloc_INSN_LIST (rtx val
, rtx next
)
120 if (unused_insn_list
)
122 r
= unused_insn_list
;
123 unused_insn_list
= XEXP (r
, 1);
126 PUT_REG_NOTE_KIND (r
, VOIDmode
);
128 gcc_assert (GET_CODE (r
) == INSN_LIST
);
131 r
= gen_rtx_INSN_LIST (VOIDmode
, val
, next
);
136 /* This call is used in place of a gen_rtx_EXPR_LIST. If there is a cached
137 node available, we'll use it, otherwise a call to gen_rtx_EXPR_LIST
140 alloc_EXPR_LIST (int kind
, rtx val
, rtx next
)
144 if (unused_expr_list
)
146 r
= unused_expr_list
;
147 unused_expr_list
= XEXP (r
, 1);
150 PUT_REG_NOTE_KIND (r
, kind
);
153 r
= gen_rtx_EXPR_LIST (kind
, val
, next
);
158 /* This call is used in place of a gen_rtx_DEPS_LIST. If there is a cached
159 node available, we'll use it, otherwise a call to gen_rtx_DEPS_LIST
162 alloc_DEPS_LIST (rtx val
, rtx next
, int ds
)
166 if (unused_deps_list
)
168 r
= unused_deps_list
;
169 unused_deps_list
= XEXP (r
, 1);
173 PUT_REG_NOTE_KIND (r
, VOIDmode
);
175 gcc_assert (GET_CODE (r
) == DEPS_LIST
);
178 r
= gen_rtx_DEPS_LIST (VOIDmode
, val
, next
, ds
);
183 /* This function will free up an entire list of EXPR_LIST nodes. */
185 free_EXPR_LIST_list (rtx
*listp
)
189 free_list (listp
, &unused_expr_list
);
192 /* This function will free up an entire list of INSN_LIST nodes. */
194 free_INSN_LIST_list (rtx
*listp
)
198 free_list (listp
, &unused_insn_list
);
201 /* This function will free up an entire list of DEPS_LIST nodes. */
203 free_DEPS_LIST_list (rtx
*listp
)
207 free_list (listp
, &unused_deps_list
);
210 /* This function will free up an individual EXPR_LIST node. */
212 free_EXPR_LIST_node (rtx ptr
)
214 XEXP (ptr
, 1) = unused_expr_list
;
215 unused_expr_list
= ptr
;
218 /* This function will free up an individual INSN_LIST node. */
220 free_INSN_LIST_node (rtx ptr
)
222 gcc_assert (GET_CODE (ptr
) == INSN_LIST
);
223 XEXP (ptr
, 1) = unused_insn_list
;
224 unused_insn_list
= ptr
;
227 /* This function will free up an individual DEPS_LIST node. */
229 free_DEPS_LIST_node (rtx ptr
)
231 gcc_assert (GET_CODE (ptr
) == DEPS_LIST
);
232 XEXP (ptr
, 1) = unused_deps_list
;
233 unused_deps_list
= ptr
;
236 /* Remove and free corresponding to ELEM node in the DEPS_LIST pointed to
239 remove_free_DEPS_LIST_elem (rtx elem
, rtx
*listp
)
241 free_DEPS_LIST_node (remove_list_elem (elem
, listp
));
244 /* Remove and free corresponding to ELEM node in the INSN_LIST pointed to
247 remove_free_INSN_LIST_elem (rtx elem
, rtx
*listp
)
249 free_INSN_LIST_node (remove_list_elem (elem
, listp
));
252 /* Create and return a copy of the DEPS_LIST LIST. */
254 copy_DEPS_LIST_list (rtx list
)
256 rtx res
= NULL_RTX
, *resp
= &res
;
260 *resp
= alloc_DEPS_LIST (XEXP (list
, 0), 0, XINT (list
, 2));
261 PUT_REG_NOTE_KIND (*resp
, REG_NOTE_KIND (list
));
262 resp
= &XEXP (*resp
, 1);
263 list
= XEXP (list
, 1);
268 #include "gt-lists.h"