vec.h 33.5 KB
Newer Older
1
/* Vector API for GNU compiler.
2
   Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
3
   Free Software Foundation, Inc.
4
   Contributed by Nathan Sidwell <nathan@codesourcery.com>
5
   Re-implemented in C++ by Diego Novillo <dnovillo@google.com>
6 7 8 9 10

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
11
Software Foundation; either version 3, or (at your option) any later
12 13 14 15 16 17 18 19
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
20 21
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */
22 23 24 25

#ifndef GCC_VEC_H
#define GCC_VEC_H

26 27
#include "statistics.h"		/* For MEM_STAT_DECL.  */

28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
/* Templated vector type and associated interfaces.

   The interface functions are typesafe and use inline functions,
   sometimes backed by out-of-line generic functions.  The vectors are
   designed to interoperate with the GTY machinery.

   FIXME - Remove the following compatibility notes after a handler
   class for vec_t is implemented.

   To preserve compatibility with the existing API, some functions
   that manipulate vector elements implement two overloads: one taking
   a pointer to the element and others that take a pointer to a
   pointer to the element.

   This used to be implemented with three different families of macros
   and structures: structure objects, scalar objects and of pointers.
   Both the structure object and pointer variants passed pointers to
   objects around -- in the former case the pointers were stored into
   the vector and in the latter case the pointers were dereferenced and
   the objects copied into the vector.  The scalar object variant was
   suitable for int-like objects, and the vector elements were returned
   by value.

   There are both 'index' and 'iterate' accessors.  The index accessor
   is implemented by operator[].  The iterator returns a boolean
   iteration condition and updates the iteration variable passed by
   reference.  Because the iterator will be inlined, the address-of
   can be optimized away.
56

57 58 59 60 61
   The vectors are implemented using the trailing array idiom, thus
   they are not resizeable without changing the address of the vector
   object itself.  This means you cannot have variables or fields of
   vector type -- always use a pointer to a vector.  The one exception
   is the final field of a structure, which could be a vector type.
62 63 64 65 66 67
   You will have to use the embedded_size & embedded_init calls to
   create such objects, and they will probably not be resizeable (so
   don't use the 'safe' allocation variants).  The trailing array
   idiom is used (rather than a pointer to an array of data), because,
   if we allow NULL to also represent an empty vector, empty vectors
   occupy minimal space in the structure containing them.
68 69 70 71

   Each operation that increases the number of active elements is
   available in 'quick' and 'safe' variants.  The former presumes that
   there is sufficient allocated space for the operation to succeed
72
   (it dies if there is not).  The latter will reallocate the
73 74 75
   vector, if needed.  Reallocation causes an exponential increase in
   vector size.  If you know you will be adding N elements, it would
   be more efficient to use the reserve operation before adding the
76 77 78 79
   elements with the 'quick' operation.  This will ensure there are at
   least as many elements as you ask for, it will exponentially
   increase if there are too few spare slots.  If you want reserve a
   specific number of slots, but do not want the exponential increase
80 81
   (for instance, you know this is the last allocation), use the
   reserve_exact operation.  You can also create a vector of a
82
   specific size from the get go.
83 84

   You should prefer the push and pop operations, as they append and
85 86
   remove from the end of the vector. If you need to remove several
   items in one go, use the truncate operation.  The insert and remove
87 88 89 90
   operations allow you to change elements in the middle of the
   vector.  There are two remove operations, one which preserves the
   element ordering 'ordered_remove', and one which does not
   'unordered_remove'.  The latter function copies the end element
91 92
   into the removed slot, rather than invoke a memmove operation.  The
   'lower_bound' function will determine where to place an item in the
93
   array using insert that will maintain sorted order.
94

95 96 97
   When a vector type is defined, first a non-memory managed version
   is created.  You can then define either or both garbage collected
   and heap allocated versions.  The allocation mechanism is specified
98 99 100 101 102
   when the vector is allocated.  This can occur via the VEC_alloc
   call or one of the VEC_safe_* functions that add elements to a
   vector.  If the vector is NULL, it will be allocated using the
   allocation strategy selected in the call.  The valid allocations
   are defined in enum vec_allocation_t.
H.J. Lu committed
103

104 105 106 107
   If you need to directly manipulate a vector, then the 'address'
   accessor will return the address of the start of the vector.  Also
   the 'space' predicate will tell you whether there is spare capacity
   in the vector.  You will not normally need to use these two functions.
H.J. Lu committed
108

109 110 111 112 113
   Variables of vector type are of type vec_t<ETYPE> where ETYPE is
   the type of the elements of the vector. Due to the way GTY works,
   you must annotate any structures you wish to insert or reference
   from a vector with a GTY(()) tag.  You need to do this even if you
   never use the GC allocated variants.
114 115 116 117

   An example of their use would be,

   struct my_struct {
118
     vec_t<tree> *v;      // A (pointer to) a vector of tree pointers.
119 120 121 122
   };

   struct my_struct *s;

123
   if (VEC_length(tree,s->v)) { we have some contents }
124
   VEC_safe_push(tree,gc,s->v,decl); // append some decl onto the end
125 126
   for (ix = 0; VEC_iterate(tree,s->v,ix,elt); ix++)
     { do something with elt }
127 128 129

*/

130
#if ENABLE_CHECKING
131 132 133 134 135 136
#define ALONE_VEC_CHECK_INFO __FILE__, __LINE__, __FUNCTION__
#define VEC_CHECK_INFO , ALONE_VEC_CHECK_INFO
#define ALONE_VEC_CHECK_DECL const char *file_, unsigned line_, const char *function_
#define VEC_CHECK_DECL , ALONE_VEC_CHECK_DECL
#define ALONE_VEC_CHECK_PASS file_, line_, function_
#define VEC_CHECK_PASS , ALONE_VEC_CHECK_PASS
137 138 139 140 141 142 143 144

#define VEC_ASSERT(EXPR,OP,T,A) \
  (void)((EXPR) ? 0 : (VEC_ASSERT_FAIL(OP,VEC(T,A)), 0))

extern void vec_assert_fail (const char *, const char * VEC_CHECK_DECL)
     ATTRIBUTE_NORETURN;
#define VEC_ASSERT_FAIL(OP,VEC) vec_assert_fail (OP,#VEC VEC_CHECK_PASS)
#else
145
#define ALONE_VEC_CHECK_INFO
146
#define VEC_CHECK_INFO
147
#define ALONE_VEC_CHECK_DECL void
148
#define VEC_CHECK_DECL
149
#define ALONE_VEC_CHECK_PASS
150 151 152 153 154 155 156 157 158 159
#define VEC_CHECK_PASS
#define VEC_ASSERT(EXPR,OP,T,A) (void)(EXPR)
#endif

#define VEC(T,A) vec_t<T>

enum vec_allocation_t { heap, gc, stack };

struct vec_prefix
{
160 161
  unsigned num_;
  unsigned alloc_;
162 163 164 165 166 167
};

/* Vector type, user visible.  */
template<typename T>
struct GTY(()) vec_t
{
168 169 170 171 172 173
  unsigned length (void) const;
  bool empty (void) const;
  T *address (void);
  T &last (ALONE_VEC_CHECK_DECL);
  const T &operator[] (unsigned) const;
  T &operator[] (unsigned);
174
  void embedded_init (int, int = 0);
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247

  template<enum vec_allocation_t A>
  vec_t<T> *copy (ALONE_MEM_STAT_DECL);

  bool space (int VEC_CHECK_DECL);
  void splice (vec_t<T> * VEC_CHECK_DECL);
  T &quick_push (T VEC_CHECK_DECL);
  T *quick_push (const T * VEC_CHECK_DECL);
  T &pop (ALONE_VEC_CHECK_DECL);
  void truncate (unsigned VEC_CHECK_DECL);
  void replace (unsigned, T VEC_CHECK_DECL);
  void quick_insert (unsigned, T VEC_CHECK_DECL);
  void quick_insert (unsigned, const T * VEC_CHECK_DECL);
  void ordered_remove (unsigned VEC_CHECK_DECL);
  void unordered_remove (unsigned VEC_CHECK_DECL);
  void block_remove (unsigned, unsigned VEC_CHECK_DECL);

  unsigned lower_bound (T, bool (*)(T, T)) const;
  unsigned lower_bound (const T *, bool (*)(const T *, const T *)) const;

  /* Class-static member functions.  Some of these will become member
     functions of a future handler class wrapping vec_t.  */
  static size_t embedded_size (int);

  template<enum vec_allocation_t A>
  static vec_t<T> *alloc (int MEM_STAT_DECL);

  static vec_t<T> *alloc (int, vec_t<T> *);

  template<enum vec_allocation_t A>
  static void free (vec_t<T> **);

  template<enum vec_allocation_t A>
  static vec_t<T> *reserve_exact (vec_t<T> *, int MEM_STAT_DECL);

  template<enum vec_allocation_t A>
  static bool reserve_exact (vec_t<T> **, int VEC_CHECK_DECL MEM_STAT_DECL);

  template<enum vec_allocation_t A>
  static vec_t<T> *reserve (vec_t<T> *, int MEM_STAT_DECL);

  template<enum vec_allocation_t A>
  static bool reserve (vec_t<T> **, int VEC_CHECK_DECL MEM_STAT_DECL);

  template<enum vec_allocation_t A>
  static void safe_splice (vec_t<T> **, vec_t<T> * VEC_CHECK_DECL
			   MEM_STAT_DECL);

  template<enum vec_allocation_t A>
  static T &safe_push (vec_t<T> **, T VEC_CHECK_DECL MEM_STAT_DECL);

  template<enum vec_allocation_t A>
  static T *safe_push (vec_t<T> **, const T * VEC_CHECK_DECL MEM_STAT_DECL);

  template<enum vec_allocation_t A>
  static void safe_grow (vec_t<T> **, int VEC_CHECK_DECL MEM_STAT_DECL);

  template<enum vec_allocation_t A>
  static void safe_grow_cleared (vec_t<T> **, int VEC_CHECK_DECL MEM_STAT_DECL);

  template<enum vec_allocation_t A>
  static void safe_insert (vec_t<T> **, unsigned, T * VEC_CHECK_DECL
			   MEM_STAT_DECL);

  template<enum vec_allocation_t A>
  static void safe_insert (vec_t<T> **, unsigned, T obj VEC_CHECK_DECL
			   MEM_STAT_DECL);

  static bool iterate (const vec_t<T> *, unsigned, T *);
  static bool iterate (const vec_t<T> *, unsigned, T **);

  vec_prefix prefix_;
  T vec_[1];
248 249
};

250

251 252 253 254 255 256
/* Garbage collection support for vec_t.  */

template<typename T>
void
gt_ggc_mx (vec_t<T> *v)
{
257 258 259
  extern void gt_ggc_mx (T &);
  for (unsigned i = 0; i < v->length (); i++)
    gt_ggc_mx ((*v)[i]);
260 261 262 263 264 265 266 267 268
}


/* PCH support for vec_t.  */

template<typename T>
void
gt_pch_nx (vec_t<T> *v)
{
269 270 271
  extern void gt_pch_nx (T &);
  for (unsigned i = 0; i < v->length (); i++)
    gt_pch_nx ((*v)[i]);
272 273 274 275 276 277
}

template<typename T>
void
gt_pch_nx (vec_t<T *> *v, gt_pointer_operator op, void *cookie)
{
278 279
  for (unsigned i = 0; i < v->length (); i++)
    op (&((*v)[i]), cookie);
280 281 282 283 284 285 286
}

template<typename T>
void
gt_pch_nx (vec_t<T> *v, gt_pointer_operator op, void *cookie)
{
  extern void gt_pch_nx (T *, gt_pointer_operator, void *);
287 288
  for (unsigned i = 0; i < v->length (); i++)
    gt_pch_nx (&((*v)[i]), op, cookie);
289 290 291
}


292 293 294
/* FIXME.  Remove these definitions and update all calling sites after
   the handler class for vec_t is implemented.  */

295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355
/* Vector of integer-like object.  */
#define DEF_VEC_I(T)			struct vec_swallow_trailing_semi
#define DEF_VEC_ALLOC_I(T,A)		struct vec_swallow_trailing_semi

/* Vector of pointer to object.  */
#define DEF_VEC_P(T)			struct vec_swallow_trailing_semi
#define DEF_VEC_ALLOC_P(T,A)		struct vec_swallow_trailing_semi

/* Vector of object.  */
#define DEF_VEC_O(T)			struct vec_swallow_trailing_semi
#define DEF_VEC_ALLOC_O(T,A)		struct vec_swallow_trailing_semi

/* Vectors on the stack.  */
#define DEF_VEC_ALLOC_P_STACK(T)	struct vec_swallow_trailing_semi
#define DEF_VEC_ALLOC_O_STACK(T)	struct vec_swallow_trailing_semi
#define DEF_VEC_ALLOC_I_STACK(T)	struct vec_swallow_trailing_semi

/* Vectors of atomic types.  Atomic types do not need to have its
   elements marked for GC and PCH.  To avoid unnecessary traversals,
   we provide template instantiations for the GC/PCH functions that
   do not traverse the vector.

   FIXME cxx-conversion - Once vec_t users are converted this can
   be provided in some other way (e.g., adding an additional template
   parameter to the vec_t class).  */
#define DEF_VEC_A(TYPE)						\
template<typename T>						\
void								\
gt_ggc_mx (vec_t<TYPE> *v ATTRIBUTE_UNUSED)			\
{								\
}								\
								\
template<typename T>						\
void								\
gt_pch_nx (vec_t<TYPE> *v ATTRIBUTE_UNUSED)			\
{								\
}								\
								\
template<typename T>						\
void								\
gt_pch_nx (vec_t<TYPE> *v ATTRIBUTE_UNUSED,			\
	   gt_pointer_operator op ATTRIBUTE_UNUSED,		\
	   void *cookie ATTRIBUTE_UNUSED)			\
{								\
}								\
struct vec_swallow_trailing_semi

#define DEF_VEC_ALLOC_A(T,A)		struct vec_swallow_trailing_semi

/* Support functions for stack vectors.  */
extern void *vec_stack_p_reserve_exact_1 (int, void *);
extern void *vec_stack_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL);
extern void *vec_stack_o_reserve_exact (void *, int, size_t, size_t
					 MEM_STAT_DECL);
extern void vec_stack_free (void *);

extern void dump_vec_loc_statistics (void);
extern void ggc_free (void *);
extern void vec_heap_free (void *);


356 357 358
/* API compatibility macros (to be removed).  */
#define VEC_length(T,V)							\
	((V) ? (V)->length () : 0)
359

360 361
#define VEC_empty(T,V)							\
	((V) ? (V)->empty () : true)
362

363 364
#define VEC_address(T,V)						\
	vec_address<T> (V)
365

366 367 368 369 370
/* FIXME.  For now, we need to continue expanding VEC_address into a
   function call.  Otherwise, the warning machinery for -Wnonnull gets
   confused thinking that VEC_address may return null in calls to
   memcpy and qsort.  This will disappear once vec_address becomes
   a member function for a handler class wrapping vec_t.  */
371 372

template<typename T>
373 374
static inline T *
vec_address (vec_t<T> *vec)
375
{
376
  return vec ? vec->address() : NULL;
377
}
378

379 380
#define VEC_last(T,V)							\
	((V)->last (ALONE_VEC_CHECK_INFO))
381

382 383
#define VEC_index(T,V,I)						\
	((*(V))[I])
384

385 386
#define VEC_iterate(T,V,I,P)						\
	(vec_t<T>::iterate(V, I, &(P)))
387

388 389
#define VEC_embedded_size(T,N)						\
	(vec_t<T>::embedded_size (N))
390

391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443
#define VEC_embedded_init(T,V,N)					\
	((V)->embedded_init (N))

#define VEC_free(T,A,V)							\
	(vec_t<T>::free<A> (&(V)))

#define VEC_copy(T,A,V)							\
	((V)->copy<A> (ALONE_MEM_STAT_INFO))

#define VEC_space(T,V,R)						\
	((V) ? (V)->space (R VEC_CHECK_INFO) : (R) == 0)

#define VEC_reserve(T,A,V,R)						\
	(vec_t<T>::reserve<A> (&(V), (int)(R) VEC_CHECK_INFO MEM_STAT_INFO))

#define VEC_reserve_exact(T,A,V,R)					\
	(vec_t<T>::reserve_exact<A> (&(V), R VEC_CHECK_INFO MEM_STAT_INFO))

#define VEC_splice(T,DST,SRC)	        				\
	(DST)->splice (SRC VEC_CHECK_INFO)

#define VEC_safe_splice(T,A,DST,SRC)					\
	 vec_t<T>::safe_splice<A> (&(DST), SRC VEC_CHECK_INFO MEM_STAT_INFO)

#define VEC_quick_push(T,V,O)						\
	((V)->quick_push (O VEC_CHECK_INFO))

#define VEC_safe_push(T,A,V,O)						\
	(vec_t<T>::safe_push<A> (&(V), O VEC_CHECK_INFO MEM_STAT_INFO))

#define VEC_pop(T,V)							\
	((V)->pop (ALONE_VEC_CHECK_INFO))

#define VEC_truncate(T,V,I)						\
	(V								\
	 ? (V)->truncate ((unsigned)(I) VEC_CHECK_INFO)			\
	 : gcc_assert ((I) == 0))

#define VEC_safe_grow(T,A,V,I)						\
	(vec_t<T>::safe_grow<A> (&(V), (int)(I) VEC_CHECK_INFO MEM_STAT_INFO))

#define VEC_safe_grow_cleared(T,A,V,I)					\
	(vec_t<T>::safe_grow_cleared<A> (&(V), (int)(I)			\
				         VEC_CHECK_INFO MEM_STAT_INFO))

#define VEC_replace(T,V,I,O)						\
	((V)->replace ((unsigned)(I), O VEC_CHECK_INFO))

#define VEC_quick_insert(T,V,I,O)					\
	((V)->quick_insert (I,O VEC_CHECK_INFO))

#define VEC_safe_insert(T,A,V,I,O)					\
	(vec_t<T>::safe_insert<A> (&(V), I, O VEC_CHECK_INFO MEM_STAT_INFO))
444

445 446
#define VEC_ordered_remove(T,V,I)					\
	((V)->ordered_remove (I VEC_CHECK_INFO))
447

448 449
#define VEC_unordered_remove(T,V,I)					\
	((V)->unordered_remove (I VEC_CHECK_INFO))
450

451 452
#define VEC_block_remove(T,V,I,L)					\
	((V)->block_remove (I, L VEC_CHECK_INFO))
453

454 455 456 457 458
#define VEC_lower_bound(T,V,O,LT)					\
	((V)->lower_bound (O, LT))


/* Return the number of active elements in this vector.  */
459 460

template<typename T>
461 462
inline unsigned
vec_t<T>::length (void) const
463
{
464
  return prefix_.num_;
465
}
466 467


468 469 470 471 472 473 474 475
/* Return true if this vector has no active elements.  */

template<typename T>
inline bool
vec_t<T>::empty (void) const
{
  return length () == 0;
}
476

477

478 479 480
/* Return the address of the array of elements.  If you need to
   directly manipulate the array (for instance, you want to feed it
   to qsort), use this accessor.  */
481 482

template<typename T>
483 484
inline T *
vec_t<T>::address (void)
485
{
486
  return vec_;
487 488
}

489

490 491 492 493 494 495 496 497 498
/* Get the final element of the vector, which must not be empty.  */

template<typename T>
T &
vec_t<T>::last (ALONE_VEC_CHECK_DECL)
{
  VEC_ASSERT (prefix_.num_, "last", T, base);
  return (*this)[prefix_.num_ - 1];
}
499

500

501 502
/* Index into vector.  Return the IX'th element.  IX must be in the
   domain of the vector.  */
503 504

template<typename T>
505 506
const T &
vec_t<T>::operator[] (unsigned ix) const
507
{
508 509
  gcc_assert (ix < prefix_.num_);
  return vec_[ix];
510 511 512
}

template<typename T>
513 514
T &
vec_t<T>::operator[] (unsigned ix)
515
{
516 517
  gcc_assert (ix < prefix_.num_);
  return vec_[ix];
518
}
519

520

521 522 523
/* Return iteration condition and update PTR to point to the IX'th
   element of VEC.  Use this to iterate over the elements of a vector
   as follows,
524

525 526 527 528 529 530
     for (ix = 0; vec_t<T>::iterate(v, ix, &ptr); ix++)
       continue;
   
   FIXME.  This is a static member function because if VEC is NULL,
   PTR should be initialized to NULL.  This will become a regular
   member function of the handler class.  */
531 532

template<typename T>
533 534
bool
vec_t<T>::iterate (const vec_t<T> *vec, unsigned ix, T *ptr)
535
{
536
  if (vec && ix < vec->prefix_.num_)
537
    {
538
      *ptr = vec->vec_[ix];
539 540 541 542 543 544 545 546 547
      return true;
    }
  else
    {
      *ptr = 0;
      return false;
    }
}

548 549 550 551 552 553 554 555 556 557 558

/* Return iteration condition and update *PTR to point to the
   IX'th element of VEC.  Use this to iterate over the elements of a
   vector as follows,

     for (ix = 0; v->iterate(ix, &ptr); ix++)
       continue;

   This variant is for vectors of objects.  FIXME, to be removed
   once the distinction between vec_t<T> and vec_t<T *> disappears.  */

559
template<typename T>
560 561
bool
vec_t<T>::iterate (const vec_t<T> *vec, unsigned ix, T **ptr)
562
{
563
  if (vec && ix < vec->prefix_.num_)
564
    {
565
      *ptr = CONST_CAST (T *, &vec->vec_[ix]);
566 567 568 569 570 571 572 573
      return true;
    }
  else
    {
      *ptr = 0;
      return false;
    }
}
574

575

576 577
/* Convenience macro for forward iteration.  */

578
#define FOR_EACH_VEC_ELT(T, V, I, P)			\
579 580
  for (I = 0; VEC_iterate (T, (V), (I), (P)); ++(I))

581 582 583 584 585
/* Likewise, but start from FROM rather than 0.  */

#define FOR_EACH_VEC_ELT_FROM(T, V, I, P, FROM)		\
  for (I = (FROM); VEC_iterate (T, (V), (I), (P)); ++(I))

586 587
/* Convenience macro for reverse iteration.  */

588 589 590
#define FOR_EACH_VEC_ELT_REVERSE(T, V, I, P)		\
  for (I = VEC_length (T, (V)) - 1;			\
       VEC_iterate (T, (V), (I), (P));			\
591 592
       (I)--)

593

594 595
/* Return the number of bytes needed to embed an instance of vec_t inside
   another data structure.
596

597 598 599
   Use these methods to determine the required size and initialization
   of a vector V of type T embedded within another structure (as the
   final member):
600

601
   size_t vec_t<T>::embedded_size<T> (int reserve);
602
   void v->embedded_init(int reserve, int active);
603

604
   These allow the caller to perform the memory allocation.  */
605 606

template<typename T>
607 608
size_t
vec_t<T>::embedded_size (int nelems)
609
{
610
  return offsetof (vec_t<T>, vec_) + nelems * sizeof (T);
611 612
}

613 614 615

/* Initialize the vector to contain room for NELEMS elements and
   ACTIVE active elements.  */
616 617

template<typename T>
618
void
619
vec_t<T>::embedded_init (int nelems, int active)
620
{
621 622
  prefix_.num_ = active;
  prefix_.alloc_ = nelems;
623 624 625
}


626
/* Allocate a new vector with space for RESERVE objects.  If RESERVE
627 628
   is zero, NO vector is created.

629 630
   Note that this allocator must always be a macro:

631 632
   We support a vector which starts out with space on the stack and
   switches to heap space when forced to reallocate.  This works a
633 634
   little differently.  In the case of stack vectors, vec_alloc will
   expand to a call to vec_alloc_1 that calls XALLOCAVAR to request the
635 636
   initial allocation.  This uses alloca to get the initial space.
   Since alloca can not be usefully called in an inline function,
637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656
   vec_alloc must always be a macro.

   Important limitations of stack vectors:

   - Only the initial allocation will be made using alloca, so pass a
     reasonable estimate that doesn't use too much stack space; don't
     pass zero.

   - Don't return a stack-allocated vector from the function which
     allocated it.  */

#define VEC_alloc(T,A,N)						\
  ((A == stack)								\
    ? vec_t<T>::alloc (N, XALLOCAVAR (vec_t<T>, vec_t<T>::embedded_size (N)))\
    : vec_t<T>::alloc<A> (N MEM_STAT_INFO))

template<typename T>
template<enum vec_allocation_t A>
vec_t<T> *
vec_t<T>::alloc (int nelems MEM_STAT_DECL)
657
{
658
  return reserve_exact<A> ((vec_t<T> *) NULL, nelems PASS_MEM_STAT);
659 660 661
}

template<typename T>
662 663
vec_t<T> *
vec_t<T>::alloc (int nelems, vec_t<T> *space)
664
{
665
  return static_cast <vec_t<T> *> (vec_stack_p_reserve_exact_1 (nelems, space));
666
}
667

668

669
/* Free vector *V and set it to NULL.  */
670

671 672 673 674
template<typename T>
template<enum vec_allocation_t A>
void
vec_t<T>::free (vec_t<T> **v)
675
{
676
  if (*v)
677 678
    {
      if (A == heap)
679
	vec_heap_free (*v);
680
      else if (A == gc)
681
	ggc_free (*v);
682
      else if (A == stack)
683
	vec_stack_free (*v);
684
    }
685
  *v = NULL;
686
}
687 688


689 690
/* Return a copy of this vector.  The new and old vectors need not be
   allocated by the same mechanism.  */
691

692 693 694 695
template<typename T>
template<enum vec_allocation_t A>
vec_t<T> *
vec_t<T>::copy (ALONE_MEM_STAT_DECL)
696
{
697 698
  unsigned len = VEC_length (T, this);
  vec_t<T> *new_vec = NULL;
699

700
  if (len)
701
    {
702 703
      new_vec = reserve_exact<A> (static_cast<vec_t<T> *> (NULL),
				  len PASS_MEM_STAT);
704 705
      new_vec->embedded_init (len, len);
      memcpy (new_vec->address (), vec_, sizeof (T) * len);
706
    }
707

708 709
  return new_vec;
}
H.J. Lu committed
710

711

712 713 714 715
/* If this vector has space for RESERVE additional entries, return
   true.  You usually only need to use this if you are doing your
   own vector reallocation, for instance on an embedded vector.  This
   returns true in exactly the same circumstances that vec_reserve
716 717
   will.  */

718
template<typename T>
719 720
bool
vec_t<T>::space (int nelems VEC_CHECK_DECL)
721
{
722 723
  VEC_ASSERT (nelems >= 0, "space", T, base);
  return prefix_.alloc_ - prefix_.num_ >= static_cast <unsigned> (nelems);
724 725
}

726

727 728 729
/* Ensure that the vector **VEC has at least RESERVE slots available.  This
   will create additional headroom.  Note this can cause **VEC to
   be reallocated.  Returns true iff reallocation actually occurred.  */
730

731 732 733 734
template<typename T>
template<enum vec_allocation_t A>
bool
vec_t<T>::reserve (vec_t<T> **vec, int nelems VEC_CHECK_DECL MEM_STAT_DECL)
735
{
736
  bool extend = (*vec) ? !(*vec)->space (nelems VEC_CHECK_PASS) : nelems != 0;
737 738

  if (extend)
739
    *vec = reserve<A> (*vec, nelems PASS_MEM_STAT);
740 741 742 743

  return extend;
}

744

745 746 747
/* Ensure that **VEC has at least NELEMS slots available.  This will not
   create additional headroom.  Note this can cause VEC to be
   reallocated.  Returns true iff reallocation actually occurred.  */
748

749 750 751 752 753
template<typename T>
template<enum vec_allocation_t A>
bool
vec_t<T>::reserve_exact (vec_t<T> **vec, int nelems VEC_CHECK_DECL
			 MEM_STAT_DECL)
754
{
755
  bool extend = (*vec) ? !(*vec)->space (nelems VEC_CHECK_PASS) : nelems != 0;
756 757

  if (extend)
758
    *vec = reserve_exact<A> (*vec, nelems PASS_MEM_STAT);
759 760 761 762

  return extend;
}

763

764 765 766 767
/* Copy the elements from SRC to the end of this vector as if by memcpy.
   SRC and this vector need not be allocated with the same mechanism,
   although they most often will be.  This vector is assumed to have
   sufficient headroom available.  */
768 769

template<typename T>
770 771
void
vec_t<T>::splice (vec_t<T> *src VEC_CHECK_DECL)
772
{
773
  if (src)
774
    {
775 776 777 778 779 780 781
      unsigned len = VEC_length (T, src);
      VEC_ASSERT (VEC_length (T, this) + len <= prefix_.alloc_, "splice", T,
		  base);
      memcpy (address () + VEC_length (T, this),
	      src->address (),
	      len * sizeof (T));
      prefix_.num_ += len;
782 783 784
    }
}

785

786
/* Copy the elements in SRC to the end of DST as if by memcpy.  DST and
787 788 789 790
   SRC need not be allocated with the same mechanism, although they most
   often will be.  DST need not have sufficient headroom and will be
   reallocated if needed.  */

791 792 793 794 795
template<typename T>
template<enum vec_allocation_t A>
void
vec_t<T>::safe_splice (vec_t<T> **dst, vec_t<T> *src VEC_CHECK_DECL
		       MEM_STAT_DECL)
796
{
797
  if (src)
798
    {
799
      reserve_exact<A> (dst, VEC_length (T, src) VEC_CHECK_PASS MEM_STAT_INFO);
800
      (*dst)->splice (src VEC_CHECK_PASS);
801 802 803
    }
}

804
  
805 806
/* Push OBJ (a new element) onto the end, returns a reference to the slot
   filled in.  There must be sufficient space in the vector.  */
807 808

template<typename T>
809 810
T &
vec_t<T>::quick_push (T obj VEC_CHECK_DECL)
811
{
812 813 814 815 816
  VEC_ASSERT (prefix_.num_ < prefix_.alloc_, "push", T, base);
  vec_[prefix_.num_] = obj;
  T &val = vec_[prefix_.num_];
  prefix_.num_++;
  return val;
817 818
}

819 820 821 822 823 824

/* Push PTR (a new pointer to an element) onto the end, returns a
   pointer to the slot filled in. The new value can be NULL, in which
   case NO initialization is performed.  There must be sufficient
   space in the vector.  */

825
template<typename T>
826 827
T *
vec_t<T>::quick_push (const T *ptr VEC_CHECK_DECL)
828
{
829 830 831 832 833
  VEC_ASSERT (prefix_.num_ < prefix_.alloc_, "push", T, base);
  T *slot = &vec_[prefix_.num_++];
  if (ptr)
    *slot = *ptr;
  return slot;
834 835
}

836

837 838
/* Push a new element OBJ onto the end of VEC.  Returns a reference to
   the slot filled in.  Reallocates V, if needed.  */
839

840 841 842 843
template<typename T>
template<enum vec_allocation_t A>
T &
vec_t<T>::safe_push (vec_t<T> **vec, T obj VEC_CHECK_DECL MEM_STAT_DECL)
844
{
845
  reserve<A> (vec, 1 VEC_CHECK_PASS PASS_MEM_STAT);
846
  return (*vec)->quick_push (obj VEC_CHECK_PASS);
847 848
}

849 850 851 852 853 854 855 856 857 858

/* Push a pointer PTR to a new element onto the end of VEC.  Returns a
   pointer to the slot filled in. For object vectors, the new value
   can be NULL, in which case NO initialization is performed.
   Reallocates VEC, if needed.  */

template<typename T>
template<enum vec_allocation_t A>
T *
vec_t<T>::safe_push (vec_t<T> **vec, const T *ptr VEC_CHECK_DECL MEM_STAT_DECL)
859
{
860
  reserve<A> (vec, 1 VEC_CHECK_PASS PASS_MEM_STAT);
861
  return (*vec)->quick_push (ptr VEC_CHECK_PASS);
862 863
}

864

865
/* Pop and return the last element off the end of the vector.  */
866

867 868

template<typename T>
869 870
T &
vec_t<T>::pop (ALONE_VEC_CHECK_DECL)
871
{
872 873
  VEC_ASSERT (prefix_.num_, "pop", T, base);
  return vec_[--prefix_.num_];
874 875
}

876

877 878
/* Set the length of the vector to LEN.  The new length must be less
   than or equal to the current length.  This is an O(1) operation.  */
879 880

template<typename T>
881 882
void
vec_t<T>::truncate (unsigned size VEC_CHECK_DECL)
883
{
884 885
  VEC_ASSERT (prefix_.num_ >= size, "truncate", T, base);
  prefix_.num_ = size;
886 887
}

888

889
/* Grow the vector VEC to a specific length.  The LEN must be as
890 891 892
   long or longer than the current length.  The new elements are
   uninitialized.  */

893 894 895 896
template<typename T>
template<enum vec_allocation_t A>
void
vec_t<T>::safe_grow (vec_t<T> **vec, int size VEC_CHECK_DECL MEM_STAT_DECL)
897
{
898
  VEC_ASSERT (size >= 0 && VEC_length (T, *vec) <= (unsigned)size,
899
	      "grow", T, A);
900 901
  reserve_exact<A> (vec, size - (int)VEC_length (T, *vec)
		    VEC_CHECK_PASS PASS_MEM_STAT);
902
  (*vec)->prefix_.num_ = size;
903 904
}

905

906
/* Grow the vector *VEC to a specific length.  The LEN must be as
907 908 909
   long or longer than the current length.  The new elements are
   initialized to zero.  */

910 911 912 913 914
template<typename T>
template<enum vec_allocation_t A>
void
vec_t<T>::safe_grow_cleared (vec_t<T> **vec, int size VEC_CHECK_DECL
			     MEM_STAT_DECL)
915
{
916
  int oldsize = VEC_length (T, *vec);
917
  safe_grow<A> (vec, size VEC_CHECK_PASS PASS_MEM_STAT);
918
  memset (&((*vec)->address ()[oldsize]), 0, sizeof (T) * (size - oldsize));
919 920
}

921

922
/* Replace the IXth element of this vector with a new value, VAL.  */
923 924

template<typename T>
925 926
void
vec_t<T>::replace (unsigned ix, T obj VEC_CHECK_DECL)
927
{
928 929
  VEC_ASSERT (ix < prefix_.num_, "replace", T, base);
  vec_[ix] = obj;
930 931
}

932

933 934
/* Insert an element, OBJ, at the IXth position of VEC.  There must be
   sufficient space.  */
H.J. Lu committed
935

936 937 938 939 940 941 942 943 944 945
template<typename T>
void
vec_t<T>::quick_insert (unsigned ix, T obj VEC_CHECK_DECL)
{
  VEC_ASSERT (prefix_.num_ < prefix_.alloc_, "insert", T, base);
  VEC_ASSERT (ix <= prefix_.num_, "insert", T, base);
  T *slot = &vec_[ix];
  memmove (slot + 1, slot, (prefix_.num_++ - ix) * sizeof (T));
  *slot = obj;
}
946

947 948 949 950

/* Insert an element, *PTR, at the IXth position of V.  The new value
   can be NULL, in which case no initialization of the inserted slot
   takes place. There must be sufficient space.  */
951 952

template<typename T>
953 954
void
vec_t<T>::quick_insert (unsigned ix, const T *ptr VEC_CHECK_DECL)
955
{
956 957 958 959 960 961
  VEC_ASSERT (prefix_.num_ < prefix_.alloc_, "insert", T, base);
  VEC_ASSERT (ix <= prefix_.num_, "insert", T, base);
  T *slot = &vec_[ix];
  memmove (slot + 1, slot, (prefix_.num_++ - ix) * sizeof (T));
  if (ptr)
    *slot = *ptr;
962 963
}

964 965 966 967

/* Insert an element, VAL, at the IXth position of VEC. Reallocate
   VEC, if necessary.  */

968
template<typename T>
969 970 971 972
template<enum vec_allocation_t A>
void
vec_t<T>::safe_insert (vec_t<T> **vec, unsigned ix, T obj VEC_CHECK_DECL
		       MEM_STAT_DECL)
973
{
974
  reserve<A> (vec, 1 VEC_CHECK_PASS PASS_MEM_STAT);
975
  (*vec)->quick_insert (ix, obj VEC_CHECK_PASS);
976 977
}

978

979
/* Insert an element, *PTR, at the IXth position of VEC. Return a pointer
980 981 982
   to the slot created.  For vectors of object, the new value can be
   NULL, in which case no initialization of the inserted slot takes
   place. Reallocate V, if necessary.  */
983

984 985 986 987 988
template<typename T>
template<enum vec_allocation_t A>
void
vec_t<T>::safe_insert (vec_t<T> **vec, unsigned ix, T *ptr VEC_CHECK_DECL
		       MEM_STAT_DECL)
989
{
990
  reserve<A> (vec, 1 VEC_CHECK_PASS PASS_MEM_STAT);
991
  (*vec)->quick_insert (ix, ptr VEC_CHECK_PASS);
992 993 994
}


995
/* Remove an element from the IXth position of this vector.  Ordering of
996 997
   remaining elements is preserved.  This is an O(N) operation due to
   a memmove.  */
998

999
template<typename T>
1000 1001
void
vec_t<T>::ordered_remove (unsigned ix VEC_CHECK_DECL)
1002
{
1003 1004 1005
  VEC_ASSERT (ix < prefix_.num_, "remove", T, base);
  T *slot = &vec_[ix];
  memmove (slot, slot + 1, (--prefix_.num_ - ix) * sizeof (T));
1006 1007
}

1008

1009
/* Remove an element from the IXth position of VEC.  Ordering of
1010
   remaining elements is destroyed.  This is an O(1) operation.  */
1011

1012
template<typename T>
1013 1014
void
vec_t<T>::unordered_remove (unsigned ix VEC_CHECK_DECL)
1015
{
1016 1017
  VEC_ASSERT (ix < prefix_.num_, "remove", T, base);
  vec_[ix] = vec_[--prefix_.num_];
1018 1019
}

1020

1021
/* Remove LEN elements starting at the IXth.  Ordering is retained.
1022
   This is an O(N) operation due to memmove.  */
1023

1024
template<typename T>
1025 1026
void
vec_t<T>::block_remove (unsigned ix, unsigned len VEC_CHECK_DECL)
1027
{
1028 1029 1030 1031
  VEC_ASSERT (ix + len <= prefix_.num_, "block_remove", T, base);
  T *slot = &vec_[ix];
  prefix_.num_ -= len;
  memmove (slot, slot + len, (prefix_.num_ - ix) * sizeof (T));
1032
}
1033

1034 1035 1036
/* Sort the contents of V with qsort.  Use CMP as the comparison function.  */
#define VEC_qsort(T,V,CMP)						\
	qsort (VEC_address (T, V), VEC_length (T, V), sizeof (T), CMP)
1037

H.J. Lu committed
1038

1039 1040 1041 1042
/* Find and return the first position in which OBJ could be inserted
   without changing the ordering of this vector.  LESSTHAN is a
   function that returns true if the first argument is strictly less
   than the second.  */
1043

1044
template<typename T>
1045 1046
unsigned
vec_t<T>::lower_bound (T obj, bool (*lessthan)(T, T)) const
1047
{
1048 1049 1050 1051
  unsigned int len = VEC_length (T, this);
  unsigned int half, middle;
  unsigned int first = 0;
  while (len > 0)
1052
    {
1053 1054 1055 1056 1057
      half = len >> 1;
      middle = first;
      middle += half;
      T middle_elem = (*this)[middle];
      if (lessthan (middle_elem, obj))
1058
	{
1059 1060 1061
	  first = middle;
	  ++first;
	  len = len - half - 1;
1062 1063
	}
      else
1064
	len = half;
1065
    }
1066
  return first;
1067 1068
}

1069 1070 1071 1072 1073 1074

/* Find and return the first position in which *PTR could be inserted
   without changing the ordering of this vector.  LESSTHAN is a
   function that returns true if the first argument is strictly less
   than the second.  */

1075
template<typename T>
1076 1077
unsigned
vec_t<T>::lower_bound (const T *ptr,
1078
		       bool (*lessthan)(const T *, const T *)) const
1079
{
1080 1081 1082 1083
  unsigned int len = VEC_length (T, this);
  unsigned int half, middle;
  unsigned int first = 0;
  while (len > 0)
1084
    {
1085 1086 1087 1088 1089
      half = len >> 1;
      middle = first;
      middle += half;
      const T *middle_elem = &(*this)[middle];
      if (lessthan (middle_elem, ptr))
1090
	{
1091 1092 1093
	  first = middle;
	  ++first;
	  len = len - half - 1;
1094 1095
	}
      else
1096
	len = half;
1097
    }
1098
  return first;
1099 1100
}

1101

1102 1103
void *vec_heap_o_reserve_1 (void *, int, size_t, size_t, bool MEM_STAT_DECL);
void *vec_gc_o_reserve_1 (void *, int, size_t, size_t, bool MEM_STAT_DECL);
1104

1105 1106 1107 1108
/* Ensure there are at least RESERVE free slots in VEC_, growing
   exponentially.  If RESERVE < 0 grow exactly, else grow
   exponentially.  As a special case, if VEC_ is NULL, and RESERVE is
   0, no vector will be created. */
1109

1110 1111
template<typename T>
template<enum vec_allocation_t A>
1112
vec_t<T> *
1113
vec_t<T>::reserve (vec_t<T> *vec, int reserve MEM_STAT_DECL)
1114
{
1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132
  void *res = NULL;
  size_t off = offsetof (vec_t<T>, vec_);
  size_t sz = sizeof (T);

  switch (A)
    {
      case gc:
	res = vec_gc_o_reserve_1 (vec, reserve, off, sz, false PASS_MEM_STAT);
	break;
      case heap:
	res = vec_heap_o_reserve_1 (vec, reserve, off, sz, false PASS_MEM_STAT);
	break;
      case stack:
	res = vec_stack_o_reserve (vec, reserve, off, sz PASS_MEM_STAT);
	break;
    }

  return static_cast <vec_t<T> *> (res);
1133 1134 1135
}


1136
/* Ensure there are at least RESERVE free slots in VEC, growing
1137
   exactly.  If RESERVE < 0 grow exactly, else grow exponentially.  As
1138
   a special case, if VEC is NULL, and RESERVE is 0, no vector will be
1139
   created. */
1140

1141 1142
template<typename T>
template<enum vec_allocation_t A>
1143
vec_t<T> *
1144
vec_t<T>::reserve_exact (vec_t<T> *vec, int reserve MEM_STAT_DECL)
1145
{
1146 1147 1148 1149 1150 1151 1152
  void *res = NULL;
  size_t off = sizeof (struct vec_prefix);
  size_t sz = sizeof (T);

  gcc_assert (offsetof (vec_t<T>, vec_) == sizeof (struct vec_prefix));

  switch (A)
1153
    {
1154 1155 1156 1157 1158 1159 1160 1161 1162
      case gc:
	res = vec_gc_o_reserve_1 (vec, reserve, off, sz, true PASS_MEM_STAT);
	break;
      case heap:
	res = vec_heap_o_reserve_1 (vec, reserve, off, sz, true PASS_MEM_STAT);
	break;
      case stack:
	res = vec_stack_o_reserve_exact (vec, reserve, off, sz PASS_MEM_STAT);
	break;
1163
    }
1164 1165

  return static_cast <vec_t<T> *> (res);
1166 1167
}

1168
#endif /* GCC_VEC_H */