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