Move ici specific files to new directory ici; add new file ici/ici.c
[official-gcc.git] / gcc / ici / feature-list.c
blob384792794517f729f4dfa9bfe743091e8bf8d11e
1 /* High-level access points to global compiler state in GCC.
2 Copyright (C) 2009 Free Software Foundation, Inc.
4 Contributed by Inria.
6 Authors: Grigori Fursin <grigori.fursin@inria.fr>, Cupertino Miranda
7 <cupertinomiranda@gmail.com>, Zbigniew Chamski <zbigniew.chamski@gmail.com>.
9 This file is part of GCC.
11 GCC is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free
13 Software Foundation; either version 3, or (at your option) any later
14 version.
16 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17 WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 for more details.
21 You should have received a copy of the GNU General Public License
22 along with GCC; see the file COPYING3. If not see
23 <http://www.gnu.org/licenses/>. */
25 #include "feature-internal.h"
27 #include "config.h"
28 #include "system.h"
30 #include "coretypes.h"
31 #include "tm.h"
32 #include "line-map.h"
33 #include "input.h"
34 #include "tree.h"
35 #include "basic-block.h"
36 #include "tree-inline.h"
37 #include "tree-flow.h"
38 #include "tree-pass.h"
40 #include "version.h"
41 #include "opts.h"
42 #include "params.h"
43 #include "function.h"
44 #include "input.h"
46 /* FORNOW: ZC: make declarations from "passes.c" visible here */
47 /* A map from static pass dump id to optimization pass. */
48 extern struct opt_pass **passes_by_id;
49 extern int passes_by_id_size;
52 /* FICI0: "function_name": get name of current function if the
53 current function is defined, and return NULL otherwise. */
54 static const void *function_name (void)
56 /* DEBUG */ if (!cfun) printf("DEBUG: function_name: cfun is empty\n");
57 if (cfun)
58 return (const void *) current_function_name();
59 else
60 return NULL;
63 const struct feature feature_function_name = {
64 "function_name", /* name */
65 NULL, /* data */
66 0, /* no data */
67 &function_name, /* callback */
68 NULL, /* no get subfeature callback */
69 NULL /* no set subfeature callback */
72 /* FICI0: "first_pass": get name of the first pass of the compiler */
73 struct opt_pass *_pass_parents[] = { NULL, NULL, NULL, NULL, NULL,
74 NULL, NULL, NULL, NULL, NULL};
75 int _pass_parents_count = 0;
76 struct opt_pass *_current_pass = NULL;
78 static const void *first_pass (void)
80 _current_pass = all_passes;
81 return (const void *) _current_pass->name;
84 const struct feature feature_first_pass = {
85 "first_pass", /* name */
86 NULL, /* data */
87 0, /* no data */
88 &first_pass, /* callback */
89 NULL, /* no get subfeature callback */
90 NULL /* no set subfeature callback */
93 /* FICI0: "next_pass": get the name of the next pass to be executed */
94 static const void *next_pass (void)
96 if(_current_pass == NULL)
98 return (const void *) NULL;
101 if(_current_pass->sub != NULL)
103 /* Insert _current_pass->next in parents list */
104 _pass_parents[_pass_parents_count++] = _current_pass->next;
105 _current_pass = _current_pass->sub;
107 return (const void *) _current_pass->name;
110 if(_current_pass->next == NULL)
112 while(_pass_parents[_pass_parents_count] == NULL
113 && _pass_parents_count > 0)
114 _pass_parents_count--;
116 _current_pass = _pass_parents[_pass_parents_count];
117 /* Delete _current_pass in parents list */
118 _pass_parents[_pass_parents_count] = NULL;
120 return (const void *) (_current_pass != NULL ?
121 _current_pass->name :
122 NULL);
125 _current_pass = _current_pass->next;
126 return (const void *) _current_pass->name;
129 const struct feature feature_next_pass = {
130 "next_pass", /* name */
131 NULL, /* data */
132 0, /* data size */
133 &next_pass, /* callback */
134 NULL, /* no get subfeature callback */
135 NULL /* no set subfeature callback */
139 /* FICI0: compiler_all_passes */
140 /* list of all passes requires names or address/sourceloc of each instance */
141 static const void *
142 all_gcc_pass_names (void); /* forward declaration - code references feature */
144 struct feature feature_named_passes = {
145 "named_passes", /* name */
146 NULL, /* initial data */
147 0, /* initially no data */
148 &all_gcc_pass_names, /* callback */
149 NULL, /* no get subfeature callback */
150 NULL /* no set subfeature callback */
154 static const void *
155 all_gcc_pass_names (void)
157 int i;
158 char *new_name;
159 const char **pass_name =
160 (const char **) xmalloc (passes_by_id_size * sizeof (const char *));
162 for (i = 0; i < passes_by_id_size; i++)
164 if (passes_by_id[i] == NULL)
165 pass_name[i] = "<no pass defined>";
166 else
168 if (passes_by_id[i]->name != NULL)
169 pass_name[i] = passes_by_id[i]->name;
170 else
172 /* be defensive - do not allow string overflow */
173 gcc_assert (passes_by_id_size < 1000);
174 new_name = (char *) xmalloc (strlen ("pass_XXX") + 1);
175 sprintf (new_name, "pass_%03d", i);
176 /* store the new name in the option as well */
177 /* to keep memory clean when freeing a pass, any non-NULL
178 pass name of the format "pass_%03d" should be freed as
179 well, because it was dynamically allocated. */
180 pass_name[i] = passes_by_id[i]->name = (const char *) new_name;
185 /* memoize the result */
186 feature_named_passes.data = (void *) pass_name ;
187 feature_named_passes.data_size =
188 passes_by_id_size * sizeof (char *);
189 return (void *) pass_name;
193 /* FICI0: get name of the current pass */
194 static const void *
195 get_gcc_pass_name (void)
197 return (const void *) get_current_pass_name ();
201 const struct feature feature_crnt_pass_name = {
202 "pass_name", /* name */
203 NULL, /* data */
204 0, /* no data */
205 &get_gcc_pass_name, /* callback */
206 NULL, /* no get subfeature callback */
207 NULL /* no set subfeature callback */
211 /* FICI0: "compiler_version": get version string of the compiler */
212 static const void *
213 get_compiler_version_string (void);
216 /* FICI0: query compiler version */
217 const struct feature feature_compiler_version = {
218 "compiler_version", /* GCC version */
219 NULL, /* data */
220 0, /* no data */
221 get_compiler_version_string, /* data: version_string of GCC */
222 NULL, /* no get subfeature callback */
223 NULL /* no set subfeature callback */
227 static const void *
228 get_compiler_version_string (void)
230 /* this is the time to memoize the value if necessary */
231 return (const void *) version_string;
235 /* FICI0: "flags": get the command-line flags of the compiler
236 * return values:
237 * - string subfeatures: pointer-to-char corresponding to the string;
238 * - integer/boolean/bit subfeatures: integer converted to pointer-to-void.
240 static const void *get_gcc_option_names(void);
242 static const void *
243 get_gcc_option_value (const char *opt)
245 size_t opt_index;
246 const struct cl_option *option;
247 struct cl_option_state state;
248 bool was_set;
250 opt_index = find_opt (opt, -1);
251 if (opt_index == cl_options_count)
252 return (const char *) NULL;
254 /* at this point, the option is known to exist */
255 option = &cl_options[opt_index];
256 was_set = get_option_state (opt_index, &state);
258 /* check if option is set, and return the value (int or ptr); IMPORANT:
259 the user has to know how to interpret the value that's returned. */
260 if (!was_set)
261 return (const void *) NULL;
262 else switch (cl_options[opt_index].var_type) {
263 case CLVC_STRING:
264 /* for string options, return actual string */
265 return (state.data ? state.data : (const void *) "");
267 case CLVC_BOOLEAN:
268 case CLVC_EQUAL:
269 /* booleans and integers are stored by converting them to a 'const
270 void *'. */
271 return state.data;
272 case CLVC_BIT_CLEAR:
273 case CLVC_BIT_SET:
274 /* bits set/cleared: return the char (0 or 1) converted to 'const void *' */
275 return (const void *) ((long int) state.ch);
276 default:
277 gcc_unreachable ();
282 /* value is a pointer to the actual value. NULL means no value.
283 Implementation is based on static unsigned int handle_option in gcc/opts.c
285 static void *
286 set_gcc_option_value (const char *opt __attribute__ ((unused)),
287 void *value __attribute__ ((unused)))
289 /* not implemented yet */
290 return NULL;
294 /* FICI0: "compiler_flags": get list/values of compiler flags. Example:
295 call 'ici_get_feature ("compiler_params")' to get the list of parameters.
296 The value returned by this call will be memoized in the 'data' field.
297 Reset the 'data' field to NULL (and 'data_size' to zero) to force
298 a recomputation of the list.
300 struct feature feature_compiler_flags = {
301 "compiler_flags", /* name */
302 NULL, /* initially NULL to trigger callback, later
303 stores the memoized result */
304 0, /* no data */
305 get_gcc_option_names, /* return list of option names */
306 get_gcc_option_value, /* get value of named option */
307 set_gcc_option_value /* set value of named option */
311 static const void *get_gcc_option_names (void)
313 size_t i;
315 const char **option_names =
316 (const char **) xmalloc (cl_options_count * sizeof (const char *));
318 for (i = 0; i < cl_options_count; i++)
319 option_names[i] = cl_options[i].opt_text;
321 feature_compiler_flags.data = option_names;
322 feature_compiler_flags.data_size = cl_options_count * sizeof (const char *);
324 return (const void *) option_names;
328 /* FICI0: "compiler_params": get list/values of compiler parameters. */
330 /* forward declaration - definition follows feature initializer */
331 static const void *get_gcc_param_names (void);
334 static const void *
335 get_gcc_param_value (const char *name)
337 size_t i;
339 /* Scan the parameter table to find a matching entry - from 'set_param_value' */
340 for (i = 0; i < num_compiler_params; ++i)
341 if (strcmp (compiler_params[i].option, name) == 0)
342 return (void *) ((long int) compiler_params[i].value);
344 /* If we didn't find the parameter, return the invalid parameter value */
345 return (void *)(-1);
348 static void *set_gcc_param_value (const char *name, void *value)
350 size_t i;
352 /* Scan the parameter table to find a matching entry - from 'set_param_value' */
353 for (i = 0; i < num_compiler_params; ++i)
354 if (strcmp (compiler_params[i].option, name) == 0)
355 compiler_params[i].value = (int) ((long int) value);
357 /* If we didn't find the parameter, return the invalid parameter value */
358 return (void *)(-1);
361 /* FICI0: "compiler_params": get list/values of compiler parameters.
362 Call 'ici_get_feature ("compiler_params")' to get the list of parameters.
363 The value returned by this call will be memoized in the 'data' field.
364 Reset the 'data' field to NULL (and 'data_size' to zero) to force
365 a recomputation of the list.
367 struct feature feature_compiler_params = {
368 "compiler_params", /* name */
369 NULL, /* initially NULL to trigger callback, later
370 stores memoized callback result */
371 0, /* no data */
372 get_gcc_param_names, /* return list of parameter names */
373 get_gcc_param_value, /* get value of named parameter - always an integer */
374 set_gcc_param_value /* set value of named parameter */
378 static const void *
379 get_gcc_param_names (void)
381 size_t i;
382 const char **param_list =
383 (const char **) xmalloc (num_compiler_params * sizeof (const char *));
385 /* collect all parameter names */
386 for (i = 0; i < num_compiler_params; i++)
387 param_list[i] = compiler_params[i].option;
389 /* memoize list in feature descriptor */
390 feature_compiler_params.data = param_list;
391 feature_compiler_params.data_size =
392 num_compiler_params * sizeof (const char *);
394 return (void *) param_list;
398 /* FICI3: Get cfun source code information:
399 - declaration line
400 - declaration filename
401 - definition start/end line
402 - definition filename
405 static const void *
406 get_cfun_decl_line (void)
408 if (!cfun)
409 return (const void *) -1;
411 return (const void *) ((long int) LOCATION_LINE (DECL_SOURCE_LOCATION (cfun->decl)));
414 static const void *
415 get_cfun_decl_filename (void)
417 if (!cfun)
418 return NULL;
420 return (const void *) LOCATION_FILE (DECL_SOURCE_LOCATION (cfun->decl));
423 static const void *
424 get_cfun_def_start_line (void)
426 if (!cfun)
427 return (const void *) -1;
429 return (const void *) ((long int) LOCATION_LINE (cfun->function_start_locus));
432 static const void *
433 get_cfun_def_end_line (void)
435 if (!cfun)
436 return (const void *) -1;
438 return (const void *) ((long int) LOCATION_LINE (cfun->function_end_locus));
441 static const void *
442 get_cfun_def_filename (void)
444 if (!cfun)
445 return NULL;
447 return (const void *) LOCATION_FILE (cfun->function_start_locus);
450 static const void *
451 is_cfun_artificial (void)
453 if (!cfun)
454 return NULL;
456 return (const void *) ((long int) DECL_ARTIFICIAL (cfun->decl));
459 static const void *
460 get_main_input_filename (void)
462 /* GSoC: this is the path to main input file. */
463 return (const void *) main_input_filename;
466 const struct feature feature_function_start = {
467 "function_start_line", /* name */
468 NULL, /* data */
469 0, /* no data */
470 &get_cfun_def_start_line, /* callback */
471 NULL, /* no get subfeature callback */
472 NULL /* no set subfeature callback */
475 const struct feature feature_function_is_artificial = {
476 "function_is_artificial", /* name */
477 NULL, /* data */
478 0, /* no data */
479 &is_cfun_artificial, /* callback */
480 NULL, /* no get subfeature callback */
481 NULL /* no set subfeature callback */
484 const struct feature feature_main_input_filename = {
485 "main_input_filename", /* name */
486 NULL, /* data */
487 0, /* no data */
488 &get_main_input_filename, /* callback */
489 NULL, /* no get subfeature callback */
490 NULL /* no set subfeature callback */
493 const struct feature feature_function_end = {
494 "function_end_line", /* name */
495 NULL, /* data */
496 0, /* no data */
497 &get_cfun_def_end_line, /* callback */
498 NULL, /* no get subfeature callback */
499 NULL /* no set subfeature callback */
502 const struct feature feature_function_file = {
503 "function_filename", /* name */
504 NULL, /* data */
505 0, /* no data */
506 &get_cfun_def_filename, /* callback */
507 NULL, /* no get subfeature callback */
508 NULL /* no set subfeature callback */
511 const struct feature feature_function_decl_line = {
512 "function_decl_line", /* name */
513 NULL, /* data */
514 0, /* no data */
515 &get_cfun_decl_line, /* callback */
516 NULL, /* no get subfeature callback */
517 NULL /* no set subfeature callback */
520 const struct feature feature_function_decl_file = {
521 "function_decl_filename", /* name */
522 NULL, /* data */
523 0, /* no data */
524 &get_cfun_decl_filename, /* callback */
525 NULL, /* no get subfeature callback */
526 NULL /* no set subfeature callback */
529 /* FICI0: initialize all known features */
530 void init_features (void)
532 register_feature (&feature_function_name);
533 register_feature (&feature_crnt_pass_name);
535 register_feature (&feature_first_pass);
536 register_feature (&feature_next_pass);
537 register_feature (&feature_compiler_version);
539 register_feature (&feature_compiler_flags);
540 register_feature (&feature_compiler_params);
541 register_feature (&feature_named_passes);
543 register_feature (&feature_function_start);
544 register_feature (&feature_function_end);
545 register_feature (&feature_function_file);
546 register_feature (&feature_function_decl_line);
547 register_feature (&feature_function_decl_file);
548 register_feature (&feature_function_is_artificial);
549 register_feature (&feature_main_input_filename);