comparison gcc/cgraphclones.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
comparison
equal deleted inserted replaced
111:04ced10e8804 131:84e7813d76e9
1 /* Callgraph clones 1 /* Callgraph clones
2 Copyright (C) 2003-2017 Free Software Foundation, Inc. 2 Copyright (C) 2003-2018 Free Software Foundation, Inc.
3 Contributed by Jan Hubicka 3 Contributed by Jan Hubicka
4 4
5 This file is part of GCC. 5 This file is part of GCC.
6 6
7 GCC is free software; you can redistribute it and/or modify it under 7 GCC is free software; you can redistribute it and/or modify it under
85 the callgraph. */ 85 the callgraph. */
86 86
87 cgraph_edge * 87 cgraph_edge *
88 cgraph_edge::clone (cgraph_node *n, gcall *call_stmt, unsigned stmt_uid, 88 cgraph_edge::clone (cgraph_node *n, gcall *call_stmt, unsigned stmt_uid,
89 profile_count num, profile_count den, 89 profile_count num, profile_count den,
90 int freq_scale, bool update_original) 90 bool update_original)
91 { 91 {
92 cgraph_edge *new_edge; 92 cgraph_edge *new_edge;
93 profile_count gcov_count 93 profile_count::adjust_for_ipa_scaling (&num, &den);
94 = (num == profile_count::zero () || den > 0) 94 profile_count prof_count = count.apply_scale (num, den);
95 ? count.apply_scale (num, den) : count;
96 gcov_type freq;
97
98 /* We do not want to ignore loop nest after frequency drops to 0. */
99 if (!freq_scale)
100 freq_scale = 1;
101 freq = frequency * (gcov_type) freq_scale / CGRAPH_FREQ_BASE;
102 if (freq > CGRAPH_FREQ_MAX)
103 freq = CGRAPH_FREQ_MAX;
104 95
105 if (indirect_unknown_callee) 96 if (indirect_unknown_callee)
106 { 97 {
107 tree decl; 98 tree decl;
108 99
111 via cgraph_resolve_speculation and not here. */ 102 via cgraph_resolve_speculation and not here. */
112 && !speculative) 103 && !speculative)
113 { 104 {
114 cgraph_node *callee = cgraph_node::get (decl); 105 cgraph_node *callee = cgraph_node::get (decl);
115 gcc_checking_assert (callee); 106 gcc_checking_assert (callee);
116 new_edge = n->create_edge (callee, call_stmt, gcov_count, freq); 107 new_edge = n->create_edge (callee, call_stmt, prof_count);
117 } 108 }
118 else 109 else
119 { 110 {
120 new_edge = n->create_indirect_edge (call_stmt, 111 new_edge = n->create_indirect_edge (call_stmt,
121 indirect_info->ecf_flags, 112 indirect_info->ecf_flags,
122 gcov_count, freq, false); 113 prof_count, false);
123 *new_edge->indirect_info = *indirect_info; 114 *new_edge->indirect_info = *indirect_info;
124 } 115 }
125 } 116 }
126 else 117 else
127 { 118 {
128 new_edge = n->create_edge (callee, call_stmt, gcov_count, freq); 119 new_edge = n->create_edge (callee, call_stmt, prof_count);
129 if (indirect_info) 120 if (indirect_info)
130 { 121 {
131 new_edge->indirect_info 122 new_edge->indirect_info
132 = ggc_cleared_alloc<cgraph_indirect_call_info> (); 123 = ggc_cleared_alloc<cgraph_indirect_call_info> ();
133 *new_edge->indirect_info = *indirect_info; 124 *new_edge->indirect_info = *indirect_info;
140 /* Clone flags that depend on call_stmt availability manually. */ 131 /* Clone flags that depend on call_stmt availability manually. */
141 new_edge->can_throw_external = can_throw_external; 132 new_edge->can_throw_external = can_throw_external;
142 new_edge->call_stmt_cannot_inline_p = call_stmt_cannot_inline_p; 133 new_edge->call_stmt_cannot_inline_p = call_stmt_cannot_inline_p;
143 new_edge->speculative = speculative; 134 new_edge->speculative = speculative;
144 new_edge->in_polymorphic_cdtor = in_polymorphic_cdtor; 135 new_edge->in_polymorphic_cdtor = in_polymorphic_cdtor;
136
137 /* Update IPA profile. Local profiles need no updating in original. */
145 if (update_original) 138 if (update_original)
146 { 139 count = count.combine_with_ipa_count (count.ipa ()
147 count -= new_edge->count; 140 - new_edge->count.ipa ());
148 }
149 symtab->call_edge_duplication_hooks (this, new_edge); 141 symtab->call_edge_duplication_hooks (this, new_edge);
150 return new_edge; 142 return new_edge;
151 } 143 }
152 144
153 /* Build variant of function type ORIG_TYPE skipping ARGS_TO_SKIP and the 145 /* Build variant of function type ORIG_TYPE skipping ARGS_TO_SKIP and the
228 we expect first argument to be THIS pointer. */ 220 we expect first argument to be THIS pointer. */
229 if (args_to_skip && bitmap_bit_p (args_to_skip, 0)) 221 if (args_to_skip && bitmap_bit_p (args_to_skip, 0))
230 DECL_VINDEX (new_decl) = NULL_TREE; 222 DECL_VINDEX (new_decl) = NULL_TREE;
231 223
232 /* When signature changes, we need to clear builtin info. */ 224 /* When signature changes, we need to clear builtin info. */
233 if (DECL_BUILT_IN (new_decl) 225 if (fndecl_built_in_p (new_decl)
234 && args_to_skip 226 && args_to_skip
235 && !bitmap_empty_p (args_to_skip)) 227 && !bitmap_empty_p (args_to_skip))
236 { 228 {
237 DECL_BUILT_IN_CLASS (new_decl) = NOT_BUILT_IN; 229 DECL_BUILT_IN_CLASS (new_decl) = NOT_BUILT_IN;
238 DECL_FUNCTION_CODE (new_decl) = (enum built_in_function) 0; 230 DECL_FUNCTION_CODE (new_decl) = (enum built_in_function) 0;
280 thunk->get_untransformed_body (); 272 thunk->get_untransformed_body ();
281 273
282 cgraph_edge *cs; 274 cgraph_edge *cs;
283 for (cs = node->callers; cs; cs = cs->next_caller) 275 for (cs = node->callers; cs; cs = cs->next_caller)
284 if (cs->caller->thunk.thunk_p 276 if (cs->caller->thunk.thunk_p
277 && cs->caller->thunk.fixed_offset == thunk->thunk.fixed_offset
278 && cs->caller->thunk.virtual_value == thunk->thunk.virtual_value
279 && cs->caller->thunk.indirect_offset == thunk->thunk.indirect_offset
285 && cs->caller->thunk.this_adjusting == thunk->thunk.this_adjusting 280 && cs->caller->thunk.this_adjusting == thunk->thunk.this_adjusting
286 && cs->caller->thunk.fixed_offset == thunk->thunk.fixed_offset 281 && cs->caller->thunk.virtual_offset_p == thunk->thunk.virtual_offset_p)
287 && cs->caller->thunk.virtual_offset_p == thunk->thunk.virtual_offset_p
288 && cs->caller->thunk.virtual_value == thunk->thunk.virtual_value)
289 return cs->caller; 282 return cs->caller;
290 283
291 tree new_decl; 284 tree new_decl;
292 if (!node->clone.args_to_skip) 285 if (!node->clone.args_to_skip)
293 new_decl = copy_node (thunk->decl); 286 new_decl = copy_node (thunk->decl);
335 new_thunk->unique_name = in_lto_p; 328 new_thunk->unique_name = in_lto_p;
336 new_thunk->former_clone_of = thunk->decl; 329 new_thunk->former_clone_of = thunk->decl;
337 new_thunk->clone.args_to_skip = node->clone.args_to_skip; 330 new_thunk->clone.args_to_skip = node->clone.args_to_skip;
338 new_thunk->clone.combined_args_to_skip = node->clone.combined_args_to_skip; 331 new_thunk->clone.combined_args_to_skip = node->clone.combined_args_to_skip;
339 332
340 cgraph_edge *e = new_thunk->create_edge (node, NULL, new_thunk->count, 333 cgraph_edge *e = new_thunk->create_edge (node, NULL, new_thunk->count);
341 CGRAPH_FREQ_BASE);
342 symtab->call_edge_duplication_hooks (thunk->callees, e); 334 symtab->call_edge_duplication_hooks (thunk->callees, e);
343 symtab->call_cgraph_duplication_hooks (thunk, new_thunk); 335 symtab->call_cgraph_duplication_hooks (thunk, new_thunk);
344 return new_thunk; 336 return new_thunk;
345 } 337 }
346 338
420 the outline function the new one is (even indirectly) inlined to. All hooks 412 the outline function the new one is (even indirectly) inlined to. All hooks
421 will see this in node's global.inlined_to, when invoked. Can be NULL if the 413 will see this in node's global.inlined_to, when invoked. Can be NULL if the
422 node is not inlined. */ 414 node is not inlined. */
423 415
424 cgraph_node * 416 cgraph_node *
425 cgraph_node::create_clone (tree new_decl, profile_count prof_count, int freq, 417 cgraph_node::create_clone (tree new_decl, profile_count prof_count,
426 bool update_original, 418 bool update_original,
427 vec<cgraph_edge *> redirect_callers, 419 vec<cgraph_edge *> redirect_callers,
428 bool call_duplication_hook, 420 bool call_duplication_hook,
429 cgraph_node *new_inlined_to, 421 cgraph_node *new_inlined_to,
430 bitmap args_to_skip, const char *suffix) 422 bitmap args_to_skip, const char *suffix)
431 { 423 {
432 cgraph_node *new_node = symtab->create_empty (); 424 cgraph_node *new_node = symtab->create_empty ();
433 cgraph_edge *e; 425 cgraph_edge *e;
434 unsigned i; 426 unsigned i;
427 profile_count old_count = count;
435 428
436 if (new_inlined_to) 429 if (new_inlined_to)
437 dump_callgraph_transformation (this, new_inlined_to, "inlining to"); 430 dump_callgraph_transformation (this, new_inlined_to, "inlining to");
438 431
432 /* When inlining we scale precisely to prof_count, when cloning we can
433 preserve local profile. */
434 if (!new_inlined_to)
435 prof_count = count.combine_with_ipa_count (prof_count);
439 new_node->count = prof_count; 436 new_node->count = prof_count;
437
438 /* Update IPA profile. Local profiles need no updating in original. */
439 if (update_original)
440 count = count.combine_with_ipa_count (count.ipa () - prof_count.ipa ());
440 new_node->decl = new_decl; 441 new_node->decl = new_decl;
441 new_node->register_symbol (); 442 new_node->register_symbol ();
442 new_node->origin = origin; 443 new_node->origin = origin;
443 new_node->lto_file_data = lto_file_data; 444 new_node->lto_file_data = lto_file_data;
444 if (new_node->origin) 445 if (new_node->origin)
480 { 481 {
481 /* Redirect calls to the old version node to point to its new 482 /* Redirect calls to the old version node to point to its new
482 version. The only exception is when the edge was proved to 483 version. The only exception is when the edge was proved to
483 be unreachable during the clonning procedure. */ 484 be unreachable during the clonning procedure. */
484 if (!e->callee 485 if (!e->callee
485 || DECL_BUILT_IN_CLASS (e->callee->decl) != BUILT_IN_NORMAL 486 || !fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE))
486 || DECL_FUNCTION_CODE (e->callee->decl) != BUILT_IN_UNREACHABLE)
487 e->redirect_callee_duplicating_thunks (new_node); 487 e->redirect_callee_duplicating_thunks (new_node);
488 } 488 }
489 new_node->expand_all_artificial_thunks (); 489 new_node->expand_all_artificial_thunks ();
490 490
491 for (e = callees;e; e=e->next_callee) 491 for (e = callees;e; e=e->next_callee)
492 e->clone (new_node, e->call_stmt, e->lto_stmt_uid, new_node->count, count, 492 e->clone (new_node, e->call_stmt, e->lto_stmt_uid, new_node->count, old_count,
493 freq, update_original); 493 update_original);
494 494
495 for (e = indirect_calls; e; e = e->next_callee) 495 for (e = indirect_calls; e; e = e->next_callee)
496 e->clone (new_node, e->call_stmt, e->lto_stmt_uid, 496 e->clone (new_node, e->call_stmt, e->lto_stmt_uid,
497 new_node->count, count, freq, update_original); 497 new_node->count, old_count, update_original);
498 new_node->clone_references (this); 498 new_node->clone_references (this);
499 499
500 new_node->next_sibling_clone = clones; 500 new_node->next_sibling_clone = clones;
501 if (clones) 501 if (clones)
502 clones->prev_sibling_clone = new_node; 502 clones->prev_sibling_clone = new_node;
503 clones = new_node; 503 clones = new_node;
504 new_node->clone_of = this; 504 new_node->clone_of = this;
505
506 if (update_original)
507 count -= prof_count;
508 505
509 if (call_duplication_hook) 506 if (call_duplication_hook)
510 symtab->call_cgraph_duplication_hooks (this, new_node); 507 symtab->call_cgraph_duplication_hooks (this, new_node);
511 508
512 if (!new_inlined_to) 509 if (!new_inlined_to)
589 name[len] = '.'; 586 name[len] = '.';
590 DECL_NAME (new_decl) = get_identifier (name); 587 DECL_NAME (new_decl) = get_identifier (name);
591 SET_DECL_ASSEMBLER_NAME (new_decl, clone_function_name (old_decl, suffix)); 588 SET_DECL_ASSEMBLER_NAME (new_decl, clone_function_name (old_decl, suffix));
592 SET_DECL_RTL (new_decl, NULL); 589 SET_DECL_RTL (new_decl, NULL);
593 590
594 new_node = create_clone (new_decl, count, CGRAPH_FREQ_BASE, false, 591 new_node = create_clone (new_decl, count, false,
595 redirect_callers, false, NULL, args_to_skip, suffix); 592 redirect_callers, false, NULL, args_to_skip, suffix);
596 593
597 /* Update the properties. 594 /* Update the properties.
598 Make clone visible only within this translation unit. Make sure 595 Make clone visible only within this translation unit. Make sure
599 that is not weak also. 596 that is not weak also.
771 768
772 void 769 void
773 cgraph_node::create_edge_including_clones (cgraph_node *callee, 770 cgraph_node::create_edge_including_clones (cgraph_node *callee,
774 gimple *old_stmt, gcall *stmt, 771 gimple *old_stmt, gcall *stmt,
775 profile_count count, 772 profile_count count,
776 int freq,
777 cgraph_inline_failed_t reason) 773 cgraph_inline_failed_t reason)
778 { 774 {
779 cgraph_node *node; 775 cgraph_node *node;
780 cgraph_edge *edge; 776 cgraph_edge *edge;
781 777
782 if (!get_edge (stmt)) 778 if (!get_edge (stmt))
783 { 779 {
784 edge = create_edge (callee, stmt, count, freq); 780 edge = create_edge (callee, stmt, count);
785 edge->inline_failed = reason; 781 edge->inline_failed = reason;
786 } 782 }
787 783
788 node = clones; 784 node = clones;
789 if (node) 785 if (node)
799 master where edges has been removed. */ 795 master where edges has been removed. */
800 if (edge) 796 if (edge)
801 edge->set_call_stmt (stmt); 797 edge->set_call_stmt (stmt);
802 else if (! node->get_edge (stmt)) 798 else if (! node->get_edge (stmt))
803 { 799 {
804 edge = node->create_edge (callee, stmt, count, freq); 800 edge = node->create_edge (callee, stmt, count);
805 edge->inline_failed = reason; 801 edge->inline_failed = reason;
806 } 802 }
807 803
808 if (node->clones) 804 if (node->clones)
809 node = node->clones; 805 node = node->clones;
902 for (e = callees; e; e=e->next_callee) 898 for (e = callees; e; e=e->next_callee)
903 if (!bbs_to_copy 899 if (!bbs_to_copy
904 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index)) 900 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
905 e->clone (new_version, e->call_stmt, 901 e->clone (new_version, e->call_stmt,
906 e->lto_stmt_uid, count, count, 902 e->lto_stmt_uid, count, count,
907 CGRAPH_FREQ_BASE,
908 true); 903 true);
909 for (e = indirect_calls; e; e=e->next_callee) 904 for (e = indirect_calls; e; e=e->next_callee)
910 if (!bbs_to_copy 905 if (!bbs_to_copy
911 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index)) 906 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
912 e->clone (new_version, e->call_stmt, 907 e->clone (new_version, e->call_stmt,
913 e->lto_stmt_uid, count, count, 908 e->lto_stmt_uid, count, count,
914 CGRAPH_FREQ_BASE,
915 true); 909 true);
916 FOR_EACH_VEC_ELT (redirect_callers, i, e) 910 FOR_EACH_VEC_ELT (redirect_callers, i, e)
917 { 911 {
918 /* Redirect calls to the old version node to point to its new 912 /* Redirect calls to the old version node to point to its new
919 version. */ 913 version. */
971 965
972 /* Generate a new name for the new version. */ 966 /* Generate a new name for the new version. */
973 DECL_NAME (new_decl) = clone_function_name (old_decl, suffix); 967 DECL_NAME (new_decl) = clone_function_name (old_decl, suffix);
974 SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl)); 968 SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
975 SET_DECL_RTL (new_decl, NULL); 969 SET_DECL_RTL (new_decl, NULL);
970
971 DECL_VIRTUAL_P (new_decl) = 0;
976 972
977 /* When the old decl was a con-/destructor make sure the clone isn't. */ 973 /* When the old decl was a con-/destructor make sure the clone isn't. */
978 DECL_STATIC_CONSTRUCTOR (new_decl) = 0; 974 DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
979 DECL_STATIC_DESTRUCTOR (new_decl) = 0; 975 DECL_STATIC_DESTRUCTOR (new_decl) = 0;
980 976
1011 new_version_node->unique_name = true; 1007 new_version_node->unique_name = true;
1012 1008
1013 /* Update the call_expr on the edges to call the new version node. */ 1009 /* Update the call_expr on the edges to call the new version node. */
1014 update_call_expr (new_version_node); 1010 update_call_expr (new_version_node);
1015 1011
1016 symtab->call_cgraph_insertion_hooks (this); 1012 symtab->call_cgraph_insertion_hooks (new_version_node);
1017 return new_version_node; 1013 return new_version_node;
1018 } 1014 }
1019 1015
1020 /* Given virtual clone, turn it into actual clone. */ 1016 /* Given virtual clone, turn it into actual clone. */
1021 1017