1 /* High-level pass management for GCC plugins.
2 Copyright (C) 2009 Free Software Foundation, Inc.
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
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
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/>. */
26 #undef FLOAT /* This is for hpux. They should change hpux. */
27 #undef FFS /* Some systems define this in param.h. */
29 #include "coretypes.h"
32 #include "tree-pass.h"
33 #include "highlev-plugin-internal.h"
34 #include "feature-internal.h"
35 #include "pass-manager.h"
38 static htab_t passes_hash
= NULL
;
40 /* Hash table dependent functions. */
42 passes_htab_hash (const void *x
)
44 const struct opt_pass
*p
= (const struct opt_pass
*) x
;
47 internal_error ("passes_htab_hash: called with NULL pass pointer!");
50 return htab_hash_string(p
->name
);
52 internal_error ("passes_htab_hash: NULL-named pass!\n");
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
;
79 /* Build the array of names of all registered passes. */
80 const char **list_passes (void)
82 size_t size
= htab_elements (passes_hash
);
84 (const char **) xmalloc (sizeof (const char *) * (size
+ 1));
85 const char ***tmp
= &list
;
86 const char **ret
= list
;
89 htab_traverse_noresize (passes_hash
, add_pass_name
, tmp
);
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
)
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
);
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. */
156 initialize_ici_pass_list (int num
)
159 struct opt_pass
**list
;
160 list
= (struct opt_pass
**) xmalloc (sizeof (struct opt_pass
*) * (num
+ 1));
161 for (i
= 0; i
<= num
; ++i
)
163 return ((void *) list
);
166 /* Add pass by name to a list of pointers to pass at position indexed
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. */
186 run_ici_pass_list_ipa_summary (void *list
)
188 struct opt_pass
**pass
;
193 pass
= (struct opt_pass
**) list
;
196 execute_one_ipa_summary_pass (*pass
);
202 /* Execute passes in the list one by one on current function. */
204 run_ici_pass_list (void *list
)
206 struct opt_pass
**pass
;
211 pass
= (struct opt_pass
**) list
;
214 execute_one_pass (*pass
);
220 /* Executes passes in the list on cgraph functions, one function a time
223 run_ici_pass_list_per_function (void *list
)
225 do_per_function_toporder ((void (*)(void *)) run_ici_pass_list
,
229 /* Delete the the list of pointers to pass. */
231 delete_ici_pass_list (void *list
)
236 free ((struct opt_pass
**) list
);