/* Input functions for reading LTO sections.

   Copyright (C) 2009-2016 Free Software Foundation, Inc.
   Contributed by Kenneth Zadeck <zadeck@naturalbridge.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 "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "cgraph.h"
#include "lto-streamer.h"
#include "lto-compress.h"

/* Section names.  These must correspond to the values of
   enum lto_section_type.  */
const char *lto_section_name[LTO_N_SECTION_TYPES] =
{
  "decls",
  "function_body",
  "statics",
  "symtab",
  "refs",
  "asm",
  "jmpfuncs",
  "pureconst",
  "reference",
  "profile",
  "symbol_nodes",
  "opts",
  "cgraphopt",
  "inline",
  "ipcp_trans",
  "icf",
  "offload_table",
  "mode_table",
  "hsa"
};


/* Hooks so that the ipa passes can call into the lto front end to get
   sections.  */

static struct lto_file_decl_data ** file_decl_data;
static lto_get_section_data_f* get_section_f;
static lto_free_section_data_f* free_section_f;


/* This is called from the lto front end to set up the hooks that are
   used by the ipa passes to get the data that they will
   deserialize.  */

void
lto_set_in_hooks (struct lto_file_decl_data ** data,
		  lto_get_section_data_f* get_f,
		  lto_free_section_data_f* free_f)
{
  file_decl_data = data;
  get_section_f = get_f;
  free_section_f = free_f;
}


/* Return an array of file decl datas for all of the files passed to
   this compilation.  */

struct lto_file_decl_data **
lto_get_file_decl_data (void)
{
  gcc_assert (file_decl_data);
  return file_decl_data;
}

/* Buffer structure for accumulating data from compression callbacks.  */

struct lto_buffer
{
  char *data;
  size_t length;
};

/* Compression callback, append LENGTH bytes from DATA to the buffer pointed
   to by OPAQUE.  */

static void
lto_append_data (const char *data, unsigned length, void *opaque)
{
  struct lto_buffer *buffer = (struct lto_buffer *) opaque;

  buffer->data = (char *) xrealloc (buffer->data, buffer->length + length);
  memcpy (buffer->data + buffer->length, data, length);
  buffer->length += length;
}

/* Header placed in returned uncompressed data streams.  Allows the
   uncompressed allocated data to be mapped back to the underlying
   compressed data for use with free_section_f.  */

struct lto_data_header
{
  const char *data;
  size_t len;
};

/* Return a char pointer to the start of a data stream for an LTO pass
   or function.  FILE_DATA indicates where to obtain the data.
   SECTION_TYPE is the type of information to be obtained.  NAME is
   the name of the function and is only used when finding a function
   body; otherwise it is NULL.  LEN is the size of the data
   returned.  */

const char *
lto_get_section_data (struct lto_file_decl_data *file_data,
		      enum lto_section_type section_type,
		      const char *name,
		      size_t *len, bool decompress)
{
  const char *data = (get_section_f) (file_data, section_type, name, len);
  const size_t header_length = sizeof (struct lto_data_header);
  struct lto_data_header *header;
  struct lto_buffer buffer;
  struct lto_compression_stream *stream;
  lto_stats.section_size[section_type] += *len;

  if (data == NULL)
    return NULL;

  /* WPA->ltrans streams are not compressed with exception of function bodies
     and variable initializers that has been verbatim copied from earlier
     compilations.  */
  if (!flag_ltrans || decompress)
    {
      /* Create a mapping header containing the underlying data and length,
	 and prepend this to the uncompression buffer.  The uncompressed data
	 then follows, and a pointer to the start of the uncompressed data is
	 returned.  */
      header = (struct lto_data_header *) xmalloc (header_length);
      header->data = data;
      header->len = *len;

      buffer.data = (char *) header;
      buffer.length = header_length;

      stream = lto_start_uncompression (lto_append_data, &buffer);
      lto_uncompress_block (stream, data, *len);
      lto_end_uncompression (stream);

      *len = buffer.length - header_length;
      data = buffer.data + header_length;
    }

  lto_check_version (((const lto_header *)data)->major_version,
		     ((const lto_header *)data)->minor_version);
  return data;
}

/* Get the section data without any header parsing or uncompression.  */

const char *
lto_get_raw_section_data (struct lto_file_decl_data *file_data,
			  enum lto_section_type section_type,
			  const char *name,
			  size_t *len)
{
  return (get_section_f) (file_data, section_type, name, len);
}

/* Free the data found from the above call.  The first three
   parameters are the same as above.  DATA is the data to be freed and
   LEN is the length of that data.  */

void
lto_free_section_data (struct lto_file_decl_data *file_data,
		       enum lto_section_type section_type,
		       const char *name,
		       const char *data,
		       size_t len, bool decompress)
{
  const size_t header_length = sizeof (struct lto_data_header);
  const char *real_data = data - header_length;
  const struct lto_data_header *header
    = (const struct lto_data_header *) real_data;

  gcc_assert (free_section_f);

  if (flag_ltrans && !decompress)
    {
      (free_section_f) (file_data, section_type, name, data, len);
      return;
    }

  /* The underlying data address has been extracted from the mapping header.
     Free that, then free the allocated uncompression buffer.  */
  (free_section_f) (file_data, section_type, name, header->data, header->len);
  free (CONST_CAST (char *, real_data));
}

/* Free data allocated by lto_get_raw_section_data.  */

void
lto_free_raw_section_data (struct lto_file_decl_data *file_data,
		           enum lto_section_type section_type,
		           const char *name,
		           const char *data,
		           size_t len)
{
  (free_section_f) (file_data, section_type, name, data, len);
}

/* Load a section of type SECTION_TYPE from FILE_DATA, parse the
   header and then return an input block pointing to the section.  The
   raw pointer to the section is returned in DATAR and LEN.  These are
   used to free the section.  Return NULL if the section is not present.  */

struct lto_input_block *
lto_create_simple_input_block (struct lto_file_decl_data *file_data,
			       enum lto_section_type section_type,
			       const char **datar, size_t *len)
{
  const char *data = lto_get_section_data (file_data, section_type, NULL, len);
  const struct lto_simple_header * header
    = (const struct lto_simple_header *) data;

  int main_offset = sizeof (struct lto_simple_header);

  if (!data)
    return NULL;

  *datar = data;
  return new lto_input_block (data + main_offset, header->main_size,
			      file_data->mode_table);
}


/* Close the section returned from a call to
   LTO_CREATE_SIMPLE_INPUT_BLOCK.  IB is the input block returned from
   that call.  The FILE_DATA and SECTION_TYPE are the same as what was
   passed to that call and the DATA and LEN are what was returned from
   that call.  */

void
lto_destroy_simple_input_block (struct lto_file_decl_data *file_data,
				enum lto_section_type section_type,
				struct lto_input_block *ib,
				const char *data, size_t len)
{
  delete ib;
  lto_free_section_data (file_data, section_type, NULL, data, len);
}

/*****************************************************************************/
/* Record renamings of static declarations                                   */
/*****************************************************************************/

struct lto_renaming_slot
{
  const char *old_name;
  const char *new_name;
};

/* Returns a hash code for P.  */

static hashval_t
hash_name (const void *p)
{
  const struct lto_renaming_slot *ds = (const struct lto_renaming_slot *) p;
  return (hashval_t) htab_hash_string (ds->new_name);
}

/* Returns nonzero if P1 and P2 are equal.  */

static int
eq_name (const void *p1, const void *p2)
{
  const struct lto_renaming_slot *s1 =
    (const struct lto_renaming_slot *) p1;
  const struct lto_renaming_slot *s2 =
    (const struct lto_renaming_slot *) p2;

  return strcmp (s1->new_name, s2->new_name) == 0;
}

/* Free a renaming table entry.  */

static void
renaming_slot_free (void *slot)
{
  struct lto_renaming_slot *s = (struct lto_renaming_slot *) slot;

  free (CONST_CAST (void *, (const void *) s->old_name));
  free (CONST_CAST (void *, (const void *) s->new_name));
  free ((void *) s);
}

/* Create an empty hash table for recording declaration renamings.  */

htab_t
lto_create_renaming_table (void)
{
  return htab_create (37, hash_name, eq_name, renaming_slot_free);
}

/* Record a declaration name mapping OLD_NAME -> NEW_NAME.  DECL_DATA
   holds the renaming hash table to use.  */

void
lto_record_renamed_decl (struct lto_file_decl_data *decl_data,
			 const char *old_name, const char *new_name)
{
  void **slot;
  struct lto_renaming_slot r_slot;

  r_slot.new_name = new_name;
  slot = htab_find_slot (decl_data->renaming_hash_table, &r_slot, INSERT);
  if (*slot == NULL)
    {
      struct lto_renaming_slot *new_slot = XNEW (struct lto_renaming_slot);
      new_slot->old_name = xstrdup (old_name);
      new_slot->new_name = xstrdup (new_name);
      *slot = new_slot;
    }
  else
    gcc_unreachable ();
}


/* Given a string NAME, return the string that it has been mapped to
   by lto_record_renamed_decl.  If NAME was not renamed, it is
   returned unchanged.  DECL_DATA holds the renaming hash table to use.  */

const char *
lto_get_decl_name_mapping (struct lto_file_decl_data *decl_data,
			   const char *name)
{
  htab_t renaming_hash_table = decl_data->renaming_hash_table;
  struct lto_renaming_slot *slot;
  struct lto_renaming_slot r_slot;

  r_slot.new_name = name;
  slot = (struct lto_renaming_slot *) htab_find (renaming_hash_table, &r_slot);
  if (slot)
    return slot->old_name;
  else
    return name;
}

/*****************************************************************************/
/* Input decl state object.                                                  */
/*****************************************************************************/

/* Return a newly created in-decl state object. */

struct lto_in_decl_state *
lto_new_in_decl_state (void)
{
  return ggc_cleared_alloc<lto_in_decl_state> ();
}

/* Delete STATE and its components. */

void
lto_delete_in_decl_state (struct lto_in_decl_state *state)
{
  int i;

  for (i = 0; i < LTO_N_DECL_STREAMS; i++)
    vec_free (state->streams[i]);
  ggc_free (state);
}

/* Search the in-decl state of a function FUNC contained in the file
   associated with FILE_DATA.  Return NULL if not found.  */

struct lto_in_decl_state*
lto_get_function_in_decl_state (struct lto_file_decl_data *file_data,
				tree func)
{
  struct lto_in_decl_state temp;
  lto_in_decl_state **slot;

  temp.fn_decl = func;
  slot = file_data->function_decl_states->find_slot (&temp, NO_INSERT);
  return slot? *slot : NULL;
}

/* Free decl_states.  */

void
lto_free_function_in_decl_state (struct lto_in_decl_state *state)
{
  int i;
  for (i = 0; i < LTO_N_DECL_STREAMS; i++)
    vec_free (state->streams[i]);
  ggc_free (state);
}

/* Free decl_states associated with NODE.  This makes it possible to furhter
   release trees needed by the NODE's body.  */

void
lto_free_function_in_decl_state_for_node (symtab_node *node)
{
  struct lto_in_decl_state temp;
  lto_in_decl_state **slot;

  if (!node->lto_file_data)
    return;

  temp.fn_decl = node->decl;
  slot
    = node->lto_file_data->function_decl_states->find_slot (&temp, NO_INSERT);
  if (slot && *slot)
    {
      lto_free_function_in_decl_state (*slot);
      node->lto_file_data->function_decl_states->clear_slot (slot);
    }
  node->lto_file_data = NULL;
}


/* Report read pass end of the section.  */

void
lto_section_overrun (struct lto_input_block *ib)
{
  fatal_error (input_location, "bytecode stream: trying to read %d bytes "
	       "after the end of the input buffer", ib->p - ib->len);
}

/* Report out of range value.  */

void
lto_value_range_error (const char *purpose, HOST_WIDE_INT val,
		       HOST_WIDE_INT min, HOST_WIDE_INT max)
{
  fatal_error (input_location,
	       "%s out of range: Range is %i to %i, value is %i",
	       purpose, (int)min, (int)max, (int)val);
}
