Mercurial > hg > CbC > CbC_gcc
comparison gcc/cgraphunit.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
65:65488c3d617d | 67:f6334be47118 |
---|---|
1 /* Callgraph based interprocedural optimizations. | 1 /* Callgraph based interprocedural optimizations. |
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 | 2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, |
3 Free Software Foundation, Inc. | 3 2011 Free Software Foundation, Inc. |
4 Contributed by Jan Hubicka | 4 Contributed by Jan Hubicka |
5 | 5 |
6 This file is part of GCC. | 6 This file is part of GCC. |
7 | 7 |
8 GCC is free software; you can redistribute it and/or modify it under | 8 GCC is free software; you can redistribute it and/or modify it under |
143 static void cgraph_mark_functions_to_output (void); | 143 static void cgraph_mark_functions_to_output (void); |
144 static void cgraph_expand_function (struct cgraph_node *); | 144 static void cgraph_expand_function (struct cgraph_node *); |
145 static void cgraph_output_pending_asms (void); | 145 static void cgraph_output_pending_asms (void); |
146 static void cgraph_analyze_function (struct cgraph_node *); | 146 static void cgraph_analyze_function (struct cgraph_node *); |
147 | 147 |
148 static FILE *cgraph_dump_file; | 148 FILE *cgraph_dump_file; |
149 | |
150 /* A vector of FUNCTION_DECLs declared as static constructors. */ | |
151 static GTY (()) VEC(tree, gc) *static_ctors; | |
152 /* A vector of FUNCTION_DECLs declared as static destructors. */ | |
153 static GTY (()) VEC(tree, gc) *static_dtors; | |
154 | 149 |
155 /* Used for vtable lookup in thunk adjusting. */ | 150 /* Used for vtable lookup in thunk adjusting. */ |
156 static GTY (()) tree vtable_entry_type; | 151 static GTY (()) tree vtable_entry_type; |
157 | |
158 /* When target does not have ctors and dtors, we call all constructor | |
159 and destructor by special initialization/destruction function | |
160 recognized by collect2. | |
161 | |
162 When we are going to build this function, collect all constructors and | |
163 destructors and turn them into normal functions. */ | |
164 | |
165 static void | |
166 record_cdtor_fn (tree fndecl) | |
167 { | |
168 struct cgraph_node *node; | |
169 if (targetm.have_ctors_dtors | |
170 || (!DECL_STATIC_CONSTRUCTOR (fndecl) | |
171 && !DECL_STATIC_DESTRUCTOR (fndecl))) | |
172 return; | |
173 | |
174 if (DECL_STATIC_CONSTRUCTOR (fndecl)) | |
175 { | |
176 VEC_safe_push (tree, gc, static_ctors, fndecl); | |
177 DECL_STATIC_CONSTRUCTOR (fndecl) = 0; | |
178 } | |
179 if (DECL_STATIC_DESTRUCTOR (fndecl)) | |
180 { | |
181 VEC_safe_push (tree, gc, static_dtors, fndecl); | |
182 DECL_STATIC_DESTRUCTOR (fndecl) = 0; | |
183 } | |
184 node = cgraph_node (fndecl); | |
185 node->local.disregard_inline_limits = 1; | |
186 cgraph_mark_reachable_node (node); | |
187 } | |
188 | |
189 /* Define global constructors/destructor functions for the CDTORS, of | |
190 which they are LEN. The CDTORS are sorted by initialization | |
191 priority. If CTOR_P is true, these are constructors; otherwise, | |
192 they are destructors. */ | |
193 | |
194 static void | |
195 build_cdtor (bool ctor_p, tree *cdtors, size_t len) | |
196 { | |
197 size_t i; | |
198 | |
199 i = 0; | |
200 while (i < len) | |
201 { | |
202 tree body; | |
203 tree fn; | |
204 priority_type priority; | |
205 | |
206 priority = 0; | |
207 body = NULL_TREE; | |
208 /* Find the next batch of constructors/destructors with the same | |
209 initialization priority. */ | |
210 do | |
211 { | |
212 priority_type p; | |
213 fn = cdtors[i]; | |
214 p = ctor_p ? DECL_INIT_PRIORITY (fn) : DECL_FINI_PRIORITY (fn); | |
215 if (!body) | |
216 priority = p; | |
217 else if (p != priority) | |
218 break; | |
219 append_to_statement_list (build_function_call_expr (UNKNOWN_LOCATION, | |
220 fn, 0), | |
221 &body); | |
222 ++i; | |
223 } | |
224 while (i < len); | |
225 gcc_assert (body != NULL_TREE); | |
226 /* Generate a function to call all the function of like | |
227 priority. */ | |
228 cgraph_build_static_cdtor (ctor_p ? 'I' : 'D', body, priority); | |
229 } | |
230 } | |
231 | |
232 /* Comparison function for qsort. P1 and P2 are actually of type | |
233 "tree *" and point to static constructors. DECL_INIT_PRIORITY is | |
234 used to determine the sort order. */ | |
235 | |
236 static int | |
237 compare_ctor (const void *p1, const void *p2) | |
238 { | |
239 tree f1; | |
240 tree f2; | |
241 int priority1; | |
242 int priority2; | |
243 | |
244 f1 = *(const tree *)p1; | |
245 f2 = *(const tree *)p2; | |
246 priority1 = DECL_INIT_PRIORITY (f1); | |
247 priority2 = DECL_INIT_PRIORITY (f2); | |
248 | |
249 if (priority1 < priority2) | |
250 return -1; | |
251 else if (priority1 > priority2) | |
252 return 1; | |
253 else | |
254 /* Ensure a stable sort. */ | |
255 return (const tree *)p1 - (const tree *)p2; | |
256 } | |
257 | |
258 /* Comparison function for qsort. P1 and P2 are actually of type | |
259 "tree *" and point to static destructors. DECL_FINI_PRIORITY is | |
260 used to determine the sort order. */ | |
261 | |
262 static int | |
263 compare_dtor (const void *p1, const void *p2) | |
264 { | |
265 tree f1; | |
266 tree f2; | |
267 int priority1; | |
268 int priority2; | |
269 | |
270 f1 = *(const tree *)p1; | |
271 f2 = *(const tree *)p2; | |
272 priority1 = DECL_FINI_PRIORITY (f1); | |
273 priority2 = DECL_FINI_PRIORITY (f2); | |
274 | |
275 if (priority1 < priority2) | |
276 return -1; | |
277 else if (priority1 > priority2) | |
278 return 1; | |
279 else | |
280 /* Ensure a stable sort. */ | |
281 return (const tree *)p1 - (const tree *)p2; | |
282 } | |
283 | |
284 /* Generate functions to call static constructors and destructors | |
285 for targets that do not support .ctors/.dtors sections. These | |
286 functions have magic names which are detected by collect2. */ | |
287 | |
288 static void | |
289 cgraph_build_cdtor_fns (void) | |
290 { | |
291 if (!VEC_empty (tree, static_ctors)) | |
292 { | |
293 gcc_assert (!targetm.have_ctors_dtors); | |
294 qsort (VEC_address (tree, static_ctors), | |
295 VEC_length (tree, static_ctors), | |
296 sizeof (tree), | |
297 compare_ctor); | |
298 build_cdtor (/*ctor_p=*/true, | |
299 VEC_address (tree, static_ctors), | |
300 VEC_length (tree, static_ctors)); | |
301 VEC_truncate (tree, static_ctors, 0); | |
302 } | |
303 | |
304 if (!VEC_empty (tree, static_dtors)) | |
305 { | |
306 gcc_assert (!targetm.have_ctors_dtors); | |
307 qsort (VEC_address (tree, static_dtors), | |
308 VEC_length (tree, static_dtors), | |
309 sizeof (tree), | |
310 compare_dtor); | |
311 build_cdtor (/*ctor_p=*/false, | |
312 VEC_address (tree, static_dtors), | |
313 VEC_length (tree, static_dtors)); | |
314 VEC_truncate (tree, static_dtors, 0); | |
315 } | |
316 } | |
317 | 152 |
318 /* Determine if function DECL is needed. That is, visible to something | 153 /* Determine if function DECL is needed. That is, visible to something |
319 either outside this translation unit, something magic in the system | 154 either outside this translation unit, something magic in the system |
320 configury. */ | 155 configury. */ |
321 | 156 |
350 /* Externally visible functions must be output. The exception is | 185 /* Externally visible functions must be output. The exception is |
351 COMDAT functions that must be output only when they are needed. | 186 COMDAT functions that must be output only when they are needed. |
352 | 187 |
353 When not optimizing, also output the static functions. (see | 188 When not optimizing, also output the static functions. (see |
354 PR24561), but don't do so for always_inline functions, functions | 189 PR24561), but don't do so for always_inline functions, functions |
355 declared inline and nested functions. These was optimized out | 190 declared inline and nested functions. These were optimized out |
356 in the original implementation and it is unclear whether we want | 191 in the original implementation and it is unclear whether we want |
357 to change the behavior here. */ | 192 to change the behavior here. */ |
358 if (((TREE_PUBLIC (decl) | 193 if (((TREE_PUBLIC (decl) |
359 || (!optimize && !node->local.disregard_inline_limits | 194 || (!optimize |
195 && !node->local.disregard_inline_limits | |
360 && !DECL_DECLARED_INLINE_P (decl) | 196 && !DECL_DECLARED_INLINE_P (decl) |
361 && !node->origin)) | 197 && !(DECL_CONTEXT (decl) |
198 && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL))) | |
362 && !flag_whole_program | 199 && !flag_whole_program |
363 && !flag_lto | 200 && !flag_lto) |
364 && !flag_whopr) | |
365 && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)) | 201 && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)) |
366 return true; | |
367 | |
368 /* Constructors and destructors are reachable from the runtime by | |
369 some mechanism. */ | |
370 if (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl)) | |
371 return true; | 202 return true; |
372 | 203 |
373 return false; | 204 return false; |
374 } | 205 } |
375 | 206 |
413 gimple_register_cfg_hooks (); | 244 gimple_register_cfg_hooks (); |
414 if (!node->analyzed) | 245 if (!node->analyzed) |
415 cgraph_analyze_function (node); | 246 cgraph_analyze_function (node); |
416 push_cfun (DECL_STRUCT_FUNCTION (fndecl)); | 247 push_cfun (DECL_STRUCT_FUNCTION (fndecl)); |
417 current_function_decl = fndecl; | 248 current_function_decl = fndecl; |
418 compute_inline_parameters (node); | |
419 if ((cgraph_state == CGRAPH_STATE_IPA_SSA | 249 if ((cgraph_state == CGRAPH_STATE_IPA_SSA |
420 && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl))) | 250 && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl))) |
421 /* When not optimizing, be sure we run early local passes anyway | 251 /* When not optimizing, be sure we run early local passes anyway |
422 to expand OMP. */ | 252 to expand OMP. */ |
423 || !optimize) | 253 || !optimize) |
424 execute_pass_list (pass_early_local_passes.pass.sub); | 254 execute_pass_list (pass_early_local_passes.pass.sub); |
255 else | |
256 compute_inline_parameters (node); | |
425 free_dominance_info (CDI_POST_DOMINATORS); | 257 free_dominance_info (CDI_POST_DOMINATORS); |
426 free_dominance_info (CDI_DOMINATORS); | 258 free_dominance_info (CDI_DOMINATORS); |
427 pop_cfun (); | 259 pop_cfun (); |
428 current_function_decl = NULL; | 260 current_function_decl = NULL; |
429 break; | 261 break; |
520 node->pid = cgraph_max_pid ++; | 352 node->pid = cgraph_max_pid ++; |
521 notice_global_symbol (decl); | 353 notice_global_symbol (decl); |
522 node->local.finalized = true; | 354 node->local.finalized = true; |
523 node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL; | 355 node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL; |
524 node->finalized_by_frontend = true; | 356 node->finalized_by_frontend = true; |
525 record_cdtor_fn (node->decl); | |
526 | 357 |
527 if (cgraph_decide_is_function_needed (node, decl)) | 358 if (cgraph_decide_is_function_needed (node, decl)) |
528 cgraph_mark_needed_node (node); | 359 cgraph_mark_needed_node (node); |
529 | 360 |
530 /* Since we reclaim unreachable nodes at the end of every language | 361 /* Since we reclaim unreachable nodes at the end of every language |
531 level unit, we need to be conservative about possible entry points | 362 level unit, we need to be conservative about possible entry points |
532 there. */ | 363 there. */ |
533 if ((TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))) | 364 if ((TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)) |
365 || DECL_STATIC_CONSTRUCTOR (decl) | |
366 || DECL_STATIC_DESTRUCTOR (decl) | |
367 /* COMDAT virtual functions may be referenced by vtable from | |
368 other compilation unit. Still we want to devirtualize calls | |
369 to those so we need to analyze them. | |
370 FIXME: We should introduce may edges for this purpose and update | |
371 their handling in unreachable function removal and inliner too. */ | |
372 || (DECL_VIRTUAL_P (decl) && (DECL_COMDAT (decl) || DECL_EXTERNAL (decl)))) | |
534 cgraph_mark_reachable_node (node); | 373 cgraph_mark_reachable_node (node); |
535 | 374 |
536 /* If we've not yet emitted decl, tell the debug info about it. */ | 375 /* If we've not yet emitted decl, tell the debug info about it. */ |
537 if (!TREE_ASM_WRITTEN (decl)) | 376 if (!TREE_ASM_WRITTEN (decl)) |
538 (*debug_hooks->deferred_inline_function) (decl); | 377 (*debug_hooks->deferred_inline_function) (decl); |
564 while (node != node2 && node2) | 403 while (node != node2 && node2) |
565 node2 = node2->clone_of; | 404 node2 = node2->clone_of; |
566 return node2 != NULL; | 405 return node2 != NULL; |
567 } | 406 } |
568 | 407 |
408 /* Verify edge E count and frequency. */ | |
409 | |
410 static bool | |
411 verify_edge_count_and_frequency (struct cgraph_edge *e) | |
412 { | |
413 bool error_found = false; | |
414 if (e->count < 0) | |
415 { | |
416 error ("caller edge count is negative"); | |
417 error_found = true; | |
418 } | |
419 if (e->frequency < 0) | |
420 { | |
421 error ("caller edge frequency is negative"); | |
422 error_found = true; | |
423 } | |
424 if (e->frequency > CGRAPH_FREQ_MAX) | |
425 { | |
426 error ("caller edge frequency is too large"); | |
427 error_found = true; | |
428 } | |
429 if (gimple_has_body_p (e->caller->decl) | |
430 && !e->caller->global.inlined_to | |
431 && (e->frequency | |
432 != compute_call_stmt_bb_frequency (e->caller->decl, | |
433 gimple_bb (e->call_stmt)))) | |
434 { | |
435 error ("caller edge frequency %i does not match BB frequency %i", | |
436 e->frequency, | |
437 compute_call_stmt_bb_frequency (e->caller->decl, | |
438 gimple_bb (e->call_stmt))); | |
439 error_found = true; | |
440 } | |
441 return error_found; | |
442 } | |
443 | |
444 /* Switch to THIS_CFUN if needed and print STMT to stderr. */ | |
445 static void | |
446 cgraph_debug_gimple_stmt (struct function *this_cfun, gimple stmt) | |
447 { | |
448 /* debug_gimple_stmt needs correct cfun */ | |
449 if (cfun != this_cfun) | |
450 set_cfun (this_cfun); | |
451 debug_gimple_stmt (stmt); | |
452 } | |
453 | |
569 /* Verify cgraph nodes of given cgraph node. */ | 454 /* Verify cgraph nodes of given cgraph node. */ |
570 void | 455 DEBUG_FUNCTION void |
571 verify_cgraph_node (struct cgraph_node *node) | 456 verify_cgraph_node (struct cgraph_node *node) |
572 { | 457 { |
573 struct cgraph_edge *e; | 458 struct cgraph_edge *e; |
574 struct function *this_cfun = DECL_STRUCT_FUNCTION (node->decl); | 459 struct function *this_cfun = DECL_STRUCT_FUNCTION (node->decl); |
575 struct function *saved_cfun = cfun; | |
576 basic_block this_block; | 460 basic_block this_block; |
577 gimple_stmt_iterator gsi; | 461 gimple_stmt_iterator gsi; |
578 bool error_found = false; | 462 bool error_found = false; |
579 | 463 |
580 if (errorcount || sorrycount) | 464 if (seen_error ()) |
581 return; | 465 return; |
582 | 466 |
583 timevar_push (TV_CGRAPH_VERIFY); | 467 timevar_push (TV_CGRAPH_VERIFY); |
584 /* debug_generic_stmt needs correct cfun */ | |
585 set_cfun (this_cfun); | |
586 for (e = node->callees; e; e = e->next_callee) | 468 for (e = node->callees; e; e = e->next_callee) |
587 if (e->aux) | 469 if (e->aux) |
588 { | 470 { |
589 error ("aux field set for edge %s->%s", | 471 error ("aux field set for edge %s->%s", |
590 identifier_to_locale (cgraph_node_name (e->caller)), | 472 identifier_to_locale (cgraph_node_name (e->caller)), |
591 identifier_to_locale (cgraph_node_name (e->callee))); | 473 identifier_to_locale (cgraph_node_name (e->callee))); |
592 error_found = true; | 474 error_found = true; |
593 } | 475 } |
594 if (node->count < 0) | 476 if (node->count < 0) |
595 { | 477 { |
596 error ("Execution count is negative"); | 478 error ("execution count is negative"); |
597 error_found = true; | 479 error_found = true; |
598 } | 480 } |
599 if (node->global.inlined_to && node->local.externally_visible) | 481 if (node->global.inlined_to && node->local.externally_visible) |
600 { | 482 { |
601 error ("Externally visible inline clone"); | 483 error ("externally visible inline clone"); |
602 error_found = true; | 484 error_found = true; |
603 } | 485 } |
604 if (node->global.inlined_to && node->address_taken) | 486 if (node->global.inlined_to && node->address_taken) |
605 { | 487 { |
606 error ("Inline clone with address taken"); | 488 error ("inline clone with address taken"); |
607 error_found = true; | 489 error_found = true; |
608 } | 490 } |
609 if (node->global.inlined_to && node->needed) | 491 if (node->global.inlined_to && node->needed) |
610 { | 492 { |
611 error ("Inline clone is needed"); | 493 error ("inline clone is needed"); |
612 error_found = true; | 494 error_found = true; |
613 } | 495 } |
614 for (e = node->indirect_calls; e; e = e->next_callee) | 496 for (e = node->indirect_calls; e; e = e->next_callee) |
615 { | 497 { |
616 if (e->aux) | 498 if (e->aux) |
623 || !e->indirect_info) | 505 || !e->indirect_info) |
624 { | 506 { |
625 error ("An indirect edge from %s is not marked as indirect or has " | 507 error ("An indirect edge from %s is not marked as indirect or has " |
626 "associated indirect_info, the corresponding statement is: ", | 508 "associated indirect_info, the corresponding statement is: ", |
627 identifier_to_locale (cgraph_node_name (e->caller))); | 509 identifier_to_locale (cgraph_node_name (e->caller))); |
628 debug_gimple_stmt (e->call_stmt); | 510 cgraph_debug_gimple_stmt (this_cfun, e->call_stmt); |
629 error_found = true; | 511 error_found = true; |
630 } | 512 } |
631 } | 513 } |
632 for (e = node->callers; e; e = e->next_caller) | 514 for (e = node->callers; e; e = e->next_caller) |
633 { | 515 { |
634 if (e->count < 0) | 516 if (verify_edge_count_and_frequency (e)) |
635 { | 517 error_found = true; |
636 error ("caller edge count is negative"); | |
637 error_found = true; | |
638 } | |
639 if (e->frequency < 0) | |
640 { | |
641 error ("caller edge frequency is negative"); | |
642 error_found = true; | |
643 } | |
644 if (e->frequency > CGRAPH_FREQ_MAX) | |
645 { | |
646 error ("caller edge frequency is too large"); | |
647 error_found = true; | |
648 } | |
649 if (gimple_has_body_p (e->caller->decl) | |
650 && !e->caller->global.inlined_to | |
651 && (e->frequency | |
652 != compute_call_stmt_bb_frequency (e->caller->decl, | |
653 gimple_bb (e->call_stmt)))) | |
654 { | |
655 error ("caller edge frequency %i does not match BB freqency %i", | |
656 e->frequency, | |
657 compute_call_stmt_bb_frequency (e->caller->decl, | |
658 gimple_bb (e->call_stmt))); | |
659 error_found = true; | |
660 } | |
661 if (!e->inline_failed) | 518 if (!e->inline_failed) |
662 { | 519 { |
663 if (node->global.inlined_to | 520 if (node->global.inlined_to |
664 != (e->caller->global.inlined_to | 521 != (e->caller->global.inlined_to |
665 ? e->caller->global.inlined_to : e->caller)) | 522 ? e->caller->global.inlined_to : e->caller)) |
678 { | 535 { |
679 error ("inlined_to pointer set for noninline callers"); | 536 error ("inlined_to pointer set for noninline callers"); |
680 error_found = true; | 537 error_found = true; |
681 } | 538 } |
682 } | 539 } |
540 for (e = node->indirect_calls; e; e = e->next_callee) | |
541 if (verify_edge_count_and_frequency (e)) | |
542 error_found = true; | |
683 if (!node->callers && node->global.inlined_to) | 543 if (!node->callers && node->global.inlined_to) |
684 { | 544 { |
685 error ("inlined_to pointer is set but no predecessors found"); | 545 error ("inlined_to pointer is set but no predecessors found"); |
686 error_found = true; | 546 error_found = true; |
687 } | 547 } |
689 { | 549 { |
690 error ("inlined_to pointer refers to itself"); | 550 error ("inlined_to pointer refers to itself"); |
691 error_found = true; | 551 error_found = true; |
692 } | 552 } |
693 | 553 |
694 if (!cgraph_node (node->decl)) | 554 if (!cgraph_get_node (node->decl)) |
695 { | 555 { |
696 error ("node not found in cgraph_hash"); | 556 error ("node not found in cgraph_hash"); |
697 error_found = true; | 557 error_found = true; |
698 } | 558 } |
699 | 559 |
788 if (e) | 648 if (e) |
789 { | 649 { |
790 if (e->aux) | 650 if (e->aux) |
791 { | 651 { |
792 error ("shared call_stmt:"); | 652 error ("shared call_stmt:"); |
793 debug_gimple_stmt (stmt); | 653 cgraph_debug_gimple_stmt (this_cfun, stmt); |
794 error_found = true; | 654 error_found = true; |
795 } | 655 } |
796 if (!e->indirect_unknown_callee) | 656 if (!e->indirect_unknown_callee) |
797 { | 657 { |
658 struct cgraph_node *n; | |
659 | |
798 if (e->callee->same_body_alias) | 660 if (e->callee->same_body_alias) |
799 { | 661 { |
800 error ("edge points to same body alias:"); | 662 error ("edge points to same body alias:"); |
801 debug_tree (e->callee->decl); | 663 debug_tree (e->callee->decl); |
802 error_found = true; | 664 error_found = true; |
803 } | 665 } |
804 else if (!node->global.inlined_to | 666 else if (!e->callee->global.inlined_to |
805 && !e->callee->global.inlined_to | |
806 && decl | 667 && decl |
668 && cgraph_get_node (decl) | |
669 && (e->callee->former_clone_of | |
670 != cgraph_get_node (decl)->decl) | |
807 && !clone_of_p (cgraph_node (decl), | 671 && !clone_of_p (cgraph_node (decl), |
808 e->callee)) | 672 e->callee)) |
809 { | 673 { |
810 error ("edge points to wrong declaration:"); | 674 error ("edge points to wrong declaration:"); |
811 debug_tree (e->callee->decl); | 675 debug_tree (e->callee->decl); |
812 fprintf (stderr," Instead of:"); | 676 fprintf (stderr," Instead of:"); |
813 debug_tree (decl); | 677 debug_tree (decl); |
814 error_found = true; | 678 error_found = true; |
815 } | 679 } |
680 else if (decl | |
681 && (n = cgraph_get_node_or_alias (decl)) | |
682 && (n->same_body_alias | |
683 && n->thunk.thunk_p)) | |
684 { | |
685 error ("a call to thunk improperly represented " | |
686 "in the call graph:"); | |
687 cgraph_debug_gimple_stmt (this_cfun, stmt); | |
688 error_found = true; | |
689 } | |
816 } | 690 } |
817 else if (decl) | 691 else if (decl) |
818 { | 692 { |
819 error ("an indirect edge with unknown callee " | 693 error ("an indirect edge with unknown callee " |
820 "corresponding to a call_stmt with " | 694 "corresponding to a call_stmt with " |
821 "a known declaration:"); | 695 "a known declaration:"); |
822 error_found = true; | 696 error_found = true; |
823 debug_gimple_stmt (e->call_stmt); | 697 cgraph_debug_gimple_stmt (this_cfun, e->call_stmt); |
824 } | 698 } |
825 e->aux = (void *)1; | 699 e->aux = (void *)1; |
826 } | 700 } |
827 else if (decl) | 701 else if (decl) |
828 { | 702 { |
829 error ("missing callgraph edge for call stmt:"); | 703 error ("missing callgraph edge for call stmt:"); |
830 debug_gimple_stmt (stmt); | 704 cgraph_debug_gimple_stmt (this_cfun, stmt); |
831 error_found = true; | 705 error_found = true; |
832 } | 706 } |
833 } | 707 } |
834 } | 708 } |
835 pointer_set_destroy (visited_nodes); | 709 pointer_set_destroy (visited_nodes); |
843 if (!e->aux) | 717 if (!e->aux) |
844 { | 718 { |
845 error ("edge %s->%s has no corresponding call_stmt", | 719 error ("edge %s->%s has no corresponding call_stmt", |
846 identifier_to_locale (cgraph_node_name (e->caller)), | 720 identifier_to_locale (cgraph_node_name (e->caller)), |
847 identifier_to_locale (cgraph_node_name (e->callee))); | 721 identifier_to_locale (cgraph_node_name (e->callee))); |
848 debug_gimple_stmt (e->call_stmt); | 722 cgraph_debug_gimple_stmt (this_cfun, e->call_stmt); |
849 error_found = true; | 723 error_found = true; |
850 } | 724 } |
851 e->aux = 0; | 725 e->aux = 0; |
852 } | 726 } |
853 for (e = node->indirect_calls; e; e = e->next_callee) | 727 for (e = node->indirect_calls; e; e = e->next_callee) |
854 { | 728 { |
855 if (!e->aux) | 729 if (!e->aux) |
856 { | 730 { |
857 error ("an indirect edge from %s has no corresponding call_stmt", | 731 error ("an indirect edge from %s has no corresponding call_stmt", |
858 identifier_to_locale (cgraph_node_name (e->caller))); | 732 identifier_to_locale (cgraph_node_name (e->caller))); |
859 debug_gimple_stmt (e->call_stmt); | 733 cgraph_debug_gimple_stmt (this_cfun, e->call_stmt); |
860 error_found = true; | 734 error_found = true; |
861 } | 735 } |
862 e->aux = 0; | 736 e->aux = 0; |
863 } | 737 } |
864 } | 738 } |
865 if (error_found) | 739 if (error_found) |
866 { | 740 { |
867 dump_cgraph_node (stderr, node); | 741 dump_cgraph_node (stderr, node); |
868 internal_error ("verify_cgraph_node failed"); | 742 internal_error ("verify_cgraph_node failed"); |
869 } | 743 } |
870 set_cfun (saved_cfun); | |
871 timevar_pop (TV_CGRAPH_VERIFY); | 744 timevar_pop (TV_CGRAPH_VERIFY); |
872 } | 745 } |
873 | 746 |
874 /* Verify whole cgraph structure. */ | 747 /* Verify whole cgraph structure. */ |
875 void | 748 DEBUG_FUNCTION void |
876 verify_cgraph (void) | 749 verify_cgraph (void) |
877 { | 750 { |
878 struct cgraph_node *node; | 751 struct cgraph_node *node; |
879 | 752 |
880 if (sorrycount || errorcount) | 753 if (seen_error ()) |
881 return; | 754 return; |
882 | 755 |
883 for (node = cgraph_nodes; node; node = node->next) | 756 for (node = cgraph_nodes; node; node = node->next) |
884 verify_cgraph_node (node); | 757 verify_cgraph_node (node); |
885 } | 758 } |
889 static void | 762 static void |
890 cgraph_output_pending_asms (void) | 763 cgraph_output_pending_asms (void) |
891 { | 764 { |
892 struct cgraph_asm_node *can; | 765 struct cgraph_asm_node *can; |
893 | 766 |
894 if (errorcount || sorrycount) | 767 if (seen_error ()) |
895 return; | 768 return; |
896 | 769 |
897 for (can = cgraph_asm_nodes; can; can = can->next) | 770 for (can = cgraph_asm_nodes; can; can = can->next) |
898 assemble_asm (can->asm_str); | 771 assemble_asm (can->asm_str); |
899 cgraph_asm_nodes = NULL; | 772 cgraph_asm_nodes = NULL; |
908 | 781 |
909 current_function_decl = decl; | 782 current_function_decl = decl; |
910 push_cfun (DECL_STRUCT_FUNCTION (decl)); | 783 push_cfun (DECL_STRUCT_FUNCTION (decl)); |
911 | 784 |
912 assign_assembler_name_if_neeeded (node->decl); | 785 assign_assembler_name_if_neeeded (node->decl); |
786 | |
787 /* disregard_inline_limits affects topological order of the early optimization, | |
788 so we need to compute it ahead of rest of inline parameters. */ | |
789 node->local.disregard_inline_limits | |
790 = DECL_DISREGARD_INLINE_LIMITS (node->decl); | |
913 | 791 |
914 /* Make sure to gimplify bodies only once. During analyzing a | 792 /* Make sure to gimplify bodies only once. During analyzing a |
915 function we lower it, which will require gimplified nested | 793 function we lower it, which will require gimplified nested |
916 functions, so we can end up here with an already gimplified | 794 functions, so we can end up here with an already gimplified |
917 body. */ | 795 body. */ |
924 | 802 |
925 pop_cfun (); | 803 pop_cfun (); |
926 current_function_decl = save; | 804 current_function_decl = save; |
927 } | 805 } |
928 | 806 |
807 /* Process attributes common for vars and functions. */ | |
808 | |
809 static void | |
810 process_common_attributes (tree decl) | |
811 { | |
812 tree weakref = lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)); | |
813 | |
814 if (weakref && !lookup_attribute ("alias", DECL_ATTRIBUTES (decl))) | |
815 { | |
816 warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes, | |
817 "%<weakref%> attribute should be accompanied with" | |
818 " an %<alias%> attribute"); | |
819 DECL_WEAK (decl) = 0; | |
820 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref", | |
821 DECL_ATTRIBUTES (decl)); | |
822 } | |
823 } | |
824 | |
929 /* Look for externally_visible and used attributes and mark cgraph nodes | 825 /* Look for externally_visible and used attributes and mark cgraph nodes |
930 accordingly. | 826 accordingly. |
931 | 827 |
932 We cannot mark the nodes at the point the attributes are processed (in | 828 We cannot mark the nodes at the point the attributes are processed (in |
933 handle_*_attribute) because the copy of the declarations available at that | 829 handle_*_attribute) because the copy of the declarations available at that |
960 for (node = cgraph_nodes; node != first; node = node->next) | 856 for (node = cgraph_nodes; node != first; node = node->next) |
961 { | 857 { |
962 tree decl = node->decl; | 858 tree decl = node->decl; |
963 if (DECL_PRESERVE_P (decl)) | 859 if (DECL_PRESERVE_P (decl)) |
964 cgraph_mark_needed_node (node); | 860 cgraph_mark_needed_node (node); |
965 if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl))) | 861 if (TARGET_DLLIMPORT_DECL_ATTRIBUTES |
862 && lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)) | |
863 && TREE_PUBLIC (node->decl)) | |
864 { | |
865 if (node->local.finalized) | |
866 cgraph_mark_needed_node (node); | |
867 } | |
868 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl))) | |
966 { | 869 { |
967 if (! TREE_PUBLIC (node->decl)) | 870 if (! TREE_PUBLIC (node->decl)) |
968 warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes, | 871 warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes, |
969 "%<externally_visible%>" | 872 "%<externally_visible%>" |
970 " attribute have effect only on public objects"); | 873 " attribute have effect only on public objects"); |
971 else if (node->local.finalized) | 874 else if (node->local.finalized) |
972 cgraph_mark_needed_node (node); | 875 cgraph_mark_needed_node (node); |
973 } | 876 } |
877 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)) | |
878 && node->local.finalized) | |
879 { | |
880 warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes, | |
881 "%<weakref%> attribute ignored" | |
882 " because function is defined"); | |
883 DECL_WEAK (decl) = 0; | |
884 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref", | |
885 DECL_ATTRIBUTES (decl)); | |
886 } | |
887 process_common_attributes (decl); | |
974 } | 888 } |
975 for (vnode = varpool_nodes; vnode != first_var; vnode = vnode->next) | 889 for (vnode = varpool_nodes; vnode != first_var; vnode = vnode->next) |
976 { | 890 { |
977 tree decl = vnode->decl; | 891 tree decl = vnode->decl; |
978 if (DECL_PRESERVE_P (decl)) | 892 if (DECL_PRESERVE_P (decl)) |
979 { | 893 { |
980 vnode->force_output = true; | 894 vnode->force_output = true; |
981 if (vnode->finalized) | 895 if (vnode->finalized) |
982 varpool_mark_needed_node (vnode); | 896 varpool_mark_needed_node (vnode); |
983 } | 897 } |
984 if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl))) | 898 if (TARGET_DLLIMPORT_DECL_ATTRIBUTES |
899 && lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)) | |
900 && TREE_PUBLIC (vnode->decl)) | |
901 { | |
902 if (vnode->finalized) | |
903 varpool_mark_needed_node (vnode); | |
904 } | |
905 else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl))) | |
985 { | 906 { |
986 if (! TREE_PUBLIC (vnode->decl)) | 907 if (! TREE_PUBLIC (vnode->decl)) |
987 warning_at (DECL_SOURCE_LOCATION (vnode->decl), OPT_Wattributes, | 908 warning_at (DECL_SOURCE_LOCATION (vnode->decl), OPT_Wattributes, |
988 "%<externally_visible%>" | 909 "%<externally_visible%>" |
989 " attribute have effect only on public objects"); | 910 " attribute have effect only on public objects"); |
990 else if (vnode->finalized) | 911 else if (vnode->finalized) |
991 varpool_mark_needed_node (vnode); | 912 varpool_mark_needed_node (vnode); |
992 } | 913 } |
914 if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)) | |
915 && vnode->finalized | |
916 && DECL_INITIAL (decl)) | |
917 { | |
918 warning_at (DECL_SOURCE_LOCATION (vnode->decl), OPT_Wattributes, | |
919 "%<weakref%> attribute ignored" | |
920 " because variable is initialized"); | |
921 DECL_WEAK (decl) = 0; | |
922 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref", | |
923 DECL_ATTRIBUTES (decl)); | |
924 } | |
925 process_common_attributes (decl); | |
993 } | 926 } |
994 } | 927 } |
995 | 928 |
996 /* Process CGRAPH_NODES_NEEDED queue, analyze each function (and transitively | 929 /* Process CGRAPH_NODES_NEEDED queue, analyze each function (and transitively |
997 each reachable functions) and build cgraph. | 930 each reachable functions) and build cgraph. |
1006 static struct cgraph_node *first_analyzed; | 939 static struct cgraph_node *first_analyzed; |
1007 struct cgraph_node *first_processed = first_analyzed; | 940 struct cgraph_node *first_processed = first_analyzed; |
1008 static struct varpool_node *first_analyzed_var; | 941 static struct varpool_node *first_analyzed_var; |
1009 struct cgraph_node *node, *next; | 942 struct cgraph_node *node, *next; |
1010 | 943 |
944 bitmap_obstack_initialize (NULL); | |
1011 process_function_and_variable_attributes (first_processed, | 945 process_function_and_variable_attributes (first_processed, |
1012 first_analyzed_var); | 946 first_analyzed_var); |
1013 first_processed = cgraph_nodes; | 947 first_processed = cgraph_nodes; |
1014 first_analyzed_var = varpool_nodes; | 948 first_analyzed_var = varpool_nodes; |
1015 varpool_analyze_pending_decls (); | 949 varpool_analyze_pending_decls (); |
1086 for (node = cgraph_nodes; node != first_analyzed; node = node->next) | 1020 for (node = cgraph_nodes; node != first_analyzed; node = node->next) |
1087 if (node->needed) | 1021 if (node->needed) |
1088 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node)); | 1022 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node)); |
1089 fprintf (cgraph_dump_file, "\n\nInitial "); | 1023 fprintf (cgraph_dump_file, "\n\nInitial "); |
1090 dump_cgraph (cgraph_dump_file); | 1024 dump_cgraph (cgraph_dump_file); |
1025 dump_varpool (cgraph_dump_file); | |
1091 } | 1026 } |
1092 | 1027 |
1093 if (cgraph_dump_file) | 1028 if (cgraph_dump_file) |
1094 fprintf (cgraph_dump_file, "\nReclaiming functions:"); | 1029 fprintf (cgraph_dump_file, "\nReclaiming functions:"); |
1095 | 1030 |
1115 } | 1050 } |
1116 if (cgraph_dump_file) | 1051 if (cgraph_dump_file) |
1117 { | 1052 { |
1118 fprintf (cgraph_dump_file, "\n\nReclaimed "); | 1053 fprintf (cgraph_dump_file, "\n\nReclaimed "); |
1119 dump_cgraph (cgraph_dump_file); | 1054 dump_cgraph (cgraph_dump_file); |
1120 } | 1055 dump_varpool (cgraph_dump_file); |
1056 } | |
1057 bitmap_obstack_release (NULL); | |
1121 first_analyzed = cgraph_nodes; | 1058 first_analyzed = cgraph_nodes; |
1122 ggc_collect (); | 1059 ggc_collect (); |
1123 } | 1060 } |
1124 | 1061 |
1125 | 1062 |
1133 /* Do not skip analyzing the functions if there were errors, we | 1070 /* Do not skip analyzing the functions if there were errors, we |
1134 miss diagnostics for following functions otherwise. */ | 1071 miss diagnostics for following functions otherwise. */ |
1135 | 1072 |
1136 /* Emit size functions we didn't inline. */ | 1073 /* Emit size functions we didn't inline. */ |
1137 finalize_size_functions (); | 1074 finalize_size_functions (); |
1138 | |
1139 /* Call functions declared with the "constructor" or "destructor" | |
1140 attribute. */ | |
1141 cgraph_build_cdtor_fns (); | |
1142 | 1075 |
1143 /* Mark alias targets necessary and emit diagnostics. */ | 1076 /* Mark alias targets necessary and emit diagnostics. */ |
1144 finish_aliases_1 (); | 1077 finish_aliases_1 (); |
1145 | 1078 |
1146 if (!quiet_flag) | 1079 if (!quiet_flag) |
1195 /* We need to output all local functions that are used and not | 1128 /* We need to output all local functions that are used and not |
1196 always inlined, as well as those that are reachable from | 1129 always inlined, as well as those that are reachable from |
1197 outside the current compilation unit. */ | 1130 outside the current compilation unit. */ |
1198 if (node->analyzed | 1131 if (node->analyzed |
1199 && !node->global.inlined_to | 1132 && !node->global.inlined_to |
1200 && (node->needed || node->reachable_from_other_partition | 1133 && (!cgraph_only_called_directly_p (node) |
1201 || node->address_taken | |
1202 || (e && node->reachable)) | 1134 || (e && node->reachable)) |
1203 && !TREE_ASM_WRITTEN (decl) | 1135 && !TREE_ASM_WRITTEN (decl) |
1204 && !DECL_EXTERNAL (decl)) | 1136 && !DECL_EXTERNAL (decl)) |
1205 { | 1137 { |
1206 node->process = 1; | 1138 node->process = 1; |
1354 | 1286 |
1355 /* Form the vtable address. */ | 1287 /* Form the vtable address. */ |
1356 vtabletmp2 = create_tmp_var (TREE_TYPE (TREE_TYPE (vtabletmp)), | 1288 vtabletmp2 = create_tmp_var (TREE_TYPE (TREE_TYPE (vtabletmp)), |
1357 "vtableaddr"); | 1289 "vtableaddr"); |
1358 stmt = gimple_build_assign (vtabletmp2, | 1290 stmt = gimple_build_assign (vtabletmp2, |
1359 build1 (INDIRECT_REF, | 1291 build_simple_mem_ref (vtabletmp)); |
1360 TREE_TYPE (vtabletmp2), vtabletmp)); | |
1361 gsi_insert_after (bsi, stmt, GSI_NEW_STMT); | 1292 gsi_insert_after (bsi, stmt, GSI_NEW_STMT); |
1362 mark_symbols_for_renaming (stmt); | 1293 mark_symbols_for_renaming (stmt); |
1363 find_referenced_vars_in (stmt); | 1294 find_referenced_vars_in (stmt); |
1364 | 1295 |
1365 /* Find the entry with the vcall offset. */ | 1296 /* Find the entry with the vcall offset. */ |
1374 | 1305 |
1375 /* Get the offset itself. */ | 1306 /* Get the offset itself. */ |
1376 vtabletmp3 = create_tmp_var (TREE_TYPE (TREE_TYPE (vtabletmp2)), | 1307 vtabletmp3 = create_tmp_var (TREE_TYPE (TREE_TYPE (vtabletmp2)), |
1377 "vcalloffset"); | 1308 "vcalloffset"); |
1378 stmt = gimple_build_assign (vtabletmp3, | 1309 stmt = gimple_build_assign (vtabletmp3, |
1379 build1 (INDIRECT_REF, | 1310 build_simple_mem_ref (vtabletmp2)); |
1380 TREE_TYPE (vtabletmp3), | |
1381 vtabletmp2)); | |
1382 gsi_insert_after (bsi, stmt, GSI_NEW_STMT); | 1311 gsi_insert_after (bsi, stmt, GSI_NEW_STMT); |
1383 mark_symbols_for_renaming (stmt); | 1312 mark_symbols_for_renaming (stmt); |
1384 find_referenced_vars_in (stmt); | 1313 find_referenced_vars_in (stmt); |
1385 | 1314 |
1386 /* Cast to sizetype. */ | 1315 /* Cast to sizetype. */ |
1440 tree thunk_fndecl = node->decl; | 1369 tree thunk_fndecl = node->decl; |
1441 tree a = DECL_ARGUMENTS (thunk_fndecl); | 1370 tree a = DECL_ARGUMENTS (thunk_fndecl); |
1442 | 1371 |
1443 current_function_decl = thunk_fndecl; | 1372 current_function_decl = thunk_fndecl; |
1444 | 1373 |
1374 /* Ensure thunks are emitted in their correct sections. */ | |
1375 resolve_unique_section (thunk_fndecl, 0, flag_function_sections); | |
1376 | |
1445 if (this_adjusting | 1377 if (this_adjusting |
1446 && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset, | 1378 && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset, |
1447 virtual_value, alias)) | 1379 virtual_value, alias)) |
1448 { | 1380 { |
1449 const char *fnname; | 1381 const char *fnname; |
1513 if (!VOID_TYPE_P (restype)) | 1445 if (!VOID_TYPE_P (restype)) |
1514 { | 1446 { |
1515 if (!is_gimple_reg_type (restype)) | 1447 if (!is_gimple_reg_type (restype)) |
1516 { | 1448 { |
1517 restmp = resdecl; | 1449 restmp = resdecl; |
1518 cfun->local_decls = tree_cons (NULL_TREE, restmp, cfun->local_decls); | 1450 add_local_decl (cfun, restmp); |
1519 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp; | 1451 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp; |
1520 } | 1452 } |
1521 else | 1453 else |
1522 restmp = create_tmp_var_raw (restype, "retval"); | 1454 restmp = create_tmp_var_raw (restype, "retval"); |
1523 } | 1455 } |
1524 | 1456 |
1525 for (arg = a; arg; arg = TREE_CHAIN (arg)) | 1457 for (arg = a; arg; arg = DECL_CHAIN (arg)) |
1526 nargs++; | 1458 nargs++; |
1527 vargs = VEC_alloc (tree, heap, nargs); | 1459 vargs = VEC_alloc (tree, heap, nargs); |
1528 if (this_adjusting) | 1460 if (this_adjusting) |
1529 VEC_quick_push (tree, vargs, | 1461 VEC_quick_push (tree, vargs, |
1530 thunk_adjust (&bsi, | 1462 thunk_adjust (&bsi, |
1531 a, 1, fixed_offset, | 1463 a, 1, fixed_offset, |
1532 virtual_offset)); | 1464 virtual_offset)); |
1533 else | 1465 else |
1534 VEC_quick_push (tree, vargs, a); | 1466 VEC_quick_push (tree, vargs, a); |
1535 for (i = 1, arg = TREE_CHAIN (a); i < nargs; i++, arg = TREE_CHAIN (arg)) | 1467 for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg)) |
1536 VEC_quick_push (tree, vargs, arg); | 1468 VEC_quick_push (tree, vargs, arg); |
1537 call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs); | 1469 call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs); |
1538 VEC_free (tree, heap, vargs); | 1470 VEC_free (tree, heap, vargs); |
1539 gimple_call_set_cannot_inline (call, true); | 1471 gimple_call_set_cannot_inline (call, true); |
1540 gimple_call_set_from_thunk (call, true); | 1472 gimple_call_set_from_thunk (call, true); |
1560 return_bb = create_basic_block (NULL, (void *) 0, then_bb); | 1492 return_bb = create_basic_block (NULL, (void *) 0, then_bb); |
1561 else_bb = create_basic_block (NULL, (void *) 0, else_bb); | 1493 else_bb = create_basic_block (NULL, (void *) 0, else_bb); |
1562 remove_edge (single_succ_edge (bb)); | 1494 remove_edge (single_succ_edge (bb)); |
1563 true_label = gimple_block_label (then_bb); | 1495 true_label = gimple_block_label (then_bb); |
1564 stmt = gimple_build_cond (NE_EXPR, restmp, | 1496 stmt = gimple_build_cond (NE_EXPR, restmp, |
1565 fold_convert (TREE_TYPE (restmp), | 1497 build_zero_cst (TREE_TYPE (restmp)), |
1566 integer_zero_node), | |
1567 NULL_TREE, NULL_TREE); | 1498 NULL_TREE, NULL_TREE); |
1568 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT); | 1499 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT); |
1569 make_edge (bb, then_bb, EDGE_TRUE_VALUE); | 1500 make_edge (bb, then_bb, EDGE_TRUE_VALUE); |
1570 make_edge (bb, else_bb, EDGE_FALSE_VALUE); | 1501 make_edge (bb, else_bb, EDGE_FALSE_VALUE); |
1571 make_edge (return_bb, EXIT_BLOCK_PTR, 0); | 1502 make_edge (return_bb, EXIT_BLOCK_PTR, 0); |
1578 fixed_offset, virtual_offset); | 1509 fixed_offset, virtual_offset); |
1579 if (true_label) | 1510 if (true_label) |
1580 { | 1511 { |
1581 gimple stmt; | 1512 gimple stmt; |
1582 bsi = gsi_last_bb (else_bb); | 1513 bsi = gsi_last_bb (else_bb); |
1583 stmt = gimple_build_assign (restmp, fold_convert (TREE_TYPE (restmp), | 1514 stmt = gimple_build_assign (restmp, |
1584 integer_zero_node)); | 1515 build_zero_cst (TREE_TYPE (restmp))); |
1585 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT); | 1516 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT); |
1586 bsi = gsi_last_bb (return_bb); | 1517 bsi = gsi_last_bb (return_bb); |
1587 } | 1518 } |
1588 } | 1519 } |
1589 else | 1520 else |
1615 /* We ought to not compile any inline clones. */ | 1546 /* We ought to not compile any inline clones. */ |
1616 gcc_assert (!node->global.inlined_to); | 1547 gcc_assert (!node->global.inlined_to); |
1617 | 1548 |
1618 announce_function (decl); | 1549 announce_function (decl); |
1619 node->process = 0; | 1550 node->process = 0; |
1620 | |
1621 gcc_assert (node->lowered); | |
1622 | |
1623 /* Generate RTL for the body of DECL. */ | |
1624 tree_rest_of_compilation (decl); | |
1625 | |
1626 /* Make sure that BE didn't give up on compiling. */ | |
1627 gcc_assert (TREE_ASM_WRITTEN (decl)); | |
1628 current_function_decl = NULL; | |
1629 if (node->same_body) | 1551 if (node->same_body) |
1630 { | 1552 { |
1631 struct cgraph_node *alias, *next; | 1553 struct cgraph_node *alias, *next; |
1632 bool saved_alias = node->alias; | 1554 bool saved_alias = node->alias; |
1633 for (alias = node->same_body; | 1555 for (alias = node->same_body; |
1634 alias && alias->next; alias = alias->next) | 1556 alias && alias->next; alias = alias->next) |
1635 ; | 1557 ; |
1636 /* Walk aliases in the order they were created; it is possible that | 1558 /* Walk aliases in the order they were created; it is possible that |
1637 thunks reffers to the aliases made earlier. */ | 1559 thunks refers to the aliases made earlier. */ |
1638 for (; alias; alias = next) | 1560 for (; alias; alias = next) |
1639 { | 1561 { |
1640 next = alias->previous; | 1562 next = alias->previous; |
1641 if (!alias->thunk.thunk_p) | 1563 if (!alias->thunk.thunk_p) |
1642 assemble_alias (alias->decl, | 1564 assemble_alias (alias->decl, |
1643 DECL_ASSEMBLER_NAME (alias->thunk.alias)); | 1565 DECL_ASSEMBLER_NAME (alias->thunk.alias)); |
1644 else | 1566 else |
1645 assemble_thunk (alias); | 1567 assemble_thunk (alias); |
1646 } | 1568 } |
1647 node->alias = saved_alias; | 1569 node->alias = saved_alias; |
1648 } | 1570 cgraph_process_new_functions (); |
1571 } | |
1572 | |
1573 gcc_assert (node->lowered); | |
1574 | |
1575 /* Generate RTL for the body of DECL. */ | |
1576 tree_rest_of_compilation (decl); | |
1577 | |
1578 /* Make sure that BE didn't give up on compiling. */ | |
1579 gcc_assert (TREE_ASM_WRITTEN (decl)); | |
1580 current_function_decl = NULL; | |
1649 gcc_assert (!cgraph_preserve_function_body_p (decl)); | 1581 gcc_assert (!cgraph_preserve_function_body_p (decl)); |
1650 cgraph_release_function_body (node); | 1582 cgraph_release_function_body (node); |
1651 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer | 1583 /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer |
1652 points to the dead function body. */ | 1584 points to the dead function body. */ |
1653 cgraph_node_remove_callees (node); | 1585 cgraph_node_remove_callees (node); |
1787 } | 1719 } |
1788 } | 1720 } |
1789 varpool_empty_needed_queue (); | 1721 varpool_empty_needed_queue (); |
1790 | 1722 |
1791 for (i = 0; i < max; ++i) | 1723 for (i = 0; i < max; ++i) |
1724 if (nodes[i].kind == ORDER_VAR) | |
1725 varpool_finalize_named_section_flags (nodes[i].u.v); | |
1726 | |
1727 for (i = 0; i < max; ++i) | |
1792 { | 1728 { |
1793 switch (nodes[i].kind) | 1729 switch (nodes[i].kind) |
1794 { | 1730 { |
1795 case ORDER_FUNCTION: | 1731 case ORDER_FUNCTION: |
1796 nodes[i].u.f->process = 0; | 1732 nodes[i].u.f->process = 0; |
1841 bitmap_obstack_initialize (NULL); | 1777 bitmap_obstack_initialize (NULL); |
1842 | 1778 |
1843 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL); | 1779 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_START, NULL); |
1844 | 1780 |
1845 if (!in_lto_p) | 1781 if (!in_lto_p) |
1846 execute_ipa_pass_list (all_small_ipa_passes); | 1782 { |
1783 execute_ipa_pass_list (all_small_ipa_passes); | |
1784 if (seen_error ()) | |
1785 return; | |
1786 } | |
1847 | 1787 |
1848 /* If pass_all_early_optimizations was not scheduled, the state of | 1788 /* If pass_all_early_optimizations was not scheduled, the state of |
1849 the cgraph will not be properly updated. Update it now. */ | 1789 the cgraph will not be properly updated. Update it now. */ |
1850 if (cgraph_state < CGRAPH_STATE_IPA_SSA) | 1790 if (cgraph_state < CGRAPH_STATE_IPA_SSA) |
1851 cgraph_state = CGRAPH_STATE_IPA_SSA; | 1791 cgraph_state = CGRAPH_STATE_IPA_SSA; |
1887 /* Perform simple optimizations based on callgraph. */ | 1827 /* Perform simple optimizations based on callgraph. */ |
1888 | 1828 |
1889 void | 1829 void |
1890 cgraph_optimize (void) | 1830 cgraph_optimize (void) |
1891 { | 1831 { |
1892 if (errorcount || sorrycount) | 1832 if (seen_error ()) |
1893 return; | 1833 return; |
1894 | 1834 |
1895 #ifdef ENABLE_CHECKING | 1835 #ifdef ENABLE_CHECKING |
1896 verify_cgraph (); | 1836 verify_cgraph (); |
1897 #endif | 1837 #endif |
1909 if (!quiet_flag) | 1849 if (!quiet_flag) |
1910 fprintf (stderr, "Performing interprocedural optimizations\n"); | 1850 fprintf (stderr, "Performing interprocedural optimizations\n"); |
1911 cgraph_state = CGRAPH_STATE_IPA; | 1851 cgraph_state = CGRAPH_STATE_IPA; |
1912 | 1852 |
1913 /* Don't run the IPA passes if there was any error or sorry messages. */ | 1853 /* Don't run the IPA passes if there was any error or sorry messages. */ |
1914 if (errorcount == 0 && sorrycount == 0) | 1854 if (!seen_error ()) |
1915 ipa_passes (); | 1855 ipa_passes (); |
1916 | 1856 |
1917 /* Do nothing else if any IPA pass found errors. */ | 1857 /* Do nothing else if any IPA pass found errors. */ |
1918 if (errorcount || sorrycount) | 1858 if (seen_error ()) |
1919 { | 1859 { |
1920 timevar_pop (TV_CGRAPHOPT); | 1860 timevar_pop (TV_CGRAPHOPT); |
1921 return; | 1861 return; |
1922 } | 1862 } |
1923 | 1863 |
1966 | 1906 |
1967 if (cgraph_dump_file) | 1907 if (cgraph_dump_file) |
1968 { | 1908 { |
1969 fprintf (cgraph_dump_file, "\nFinal "); | 1909 fprintf (cgraph_dump_file, "\nFinal "); |
1970 dump_cgraph (cgraph_dump_file); | 1910 dump_cgraph (cgraph_dump_file); |
1911 dump_varpool (cgraph_dump_file); | |
1971 } | 1912 } |
1972 #ifdef ENABLE_CHECKING | 1913 #ifdef ENABLE_CHECKING |
1973 verify_cgraph (); | 1914 verify_cgraph (); |
1974 /* Double check that all inline clones are gone and that all | 1915 /* Double check that all inline clones are gone and that all |
1975 function bodies have been released from memory. */ | 1916 function bodies have been released from memory. */ |
1976 if (!(sorrycount || errorcount)) | 1917 if (!seen_error ()) |
1977 { | 1918 { |
1978 struct cgraph_node *node; | 1919 struct cgraph_node *node; |
1979 bool error_found = false; | 1920 bool error_found = false; |
1980 | 1921 |
1981 for (node = cgraph_nodes; node; node = node->next) | 1922 for (node = cgraph_nodes; node; node = node->next) |
1990 internal_error ("nodes with unreleased memory found"); | 1931 internal_error ("nodes with unreleased memory found"); |
1991 } | 1932 } |
1992 #endif | 1933 #endif |
1993 } | 1934 } |
1994 | 1935 |
1995 | |
1996 /* Generate and emit a static constructor or destructor. WHICH must | |
1997 be one of 'I' (for a constructor) or 'D' (for a destructor). BODY | |
1998 is a STATEMENT_LIST containing GENERIC statements. PRIORITY is the | |
1999 initialization priority for this constructor or destructor. */ | |
2000 | |
2001 void | |
2002 cgraph_build_static_cdtor (char which, tree body, int priority) | |
2003 { | |
2004 static int counter = 0; | |
2005 char which_buf[16]; | |
2006 tree decl, name, resdecl; | |
2007 | |
2008 /* The priority is encoded in the constructor or destructor name. | |
2009 collect2 will sort the names and arrange that they are called at | |
2010 program startup. */ | |
2011 sprintf (which_buf, "%c_%.5d_%d", which, priority, counter++); | |
2012 name = get_file_function_name (which_buf); | |
2013 | |
2014 decl = build_decl (input_location, FUNCTION_DECL, name, | |
2015 build_function_type (void_type_node, void_list_node)); | |
2016 current_function_decl = decl; | |
2017 | |
2018 resdecl = build_decl (input_location, | |
2019 RESULT_DECL, NULL_TREE, void_type_node); | |
2020 DECL_ARTIFICIAL (resdecl) = 1; | |
2021 DECL_RESULT (decl) = resdecl; | |
2022 DECL_CONTEXT (resdecl) = decl; | |
2023 | |
2024 allocate_struct_function (decl, false); | |
2025 | |
2026 TREE_STATIC (decl) = 1; | |
2027 TREE_USED (decl) = 1; | |
2028 DECL_ARTIFICIAL (decl) = 1; | |
2029 DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1; | |
2030 DECL_SAVED_TREE (decl) = body; | |
2031 if (!targetm.have_ctors_dtors) | |
2032 { | |
2033 TREE_PUBLIC (decl) = 1; | |
2034 DECL_PRESERVE_P (decl) = 1; | |
2035 } | |
2036 DECL_UNINLINABLE (decl) = 1; | |
2037 | |
2038 DECL_INITIAL (decl) = make_node (BLOCK); | |
2039 TREE_USED (DECL_INITIAL (decl)) = 1; | |
2040 | |
2041 DECL_SOURCE_LOCATION (decl) = input_location; | |
2042 cfun->function_end_locus = input_location; | |
2043 | |
2044 switch (which) | |
2045 { | |
2046 case 'I': | |
2047 DECL_STATIC_CONSTRUCTOR (decl) = 1; | |
2048 decl_init_priority_insert (decl, priority); | |
2049 break; | |
2050 case 'D': | |
2051 DECL_STATIC_DESTRUCTOR (decl) = 1; | |
2052 decl_fini_priority_insert (decl, priority); | |
2053 break; | |
2054 default: | |
2055 gcc_unreachable (); | |
2056 } | |
2057 | |
2058 gimplify_function_tree (decl); | |
2059 | |
2060 cgraph_add_new_function (decl, false); | |
2061 cgraph_mark_needed_node (cgraph_node (decl)); | |
2062 set_cfun (NULL); | |
2063 } | |
2064 | |
2065 void | 1936 void |
2066 init_cgraph (void) | 1937 init_cgraph (void) |
2067 { | 1938 { |
2068 cgraph_dump_file = dump_begin (TDI_cgraph, NULL); | 1939 if (!cgraph_dump_file) |
1940 cgraph_dump_file = dump_begin (TDI_cgraph, NULL); | |
2069 } | 1941 } |
2070 | 1942 |
2071 /* The edges representing the callers of the NEW_VERSION node were | 1943 /* The edges representing the callers of the NEW_VERSION node were |
2072 fixed by cgraph_function_versioning (), now the call_expr in their | 1944 fixed by cgraph_function_versioning (), now the call_expr in their |
2073 respective tree code should be updated to call the NEW_VERSION. */ | 1945 respective tree code should be updated to call the NEW_VERSION. */ |
2092 /* Create a new cgraph node which is the new version of | 1964 /* Create a new cgraph node which is the new version of |
2093 OLD_VERSION node. REDIRECT_CALLERS holds the callers | 1965 OLD_VERSION node. REDIRECT_CALLERS holds the callers |
2094 edges which should be redirected to point to | 1966 edges which should be redirected to point to |
2095 NEW_VERSION. ALL the callees edges of OLD_VERSION | 1967 NEW_VERSION. ALL the callees edges of OLD_VERSION |
2096 are cloned to the new version node. Return the new | 1968 are cloned to the new version node. Return the new |
2097 version node. */ | 1969 version node. |
1970 | |
1971 If non-NULL BLOCK_TO_COPY determine what basic blocks | |
1972 was copied to prevent duplications of calls that are dead | |
1973 in the clone. */ | |
2098 | 1974 |
2099 static struct cgraph_node * | 1975 static struct cgraph_node * |
2100 cgraph_copy_node_for_versioning (struct cgraph_node *old_version, | 1976 cgraph_copy_node_for_versioning (struct cgraph_node *old_version, |
2101 tree new_decl, | 1977 tree new_decl, |
2102 VEC(cgraph_edge_p,heap) *redirect_callers) | 1978 VEC(cgraph_edge_p,heap) *redirect_callers, |
1979 bitmap bbs_to_copy) | |
2103 { | 1980 { |
2104 struct cgraph_node *new_version; | 1981 struct cgraph_node *new_version; |
2105 struct cgraph_edge *e; | 1982 struct cgraph_edge *e; |
2106 struct cgraph_edge *next_callee; | |
2107 unsigned i; | 1983 unsigned i; |
2108 | 1984 |
2109 gcc_assert (old_version); | 1985 gcc_assert (old_version); |
2110 | 1986 |
2111 new_version = cgraph_node (new_decl); | 1987 new_version = cgraph_node (new_decl); |
2112 | 1988 |
2113 new_version->analyzed = true; | 1989 new_version->analyzed = true; |
2114 new_version->local = old_version->local; | 1990 new_version->local = old_version->local; |
1991 new_version->local.externally_visible = false; | |
1992 new_version->local.local = true; | |
1993 new_version->local.vtable_method = false; | |
2115 new_version->global = old_version->global; | 1994 new_version->global = old_version->global; |
2116 new_version->rtl = new_version->rtl; | 1995 new_version->rtl = old_version->rtl; |
2117 new_version->reachable = true; | 1996 new_version->reachable = true; |
2118 new_version->count = old_version->count; | 1997 new_version->count = old_version->count; |
2119 | 1998 |
2120 /* Clone the old node callees. Recursive calls are | 1999 for (e = old_version->callees; e; e=e->next_callee) |
2121 also cloned. */ | 2000 if (!bbs_to_copy |
2122 for (e = old_version->callees;e; e=e->next_callee) | 2001 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index)) |
2123 { | |
2124 cgraph_clone_edge (e, new_version, e->call_stmt, | 2002 cgraph_clone_edge (e, new_version, e->call_stmt, |
2125 e->lto_stmt_uid, REG_BR_PROB_BASE, | 2003 e->lto_stmt_uid, REG_BR_PROB_BASE, |
2126 CGRAPH_FREQ_BASE, | 2004 CGRAPH_FREQ_BASE, |
2127 e->loop_nest, true); | 2005 e->loop_nest, true); |
2128 } | 2006 for (e = old_version->indirect_calls; e; e=e->next_callee) |
2129 /* Fix recursive calls. | 2007 if (!bbs_to_copy |
2130 If OLD_VERSION has a recursive call after the | 2008 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index)) |
2131 previous edge cloning, the new version will have an edge | 2009 cgraph_clone_edge (e, new_version, e->call_stmt, |
2132 pointing to the old version, which is wrong; | 2010 e->lto_stmt_uid, REG_BR_PROB_BASE, |
2133 Redirect it to point to the new version. */ | 2011 CGRAPH_FREQ_BASE, |
2134 for (e = new_version->callees ; e; e = next_callee) | 2012 e->loop_nest, true); |
2135 { | 2013 FOR_EACH_VEC_ELT (cgraph_edge_p, redirect_callers, i, e) |
2136 next_callee = e->next_callee; | |
2137 if (e->callee == old_version) | |
2138 cgraph_redirect_edge_callee (e, new_version); | |
2139 | |
2140 if (!next_callee) | |
2141 break; | |
2142 } | |
2143 for (i = 0; VEC_iterate (cgraph_edge_p, redirect_callers, i, e); i++) | |
2144 { | 2014 { |
2145 /* Redirect calls to the old version node to point to its new | 2015 /* Redirect calls to the old version node to point to its new |
2146 version. */ | 2016 version. */ |
2147 cgraph_redirect_edge_callee (e, new_version); | 2017 cgraph_redirect_edge_callee (e, new_version); |
2148 } | 2018 } |
2160 | 2030 |
2161 TREE_MAP is a mapping of tree nodes we want to replace with | 2031 TREE_MAP is a mapping of tree nodes we want to replace with |
2162 new ones (according to results of prior analysis). | 2032 new ones (according to results of prior analysis). |
2163 OLD_VERSION_NODE is the node that is versioned. | 2033 OLD_VERSION_NODE is the node that is versioned. |
2164 It returns the new version's cgraph node. | 2034 It returns the new version's cgraph node. |
2165 ARGS_TO_SKIP lists arguments to be omitted from functions | 2035 If non-NULL ARGS_TO_SKIP determine function parameters to remove |
2166 */ | 2036 from new version. |
2037 If non-NULL BLOCK_TO_COPY determine what basic blocks to copy. | |
2038 If non_NULL NEW_ENTRY determine new entry BB of the clone. */ | |
2167 | 2039 |
2168 struct cgraph_node * | 2040 struct cgraph_node * |
2169 cgraph_function_versioning (struct cgraph_node *old_version_node, | 2041 cgraph_function_versioning (struct cgraph_node *old_version_node, |
2170 VEC(cgraph_edge_p,heap) *redirect_callers, | 2042 VEC(cgraph_edge_p,heap) *redirect_callers, |
2171 VEC (ipa_replace_map_p,gc)* tree_map, | 2043 VEC (ipa_replace_map_p,gc)* tree_map, |
2172 bitmap args_to_skip) | 2044 bitmap args_to_skip, |
2045 bitmap bbs_to_copy, | |
2046 basic_block new_entry_block, | |
2047 const char *clone_name) | |
2173 { | 2048 { |
2174 tree old_decl = old_version_node->decl; | 2049 tree old_decl = old_version_node->decl; |
2175 struct cgraph_node *new_version_node = NULL; | 2050 struct cgraph_node *new_version_node = NULL; |
2176 tree new_decl; | 2051 tree new_decl; |
2177 | 2052 |
2178 if (!tree_versionable_function_p (old_decl)) | 2053 if (!tree_versionable_function_p (old_decl)) |
2179 return NULL; | 2054 return NULL; |
2055 | |
2056 gcc_assert (old_version_node->local.can_change_signature || !args_to_skip); | |
2180 | 2057 |
2181 /* Make a new FUNCTION_DECL tree node for the | 2058 /* Make a new FUNCTION_DECL tree node for the |
2182 new version. */ | 2059 new version. */ |
2183 if (!args_to_skip) | 2060 if (!args_to_skip) |
2184 new_decl = copy_node (old_decl); | 2061 new_decl = copy_node (old_decl); |
2185 else | 2062 else |
2186 new_decl = build_function_decl_skip_args (old_decl, args_to_skip); | 2063 new_decl = build_function_decl_skip_args (old_decl, args_to_skip); |
2187 | 2064 |
2065 /* Generate a new name for the new version. */ | |
2066 DECL_NAME (new_decl) = clone_function_name (old_decl, clone_name); | |
2067 SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl)); | |
2068 SET_DECL_RTL (new_decl, NULL); | |
2069 | |
2188 /* Create the new version's call-graph node. | 2070 /* Create the new version's call-graph node. |
2189 and update the edges of the new node. */ | 2071 and update the edges of the new node. */ |
2190 new_version_node = | 2072 new_version_node = |
2191 cgraph_copy_node_for_versioning (old_version_node, new_decl, | 2073 cgraph_copy_node_for_versioning (old_version_node, new_decl, |
2192 redirect_callers); | 2074 redirect_callers, bbs_to_copy); |
2193 | 2075 |
2194 /* Copy the OLD_VERSION_NODE function tree to the new version. */ | 2076 /* Copy the OLD_VERSION_NODE function tree to the new version. */ |
2195 tree_function_versioning (old_decl, new_decl, tree_map, false, args_to_skip); | 2077 tree_function_versioning (old_decl, new_decl, tree_map, false, args_to_skip, |
2078 bbs_to_copy, new_entry_block); | |
2196 | 2079 |
2197 /* Update the new version's properties. | 2080 /* Update the new version's properties. |
2198 Make The new version visible only within this translation unit. Make sure | 2081 Make The new version visible only within this translation unit. Make sure |
2199 that is not weak also. | 2082 that is not weak also. |
2200 ??? We cannot use COMDAT linkage because there is no | 2083 ??? We cannot use COMDAT linkage because there is no |
2261 n = n->next_sibling_clone; | 2144 n = n->next_sibling_clone; |
2262 } | 2145 } |
2263 } | 2146 } |
2264 | 2147 |
2265 /* Copy the OLD_VERSION_NODE function tree to the new version. */ | 2148 /* Copy the OLD_VERSION_NODE function tree to the new version. */ |
2266 tree_function_versioning (node->decl, first_clone->decl, NULL, true, NULL); | 2149 tree_function_versioning (node->decl, first_clone->decl, NULL, true, NULL, |
2150 NULL, NULL); | |
2267 | 2151 |
2268 DECL_EXTERNAL (first_clone->decl) = 0; | 2152 DECL_EXTERNAL (first_clone->decl) = 0; |
2269 DECL_COMDAT_GROUP (first_clone->decl) = NULL_TREE; | 2153 DECL_COMDAT_GROUP (first_clone->decl) = NULL_TREE; |
2270 TREE_PUBLIC (first_clone->decl) = 0; | 2154 TREE_PUBLIC (first_clone->decl) = 0; |
2271 DECL_COMDAT (first_clone->decl) = 0; | 2155 DECL_COMDAT (first_clone->decl) = 0; |
2282 /* Given virtual clone, turn it into actual clone. */ | 2166 /* Given virtual clone, turn it into actual clone. */ |
2283 static void | 2167 static void |
2284 cgraph_materialize_clone (struct cgraph_node *node) | 2168 cgraph_materialize_clone (struct cgraph_node *node) |
2285 { | 2169 { |
2286 bitmap_obstack_initialize (NULL); | 2170 bitmap_obstack_initialize (NULL); |
2171 node->former_clone_of = node->clone_of->decl; | |
2172 if (node->clone_of->former_clone_of) | |
2173 node->former_clone_of = node->clone_of->former_clone_of; | |
2287 /* Copy the OLD_VERSION_NODE function tree to the new version. */ | 2174 /* Copy the OLD_VERSION_NODE function tree to the new version. */ |
2288 tree_function_versioning (node->clone_of->decl, node->decl, | 2175 tree_function_versioning (node->clone_of->decl, node->decl, |
2289 node->clone.tree_map, true, | 2176 node->clone.tree_map, true, |
2290 node->clone.args_to_skip); | 2177 node->clone.args_to_skip, NULL, NULL); |
2291 if (cgraph_dump_file) | 2178 if (cgraph_dump_file) |
2292 { | 2179 { |
2293 dump_function_to_file (node->clone_of->decl, cgraph_dump_file, dump_flags); | 2180 dump_function_to_file (node->clone_of->decl, cgraph_dump_file, dump_flags); |
2294 dump_function_to_file (node->decl, cgraph_dump_file, dump_flags); | 2181 dump_function_to_file (node->decl, cgraph_dump_file, dump_flags); |
2295 } | 2182 } |
2302 else | 2189 else |
2303 node->clone_of->clones = node->next_sibling_clone; | 2190 node->clone_of->clones = node->next_sibling_clone; |
2304 node->next_sibling_clone = NULL; | 2191 node->next_sibling_clone = NULL; |
2305 node->prev_sibling_clone = NULL; | 2192 node->prev_sibling_clone = NULL; |
2306 if (!node->clone_of->analyzed && !node->clone_of->clones) | 2193 if (!node->clone_of->analyzed && !node->clone_of->clones) |
2307 cgraph_remove_node (node->clone_of); | 2194 { |
2195 cgraph_release_function_body (node->clone_of); | |
2196 cgraph_node_remove_callees (node->clone_of); | |
2197 ipa_remove_all_references (&node->clone_of->ref_list); | |
2198 } | |
2308 node->clone_of = NULL; | 2199 node->clone_of = NULL; |
2309 bitmap_obstack_release (NULL); | 2200 bitmap_obstack_release (NULL); |
2310 } | 2201 } |
2311 | 2202 |
2312 /* If necessary, change the function declaration in the call statement | 2203 /* If necessary, change the function declaration in the call statement |
2316 cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e) | 2207 cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e) |
2317 { | 2208 { |
2318 tree decl = gimple_call_fndecl (e->call_stmt); | 2209 tree decl = gimple_call_fndecl (e->call_stmt); |
2319 gimple new_stmt; | 2210 gimple new_stmt; |
2320 gimple_stmt_iterator gsi; | 2211 gimple_stmt_iterator gsi; |
2321 | 2212 bool gsi_computed = false; |
2322 if (!decl || decl == e->callee->decl | 2213 #ifdef ENABLE_CHECKING |
2214 struct cgraph_node *node; | |
2215 #endif | |
2216 | |
2217 if (e->indirect_unknown_callee | |
2218 || decl == e->callee->decl | |
2323 /* Don't update call from same body alias to the real function. */ | 2219 /* Don't update call from same body alias to the real function. */ |
2324 || cgraph_get_node (decl) == cgraph_get_node (e->callee->decl)) | 2220 || (decl && cgraph_get_node (decl) == cgraph_get_node (e->callee->decl))) |
2325 return e->call_stmt; | 2221 return e->call_stmt; |
2222 | |
2223 #ifdef ENABLE_CHECKING | |
2224 if (decl) | |
2225 { | |
2226 node = cgraph_get_node (decl); | |
2227 gcc_assert (!node || !node->clone.combined_args_to_skip); | |
2228 } | |
2229 #endif | |
2326 | 2230 |
2327 if (cgraph_dump_file) | 2231 if (cgraph_dump_file) |
2328 { | 2232 { |
2329 fprintf (cgraph_dump_file, "updating call of %s/%i -> %s/%i: ", | 2233 fprintf (cgraph_dump_file, "updating call of %s/%i -> %s/%i: ", |
2330 cgraph_node_name (e->caller), e->caller->uid, | 2234 cgraph_node_name (e->caller), e->caller->uid, |
2331 cgraph_node_name (e->callee), e->callee->uid); | 2235 cgraph_node_name (e->callee), e->callee->uid); |
2332 print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags); | 2236 print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags); |
2237 if (e->callee->clone.combined_args_to_skip) | |
2238 { | |
2239 fprintf (cgraph_dump_file, " combined args to skip: "); | |
2240 dump_bitmap (cgraph_dump_file, | |
2241 e->callee->clone.combined_args_to_skip); | |
2242 } | |
2243 } | |
2244 | |
2245 if (e->indirect_info && | |
2246 e->indirect_info->thunk_delta != 0 | |
2247 && (!e->callee->clone.combined_args_to_skip | |
2248 || !bitmap_bit_p (e->callee->clone.combined_args_to_skip, 0))) | |
2249 { | |
2250 if (cgraph_dump_file) | |
2251 fprintf (cgraph_dump_file, " Thunk delta is " | |
2252 HOST_WIDE_INT_PRINT_DEC "\n", e->indirect_info->thunk_delta); | |
2253 gsi = gsi_for_stmt (e->call_stmt); | |
2254 gsi_computed = true; | |
2255 gimple_adjust_this_by_delta (&gsi, | |
2256 build_int_cst (sizetype, | |
2257 e->indirect_info->thunk_delta)); | |
2258 e->indirect_info->thunk_delta = 0; | |
2333 } | 2259 } |
2334 | 2260 |
2335 if (e->callee->clone.combined_args_to_skip) | 2261 if (e->callee->clone.combined_args_to_skip) |
2336 new_stmt = gimple_call_copy_skip_args (e->call_stmt, | 2262 { |
2337 e->callee->clone.combined_args_to_skip); | 2263 int lp_nr; |
2264 | |
2265 new_stmt | |
2266 = gimple_call_copy_skip_args (e->call_stmt, | |
2267 e->callee->clone.combined_args_to_skip); | |
2268 gimple_call_set_fndecl (new_stmt, e->callee->decl); | |
2269 | |
2270 if (gimple_vdef (new_stmt) | |
2271 && TREE_CODE (gimple_vdef (new_stmt)) == SSA_NAME) | |
2272 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt; | |
2273 | |
2274 if (!gsi_computed) | |
2275 gsi = gsi_for_stmt (e->call_stmt); | |
2276 gsi_replace (&gsi, new_stmt, false); | |
2277 /* We need to defer cleaning EH info on the new statement to | |
2278 fixup-cfg. We may not have dominator information at this point | |
2279 and thus would end up with unreachable blocks and have no way | |
2280 to communicate that we need to run CFG cleanup then. */ | |
2281 lp_nr = lookup_stmt_eh_lp (e->call_stmt); | |
2282 if (lp_nr != 0) | |
2283 { | |
2284 remove_stmt_from_eh_lp (e->call_stmt); | |
2285 add_stmt_to_eh_lp (new_stmt, lp_nr); | |
2286 } | |
2287 } | |
2338 else | 2288 else |
2339 new_stmt = e->call_stmt; | 2289 { |
2340 if (gimple_vdef (new_stmt) | 2290 new_stmt = e->call_stmt; |
2341 && TREE_CODE (gimple_vdef (new_stmt)) == SSA_NAME) | 2291 gimple_call_set_fndecl (new_stmt, e->callee->decl); |
2342 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt; | 2292 update_stmt (new_stmt); |
2343 gimple_call_set_fndecl (new_stmt, e->callee->decl); | 2293 } |
2344 | |
2345 gsi = gsi_for_stmt (e->call_stmt); | |
2346 gsi_replace (&gsi, new_stmt, true); | |
2347 update_stmt (new_stmt); | |
2348 | |
2349 /* Update EH information too, just in case. */ | |
2350 maybe_clean_or_replace_eh_stmt (e->call_stmt, new_stmt); | |
2351 | 2294 |
2352 cgraph_set_call_stmt_including_clones (e->caller, e->call_stmt, new_stmt); | 2295 cgraph_set_call_stmt_including_clones (e->caller, e->call_stmt, new_stmt); |
2353 | 2296 |
2354 if (cgraph_dump_file) | 2297 if (cgraph_dump_file) |
2355 { | 2298 { |
2389 { | 2332 { |
2390 if (gimple_has_body_p (node->clone_of->decl)) | 2333 if (gimple_has_body_p (node->clone_of->decl)) |
2391 { | 2334 { |
2392 if (cgraph_dump_file) | 2335 if (cgraph_dump_file) |
2393 { | 2336 { |
2394 fprintf (cgraph_dump_file, "clonning %s to %s\n", | 2337 fprintf (cgraph_dump_file, "cloning %s to %s\n", |
2395 cgraph_node_name (node->clone_of), | 2338 cgraph_node_name (node->clone_of), |
2396 cgraph_node_name (node)); | 2339 cgraph_node_name (node)); |
2397 if (node->clone.tree_map) | 2340 if (node->clone.tree_map) |
2398 { | 2341 { |
2399 unsigned int i; | 2342 unsigned int i; |
2434 } | 2377 } |
2435 for (node = cgraph_nodes; node; node = node->next) | 2378 for (node = cgraph_nodes; node; node = node->next) |
2436 if (!node->analyzed && node->callees) | 2379 if (!node->analyzed && node->callees) |
2437 cgraph_node_remove_callees (node); | 2380 cgraph_node_remove_callees (node); |
2438 if (cgraph_dump_file) | 2381 if (cgraph_dump_file) |
2439 fprintf (cgraph_dump_file, "Updating call sites\n"); | |
2440 for (node = cgraph_nodes; node; node = node->next) | |
2441 if (node->analyzed && !node->clone_of | |
2442 && gimple_has_body_p (node->decl)) | |
2443 { | |
2444 struct cgraph_edge *e; | |
2445 | |
2446 current_function_decl = node->decl; | |
2447 push_cfun (DECL_STRUCT_FUNCTION (node->decl)); | |
2448 for (e = node->callees; e; e = e->next_callee) | |
2449 cgraph_redirect_edge_call_stmt_to_callee (e); | |
2450 gcc_assert (!need_ssa_update_p (cfun)); | |
2451 pop_cfun (); | |
2452 current_function_decl = NULL; | |
2453 #ifdef ENABLE_CHECKING | |
2454 verify_cgraph_node (node); | |
2455 #endif | |
2456 } | |
2457 if (cgraph_dump_file) | |
2458 fprintf (cgraph_dump_file, "Materialization Call site updates done.\n"); | 2382 fprintf (cgraph_dump_file, "Materialization Call site updates done.\n"); |
2459 /* All changes to parameters have been performed. In order not to | |
2460 incorrectly repeat them, we simply dispose of the bitmaps that drive the | |
2461 changes. */ | |
2462 for (node = cgraph_nodes; node; node = node->next) | |
2463 node->clone.combined_args_to_skip = NULL; | |
2464 #ifdef ENABLE_CHECKING | 2383 #ifdef ENABLE_CHECKING |
2465 verify_cgraph (); | 2384 verify_cgraph (); |
2466 #endif | 2385 #endif |
2467 cgraph_remove_unreachable_nodes (false, cgraph_dump_file); | 2386 cgraph_remove_unreachable_nodes (false, cgraph_dump_file); |
2468 } | 2387 } |