Mercurial > hg > CbC > CbC_gcc
comparison gcc/lto-section-in.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 | b7f97abdc517 |
comparison
equal
deleted
inserted
replaced
52:c156f1bd5cd9 | 55:77e2b8dfacca |
---|---|
1 /* Input functions for reading LTO sections. | |
2 | |
3 Copyright 2009 Free Software Foundation, Inc. | |
4 Contributed by Kenneth Zadeck <zadeck@naturalbridge.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 "params.h" | |
31 #include "input.h" | |
32 #include "varray.h" | |
33 #include "hashtab.h" | |
34 #include "basic-block.h" | |
35 #include "tree-flow.h" | |
36 #include "cgraph.h" | |
37 #include "function.h" | |
38 #include "ggc.h" | |
39 #include "diagnostic.h" | |
40 #include "except.h" | |
41 #include "vec.h" | |
42 #include "timevar.h" | |
43 #include "output.h" | |
44 #include "lto-streamer.h" | |
45 #include "lto-compress.h" | |
46 | |
47 /* Section names. These must correspond to the values of | |
48 enum lto_section_type. */ | |
49 const char *lto_section_name[LTO_N_SECTION_TYPES] = | |
50 { | |
51 "decls", | |
52 "function_body", | |
53 "static_initializer", | |
54 "cgraph", | |
55 "ipa_pure_const", | |
56 "ipa_reference", | |
57 "symtab", | |
58 "wpa_fixup", | |
59 "opts" | |
60 }; | |
61 | |
62 unsigned char | |
63 lto_input_1_unsigned (struct lto_input_block *ib) | |
64 { | |
65 if (ib->p >= ib->len) | |
66 internal_error ("bytecode stream: trying to read %d bytes " | |
67 "after the end of the input buffer", ib->p - ib->len); | |
68 | |
69 return (ib->data[ib->p++]); | |
70 } | |
71 | |
72 | |
73 /* Read an ULEB128 Number of IB. */ | |
74 | |
75 unsigned HOST_WIDE_INT | |
76 lto_input_uleb128 (struct lto_input_block *ib) | |
77 { | |
78 unsigned HOST_WIDE_INT result = 0; | |
79 int shift = 0; | |
80 unsigned HOST_WIDE_INT byte; | |
81 | |
82 while (true) | |
83 { | |
84 byte = lto_input_1_unsigned (ib); | |
85 result |= (byte & 0x7f) << shift; | |
86 shift += 7; | |
87 if ((byte & 0x80) == 0) | |
88 return result; | |
89 } | |
90 } | |
91 | |
92 /* HOST_WIDEST_INT version of lto_input_uleb128. IB is as in | |
93 lto_input_uleb128. */ | |
94 | |
95 unsigned HOST_WIDEST_INT | |
96 lto_input_widest_uint_uleb128 (struct lto_input_block *ib) | |
97 { | |
98 unsigned HOST_WIDEST_INT result = 0; | |
99 int shift = 0; | |
100 unsigned HOST_WIDEST_INT byte; | |
101 | |
102 while (true) | |
103 { | |
104 byte = lto_input_1_unsigned (ib); | |
105 result |= (byte & 0x7f) << shift; | |
106 shift += 7; | |
107 if ((byte & 0x80) == 0) | |
108 return result; | |
109 } | |
110 } | |
111 | |
112 /* Read an SLEB128 Number of IB. */ | |
113 | |
114 HOST_WIDE_INT | |
115 lto_input_sleb128 (struct lto_input_block *ib) | |
116 { | |
117 HOST_WIDE_INT result = 0; | |
118 int shift = 0; | |
119 unsigned HOST_WIDE_INT byte; | |
120 | |
121 while (true) | |
122 { | |
123 byte = lto_input_1_unsigned (ib); | |
124 result |= (byte & 0x7f) << shift; | |
125 shift += 7; | |
126 if ((byte & 0x80) == 0) | |
127 { | |
128 if ((shift < HOST_BITS_PER_WIDE_INT) && (byte & 0x40)) | |
129 result |= - ((HOST_WIDE_INT)1 << shift); | |
130 | |
131 return result; | |
132 } | |
133 } | |
134 } | |
135 | |
136 | |
137 /* Hooks so that the ipa passes can call into the lto front end to get | |
138 sections. */ | |
139 | |
140 static struct lto_file_decl_data ** file_decl_data; | |
141 static lto_get_section_data_f* get_section_f; | |
142 static lto_free_section_data_f* free_section_f; | |
143 | |
144 | |
145 /* This is called from the lto front end to set up the hooks that are | |
146 used by the ipa passes to get the data that they will | |
147 deserialize. */ | |
148 | |
149 void | |
150 lto_set_in_hooks (struct lto_file_decl_data ** data, | |
151 lto_get_section_data_f* get_f, | |
152 lto_free_section_data_f* free_f) | |
153 { | |
154 file_decl_data = data; | |
155 get_section_f = get_f; | |
156 free_section_f = free_f; | |
157 } | |
158 | |
159 | |
160 /* Return an array of file decl datas for all of the files passed to | |
161 this compilation. */ | |
162 | |
163 struct lto_file_decl_data ** | |
164 lto_get_file_decl_data (void) | |
165 { | |
166 gcc_assert (file_decl_data); | |
167 return file_decl_data; | |
168 } | |
169 | |
170 /* Buffer structure for accumulating data from compression callbacks. */ | |
171 | |
172 struct lto_buffer | |
173 { | |
174 char *data; | |
175 size_t length; | |
176 }; | |
177 | |
178 /* Compression callback, append LENGTH bytes from DATA to the buffer pointed | |
179 to by OPAQUE. */ | |
180 | |
181 static void | |
182 lto_append_data (const char *data, unsigned length, void *opaque) | |
183 { | |
184 struct lto_buffer *buffer = (struct lto_buffer *) opaque; | |
185 | |
186 buffer->data = (char *) xrealloc (buffer->data, buffer->length + length); | |
187 memcpy (buffer->data + buffer->length, data, length); | |
188 buffer->length += length; | |
189 } | |
190 | |
191 /* Header placed in returned uncompressed data streams. Allows the | |
192 uncompressed allocated data to be mapped back to the underlying | |
193 compressed data for use with free_section_f. */ | |
194 | |
195 struct lto_data_header | |
196 { | |
197 const char *data; | |
198 size_t len; | |
199 }; | |
200 | |
201 /* Return a char pointer to the start of a data stream for an LTO pass | |
202 or function. FILE_DATA indicates where to obtain the data. | |
203 SECTION_TYPE is the type of information to be obtained. NAME is | |
204 the name of the function and is only used when finding a function | |
205 body; otherwise it is NULL. LEN is the size of the data | |
206 returned. */ | |
207 | |
208 const char * | |
209 lto_get_section_data (struct lto_file_decl_data *file_data, | |
210 enum lto_section_type section_type, | |
211 const char *name, | |
212 size_t *len) | |
213 { | |
214 const char *data = (get_section_f) (file_data, section_type, name, len); | |
215 const size_t header_length = sizeof (struct lto_data_header); | |
216 struct lto_data_header *header; | |
217 struct lto_buffer buffer; | |
218 struct lto_compression_stream *stream; | |
219 lto_stats.section_size[section_type] += *len; | |
220 | |
221 if (data == NULL) | |
222 return NULL; | |
223 | |
224 /* FIXME lto: WPA mode does not write compressed sections, so for now | |
225 suppress uncompression if flag_ltrans. */ | |
226 if (flag_ltrans) | |
227 return data; | |
228 | |
229 /* Create a mapping header containing the underlying data and length, | |
230 and prepend this to the uncompression buffer. The uncompressed data | |
231 then follows, and a pointer to the start of the uncompressed data is | |
232 returned. */ | |
233 header = (struct lto_data_header *) xmalloc (header_length); | |
234 header->data = data; | |
235 header->len = *len; | |
236 | |
237 buffer.data = (char *) header; | |
238 buffer.length = header_length; | |
239 | |
240 stream = lto_start_uncompression (lto_append_data, &buffer); | |
241 lto_uncompress_block (stream, data, *len); | |
242 lto_end_uncompression (stream); | |
243 | |
244 *len = buffer.length - header_length; | |
245 return buffer.data + header_length; | |
246 } | |
247 | |
248 | |
249 /* Free the data found from the above call. The first three | |
250 parameters are the same as above. DATA is the data to be freed and | |
251 LEN is the length of that data. */ | |
252 | |
253 void | |
254 lto_free_section_data (struct lto_file_decl_data *file_data, | |
255 enum lto_section_type section_type, | |
256 const char *name, | |
257 const char *data, | |
258 size_t len) | |
259 { | |
260 const size_t header_length = sizeof (struct lto_data_header); | |
261 const char *real_data = data - header_length; | |
262 const struct lto_data_header *header | |
263 = (const struct lto_data_header *) real_data; | |
264 | |
265 gcc_assert (free_section_f); | |
266 | |
267 /* FIXME lto: WPA mode does not write compressed sections, so for now | |
268 suppress uncompression mapping if flag_ltrans. */ | |
269 if (flag_ltrans) | |
270 { | |
271 (free_section_f) (file_data, section_type, name, data, len); | |
272 return; | |
273 } | |
274 | |
275 /* The underlying data address has been extracted from the mapping header. | |
276 Free that, then free the allocated uncompression buffer. */ | |
277 (free_section_f) (file_data, section_type, name, header->data, header->len); | |
278 free (CONST_CAST (char *, real_data)); | |
279 } | |
280 | |
281 | |
282 /* Load a section of type SECTION_TYPE from FILE_DATA, parse the | |
283 header and then return an input block pointing to the section. The | |
284 raw pointer to the section is returned in DATAR and LEN. These are | |
285 used to free the section. Return NULL if the section is not present. */ | |
286 | |
287 struct lto_input_block * | |
288 lto_create_simple_input_block (struct lto_file_decl_data *file_data, | |
289 enum lto_section_type section_type, | |
290 const char **datar, size_t *len) | |
291 { | |
292 const char *data = lto_get_section_data (file_data, section_type, NULL, len); | |
293 const struct lto_simple_header * header | |
294 = (const struct lto_simple_header *) data; | |
295 | |
296 struct lto_input_block* ib_main; | |
297 int32_t main_offset = sizeof (struct lto_simple_header); | |
298 | |
299 if (!data) | |
300 return NULL; | |
301 | |
302 ib_main = XNEW (struct lto_input_block); | |
303 | |
304 *datar = data; | |
305 LTO_INIT_INPUT_BLOCK_PTR (ib_main, data + main_offset, | |
306 0, header->main_size); | |
307 | |
308 return ib_main; | |
309 } | |
310 | |
311 | |
312 /* Close the section returned from a call to | |
313 LTO_CREATE_SIMPLE_INPUT_BLOCK. IB is the input block returned from | |
314 that call. The FILE_DATA and SECTION_TYPE are the same as what was | |
315 passed to that call and the DATA and LEN are what was returned from | |
316 that call. */ | |
317 | |
318 void | |
319 lto_destroy_simple_input_block (struct lto_file_decl_data *file_data, | |
320 enum lto_section_type section_type, | |
321 struct lto_input_block *ib, | |
322 const char *data, size_t len) | |
323 { | |
324 free (ib); | |
325 lto_free_section_data (file_data, section_type, NULL, data, len); | |
326 } | |
327 | |
328 /*****************************************************************************/ | |
329 /* Record renamings of static declarations */ | |
330 /*****************************************************************************/ | |
331 | |
332 struct lto_renaming_slot | |
333 { | |
334 const char *old_name; | |
335 const char *new_name; | |
336 }; | |
337 | |
338 /* Returns a hash code for P. */ | |
339 | |
340 static hashval_t | |
341 hash_name (const void *p) | |
342 { | |
343 const struct lto_renaming_slot *ds = (const struct lto_renaming_slot *) p; | |
344 return (hashval_t) htab_hash_string (ds->new_name); | |
345 } | |
346 | |
347 /* Returns nonzero if P1 and P2 are equal. */ | |
348 | |
349 static int | |
350 eq_name (const void *p1, const void *p2) | |
351 { | |
352 const struct lto_renaming_slot *s1 = | |
353 (const struct lto_renaming_slot *) p1; | |
354 const struct lto_renaming_slot *s2 = | |
355 (const struct lto_renaming_slot *) p2; | |
356 | |
357 return strcmp (s1->new_name, s2->new_name) == 0; | |
358 } | |
359 | |
360 /* Free a renaming table entry. */ | |
361 | |
362 static void | |
363 renaming_slot_free (void *slot) | |
364 { | |
365 struct lto_renaming_slot *s = (struct lto_renaming_slot *) slot; | |
366 | |
367 free (CONST_CAST (void *, (const void *) s->old_name)); | |
368 free (CONST_CAST (void *, (const void *) s->new_name)); | |
369 free ((void *) s); | |
370 } | |
371 | |
372 /* Create an empty hash table for recording declaration renamings. */ | |
373 | |
374 htab_t | |
375 lto_create_renaming_table (void) | |
376 { | |
377 return htab_create (37, hash_name, eq_name, renaming_slot_free); | |
378 } | |
379 | |
380 /* Record a declaration name mapping OLD_NAME -> NEW_NAME. DECL_DATA | |
381 holds the renaming hash table to use. */ | |
382 | |
383 void | |
384 lto_record_renamed_decl (struct lto_file_decl_data *decl_data, | |
385 const char *old_name, const char *new_name) | |
386 { | |
387 void **slot; | |
388 struct lto_renaming_slot r_slot; | |
389 | |
390 r_slot.new_name = new_name; | |
391 slot = htab_find_slot (decl_data->renaming_hash_table, &r_slot, INSERT); | |
392 if (*slot == NULL) | |
393 { | |
394 struct lto_renaming_slot *new_slot = XNEW (struct lto_renaming_slot); | |
395 new_slot->old_name = xstrdup (old_name); | |
396 new_slot->new_name = xstrdup (new_name); | |
397 *slot = new_slot; | |
398 } | |
399 else | |
400 gcc_unreachable (); | |
401 } | |
402 | |
403 | |
404 /* Given a string NAME, return the string that it has been mapped to | |
405 by lto_record_renamed_decl. If NAME was not renamed, it is | |
406 returned unchanged. DECL_DATA holds the renaming hash table to use. */ | |
407 | |
408 const char * | |
409 lto_get_decl_name_mapping (struct lto_file_decl_data *decl_data, | |
410 const char *name) | |
411 { | |
412 htab_t renaming_hash_table = decl_data->renaming_hash_table; | |
413 struct lto_renaming_slot *slot; | |
414 struct lto_renaming_slot r_slot; | |
415 | |
416 r_slot.new_name = name; | |
417 slot = (struct lto_renaming_slot *) htab_find (renaming_hash_table, &r_slot); | |
418 if (slot) | |
419 return slot->old_name; | |
420 else | |
421 return name; | |
422 } | |
423 | |
424 /*****************************************************************************/ | |
425 /* Input decl state object. */ | |
426 /*****************************************************************************/ | |
427 | |
428 /* Return a newly created in-decl state object. */ | |
429 | |
430 struct lto_in_decl_state * | |
431 lto_new_in_decl_state (void) | |
432 { | |
433 struct lto_in_decl_state *state; | |
434 | |
435 state = ((struct lto_in_decl_state *) xmalloc (sizeof (*state))); | |
436 memset (state, 0, sizeof (*state)); | |
437 return state; | |
438 } | |
439 | |
440 /* Delete STATE and its components. */ | |
441 | |
442 void | |
443 lto_delete_in_decl_state (struct lto_in_decl_state *state) | |
444 { | |
445 int i; | |
446 | |
447 for (i = 0; i < LTO_N_DECL_STREAMS; i++) | |
448 if (state->streams[i].trees) | |
449 free (state->streams[i].trees); | |
450 free (state); | |
451 } | |
452 | |
453 /* Hashtable helpers. lto_in_decl_states are hash by their function decls. */ | |
454 | |
455 hashval_t | |
456 lto_hash_in_decl_state (const void *p) | |
457 { | |
458 const struct lto_in_decl_state *state = (const struct lto_in_decl_state *) p; | |
459 return htab_hash_pointer (state->fn_decl); | |
460 } | |
461 | |
462 /* Return true if the fn_decl field of the lto_in_decl_state pointed to by | |
463 P1 equals to the function decl P2. */ | |
464 | |
465 int | |
466 lto_eq_in_decl_state (const void *p1, const void *p2) | |
467 { | |
468 const struct lto_in_decl_state *state1 = | |
469 (const struct lto_in_decl_state *) p1; | |
470 const struct lto_in_decl_state *state2 = | |
471 (const struct lto_in_decl_state *) p2; | |
472 return state1->fn_decl == state2->fn_decl; | |
473 } | |
474 | |
475 | |
476 /* Search the in-decl state of a function FUNC contained in the file | |
477 associated with FILE_DATA. Return NULL if not found. */ | |
478 | |
479 struct lto_in_decl_state* | |
480 lto_get_function_in_decl_state (struct lto_file_decl_data *file_data, | |
481 tree func) | |
482 { | |
483 struct lto_in_decl_state temp; | |
484 void **slot; | |
485 | |
486 temp.fn_decl = func; | |
487 slot = htab_find_slot (file_data->function_decl_states, &temp, NO_INSERT); | |
488 return slot? ((struct lto_in_decl_state*) *slot) : NULL; | |
489 } |