/* Vector API for GNU compiler.
   Copyright (C) 2004-2021 Free Software Foundation, Inc.
   Contributed by Nathan Sidwell <nathan@codesourcery.com>
   Re-implemented in C++ by Diego Novillo <dnovillo@google.com>

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
Software Foundation; either version 3, or (at your option) any later
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
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

/* This file is compiled twice: once for the generator programs
   once for the compiler.  */
#ifdef GENERATOR_FILE
#include "bconfig.h"
#else
#include "config.h"
#endif

#include "system.h"
#include "coretypes.h"
#include "hash-table.h"
#include "selftest.h"
#ifdef GENERATOR_FILE
#include "errors.h"
#else
#include "input.h"
#include "diagnostic-core.h"
#endif

/* vNULL is an empty type with a template cast operation that returns
   a zero-initialized vec<T, A, L> instance.  Use this when you want
   to assign nil values to new vec instances or pass a nil vector as
   a function call argument.

   We use this technique because vec<T, A, L> must be PODs (they are
   stored in unions and passed in vararg functions), this means that
   they cannot have ctors/dtors.  */
vnull vNULL;

/* Vector memory usage.  */
class vec_usage: public mem_usage
{
public:
  /* Default constructor.  */
  vec_usage (): m_items (0), m_items_peak (0), m_element_size (0) {}

  /* Constructor.  */
  vec_usage (size_t allocated, size_t times, size_t peak,
	     size_t items, size_t items_peak, size_t element_size)
    : mem_usage (allocated, times, peak),
    m_items (items), m_items_peak (items_peak),
    m_element_size (element_size) {}

  /* Sum the usage with SECOND usage.  */
  vec_usage
  operator+ (const vec_usage &second)
  {
    return vec_usage (m_allocated + second.m_allocated,
		      m_times + second.m_times,
		      m_peak + second.m_peak,
		      m_items + second.m_items,
		      m_items_peak + second.m_items_peak, 0);
  }

  /* Dump usage coupled to LOC location, where TOTAL is sum of all rows.  */
  inline void
  dump (mem_location *loc, mem_usage &total) const
  {
    char s[4096];
    sprintf (s, "%s:%i (%s)", loc->get_trimmed_filename (),
	     loc->m_line, loc->m_function);

    s[48] = '\0';

    fprintf (stderr,
	     "%-48s %10" PRIu64 PRsa (10) ":%4.1f%%" PRsa (9) "%10" PRIu64
	     ":%4.1f%%" PRsa (10) PRsa (10) "\n",
	     s,
	     (uint64_t)m_element_size,
	     SIZE_AMOUNT (m_allocated),
	     m_allocated * 100.0 / total.m_allocated,
	     SIZE_AMOUNT (m_peak), (uint64_t)m_times,
	     m_times * 100.0 / total.m_times,
	     SIZE_AMOUNT (m_items), SIZE_AMOUNT (m_items_peak));
  }

  /* Dump footer.  */
  inline void
  dump_footer ()
  {
    fprintf (stderr, "%s" PRsa (64) PRsa (25) PRsa (16) "\n",
	     "Total", SIZE_AMOUNT (m_allocated),
	     SIZE_AMOUNT (m_times), SIZE_AMOUNT (m_items));
  }

  /* Dump header with NAME.  */
  static inline void
  dump_header (const char *name)
  {
    fprintf (stderr, "%-48s %10s%11s%16s%10s%17s%11s\n", name, "sizeof(T)",
	     "Leak", "Peak", "Times", "Leak items", "Peak items");
  }

  /* Current number of items allocated.  */
  size_t m_items;
  /* Peak value of number of allocated items.  */
  size_t m_items_peak;
  /* Size of element of the vector.  */
  size_t m_element_size;
};

/* Vector memory description.  */
static mem_alloc_description <vec_usage> vec_mem_desc;

/* Account the overhead.  */

void
vec_prefix::register_overhead (void *ptr, size_t elements,
			       size_t element_size MEM_STAT_DECL)
{
  vec_mem_desc.register_descriptor (ptr, VEC_ORIGIN, false
				    FINAL_PASS_MEM_STAT);
  vec_usage *usage
    = vec_mem_desc.register_instance_overhead (elements * element_size, ptr);
  usage->m_element_size = element_size;
  usage->m_items += elements;
  if (usage->m_items_peak < usage->m_items)
    usage->m_items_peak = usage->m_items;
}

/* Notice that the memory allocated for the vector has been freed.  */

void
vec_prefix::release_overhead (void *ptr, size_t size, size_t elements,
			      bool in_dtor MEM_STAT_DECL)
{
  if (!vec_mem_desc.contains_descriptor_for_instance (ptr))
    vec_mem_desc.register_descriptor (ptr, VEC_ORIGIN,
				      false FINAL_PASS_MEM_STAT);
  vec_usage *usage = vec_mem_desc.release_instance_overhead (ptr, size,
							     in_dtor);
  usage->m_items -= elements;
}

/* Calculate the number of slots to reserve a vector, making sure that
   it is of at least DESIRED size by growing ALLOC exponentially.  */

unsigned
vec_prefix::calculate_allocation_1 (unsigned alloc, unsigned desired)
{
  /* We must have run out of room.  */
  gcc_assert (alloc < desired);

  /* Exponential growth. */
  if (!alloc)
    alloc = 4;
  else if (alloc < 16)
    /* Double when small.  */
    alloc = alloc * 2;
  else
    /* Grow slower when large.  */
    alloc = (alloc * 3 / 2);

  /* If this is still too small, set it to the right size. */
  if (alloc < desired)
    alloc = desired;
  return alloc;
}

/* Dump per-site memory statistics.  */

void
dump_vec_loc_statistics (void)
{
  vec_mem_desc.dump (VEC_ORIGIN);
}

#if CHECKING_P
/* Report qsort comparator CMP consistency check failure with P1, P2, P3 as
   witness elements.  */
ATTRIBUTE_NORETURN ATTRIBUTE_COLD
static void
qsort_chk_error (const void *p1, const void *p2, const void *p3,
		 sort_r_cmp_fn *cmp, void *data)
{
  if (!p3)
    {
      int r1 = cmp (p1, p2, data), r2 = cmp (p2, p1, data);
      error ("qsort comparator not anti-symmetric: %d, %d", r1, r2);
    }
  else if (p1 == p2)
    {
      int r = cmp (p1, p3, data);
      error ("qsort comparator non-negative on sorted output: %d", r);
    }
  else
    {
      int r1 = cmp (p1, p2, data);
      int r2 = cmp (p2, p3, data);
      int r3 = cmp (p1, p3, data);
      error ("qsort comparator not transitive: %d, %d, %d", r1, r2, r3);
    }
  internal_error ("qsort checking failed");
}

/* Verify anti-symmetry and transitivity for comparator CMP on sorted array
   of N SIZE-sized elements pointed to by BASE.  */
void
qsort_chk (void *base, size_t n, size_t size, sort_r_cmp_fn *cmp, void *data)
{
#if 0
#define LIM(n) (n)
#else
  /* Limit overall time complexity to O(n log n).  */
#define LIM(n) ((n) <= 16 ? (n) : 12 + floor_log2 (n))
#endif
#define ELT(i) ((const char *) base + (i) * size)
#define CMP(i, j) cmp (ELT (i), ELT (j), data)
#define ERR2(i, j) qsort_chk_error (ELT (i), ELT (j), NULL, cmp, data)
#define ERR3(i, j, k) qsort_chk_error (ELT (i), ELT (j), ELT (k), cmp, data)
  size_t i1, i2, i, j;
  /* This outer loop iterates over maximum spans [i1, i2) such that
     elements within each span compare equal to each other.  */
  for (i1 = 0; i1 < n; i1 = i2)
    {
      /* Position i2 one past last element that compares equal to i1'th.  */
      for (i2 = i1 + 1; i2 < n; i2++)
	if (CMP (i1, i2))
	  break;
	else if (CMP (i2, i1))
	  return ERR2 (i1, i2);
      size_t lim1 = LIM (i2 - i1), lim2 = LIM (n - i2);
      /* Verify that other pairs within current span compare equal.  */
      for (i = i1 + 1; i + 1 < i2; i++)
	for (j = i + 1; j < i1 + lim1; j++)
	  if (CMP (i, j))
	    return ERR3 (i, i1, j);
	  else if (CMP (j, i))
	    return ERR2 (i, j);
      /* Verify that elements within this span compare less than
         elements beyond the span.  */
      for (i = i1; i < i2; i++)
	for (j = i2; j < i2 + lim2; j++)
	  if (CMP (i, j) >= 0)
	    return ERR3 (i, i1, j);
	  else if (CMP (j, i) <= 0)
	    return ERR2 (i, j);
    }
#undef ERR3
#undef ERR2
#undef CMP
#undef ELT
#undef LIM
}
#endif /* #if CHECKING_P */

#ifndef GENERATOR_FILE
#if CHECKING_P

namespace selftest {

/* Selftests.  */

/* Call V.safe_push for all ints from START up to, but not including LIMIT.
   Helper function for selftests.  */

static void
safe_push_range (vec <int>&v, int start, int limit)
{
  for (int i = start; i < limit; i++)
    v.safe_push (i);
}

/* Verify that vec::quick_push works correctly.  */

static void
test_quick_push ()
{
  auto_vec <int> v;
  ASSERT_EQ (0, v.length ());
  v.reserve (3);
  ASSERT_EQ (0, v.length ());
  ASSERT_TRUE (v.space (3));
  v.quick_push (5);
  v.quick_push (6);
  v.quick_push (7);
  ASSERT_EQ (3, v.length ());
  ASSERT_EQ (5, v[0]);
  ASSERT_EQ (6, v[1]);
  ASSERT_EQ (7, v[2]);
}

/* Verify that vec::safe_push works correctly.  */

static void
test_safe_push ()
{
  auto_vec <int> v;
  ASSERT_EQ (0, v.length ());
  v.safe_push (5);
  v.safe_push (6);
  v.safe_push (7);
  ASSERT_EQ (3, v.length ());
  ASSERT_EQ (5, v[0]);
  ASSERT_EQ (6, v[1]);
  ASSERT_EQ (7, v[2]);
}

/* Verify that vec::truncate works correctly.  */

static void
test_truncate ()
{
  auto_vec <int> v;
  ASSERT_EQ (0, v.length ());
  safe_push_range (v, 0, 10);
  ASSERT_EQ (10, v.length ());

  v.truncate (5);
  ASSERT_EQ (5, v.length ());
}

/* Verify that vec::safe_grow_cleared works correctly.  */

static void
test_safe_grow_cleared ()
{
  auto_vec <int> v;
  ASSERT_EQ (0, v.length ());
  v.safe_grow_cleared (50, true);
  ASSERT_EQ (50, v.length ());
  ASSERT_EQ (0, v[0]);
  ASSERT_EQ (0, v[49]);
}

/* Verify that vec::pop works correctly.  */

static void
test_pop ()
{
  auto_vec <int> v;
  safe_push_range (v, 5, 20);
  ASSERT_EQ (15, v.length ());

  int last = v.pop ();
  ASSERT_EQ (19, last);
  ASSERT_EQ (14, v.length ());
}

/* Verify that vec::safe_insert works correctly.  */

static void
test_safe_insert ()
{
  auto_vec <int> v;
  safe_push_range (v, 0, 10);
  v.safe_insert (5, 42);
  ASSERT_EQ (4, v[4]);
  ASSERT_EQ (42, v[5]);
  ASSERT_EQ (5, v[6]);
  ASSERT_EQ (11, v.length ());
}

/* Verify that vec::ordered_remove works correctly.  */

static void
test_ordered_remove ()
{
  auto_vec <int> v;
  safe_push_range (v, 0, 10);
  v.ordered_remove (5);
  ASSERT_EQ (4, v[4]);
  ASSERT_EQ (6, v[5]);
  ASSERT_EQ (9, v.length ());
}

/* Verify that vec::ordered_remove_if works correctly.  */

static void
test_ordered_remove_if (void)
{
  auto_vec <int> v;
  safe_push_range (v, 0, 10);
  unsigned ix, ix2;
  int *elem_ptr;
  VEC_ORDERED_REMOVE_IF (v, ix, ix2, elem_ptr,
			 *elem_ptr == 5 || *elem_ptr == 7);
  ASSERT_EQ (4, v[4]);
  ASSERT_EQ (6, v[5]);
  ASSERT_EQ (8, v[6]);
  ASSERT_EQ (8, v.length ());

  v.truncate (0);
  safe_push_range (v, 0, 10);
  VEC_ORDERED_REMOVE_IF_FROM_TO (v, ix, ix2, elem_ptr, 0, 6,
				 *elem_ptr == 5 || *elem_ptr == 7);
  ASSERT_EQ (4, v[4]);
  ASSERT_EQ (6, v[5]);
  ASSERT_EQ (7, v[6]);
  ASSERT_EQ (9, v.length ());

  v.truncate (0);
  safe_push_range (v, 0, 10);
  VEC_ORDERED_REMOVE_IF_FROM_TO (v, ix, ix2, elem_ptr, 0, 5,
				 *elem_ptr == 5 || *elem_ptr == 7);
  VEC_ORDERED_REMOVE_IF_FROM_TO (v, ix, ix2, elem_ptr, 8, 10,
				 *elem_ptr == 5 || *elem_ptr == 7);
  ASSERT_EQ (4, v[4]);
  ASSERT_EQ (5, v[5]);
  ASSERT_EQ (6, v[6]);
  ASSERT_EQ (10, v.length ());

  v.truncate (0);
  safe_push_range (v, 0, 10);
  VEC_ORDERED_REMOVE_IF (v, ix, ix2, elem_ptr, *elem_ptr == 5);
  ASSERT_EQ (4, v[4]);
  ASSERT_EQ (6, v[5]);
  ASSERT_EQ (7, v[6]);
  ASSERT_EQ (9, v.length ());
}

/* Verify that vec::unordered_remove works correctly.  */

static void
test_unordered_remove ()
{
  auto_vec <int> v;
  safe_push_range (v, 0, 10);
  v.unordered_remove (5);
  ASSERT_EQ (9, v.length ());
}

/* Verify that vec::block_remove works correctly.  */

static void
test_block_remove ()
{
  auto_vec <int> v;
  safe_push_range (v, 0, 10);
  v.block_remove (5, 3);
  ASSERT_EQ (3, v[3]);
  ASSERT_EQ (4, v[4]);
  ASSERT_EQ (8, v[5]);
  ASSERT_EQ (9, v[6]);
  ASSERT_EQ (7, v.length ());
}

/* Comparator for use by test_qsort.  */

static int
reverse_cmp (const void *p_i, const void *p_j)
{
  return *(const int *)p_j - *(const int *)p_i;
}

/* Verify that vec::qsort works correctly.  */

static void
test_qsort ()
{
  auto_vec <int> v;
  safe_push_range (v, 0, 10);
  v.qsort (reverse_cmp);
  ASSERT_EQ (9, v[0]);
  ASSERT_EQ (8, v[1]);
  ASSERT_EQ (1, v[8]);
  ASSERT_EQ (0, v[9]);
  ASSERT_EQ (10, v.length ());
}

/* Verify that vec::reverse works correctly.  */

static void
test_reverse ()
{
  /* Reversing an empty vec ought to be a no-op.  */
  {
    auto_vec <int> v;
    ASSERT_EQ (0, v.length ());
    v.reverse ();
    ASSERT_EQ (0, v.length ());
  }

  /* Verify reversing a vec with even length.  */
  {
    auto_vec <int> v;
    safe_push_range (v, 0, 4);
    v.reverse ();
    ASSERT_EQ (3, v[0]);
    ASSERT_EQ (2, v[1]);
    ASSERT_EQ (1, v[2]);
    ASSERT_EQ (0, v[3]);
    ASSERT_EQ (4, v.length ());
  }

  /* Verify reversing a vec with odd length.  */
  {
    auto_vec <int> v;
    safe_push_range (v, 0, 3);
    v.reverse ();
    ASSERT_EQ (2, v[0]);
    ASSERT_EQ (1, v[1]);
    ASSERT_EQ (0, v[2]);
    ASSERT_EQ (3, v.length ());
  }
}

/* A test class that increments a counter every time its dtor is called.  */

class count_dtor
{
 public:
  count_dtor (int *counter) : m_counter (counter) {}
  ~count_dtor () { (*m_counter)++; }

 private:
  int *m_counter;
};

/* Verify that auto_delete_vec deletes the elements within it.  */

static void
test_auto_delete_vec ()
{
  int dtor_count = 0;
  {
    auto_delete_vec <count_dtor> v;
    v.safe_push (new count_dtor (&dtor_count));
    v.safe_push (new count_dtor (&dtor_count));
  }
  ASSERT_EQ (dtor_count, 2);
}

/* Run all of the selftests within this file.  */

void
vec_c_tests ()
{
  test_quick_push ();
  test_safe_push ();
  test_truncate ();
  test_safe_grow_cleared ();
  test_pop ();
  test_safe_insert ();
  test_ordered_remove ();
  test_ordered_remove_if ();
  test_unordered_remove ();
  test_block_remove ();
  test_qsort ();
  test_reverse ();
  test_auto_delete_vec ();
}

} // namespace selftest

#endif /* #if CHECKING_P */
#endif /* #ifndef GENERATOR_FILE */
