Move ici specific files to new directory ici; add new file ici/ici.c
[official-gcc.git] / gcc / ici / pass-manager.c
blobd637bb9c8aa382d415808098300c86b56b52cb50
1 /* High-level pass management 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 #undef FLOAT /* This is for hpux. They should change hpux. */
27 #undef FFS /* Some systems define this in param.h. */
28 #include "system.h"
29 #include "coretypes.h"
30 #include "toplev.h"
31 #include "hashtab.h"
32 #include "tree-pass.h"
33 #include "highlev-plugin-internal.h"
34 #include "feature-internal.h"
35 #include "pass-manager.h"
36 #include "tree.h"
38 static htab_t passes_hash = NULL;
40 /* Hash table dependent functions. */
41 static hashval_t
42 passes_htab_hash (const void *x)
44 const struct opt_pass *p = (const struct opt_pass *) x;
46 if (!p)
47 internal_error ("passes_htab_hash: called with NULL pass pointer!");
49 if (p->name != NULL)
50 return htab_hash_string(p->name);
51 else
52 internal_error ("passes_htab_hash: NULL-named pass!\n");
55 static int
56 passes_htab_eq (const void *x, const void *y)
58 const struct opt_pass *p1 = (const struct opt_pass *) x;
59 const struct opt_pass *p2 = (const struct opt_pass *) y;
61 return !strcmp (p1->name, p2->name);
65 /* Accumulate pass names. */
66 static int add_pass_name (void **slot, void *data)
68 const char ***tmp = (const char ***) data;
69 const char **list = *tmp;
70 struct opt_pass *pass = *(struct opt_pass **) slot;
72 *list = pass->name;
74 *tmp = *tmp + 1;
76 return 1;
79 /* Build the array of names of all registered passes. */
80 const char **list_passes (void)
82 size_t size = htab_elements (passes_hash);
83 const char **list =
84 (const char **) xmalloc (sizeof (const char *) * (size + 1));
85 const char ***tmp = &list;
86 const char **ret = list;
88 list[size] = NULL;
89 htab_traverse_noresize (passes_hash, add_pass_name, tmp);
91 return ret;
95 /* Insert a pass mapped by is pass_name in hash table.
96 * Allocate hash table when used for the first time. */
98 /* XXX: Passes registered in this way always pointes to the
99 first insitance of the pass, with static_pass_number equals -1
100 and (pass->todo_flags_start & TODO_mark_first_instance) = true
101 if passes_htab_hash generate hash with pass->name . */
103 void register_pass_by_name (struct opt_pass *pass)
105 void **slot;
107 /* Bail out if the pass has no name or an empty name */
108 if (pass->name == NULL)
109 internal_error ("Cannot register a pass with no name");
111 if (!strcmp (pass->name, ""))
112 internal_error ("Cannot register a pass with an empty name");
114 if (passes_hash == NULL)
115 passes_hash = htab_create_alloc (150, passes_htab_hash, passes_htab_eq,
116 NULL, xcalloc, free);
118 if (passes_hash == NULL)
119 error ("Could not allocate the hastable for passes");
121 slot = htab_find_slot (passes_hash, pass, INSERT);
122 *slot = pass;
125 /* Executes a pass, from any plugin, by its pass_name.
126 IPA pass execute in this way does not generate summary. */
127 void run_pass (const char *pass_name)
129 struct opt_pass tmp_pass;
130 struct opt_pass *pass;
132 tmp_pass.name = pass_name;
134 pass = (struct opt_pass *) htab_find (passes_hash, &tmp_pass);
136 execute_one_pass (pass);
139 /* Executes an IPA pass with its summary generated before execution.
140 Take care while run IPA passes this way because GCC IPA summaries are
141 supposed to be generated for a whole list of IPA passes at one time. */
142 void run_ipa_pass (const char *pass_name)
144 struct opt_pass tmp_pass;
145 struct opt_pass *pass;
147 tmp_pass.name = pass_name;
148 pass = (struct opt_pass *) htab_find (passes_hash, &tmp_pass);
150 execute_one_ipa_summary_pass (pass);
151 execute_one_pass (pass);
154 /* Initialize a list of pointers to pass with fixed size. */
155 void *
156 initialize_ici_pass_list (int num)
158 int i;
159 struct opt_pass **list;
160 list = (struct opt_pass **) xmalloc (sizeof (struct opt_pass *) * (num + 1));
161 for (i = 0; i <= num; ++i)
162 *(list + i) = NULL;
163 return ((void *) list);
166 /* Add pass by name to a list of pointers to pass at position indexed
167 as cursor. */
168 void
169 insert_ici_pass_list (void *list, int cursor, const char *pass_name)
171 struct opt_pass tmp_pass;
172 struct opt_pass *pass;
174 tmp_pass.name = pass_name;
176 pass = (struct opt_pass *) htab_find (passes_hash, &tmp_pass);
178 if (*(((struct opt_pass **)list) + cursor) != NULL)
179 error ("Could not add pass to ICI pass list.");
181 *(((struct opt_pass **)list) + cursor) = pass;
184 /* Execute IPA summary passes. */
185 void
186 run_ici_pass_list_ipa_summary (void *list)
188 struct opt_pass **pass;
190 if (list == NULL)
191 return;
193 pass = (struct opt_pass **) list;
196 execute_one_ipa_summary_pass (*pass);
197 ++pass;
199 while (*pass);
202 /* Execute passes in the list one by one on current function. */
203 void
204 run_ici_pass_list (void *list)
206 struct opt_pass **pass;
208 if (list == NULL)
209 return;
211 pass = (struct opt_pass **) list;
214 execute_one_pass (*pass);
215 ++pass;
217 while (*pass);
220 /* Executes passes in the list on cgraph functions, one function a time
221 in top order. */
222 void
223 run_ici_pass_list_per_function (void *list)
225 do_per_function_toporder ((void (*)(void *)) run_ici_pass_list,
226 list);
229 /* Delete the the list of pointers to pass. */
230 void
231 delete_ici_pass_list (void *list)
233 if (list == NULL)
234 return;
236 free ((struct opt_pass **) list);
237 list = NULL;