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

   Copyright (C) 2011-2021 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"


/* 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;
    }
}

/* 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));
}

