/* Routines for saving various data types to a file stream.  This deals
   with various data types like strings, integers, enums, etc.

   Copyright (C) 2011-2024 Free Software Foundation, Inc.
   Contributed 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/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "cgraph.h"
#include "data-streamer.h"
#include "value-range.h"
#include "streamer-hooks.h"


/* Adds a new block to output stream OBS.  */

void
lto_append_block (struct lto_output_stream *obs)
{
  struct lto_char_ptr_base *new_block;

  gcc_assert (obs->left_in_block == 0);

  if (obs->first_block == NULL)
    {
      /* This is the first time the stream has been written
	 into.  */
      obs->block_size = 1024;
      new_block = (struct lto_char_ptr_base*) xmalloc (obs->block_size);
      obs->first_block = new_block;
    }
  else
    {
      struct lto_char_ptr_base *tptr;
      /* Get a new block that is twice as big as the last block
	 and link it into the list.  */
      obs->block_size *= 2;
      new_block = (struct lto_char_ptr_base*) xmalloc (obs->block_size);
      /* The first bytes of the block are reserved as a pointer to
	 the next block.  Set the chain of the full block to the
	 pointer to the new block.  */
      tptr = obs->current_block;
      tptr->ptr = (char *) new_block;
    }

  /* Set the place for the next char at the first position after the
     chain to the next block.  */
  obs->current_pointer
    = ((char *) new_block) + sizeof (struct lto_char_ptr_base);
  obs->current_block = new_block;
  /* Null out the newly allocated block's pointer to the next block.  */
  new_block->ptr = NULL;
  obs->left_in_block = obs->block_size - sizeof (struct lto_char_ptr_base);
}


/* Return index used to reference STRING of LEN characters in the string table
   in OB.  The string might or might not include a trailing '\0'.
   Then put the index onto the INDEX_STREAM.  
   When PERSISTENT is set, the string S is supposed to not change during
   duration of the OB and thus OB can keep pointer into it.  */

static unsigned
streamer_string_index (struct output_block *ob, const char *s, unsigned int len,
		       bool persistent)
{
  struct string_slot **slot;
  struct string_slot s_slot;

  s_slot.s = s;
  s_slot.len = len;
  s_slot.slot_num = 0;

  slot = ob->string_hash_table->find_slot (&s_slot, INSERT);
  if (*slot == NULL)
    {
      struct lto_output_stream *string_stream = ob->string_stream;
      unsigned int start = string_stream->total_size;
      struct string_slot *new_slot = XOBNEW (&ob->obstack, struct string_slot);
      const char *string;

      if (!persistent)
	{
	  char *tmp;
	  string = tmp = XOBNEWVEC (&ob->obstack, char, len);
          memcpy (tmp, s, len);
        }
      else
	string = s;

      new_slot->s = string;
      new_slot->len = len;
      new_slot->slot_num = start;
      *slot = new_slot;
      streamer_write_uhwi_stream (string_stream, len);
      streamer_write_data_stream (string_stream, string, len);
      return start + 1;
    }
  else
    {
      struct string_slot *old_slot = *slot;
      return old_slot->slot_num + 1;
    }
}


/* Output STRING of LEN characters to the string table in OB. The
   string might or might not include a trailing '\0'. Then put the
   index onto the INDEX_STREAM. 
   When PERSISTENT is set, the string S is supposed to not change during
   duration of the OB and thus OB can keep pointer into it.  */

void
streamer_write_string_with_length (struct output_block *ob,
				   struct lto_output_stream *index_stream,
				   const char *s, unsigned int len,
				   bool persistent)
{
  if (s)
    streamer_write_uhwi_stream (index_stream,
			        streamer_string_index (ob, s, len, persistent));
  else
    streamer_write_char_stream (index_stream, 0);
}


/* Output the '\0' terminated STRING to the string
   table in OB.  Then put the index onto the INDEX_STREAM.
   When PERSISTENT is set, the string S is supposed to not change during
   duration of the OB and thus OB can keep pointer into it.  */

void
streamer_write_string (struct output_block *ob,
		       struct lto_output_stream *index_stream,
		       const char *string, bool persistent)
{
  if (string)
    streamer_write_string_with_length (ob, index_stream, string,
				       strlen (string) + 1,
				       persistent);
  else
    streamer_write_char_stream (index_stream, 0);
}


/* Output STRING of LEN characters to the string table in OB.  Then
   put the index into BP.
   When PERSISTENT is set, the string S is supposed to not change during
   duration of the OB and thus OB can keep pointer into it.  */

void
bp_pack_string_with_length (struct output_block *ob, struct bitpack_d *bp,
			    const char *s, unsigned int len, bool persistent)
{
  unsigned index = 0;
  if (s)
    index = streamer_string_index (ob, s, len, persistent);
  bp_pack_var_len_unsigned (bp, index);
}


/* Output the '\0' terminated STRING to the string
   table in OB.  Then put the index onto the bitpack BP.
   When PERSISTENT is set, the string S is supposed to not change during
   duration of the OB and thus OB can keep pointer into it.  */

void
bp_pack_string (struct output_block *ob, struct bitpack_d *bp,
		const char *s, bool persistent)
{
  unsigned index = 0;
  if (s)
    index = streamer_string_index (ob, s, strlen (s) + 1, persistent);
  bp_pack_var_len_unsigned (bp, index);
}



/* Write a zero to the output stream.  */

void
streamer_write_zero (struct output_block *ob)
{
  streamer_write_char_stream (ob->main_stream, 0);
}


/* Write an unsigned HOST_WIDE_INT value WORK to OB->main_stream.  */

void
streamer_write_uhwi (struct output_block *ob, unsigned HOST_WIDE_INT work)
{
  streamer_write_uhwi_stream (ob->main_stream, work);
}


/* Write a HOST_WIDE_INT value WORK to OB->main_stream.  */

void
streamer_write_hwi (struct output_block *ob, HOST_WIDE_INT work)
{
  streamer_write_hwi_stream (ob->main_stream, work);
}

/* Write a poly_uint64 value WORK to OB->main_stream.  */

void
streamer_write_poly_uint64 (struct output_block *ob, poly_uint64 work)
{
  for (int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
    streamer_write_uhwi_stream (ob->main_stream, work.coeffs[i]);
}

/* Write a poly_int64 value WORK to OB->main_stream.  */

void
streamer_write_poly_int64 (struct output_block *ob, poly_int64 work)
{
  for (int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
    streamer_write_hwi_stream (ob->main_stream, work.coeffs[i]);
}

/* Write a gcov counter value WORK to OB->main_stream.  */

void
streamer_write_gcov_count (struct output_block *ob, gcov_type work)
{
  streamer_write_gcov_count_stream (ob->main_stream, work);
}

/* Write an unsigned HOST_WIDE_INT value WORK to OBS.  */

void
streamer_write_uhwi_stream (struct lto_output_stream *obs,
                            unsigned HOST_WIDE_INT work)
{
  if (obs->left_in_block == 0)
    lto_append_block (obs);
  char *current_pointer = obs->current_pointer;
  unsigned int left_in_block = obs->left_in_block;
  unsigned int size = 0;
  do
    {
      unsigned int byte = (work & 0x7f);
      work >>= 7;
      if (work != 0)
	/* More bytes to follow.  */
	byte |= 0x80;

      *(current_pointer++) = byte;
      left_in_block--;
      size++;
    }
  while (work != 0 && left_in_block > 0);
  if (work != 0)
    {
      obs->left_in_block = 0;
      lto_append_block (obs);
      current_pointer = obs->current_pointer;
      left_in_block = obs->left_in_block;
      do
	{
	  unsigned int byte = (work & 0x7f);
	  work >>= 7;
	  if (work != 0)
	    /* More bytes to follow.  */
	    byte |= 0x80;

	  *(current_pointer++) = byte;
	  left_in_block--;
	  size++;
	}
      while (work != 0);
    }
  obs->current_pointer = current_pointer;
  obs->left_in_block = left_in_block;
  obs->total_size += size;
}


/* Write a HOST_WIDE_INT value WORK to OBS.  */

void
streamer_write_hwi_stream (struct lto_output_stream *obs, HOST_WIDE_INT work)
{
  if (obs->left_in_block == 0)
    lto_append_block (obs);
  char *current_pointer = obs->current_pointer;
  unsigned int left_in_block = obs->left_in_block;
  unsigned int size = 0;
  bool more;
  do
    {
      unsigned int byte = (work & 0x7f);
      /* If the lower 7-bits are sign-extended 0 or -1 we are finished.  */
      work >>= 6;
      more = !(work == 0 || work == -1);
      if (more)
	{
	  /* More bits to follow.  */
	  work >>= 1;
	  byte |= 0x80;
	}

      *(current_pointer++) = byte;
      left_in_block--;
      size++;
    }
  while (more && left_in_block > 0);
  if (more)
    {
      obs->left_in_block = 0;
      lto_append_block (obs);
      current_pointer = obs->current_pointer;
      left_in_block = obs->left_in_block;
      do
	{
	  unsigned int byte = (work & 0x7f);
	  work >>= 6;
	  more = !(work == 0 || work == -1);
	  if (more)
	    {
	      work >>= 1;
	      byte |= 0x80;
	    }

	  *(current_pointer++) = byte;
	  left_in_block--;
	  size++;
	}
      while (more);
    }
  obs->current_pointer = current_pointer;
  obs->left_in_block = left_in_block;
  obs->total_size += size;
}

/* Write a GCOV counter value WORK to OBS.  */

void
streamer_write_gcov_count_stream (struct lto_output_stream *obs, gcov_type work)
{
  gcc_assert ((HOST_WIDE_INT) work == work);
  streamer_write_hwi_stream (obs, work);
}

/* Write raw DATA of length LEN to the output block OB.  */

void
streamer_write_data_stream (struct lto_output_stream *obs, const void *data,
			    size_t len)
{
  while (len)
    {
      size_t copy;

      /* No space left.  */
      if (obs->left_in_block == 0)
	lto_append_block (obs);

      /* Determine how many bytes to copy in this loop.  */
      if (len <= obs->left_in_block)
	copy = len;
      else
	copy = obs->left_in_block;

      /* Copy the data and do bookkeeping.  */
      memcpy (obs->current_pointer, data, copy);
      obs->current_pointer += copy;
      obs->total_size += copy;
      obs->left_in_block -= copy;
      data = (const char *) data + copy;
      len -= copy;
    }
}

/* Write REAL_VALUE_TYPE into OB.  */

void
streamer_write_real_value (struct output_block *ob, const REAL_VALUE_TYPE *r)
{
  bitpack_d bp = bitpack_create (ob->main_stream);
  bp_pack_real_value (&bp, r);
  streamer_write_bitpack (&bp);
}

void
streamer_write_vrange (struct output_block *ob, const vrange &v)
{
  gcc_checking_assert (!v.undefined_p ());

  // Write the common fields to all vranges.
  value_range_kind kind = v.m_kind;
  streamer_write_enum (ob->main_stream, value_range_kind, VR_LAST, kind);
  stream_write_tree (ob, v.type (), true);

  if (is_a <irange> (v))
    {
      const irange &r = as_a <irange> (v);
      streamer_write_uhwi (ob, r.num_pairs ());
      for (unsigned i = 0; i < r.num_pairs (); ++i)
	{
	  streamer_write_wide_int (ob, r.lower_bound (i));
	  streamer_write_wide_int (ob, r.upper_bound (i));
	}
      // TODO: We could avoid streaming out the value if the mask is -1.
      irange_bitmask bm = r.get_bitmask ();
      streamer_write_wide_int (ob, bm.value ());
      streamer_write_wide_int (ob, bm.mask ());
      return;
    }
  if (is_a <frange> (v))
    {
      const frange &r = as_a <frange> (v);

      // Stream out NAN bits.
      bitpack_d bp = bitpack_create (ob->main_stream);
      nan_state nan = r.get_nan_state ();
      bp_pack_value (&bp, nan.pos_p (), 1);
      bp_pack_value (&bp, nan.neg_p (), 1);
      streamer_write_bitpack (&bp);

      // Stream out bounds.
      if (kind != VR_NAN)
	{
	  REAL_VALUE_TYPE lb = r.lower_bound ();
	  REAL_VALUE_TYPE ub = r.upper_bound ();
	  streamer_write_real_value (ob, &lb);
	  streamer_write_real_value (ob, &ub);
	}
      return;
    }
  gcc_unreachable ();
}

/* Emit the physical representation of wide_int VAL to output block OB.  */

void
streamer_write_wide_int (struct output_block *ob, const wide_int &val)
{
  int len = val.get_len ();

  streamer_write_uhwi (ob, val.get_precision ());
  streamer_write_uhwi (ob, len);
  for (int i = 0; i < len; i++)
    streamer_write_hwi (ob, val.elt (i));
}

/* Emit the physical representation of widest_int W to output block OB.  */

void
streamer_write_widest_int (struct output_block *ob,
			   const widest_int &w)
{
  int len = w.get_len ();

  streamer_write_uhwi (ob, w.get_precision ());
  streamer_write_uhwi (ob, len);
  for (int i = 0; i < len; i++)
    streamer_write_hwi (ob, w.elt (i));
}

