Mercurial > hg > CbC > CbC_gcc
comparison gcc/lto-wpa-fixup.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
52:c156f1bd5cd9 | 55:77e2b8dfacca |
---|---|
1 /* Write and read any fix-up information generated by the WPA mode. | |
2 | |
3 Copyright 2009 Free Software Foundation, Inc. | |
4 Contributed by Doug Kwan <dougkwan@google.com> | |
5 | |
6 This file is part of GCC. | |
7 | |
8 GCC is free software; you can redistribute it and/or modify it under | |
9 the terms of the GNU General Public License as published by the Free | |
10 Software Foundation; either version 3, or (at your option) any later | |
11 version. | |
12 | |
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with GCC; see the file COPYING3. If not see | |
20 <http://www.gnu.org/licenses/>. */ | |
21 | |
22 #include "config.h" | |
23 #include "system.h" | |
24 #include "coretypes.h" | |
25 #include "tm.h" | |
26 #include "toplev.h" | |
27 #include "tree.h" | |
28 #include "expr.h" | |
29 #include "flags.h" | |
30 #include "cgraph.h" | |
31 #include "function.h" | |
32 #include "diagnostic.h" | |
33 #include "vec.h" | |
34 #include "bitmap.h" | |
35 #include "timevar.h" | |
36 #include "tree-flow.h" | |
37 #include "tree-pass.h" | |
38 #include "lto-streamer.h" | |
39 | |
40 /* LTO fix-up. | |
41 | |
42 In WPA mode, LTO cannot access function bodies. Some modifications in | |
43 IR require additional updates in function bodies, which are not possible | |
44 in WPA mode. So we write out information about these modifications for | |
45 LTRANS to fix up the function bodies accordingly. */ | |
46 | |
47 /* The vectors records function DECLs having multiple copies with different | |
48 exception throwing attributes. We do not mark a DECL if all copies of it | |
49 have the same exception throwing attribute. */ | |
50 static bitmap lto_nothrow_fndecls; | |
51 | |
52 /* We need to fix up GIMPLE bodies due to changes in exception setting. | |
53 Consider this example: | |
54 | |
55 a.h: | |
56 class a { | |
57 public: | |
58 a(); | |
59 ~a(); | |
60 }; | |
61 | |
62 main.cc: | |
63 #include "a.h" | |
64 | |
65 int | |
66 main (int argc, char **argv) | |
67 { | |
68 a x; | |
69 return 0; | |
70 } | |
71 | |
72 a.cc: | |
73 #include "a.h" | |
74 a::a() {} | |
75 a::~a() {} | |
76 | |
77 When main.cc is compiled, gcc only sees the constructor declaration, so | |
78 the constructor and hence the call to it are marked as exception throwing. | |
79 When a.cc is compiled, the body of the constructor is available and is | |
80 obviously not exception throwing. Thus DECL of a::a in a.o has the NOTHROW | |
81 attribute. When LTO runs, two DECLs of a::a with different exception | |
82 attributes are merged. We want the merged DECL to be not exception | |
83 throwing for better generated code. To do that, we need to fix up any | |
84 function calls that have been marked as exception throwing. */ | |
85 | |
86 /* Fix up all the call statements whose target fndecls might have changed | |
87 to NOTHROW. Note that this problem is not WPA specific. We can also | |
88 run into this problem in normal LTO with multiple input files. */ | |
89 | |
90 void | |
91 lto_fixup_nothrow_decls (void) | |
92 { | |
93 struct cgraph_node *node; | |
94 struct cgraph_edge *edge; | |
95 struct function *caller_function; | |
96 gimple call_stmt; | |
97 | |
98 /* Quit if we are in WPA mode or have not marked any DECLs. */ | |
99 if (flag_wpa || !lto_nothrow_fndecls) | |
100 return; | |
101 | |
102 /* For each node that has been marked, go over all call edges to it. */ | |
103 for (node = cgraph_nodes; node; node = node->next) | |
104 if (bitmap_bit_p (lto_nothrow_fndecls, DECL_UID (node->decl))) | |
105 { | |
106 gcc_assert (TREE_NOTHROW (node->decl)); | |
107 for (edge = node->callers; edge; edge = edge->next_caller) | |
108 { | |
109 caller_function = DECL_STRUCT_FUNCTION (edge->caller->decl); | |
110 call_stmt = edge->call_stmt; | |
111 gcc_assert (call_stmt); | |
112 if (lookup_stmt_eh_lp_fn (caller_function, call_stmt) != 0) | |
113 remove_stmt_from_eh_lp_fn (caller_function, call_stmt); | |
114 } | |
115 } | |
116 } | |
117 | |
118 /* Mark FNDECL as becoming not exception throwing. */ | |
119 | |
120 void | |
121 lto_mark_nothrow_fndecl (tree fndecl) | |
122 { | |
123 gcc_assert (TREE_CODE (fndecl) == FUNCTION_DECL); | |
124 if (!lto_nothrow_fndecls) | |
125 lto_nothrow_fndecls = lto_bitmap_alloc (); | |
126 | |
127 bitmap_set_bit (lto_nothrow_fndecls, DECL_UID (fndecl)); | |
128 } | |
129 | |
130 /* Write out fix-up information. Currently the only WPA fix-up | |
131 information is the list of DECLs marked as not exception throwing. SET | |
132 is a cgraph node set whose fix-up information is to be written. */ | |
133 | |
134 static void | |
135 lto_output_wpa_fixup (cgraph_node_set set) | |
136 { | |
137 struct lto_simple_output_block *ob; | |
138 cgraph_node_set_iterator csi; | |
139 tree fndecl; | |
140 bitmap seen_decls; | |
141 VEC(tree, heap) *decls = NULL; | |
142 unsigned HOST_WIDE_INT i, count; | |
143 | |
144 ob = lto_create_simple_output_block (LTO_section_wpa_fixup); | |
145 | |
146 /* Accumulate the DECLs to be written out. Since we do not want | |
147 duplicates, we need to use a bitmap and a vector to save the | |
148 DECLs we want. Note that we need to check if lto_nothrow_fndecls | |
149 is NULL. This happens when no DECL has been marked. */ | |
150 seen_decls = lto_bitmap_alloc (); | |
151 if (lto_nothrow_fndecls) | |
152 for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi)) | |
153 { | |
154 struct cgraph_edge *e; | |
155 struct cgraph_node *n; | |
156 | |
157 n = csi_node (csi); | |
158 fndecl = n->decl; | |
159 | |
160 /* Check if the N's function is in the set of nothrow functions. */ | |
161 if (!bitmap_bit_p (seen_decls, DECL_UID (fndecl))) | |
162 { | |
163 bitmap_set_bit (seen_decls, (DECL_UID (fndecl))); | |
164 if (bitmap_bit_p (lto_nothrow_fndecls, DECL_UID (fndecl))) | |
165 VEC_safe_push (tree, heap, decls, fndecl); | |
166 } | |
167 | |
168 /* Now check the callees and also add them if they are nothrow. This | |
169 is needed because node N may end up in a different partition than | |
170 its callees. In which case, when the file holding N is compiled, | |
171 the calls it makes to nothrow functions will not be fixed up, | |
172 causing verification issues. */ | |
173 for (e = n->callees; e; e = e->next_callee) | |
174 { | |
175 fndecl = e->callee->decl; | |
176 if (!bitmap_bit_p (seen_decls, DECL_UID (fndecl))) | |
177 { | |
178 bitmap_set_bit (seen_decls, (DECL_UID (fndecl))); | |
179 if (bitmap_bit_p (lto_nothrow_fndecls, DECL_UID (fndecl))) | |
180 VEC_safe_push (tree, heap, decls, fndecl); | |
181 } | |
182 } | |
183 } | |
184 | |
185 /* Write out number of DECLs, followed by the DECLs. */ | |
186 count = VEC_length (tree, decls); | |
187 lto_output_uleb128_stream (ob->main_stream, count); | |
188 for (i = 0; i < count; i++) | |
189 { | |
190 fndecl = VEC_index (tree, decls, i); | |
191 lto_output_fn_decl_index (ob->decl_state, ob->main_stream, fndecl); | |
192 } | |
193 | |
194 /* Release resources. */ | |
195 lto_destroy_simple_output_block (ob); | |
196 VEC_free(tree, heap, decls); | |
197 lto_bitmap_free (seen_decls); | |
198 } | |
199 | |
200 /* Read in WPA fix-up information from one file. FILE_DATA points to | |
201 DECL information of the file where as IB is the input block for the | |
202 WPA fix-up section. */ | |
203 | |
204 static void | |
205 lto_input_wpa_fixup_1 (struct lto_file_decl_data *file_data, | |
206 struct lto_input_block *ib) | |
207 { | |
208 unsigned HOST_WIDE_INT i, count, decl_index; | |
209 tree fndecl; | |
210 | |
211 count = lto_input_uleb128 (ib); | |
212 for (i = 0; i < count; i++) | |
213 { | |
214 decl_index = lto_input_uleb128 (ib); | |
215 fndecl = lto_file_decl_data_get_fn_decl (file_data, decl_index); | |
216 lto_mark_nothrow_fndecl (fndecl); | |
217 } | |
218 } | |
219 | |
220 /* Read in WPA fix-up information. */ | |
221 | |
222 static void | |
223 lto_input_wpa_fixup (void) | |
224 { | |
225 struct lto_file_decl_data ** file_data_vec | |
226 = lto_get_file_decl_data (); | |
227 struct lto_file_decl_data * file_data; | |
228 int i = 0; | |
229 | |
230 /* Fix up information is only used in LTRANS mode. */ | |
231 if (!flag_ltrans) | |
232 return; | |
233 | |
234 while ((file_data = file_data_vec[i++])) | |
235 { | |
236 const char *data; | |
237 size_t len; | |
238 struct lto_input_block *ib | |
239 = lto_create_simple_input_block (file_data, LTO_section_wpa_fixup, | |
240 &data, &len); | |
241 | |
242 lto_input_wpa_fixup_1 (file_data, ib); | |
243 lto_destroy_simple_input_block (file_data, LTO_section_wpa_fixup, ib, | |
244 data, len); | |
245 } | |
246 } | |
247 | |
248 /* Gate function for all lto streaming passes. */ | |
249 | |
250 static bool | |
251 gate_wpa_fixup (void) | |
252 { | |
253 return (flag_wpa || flag_ltrans) && gate_lto_out (); | |
254 } | |
255 | |
256 struct ipa_opt_pass_d pass_ipa_lto_wpa_fixup = | |
257 { | |
258 { | |
259 IPA_PASS, | |
260 "lto_wpa_fixup", /* name */ | |
261 gate_wpa_fixup, /* gate */ | |
262 NULL, /* execute */ | |
263 NULL, /* sub */ | |
264 NULL, /* next */ | |
265 0, /* static_pass_number */ | |
266 TV_WHOPR_WPA_FIXUP, /* tv_id */ | |
267 0, /* properties_required */ | |
268 0, /* properties_provided */ | |
269 0, /* properties_destroyed */ | |
270 0, /* todo_flags_start */ | |
271 TODO_dump_func /* todo_flags_finish */ | |
272 }, | |
273 NULL, /* generate_summary */ | |
274 lto_output_wpa_fixup, /* write_summary */ | |
275 lto_input_wpa_fixup, /* read_summary */ | |
276 NULL, /* function_read_summary */ | |
277 NULL, /* stmt_fixup */ | |
278 0, /* TODOs */ | |
279 NULL, /* function_transform */ | |
280 NULL /* variable_transform */ | |
281 }; | |
282 |