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