150397Sobrien/* Virtual array support.
2132718Skan   Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004
3132718Skan   Free Software Foundation, Inc.
450397Sobrien   Contributed by Cygnus Solutions.
550397Sobrien
690075Sobrien   This file is part of GCC.
750397Sobrien
890075Sobrien   GCC is free software; you can redistribute it and/or modify it
950397Sobrien   under the terms of the GNU General Public License as published by
1050397Sobrien   the Free Software Foundation; either version 2, or (at your option)
1150397Sobrien   any later version.
1250397Sobrien
1390075Sobrien   GCC is distributed in the hope that it will be useful, but WITHOUT
1490075Sobrien   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1590075Sobrien   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
1690075Sobrien   License for more details.
1750397Sobrien
1850397Sobrien   You should have received a copy of the GNU General Public License
1990075Sobrien   along with GCC; see the file COPYING.  If not, write to the Free
20169689Skan   the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
21169689Skan   MA 02110-1301, USA.  */
2250397Sobrien
2390075Sobrien#ifndef GCC_VARRAY_H
2490075Sobrien#define GCC_VARRAY_H
2550397Sobrien
2650397Sobrien#ifndef HOST_WIDE_INT
2750397Sobrien#include "machmode.h"
2850397Sobrien#endif
2950397Sobrien
3090075Sobrien#ifndef GCC_SYSTEM_H
3150397Sobrien#include "system.h"
32132718Skan#include "coretypes.h"
33132718Skan#include "tm.h"
3450397Sobrien#endif
3550397Sobrien
36132718Skan/* Enum indicating what the varray contains.
37132718Skan   If this is changed, `element' in varray.c needs to be updated.  */
38117395Skan
39117395Skanenum varray_data_enum {
40117395Skan  VARRAY_DATA_C,
41117395Skan  VARRAY_DATA_UC,
42117395Skan  VARRAY_DATA_S,
43117395Skan  VARRAY_DATA_US,
44117395Skan  VARRAY_DATA_I,
45117395Skan  VARRAY_DATA_U,
46117395Skan  VARRAY_DATA_L,
47117395Skan  VARRAY_DATA_UL,
48117395Skan  VARRAY_DATA_HINT,
49117395Skan  VARRAY_DATA_UHINT,
50117395Skan  VARRAY_DATA_GENERIC,
51169689Skan  VARRAY_DATA_GENERIC_NOGC,
52117395Skan  VARRAY_DATA_CPTR,
53117395Skan  VARRAY_DATA_RTX,
54117395Skan  VARRAY_DATA_RTVEC,
55117395Skan  VARRAY_DATA_TREE,
56117395Skan  VARRAY_DATA_BITMAP,
57117395Skan  VARRAY_DATA_REG,
58117395Skan  VARRAY_DATA_BB,
59117395Skan  VARRAY_DATA_TE,
60169689Skan  VARRAY_DATA_EDGE,
61169689Skan  VARRAY_DATA_TREE_PTR,
62117395Skan  NUM_VARRAY_DATA
63117395Skan};
64117395Skan
6550397Sobrien/* Union of various array types that are used.  */
66117395Skantypedef union varray_data_tag GTY (()) {
67117395Skan  char			  GTY ((length ("%0.num_elements"),
68169689Skan				tag ("VARRAY_DATA_C")))		vdt_c[1];
69117395Skan  unsigned char		  GTY ((length ("%0.num_elements"),
70169689Skan				tag ("VARRAY_DATA_UC")))	vdt_uc[1];
71117395Skan  short			  GTY ((length ("%0.num_elements"),
72169689Skan				tag ("VARRAY_DATA_S")))		vdt_s[1];
73117395Skan  unsigned short	  GTY ((length ("%0.num_elements"),
74169689Skan				tag ("VARRAY_DATA_US")))	vdt_us[1];
75117395Skan  int			  GTY ((length ("%0.num_elements"),
76169689Skan				tag ("VARRAY_DATA_I")))		vdt_i[1];
77117395Skan  unsigned int		  GTY ((length ("%0.num_elements"),
78169689Skan				tag ("VARRAY_DATA_U")))		vdt_u[1];
79117395Skan  long			  GTY ((length ("%0.num_elements"),
80169689Skan				tag ("VARRAY_DATA_L")))		vdt_l[1];
81117395Skan  unsigned long		  GTY ((length ("%0.num_elements"),
82169689Skan				tag ("VARRAY_DATA_UL")))	vdt_ul[1];
83117395Skan  HOST_WIDE_INT		  GTY ((length ("%0.num_elements"),
84169689Skan				tag ("VARRAY_DATA_HINT")))	vdt_hint[1];
85117395Skan  unsigned HOST_WIDE_INT  GTY ((length ("%0.num_elements"),
86169689Skan				tag ("VARRAY_DATA_UHINT")))	vdt_uhint[1];
87169689Skan  PTR			  GTY ((length ("%0.num_elements"), use_param,
88169689Skan				tag ("VARRAY_DATA_GENERIC")))	vdt_generic[1];
89169689Skan  PTR			  GTY ((length ("%0.num_elements"), skip (""),
90169689Skan				tag ("VARRAY_DATA_GENERIC_NOGC")))	vdt_generic_nogc[1];
91117395Skan  char			 *GTY ((length ("%0.num_elements"),
92169689Skan				tag ("VARRAY_DATA_CPTR")))	vdt_cptr[1];
93132718Skan  rtx			  GTY ((length ("%0.num_elements"),
94169689Skan				tag ("VARRAY_DATA_RTX")))	vdt_rtx[1];
95132718Skan  rtvec			  GTY ((length ("%0.num_elements"),
96169689Skan				tag ("VARRAY_DATA_RTVEC")))	vdt_rtvec[1];
97132718Skan  tree			  GTY ((length ("%0.num_elements"),
98169689Skan				tag ("VARRAY_DATA_TREE")))	vdt_tree[1];
99117395Skan  struct bitmap_head_def *GTY ((length ("%0.num_elements"),
100169689Skan				tag ("VARRAY_DATA_BITMAP")))	vdt_bitmap[1];
101169689Skan  struct reg_info_def	 *GTY ((length ("%0.num_elements"), skip,
102169689Skan				tag ("VARRAY_DATA_REG")))	vdt_reg[1];
103169689Skan  struct basic_block_def *GTY ((length ("%0.num_elements"), skip,
104169689Skan				tag ("VARRAY_DATA_BB")))	vdt_bb[1];
105117395Skan  struct elt_list	 *GTY ((length ("%0.num_elements"),
106169689Skan				tag ("VARRAY_DATA_TE")))	vdt_te[1];
107169689Skan  struct edge_def        *GTY ((length ("%0.num_elements"),
108169689Skan	                        tag ("VARRAY_DATA_EDGE")))	vdt_e[1];
109169689Skan  tree                   *GTY ((length ("%0.num_elements"), skip (""),
110169689Skan	                        tag ("VARRAY_DATA_TREE_PTR")))	vdt_tp[1];
11150397Sobrien} varray_data;
11250397Sobrien
11350397Sobrien/* Virtual array of pointers header.  */
114117395Skanstruct varray_head_tag GTY(()) {
115117395Skan  size_t	num_elements;	/* Maximum element number allocated.  */
116117395Skan  size_t        elements_used;  /* The number of elements used, if
11790075Sobrien				   using VARRAY_PUSH/VARRAY_POP.  */
118117395Skan  enum varray_data_enum type;	/* The kind of elements in the varray.  */
11950397Sobrien  const char   *name;		/* name of the varray for reporting errors */
120132718Skan  varray_data	GTY ((desc ("%0.type"))) data;	/* The data elements follow,
121117395Skan						   must be last.  */
122117395Skan};
123117395Skantypedef struct varray_head_tag *varray_type;
12450397Sobrien
12550397Sobrien/* Allocate a virtual array with NUM elements, each of which is SIZE bytes
12650397Sobrien   long, named NAME.  Array elements are zeroed.  */
127132718Skanextern varray_type varray_init (size_t, enum varray_data_enum, const char *);
12850397Sobrien
12950397Sobrien#define VARRAY_CHAR_INIT(va, num, name) \
130117395Skan  va = varray_init (num, VARRAY_DATA_C, name)
13150397Sobrien
13250397Sobrien#define VARRAY_UCHAR_INIT(va, num, name) \
133117395Skan  va = varray_init (num, VARRAY_DATA_UC, name)
13450397Sobrien
13550397Sobrien#define VARRAY_SHORT_INIT(va, num, name) \
136117395Skan  va = varray_init (num, VARRAY_DATA_S, name)
13750397Sobrien
13850397Sobrien#define VARRAY_USHORT_INIT(va, num, name) \
139117395Skan  va = varray_init (num, VARRAY_DATA_US, name)
14050397Sobrien
14150397Sobrien#define VARRAY_INT_INIT(va, num, name) \
142117395Skan  va = varray_init (num, VARRAY_DATA_I, name)
14350397Sobrien
14450397Sobrien#define VARRAY_UINT_INIT(va, num, name) \
145117395Skan  va = varray_init (num, VARRAY_DATA_U, name)
14650397Sobrien
14750397Sobrien#define VARRAY_LONG_INIT(va, num, name) \
148117395Skan  va = varray_init (num, VARRAY_DATA_L, name)
14950397Sobrien
15050397Sobrien#define VARRAY_ULONG_INIT(va, num, name) \
151117395Skan  va = varray_init (num, VARRAY_DATA_UL, name)
15250397Sobrien
15350397Sobrien#define VARRAY_WIDE_INT_INIT(va, num, name) \
154117395Skan  va = varray_init (num, VARRAY_DATA_HINT, name)
15550397Sobrien
15650397Sobrien#define VARRAY_UWIDE_INT_INIT(va, num, name) \
157117395Skan  va = varray_init (num, VARRAY_DATA_UHINT, name)
15850397Sobrien
15950397Sobrien#define VARRAY_GENERIC_PTR_INIT(va, num, name) \
160117395Skan  va = varray_init (num, VARRAY_DATA_GENERIC, name)
16150397Sobrien
162169689Skan#define VARRAY_GENERIC_PTR_NOGC_INIT(va, num, name) \
163169689Skan  va = varray_init (num, VARRAY_DATA_GENERIC_NOGC, name)
164169689Skan
16550397Sobrien#define VARRAY_CHAR_PTR_INIT(va, num, name) \
166117395Skan  va = varray_init (num, VARRAY_DATA_CPTR, name)
16750397Sobrien
16850397Sobrien#define VARRAY_RTX_INIT(va, num, name) \
169117395Skan  va = varray_init (num, VARRAY_DATA_RTX, name)
17050397Sobrien
17150397Sobrien#define VARRAY_RTVEC_INIT(va, num, name) \
172117395Skan  va = varray_init (num, VARRAY_DATA_RTVEC, name)
17350397Sobrien
17450397Sobrien#define VARRAY_TREE_INIT(va, num, name) \
175117395Skan  va = varray_init (num, VARRAY_DATA_TREE, name)
17650397Sobrien
17750397Sobrien#define VARRAY_BITMAP_INIT(va, num, name) \
178117395Skan  va = varray_init (num, VARRAY_DATA_BITMAP, name)
17950397Sobrien
18050397Sobrien#define VARRAY_REG_INIT(va, num, name) \
181117395Skan  va = varray_init (num, VARRAY_DATA_REG, name)
18250397Sobrien
18352284Sobrien#define VARRAY_BB_INIT(va, num, name) \
184117395Skan  va = varray_init (num, VARRAY_DATA_BB, name)
18552284Sobrien
18690075Sobrien#define VARRAY_ELT_LIST_INIT(va, num, name) \
187117395Skan  va = varray_init (num, VARRAY_DATA_TE, name)
18890075Sobrien
189169689Skan#define VARRAY_EDGE_INIT(va, num, name) \
190169689Skan  va = varray_init (num, VARRAY_DATA_EDGE, name)
191169689Skan
192169689Skan#define VARRAY_TREE_PTR_INIT(va, num, name) \
193169689Skan  va = varray_init (num, VARRAY_DATA_TREE_PTR, name)
194169689Skan
19550397Sobrien/* Free up memory allocated by the virtual array, but do not free any of the
19650397Sobrien   elements involved.  */
19752284Sobrien#define VARRAY_FREE(vp) \
19890075Sobrien  do { if (vp) { free (vp); vp = (varray_type) 0; } } while (0)
19950397Sobrien
20050397Sobrien/* Grow/shrink the virtual array VA to N elements.  */
201132718Skanextern varray_type varray_grow (varray_type, size_t);
20250397Sobrien
20350397Sobrien#define VARRAY_GROW(VA, N) ((VA) = varray_grow (VA, N))
20450397Sobrien
20552284Sobrien#define VARRAY_SIZE(VA)	((VA)->num_elements)
20652284Sobrien
20790075Sobrien#define VARRAY_ACTIVE_SIZE(VA)	((VA)->elements_used)
20890075Sobrien#define VARRAY_POP_ALL(VA)	((VA)->elements_used = 0)
20990075Sobrien
210117395Skan#define VARRAY_CLEAR(VA) varray_clear(VA)
211117395Skan
212132718Skanextern void varray_clear (varray_type);
213132718Skanextern void dump_varray_statistics (void);
214132718Skan
21590075Sobrien/* Check for VARRAY_xxx macros being in bound.  */
21690075Sobrien#if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
217132718Skanextern void varray_check_failed (varray_type, size_t, const char *, int,
218132718Skan				 const char *) ATTRIBUTE_NORETURN;
219132718Skanextern void varray_underflow (varray_type, const char *, int, const char *)
220132718Skan     ATTRIBUTE_NORETURN;
22190075Sobrien#define VARRAY_CHECK(VA, N, T) __extension__			\
222117395Skan(*({ varray_type const _va = (VA);				\
223132718Skan     const size_t _n = (N);					\
22490075Sobrien     if (_n >= _va->num_elements)				\
22590075Sobrien       varray_check_failed (_va, _n, __FILE__, __LINE__, __FUNCTION__);	\
22690075Sobrien     &_va->data.T[_n]; }))
227132718Skan
228132718Skan#define VARRAY_POP(VA) do {					\
229132718Skan  varray_type const _va = (VA);					\
230132718Skan  if (_va->elements_used == 0)					\
231132718Skan    varray_underflow (_va, __FILE__, __LINE__, __FUNCTION__);	\
232132718Skan  else								\
233132718Skan    _va->elements_used--;					\
234132718Skan} while (0)
235132718Skan
23650397Sobrien#else
23790075Sobrien#define VARRAY_CHECK(VA, N, T) ((VA)->data.T[N])
238132718Skan/* Pop the top element of VA.  */
239132718Skan#define VARRAY_POP(VA) do { ((VA)->elements_used--); } while (0)
24050397Sobrien#endif
24150397Sobrien
24290075Sobrien/* Push X onto VA.  T is the name of the field in varray_data
24390075Sobrien   corresponding to the type of X.  */
244117395Skan#define VARRAY_PUSH(VA, T, X)				\
245117395Skan  do							\
24690075Sobrien    {							\
24790075Sobrien      if ((VA)->elements_used >= (VA)->num_elements)	\
24890075Sobrien        VARRAY_GROW ((VA), 2 * (VA)->num_elements);	\
24990075Sobrien      (VA)->data.T[(VA)->elements_used++] = (X);	\
25090075Sobrien    }							\
25190075Sobrien  while (0)
25250397Sobrien
253169689Skan#define VARRAY_CHAR(VA, N)		VARRAY_CHECK (VA, N, vdt_c)
254169689Skan#define VARRAY_UCHAR(VA, N)		VARRAY_CHECK (VA, N, vdt_uc)
255169689Skan#define VARRAY_SHORT(VA, N)		VARRAY_CHECK (VA, N, vdt_s)
256169689Skan#define VARRAY_USHORT(VA, N)		VARRAY_CHECK (VA, N, vdt_us)
257169689Skan#define VARRAY_INT(VA, N)		VARRAY_CHECK (VA, N, vdt_i)
258169689Skan#define VARRAY_UINT(VA, N)		VARRAY_CHECK (VA, N, vdt_u)
259169689Skan#define VARRAY_LONG(VA, N)		VARRAY_CHECK (VA, N, vdt_l)
260169689Skan#define VARRAY_ULONG(VA, N)		VARRAY_CHECK (VA, N, vdt_ul)
261169689Skan#define VARRAY_WIDE_INT(VA, N)		VARRAY_CHECK (VA, N, vdt_hint)
262169689Skan#define VARRAY_UWIDE_INT(VA, N)		VARRAY_CHECK (VA, N, vdt_uhint)
263169689Skan#define VARRAY_GENERIC_PTR(VA,N)	VARRAY_CHECK (VA, N, vdt_generic)
264169689Skan#define VARRAY_GENERIC_PTR_NOGC(VA,N)	VARRAY_CHECK (VA, N, vdt_generic_nogc)
265169689Skan#define VARRAY_CHAR_PTR(VA,N)		VARRAY_CHECK (VA, N, vdt_cptr)
266169689Skan#define VARRAY_RTX(VA, N)		VARRAY_CHECK (VA, N, vdt_rtx)
267169689Skan#define VARRAY_RTVEC(VA, N)		VARRAY_CHECK (VA, N, vdt_rtvec)
268169689Skan#define VARRAY_TREE(VA, N)		VARRAY_CHECK (VA, N, vdt_tree)
269169689Skan#define VARRAY_BITMAP(VA, N)		VARRAY_CHECK (VA, N, vdt_bitmap)
270169689Skan#define VARRAY_REG(VA, N)		VARRAY_CHECK (VA, N, vdt_reg)
271169689Skan#define VARRAY_BB(VA, N)		VARRAY_CHECK (VA, N, vdt_bb)
272169689Skan#define VARRAY_ELT_LIST(VA, N)		VARRAY_CHECK (VA, N, vdt_te)
273169689Skan#define VARRAY_EDGE(VA, N)		VARRAY_CHECK (VA, N, vdt_e)
274169689Skan#define VARRAY_TREE_PTR(VA, N)		VARRAY_CHECK (VA, N, vdt_tp)
27590075Sobrien
27690075Sobrien/* Push a new element on the end of VA, extending it if necessary.  */
277169689Skan#define VARRAY_PUSH_CHAR(VA, X)		VARRAY_PUSH (VA, vdt_c, X)
278169689Skan#define VARRAY_PUSH_UCHAR(VA, X)	VARRAY_PUSH (VA, vdt_uc, X)
279169689Skan#define VARRAY_PUSH_SHORT(VA, X)	VARRAY_PUSH (VA, vdt_s, X)
280169689Skan#define VARRAY_PUSH_USHORT(VA, X)	VARRAY_PUSH (VA, vdt_us, X)
281169689Skan#define VARRAY_PUSH_INT(VA, X)		VARRAY_PUSH (VA, vdt_i, X)
282169689Skan#define VARRAY_PUSH_UINT(VA, X)		VARRAY_PUSH (VA, vdt_u, X)
283169689Skan#define VARRAY_PUSH_LONG(VA, X)		VARRAY_PUSH (VA, vdt_l, X)
284169689Skan#define VARRAY_PUSH_ULONG(VA, X)	VARRAY_PUSH (VA, vdt_ul, X)
285169689Skan#define VARRAY_PUSH_WIDE_INT(VA, X)	VARRAY_PUSH (VA, vdt_hint, X)
286169689Skan#define VARRAY_PUSH_UWIDE_INT(VA, X)	VARRAY_PUSH (VA, vdt_uhint, X)
287169689Skan#define VARRAY_PUSH_GENERIC_PTR(VA, X)	VARRAY_PUSH (VA, vdt_generic, X)
288169689Skan#define VARRAY_PUSH_GENERIC_PTR_NOGC(VA, X)	VARRAY_PUSH (VA, vdt_generic_nogc, X)
289169689Skan#define VARRAY_PUSH_CHAR_PTR(VA, X)	VARRAY_PUSH (VA, vdt_cptr, X)
290169689Skan#define VARRAY_PUSH_RTX(VA, X)		VARRAY_PUSH (VA, vdt_rtx, X)
291169689Skan#define VARRAY_PUSH_RTVEC(VA, X)	VARRAY_PUSH (VA, vdt_rtvec, X)
292169689Skan#define VARRAY_PUSH_TREE(VA, X)		VARRAY_PUSH (VA, vdt_tree, X)
293169689Skan#define VARRAY_PUSH_BITMAP(VA, X)	VARRAY_PUSH (VA, vdt_bitmap, X)
294169689Skan#define VARRAY_PUSH_REG(VA, X)		VARRAY_PUSH (VA, vdt_reg, X)
295169689Skan#define VARRAY_PUSH_BB(VA, X)		VARRAY_PUSH (VA, vdt_bb, X)
296169689Skan#define VARRAY_PUSH_EDGE(VA, X)		VARRAY_PUSH (VA, vdt_e, X)
297169689Skan#define VARRAY_PUSH_TREE_PTR(VA, X)	VARRAY_PUSH (VA, vdt_tp, X)
29890075Sobrien
29990075Sobrien/* Return the last element of VA.  */
300132718Skan#define VARRAY_TOP(VA, T) VARRAY_CHECK(VA, (VA)->elements_used - 1, T)
301132718Skan
302169689Skan#define VARRAY_TOP_CHAR(VA)		VARRAY_TOP (VA, vdt_c)
303169689Skan#define VARRAY_TOP_UCHAR(VA)	        VARRAY_TOP (VA, vdt_uc)
304169689Skan#define VARRAY_TOP_SHORT(VA)	        VARRAY_TOP (VA, vdt_s)
305169689Skan#define VARRAY_TOP_USHORT(VA)	        VARRAY_TOP (VA, vdt_us)
306169689Skan#define VARRAY_TOP_INT(VA)		VARRAY_TOP (VA, vdt_i)
307169689Skan#define VARRAY_TOP_UINT(VA)		VARRAY_TOP (VA, vdt_u)
308169689Skan#define VARRAY_TOP_LONG(VA)		VARRAY_TOP (VA, vdt_l)
309169689Skan#define VARRAY_TOP_ULONG(VA)	        VARRAY_TOP (VA, vdt_ul)
310169689Skan#define VARRAY_TOP_WIDE_INT(VA)	        VARRAY_TOP (VA, vdt_hint)
311169689Skan#define VARRAY_TOP_UWIDE_INT(VA)	VARRAY_TOP (VA, vdt_uhint)
312169689Skan#define VARRAY_TOP_GENERIC_PTR(VA)	VARRAY_TOP (VA, vdt_generic)
313169689Skan#define VARRAY_TOP_GENERIC_PTR_NOGC(VA)	VARRAY_TOP (VA, vdt_generic_nogc)
314169689Skan#define VARRAY_TOP_CHAR_PTR(VA)		VARRAY_TOP (VA, vdt_cptr)
315169689Skan#define VARRAY_TOP_RTX(VA)		VARRAY_TOP (VA, vdt_rtx)
316169689Skan#define VARRAY_TOP_RTVEC(VA)	        VARRAY_TOP (VA, vdt_rtvec)
317169689Skan#define VARRAY_TOP_TREE(VA)		VARRAY_TOP (VA, vdt_tree)
318169689Skan#define VARRAY_TOP_BITMAP(VA)	        VARRAY_TOP (VA, vdt_bitmap)
319169689Skan#define VARRAY_TOP_REG(VA)		VARRAY_TOP (VA, vdt_reg)
320169689Skan#define VARRAY_TOP_BB(VA)		VARRAY_TOP (VA, vdt_bb)
321169689Skan#define VARRAY_TOP_EDGE(VA)		VARRAY_TOP (VA, vdt_e)
322169689Skan#define VARRAY_TOP_TREE_PTR(VA)		VARRAY_TOP (VA, vdt_tp)
32390075Sobrien
32490075Sobrien#endif /* ! GCC_VARRAY_H */
325