1 /* params.c - Run-time parameters. 2 Copyright (C) 2001-2018 Free Software Foundation, Inc. 3 Written by Mark Mitchell <mark@codesourcery.com>. 4 5 This file is part of GCC. 6 7 GCC is free software; you can redistribute it and/or modify it under 8 the terms of the GNU General Public License as published by the Free 9 Software Foundation; either version 3, or (at your option) any later 10 version. 11 12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13 WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GCC; see the file COPYING3. If not see 19 <http://www.gnu.org/licenses/>. */ 20 21 #include "config.h" 22 #include "system.h" 23 #include "coretypes.h" 24 #include "common/common-target.h" 25 #include "params.h" 26 #include "params-enum.h" 27 #include "diagnostic-core.h" 28 #include "spellcheck.h" 29 30 /* An array containing the compiler parameters and their current 31 values. */ 32 33 param_info *compiler_params; 34 35 /* The number of entries in the table. */ 36 static size_t num_compiler_params; 37 38 /* Whether the parameters have all been initialized and had their 39 default values determined. */ 40 static bool params_finished; 41 42 #define DEFPARAM(ENUM, OPTION, HELP, DEFAULT, MIN, MAX) 43 #define DEFPARAMENUM5(ENUM, OPTION, HELP, DEFAULT, V0, V1, V2, V3, V4) \ 44 static const char *values_ ## ENUM [] = { #V0, #V1, #V2, #V3, #V4, NULL }; 45 #include "params.def" 46 #undef DEFPARAMENUM5 47 #undef DEFPARAM 48 49 static const param_info lang_independent_params[] = { 50 #define DEFPARAM(ENUM, OPTION, HELP, DEFAULT, MIN, MAX) \ 51 { OPTION, DEFAULT, MIN, MAX, HELP, NULL }, 52 #define DEFPARAMENUM5(ENUM, OPTION, HELP, DEFAULT, \ 53 V0, V1, V2, V3, V4) \ 54 { OPTION, (int)ENUM ## _KIND_ ## DEFAULT, 0, 4, HELP, values_ ## ENUM }, 55 #include "params.def" 56 #undef DEFPARAM 57 #undef DEFPARAMENUM5 58 { NULL, 0, 0, 0, NULL, NULL } 59 }; 60 61 /* Add the N PARAMS to the current list of compiler parameters. */ 62 63 void 64 add_params (const param_info params[], size_t n) 65 { 66 gcc_assert (!params_finished); 67 68 /* Allocate enough space for the new parameters. */ 69 compiler_params = XRESIZEVEC (param_info, compiler_params, 70 num_compiler_params + n); 71 /* Copy them into the table. */ 72 memcpy (compiler_params + num_compiler_params, 73 params, 74 n * sizeof (param_info)); 75 /* Keep track of how many parameters we have. */ 76 num_compiler_params += n; 77 } 78 79 /* Add all parameters and default values that can be set in both the 80 driver and the compiler proper. */ 81 82 void 83 global_init_params (void) 84 { 85 gcc_assert (!params_finished); 86 87 add_params (lang_independent_params, LAST_PARAM); 88 targetm_common.option_default_params (); 89 } 90 91 /* Note that all parameters have been added and all default values 92 set. */ 93 94 void 95 finish_params (void) 96 { 97 params_finished = true; 98 } 99 100 /* Reset all state within params.c so that we can rerun the compiler 101 within the same process. For use by toplev::finalize. */ 102 103 void 104 params_c_finalize (void) 105 { 106 XDELETEVEC (compiler_params); 107 compiler_params = NULL; 108 num_compiler_params = 0; 109 params_finished = false; 110 } 111 112 /* Set the value of the parameter given by NUM to VALUE in PARAMS and 113 PARAMS_SET. If EXPLICIT_P, this is being set by the user; 114 otherwise it is being set implicitly by the compiler. */ 115 116 static void 117 set_param_value_internal (compiler_param num, int value, 118 int *params, int *params_set, 119 bool explicit_p) 120 { 121 size_t i = (size_t) num; 122 123 gcc_assert (params_finished); 124 125 params[i] = value; 126 if (explicit_p) 127 params_set[i] = true; 128 } 129 130 /* Return true if it can find the matching entry for NAME in the parameter 131 table, and assign the entry index to INDEX. Return false otherwise. */ 132 133 bool 134 find_param (const char *name, enum compiler_param *index) 135 { 136 for (size_t i = 0; i < num_compiler_params; ++i) 137 if (strcmp (compiler_params[i].option, name) == 0) 138 { 139 *index = (enum compiler_param) i; 140 return true; 141 } 142 143 return false; 144 } 145 146 /* Look for the closest match for NAME in the parameter table, returning it 147 if it is a reasonable suggestion for a misspelling. Return NULL 148 otherwise. */ 149 150 const char * 151 find_param_fuzzy (const char *name) 152 { 153 best_match <const char *, const char *> bm (name); 154 for (size_t i = 0; i < num_compiler_params; ++i) 155 bm.consider (compiler_params[i].option); 156 return bm.get_best_meaningful_candidate (); 157 } 158 159 /* Return true if param with entry index INDEX should be defined using strings. 160 If so, return the value corresponding to VALUE_NAME in *VALUE_P. */ 161 162 bool 163 param_string_value_p (enum compiler_param index, const char *value_name, 164 int *value_p) 165 { 166 param_info *entry = &compiler_params[(int) index]; 167 if (entry->value_names == NULL) 168 return false; 169 170 *value_p = -1; 171 172 for (int i = 0; entry->value_names[i] != NULL; ++i) 173 if (strcmp (entry->value_names[i], value_name) == 0) 174 { 175 *value_p = i; 176 return true; 177 } 178 179 return true; 180 } 181 182 /* Set the VALUE associated with the parameter given by NAME in PARAMS 183 and PARAMS_SET. */ 184 185 void 186 set_param_value (const char *name, int value, 187 int *params, int *params_set) 188 { 189 size_t i; 190 191 /* Make sure nobody tries to set a parameter to an invalid value. */ 192 gcc_assert (value != INVALID_PARAM_VAL); 193 194 enum compiler_param index; 195 if (!find_param (name, &index)) 196 { 197 /* If we didn't find this parameter, issue an error message. */ 198 error ("invalid parameter %qs", name); 199 return; 200 } 201 i = (size_t)index; 202 203 if (value < compiler_params[i].min_value) 204 error ("minimum value of parameter %qs is %u", 205 compiler_params[i].option, 206 compiler_params[i].min_value); 207 else if (compiler_params[i].max_value > compiler_params[i].min_value 208 && value > compiler_params[i].max_value) 209 error ("maximum value of parameter %qs is %u", 210 compiler_params[i].option, 211 compiler_params[i].max_value); 212 else 213 set_param_value_internal ((compiler_param) i, value, 214 params, params_set, true); 215 } 216 217 /* Set the value of the parameter given by NUM to VALUE in PARAMS and 218 PARAMS_SET, implicitly, if it has not been set explicitly by the 219 user. */ 220 221 void 222 maybe_set_param_value (compiler_param num, int value, 223 int *params, int *params_set) 224 { 225 if (!params_set[(int) num]) 226 set_param_value_internal (num, value, params, params_set, false); 227 } 228 229 /* Set the default value of a parameter given by NUM to VALUE, before 230 option processing. */ 231 232 void 233 set_default_param_value (compiler_param num, int value) 234 { 235 gcc_assert (!params_finished); 236 237 compiler_params[(int) num].default_value = value; 238 } 239 240 /* Return the default value of parameter NUM. */ 241 242 int 243 default_param_value (compiler_param num) 244 { 245 return compiler_params[(int) num].default_value; 246 } 247 248 /* Initialize an array PARAMS with default values of the 249 parameters. */ 250 251 void 252 init_param_values (int *params) 253 { 254 size_t i; 255 256 gcc_assert (params_finished); 257 258 for (i = 0; i < num_compiler_params; i++) 259 params[i] = compiler_params[i].default_value; 260 } 261 262 /* Return the current value of num_compiler_params, for the benefit of 263 plugins that use parameters as features. */ 264 265 size_t 266 get_num_compiler_params (void) 267 { 268 return num_compiler_params; 269 } 270