Move get_current_pass_name to ici.c .
[official-gcc.git] / gcc / ici / events.c
blobe2dd1cb2f03b502901aaa0722193e6c39a4d55e6
1 /* High-level event callback mechanism for GCC plugins.
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 "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "hashtab.h"
29 #include "toplev.h"
30 #include "gcc-plugin.h"
31 #include "tree-pass.h"
33 #include "highlev-plugin-internal.h"
35 /* Event structure. */
36 struct hl_plugin_event
38 event_callback_t run; /* Callback function */
39 const char *param_name;
43 /* Parameter structure. */
44 struct event_parameter
46 const char *name; /* Name for the parameter */
47 void *value; /* Pointer to data */
48 event_parameter_type type; /* Type enumeration of value */
52 static htab_t parameters_hash = NULL;
55 /* Hash dependent functions. */
56 static hashval_t
57 string_htab_hash (const void *x)
59 const char *p = *((const char * const *) x);
61 if (p != NULL)
62 return htab_hash_string (p);
64 return 0;
68 static int
69 string_htab_eq (const void *x, const void *y)
71 const char *s1 = *((const char * const *) x);
72 const char *s2 = *((const char * const *) y);
74 return !strcmp (s1, s2);
78 static void
79 parameter_htab_del (void *p)
81 struct parameter *param = (struct parameter *) p;
82 free (param);
86 static void
87 hash_param_callback (void *gcc_data, void *user_data)
89 struct hl_plugin_event *ev = (struct hl_plugin_event *) user_data;
90 va_list va;
91 const char *name;
92 int type;
93 void *value;
95 if (gcc_data != NULL)
97 /* Possible extension:
98 Might interpret gcc_data differently for specific values of
99 ev->event, e.g. we could get a struct loop and put all the
100 struct members in named parameters. */
101 va_copy (va, * (va_list *) gcc_data);
103 while ((name = va_arg (va, const char *)) != NULL)
105 type = va_arg (va, int);
106 value = va_arg (va, void *);
107 register_event_parameter (name, value,
108 (event_parameter_type) type);
110 va_end (va);
112 ev->run ();
113 va_copy (va, * (va_list *) gcc_data);
114 while ((name = va_arg (va, const char *)) != NULL)
116 unregister_event_parameter (name);
117 va_arg (va, void *);
121 static void
122 status_callback (void *gcc_data, void *user_data)
124 struct hl_plugin_event *ev = (struct hl_plugin_event *) user_data;
126 register_event_parameter (ev->param_name, gcc_data, EP_INT);
127 ev->run ();
128 unregister_event_parameter (ev->param_name);
131 static void
132 pass_execution_callback (void *gcc_data, void *user_data)
134 struct hl_plugin_event *ev = (struct hl_plugin_event *) user_data;
135 struct opt_pass *pass = (struct opt_pass *) gcc_data;
137 register_event_parameter ("_pass_type", &(pass->type), EP_INT);
138 ev->run ();
139 unregister_event_parameter ("_pass_type");
142 /* Register a new event into hash table. */
143 void
144 register_plugin_event (const char *event_name, event_callback_t func)
146 int event;
147 struct hl_plugin_event *ev = XCNEW (struct hl_plugin_event);
149 if (event_name == NULL)
150 internal_error ("Event cannot be registered with NULL name string\n");
152 event = get_named_event_id (event_name, INSERT);
153 ev->run = func;
154 switch (event)
156 case PLUGIN_ALL_IPA_PASSES_EXECUTION:
157 case PLUGIN_ALL_PASSES_EXECUTION:
158 ev->param_name = "substitute_status";
159 register_callback ("ICI", event, status_callback, ev);
160 break;
161 case PLUGIN_AVOID_GATE:
162 ev->param_name = "gate_status";
163 register_callback ("ICI", event, status_callback, ev);
164 break;
165 case PLUGIN_PASS_EXECUTION:
166 register_callback ("ICI", event, pass_execution_callback, ev);
167 break;
168 default:
169 register_callback ("ICI", event, hash_param_callback, ev);
171 ici_refresh_internal_callbacks (event);
175 /* Unregister an event. */
176 void
177 unregister_plugin_event (const char *event_name)
179 int event = get_named_event_id (event_name, NO_INSERT);
181 if (event < 0)
182 return;
184 unregister_callback ("ICI", event);
188 /* Return the array of all event names, terminated by NULL. */
189 const char **
190 list_plugin_events (void)
192 int i;
194 /* allocate space for all names + the terminating NULL */
195 const char **all_events = XNEWVEC (const char *, (event_last + 1));
197 /* collect all event names */
198 for (i = 0; i < event_last; i++)
199 all_events[i] = plugin_event_name[i];
201 /* mark end-of-array */
202 all_events[i] = NULL;
204 return all_events;
208 /* Register parameter.
209 * Insert parameter into hash table. Allocates hash table
210 * if needed. */
211 void
212 register_event_parameter (const char *name, void* value,
213 event_parameter_type type)
215 void **slot;
216 struct event_parameter *param = XCNEW (struct event_parameter);
218 param->name = name;
219 param->value = value;
220 param->type = type;
222 if (param->name == NULL || !strcmp ("", param->name))
223 internal_error ("Parameter cannot be registered with NULL name string\n");
225 if (parameters_hash == NULL)
226 parameters_hash =
227 htab_create_alloc (150, string_htab_hash,
228 string_htab_eq, parameter_htab_del, xcalloc, free);
230 if (parameters_hash != NULL)
232 slot = htab_find_slot (parameters_hash, param, INSERT);
233 *slot = (void *) param;
238 /* Unregister parameter. Remove it from hash table. */
239 void
240 unregister_event_parameter (const char *name)
242 struct event_parameter param;
243 param.name = name;
245 if (parameters_hash == NULL)
246 internal_error ("Parameter hash not initialized.\n");
248 if (parameters_hash != NULL)
249 htab_remove_elt (parameters_hash, &param);
253 /* Get parameter pointer to data.
254 Used by plugin to get pointer to data of the parameter <name>. */
255 void *
256 get_event_parameter (const char *name)
258 struct event_parameter tmp_param, *param;
259 tmp_param.name = name;
261 if (parameters_hash == NULL)
262 internal_error ("Parameter hash not initialized.\n");
264 if (parameters_hash != NULL)
266 param = (struct event_parameter *)
267 htab_find (parameters_hash, &tmp_param);
269 if (param != NULL && param->value != NULL)
270 return param->value;
272 return NULL;
275 /* Get parameter type.
276 Used by plugin to get type of data pointer of the parameter <name>. */
277 event_parameter_type
278 get_event_parameter_type (const char *name)
280 struct event_parameter tmp_param, *param;
281 tmp_param.name = name;
283 if (parameters_hash == NULL)
284 internal_error ("Parameter hash not initialized.\n");
286 if (parameters_hash != NULL)
288 param = (struct event_parameter *)
289 htab_find (parameters_hash, &tmp_param);
291 if (param != NULL && param->value != NULL)
292 return param->type;
294 return EP_VOID;
297 /* Get list of names of all registered ICI parameters.
298 * Traverse the hash table collecting the names of entries.
300 static int
301 add_parameter_name (void **slot, void *data)
303 const char ***crnt_name_ptr = (const char ***) data;
304 struct event_parameter *parameter = *(struct event_parameter **) slot;
306 /* store the name of the current parameter at the corresponding
307 location */
308 **crnt_name_ptr = parameter->name;
310 /* advance the current location */
311 (*crnt_name_ptr)++;
313 /* return "OK" */
314 return 1;
318 /* return the array of all parameter names, terminated by NULL */
319 const char **
320 list_event_parameters (void)
322 size_t num_parameters = htab_elements (parameters_hash);
324 /* allocate space for all names + the terminating NULL */
325 const char **all_parameters = (const char **)
326 xmalloc (sizeof (const char *) * (num_parameters+1));
328 const char ***data = &all_parameters; /* data ptr for mapped function */
329 const char **first_parameter = all_parameters; /* keep track of actual start */
331 /* mark end-of-array */
332 all_parameters[num_parameters] = NULL;
334 /* collect all parameter names */
335 htab_traverse_noresize (parameters_hash, add_parameter_name, data);
337 /* use the stored start-of-array - all_parameters has changed during
338 htab_traverse_noresize */
339 return first_parameter;