/* params.c - Run-time parameters.
   Copyright (C) 2001-2016 Free Software Foundation, Inc.
   Written by Mark Mitchell <mark@codesourcery.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 "common/common-target.h"
#include "params.h"
#include "params-enum.h"
#include "diagnostic-core.h"

/* An array containing the compiler parameters and their current
   values.  */

param_info *compiler_params;

/* The number of entries in the table.  */
static size_t num_compiler_params;

/* Whether the parameters have all been initialized and had their
   default values determined.  */
static bool params_finished;

#define DEFPARAM(ENUM, OPTION, HELP, DEFAULT, MIN, MAX)
#define DEFPARAMENUM5(ENUM, OPTION, HELP, DEFAULT, V0, V1, V2, V3, V4)	\
  static const char *values_ ## ENUM [] = { #V0, #V1, #V2, #V3, #V4, NULL };
#include "params.def"
#undef DEFPARAMENUM5
#undef DEFPARAM

static const param_info lang_independent_params[] = {
#define DEFPARAM(ENUM, OPTION, HELP, DEFAULT, MIN, MAX) \
  { OPTION, DEFAULT, MIN, MAX, HELP, NULL },
#define DEFPARAMENUM5(ENUM, OPTION, HELP, DEFAULT,	     \
		      V0, V1, V2, V3, V4)		     \
  { OPTION, (int)ENUM ## _KIND_ ## DEFAULT, 0, 4, HELP, values_ ## ENUM },
#include "params.def"
#undef DEFPARAM
#undef DEFPARAMENUM5
  { NULL, 0, 0, 0, NULL, NULL }
};

/* Add the N PARAMS to the current list of compiler parameters.  */

void
add_params (const param_info params[], size_t n)
{
  gcc_assert (!params_finished);

  /* Allocate enough space for the new parameters.  */
  compiler_params = XRESIZEVEC (param_info, compiler_params,
				num_compiler_params + n);
  /* Copy them into the table.  */
  memcpy (compiler_params + num_compiler_params,
	  params,
	  n * sizeof (param_info));
  /* Keep track of how many parameters we have.  */
  num_compiler_params += n;
}

/* Add all parameters and default values that can be set in both the
   driver and the compiler proper.  */

void
global_init_params (void)
{
  gcc_assert (!params_finished);

  add_params (lang_independent_params, LAST_PARAM);
  targetm_common.option_default_params ();
}

/* Note that all parameters have been added and all default values
   set.  */

void
finish_params (void)
{
  params_finished = true;
}

/* Reset all state within params.c so that we can rerun the compiler
   within the same process.  For use by toplev::finalize.  */

void
params_c_finalize (void)
{
  XDELETEVEC (compiler_params);
  compiler_params = NULL;
  num_compiler_params = 0;
  params_finished = false;
}

/* Set the value of the parameter given by NUM to VALUE in PARAMS and
   PARAMS_SET.  If EXPLICIT_P, this is being set by the user;
   otherwise it is being set implicitly by the compiler.  */

static void
set_param_value_internal (compiler_param num, int value,
			  int *params, int *params_set,
			  bool explicit_p)
{
  size_t i = (size_t) num;

  gcc_assert (params_finished);

  params[i] = value;
  if (explicit_p)
    params_set[i] = true;
}

/* Return true if it can find the matching entry for NAME in the parameter
   table, and assign the entry index to INDEX.  Return false otherwise.  */

bool
find_param (const char *name, enum compiler_param *index)
{
  for (size_t i = 0; i < num_compiler_params; ++i)
    if (strcmp (compiler_params[i].option, name) == 0)
      {
	*index = (enum compiler_param) i;
	return true;
      }

  return false;
}

/* Return true if param with entry index INDEX should be defined using strings.
   If so, return the value corresponding to VALUE_NAME in *VALUE_P.  */

bool
param_string_value_p (enum compiler_param index, const char *value_name,
		      int *value_p)
{
  param_info *entry = &compiler_params[(int) index];
  if (entry->value_names == NULL)
    return false;

  *value_p = -1;

  for (int i = 0; entry->value_names[i] != NULL; ++i)
    if (strcmp (entry->value_names[i], value_name) == 0)
      {
	*value_p = i;
	return true;
      }

  return true;
}

/* Set the VALUE associated with the parameter given by NAME in PARAMS
   and PARAMS_SET.  */

void
set_param_value (const char *name, int value,
		 int *params, int *params_set)
{
  size_t i;

  /* Make sure nobody tries to set a parameter to an invalid value.  */
  gcc_assert (value != INVALID_PARAM_VAL);

  enum compiler_param index;
  if (!find_param (name, &index))
    {
      /* If we didn't find this parameter, issue an error message.  */
      error ("invalid parameter %qs", name);
      return;
    }
  i = (size_t)index;

  if (value < compiler_params[i].min_value)
    error ("minimum value of parameter %qs is %u",
	   compiler_params[i].option,
	   compiler_params[i].min_value);
  else if (compiler_params[i].max_value > compiler_params[i].min_value
	   && value > compiler_params[i].max_value)
    error ("maximum value of parameter %qs is %u",
	   compiler_params[i].option,
	   compiler_params[i].max_value);
  else
    set_param_value_internal ((compiler_param) i, value,
			      params, params_set, true);
}

/* Set the value of the parameter given by NUM to VALUE in PARAMS and
   PARAMS_SET, implicitly, if it has not been set explicitly by the
   user.  */

void
maybe_set_param_value (compiler_param num, int value,
		       int *params, int *params_set)
{
  if (!params_set[(int) num])
    set_param_value_internal (num, value, params, params_set, false);
}

/* Set the default value of a parameter given by NUM to VALUE, before
   option processing.  */

void
set_default_param_value (compiler_param num, int value)
{
  gcc_assert (!params_finished);

  compiler_params[(int) num].default_value = value;
}

/* Return the default value of parameter NUM.  */

int
default_param_value (compiler_param num)
{
  return compiler_params[(int) num].default_value;
}

/* Initialize an array PARAMS with default values of the
   parameters.  */

void
init_param_values (int *params)
{
  size_t i;

  gcc_assert (params_finished);

  for (i = 0; i < num_compiler_params; i++)
    params[i] = compiler_params[i].default_value;
}

/* Return the current value of num_compiler_params, for the benefit of
   plugins that use parameters as features.  */

size_t
get_num_compiler_params (void)
{
  return num_compiler_params;
}
