Line data Source code
1 : /* Callgraph clones
2 : Copyright (C) 2003-2026 Free Software Foundation, Inc.
3 : Contributed by Jan Hubicka
4 :
5 : This file is part of GCC.
6 :
7 : GCC is free software; you can redistribute it and/or modify it under
8 : the terms of the GNU General Public License as published by the Free
9 : Software Foundation; either version 3, or (at your option) any later
10 : version.
11 :
12 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 : for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with GCC; see the file COPYING3. If not see
19 : <http://www.gnu.org/licenses/>. */
20 :
21 : /* This module provide facilities for cloning functions. I.e. creating
22 : new functions based on existing functions with simple modifications,
23 : such as replacement of parameters.
24 :
25 : To allow whole program optimization without actual presence of function
26 : bodies, an additional infrastructure is provided for so-called virtual
27 : clones
28 :
29 : A virtual clone in the callgraph is a function that has no
30 : associated body, just a description of how to create its body based
31 : on a different function (which itself may be a virtual clone).
32 :
33 : The description of function modifications includes adjustments to
34 : the function's signature (which allows, for example, removing or
35 : adding function arguments), substitutions to perform on the
36 : function body, and, for inlined functions, a pointer to the
37 : function that it will be inlined into.
38 :
39 : It is also possible to redirect any edge of the callgraph from a
40 : function to its virtual clone. This implies updating of the call
41 : site to adjust for the new function signature.
42 :
43 : Most of the transformations performed by inter-procedural
44 : optimizations can be represented via virtual clones. For
45 : instance, a constant propagation pass can produce a virtual clone
46 : of the function which replaces one of its arguments by a
47 : constant. The inliner can represent its decisions by producing a
48 : clone of a function whose body will be later integrated into
49 : a given function.
50 :
51 : Using virtual clones, the program can be easily updated
52 : during the Execute stage, solving most of pass interactions
53 : problems that would otherwise occur during Transform.
54 :
55 : Virtual clones are later materialized in the LTRANS stage and
56 : turned into real functions. Passes executed after the virtual
57 : clone were introduced also perform their Transform stage
58 : on new functions, so for a pass there is no significant
59 : difference between operating on a real function or a virtual
60 : clone introduced before its Execute stage.
61 :
62 : Optimization passes then work on virtual clones introduced before
63 : their Execute stage as if they were real functions. The
64 : only difference is that clones are not visible during the
65 : Generate Summary stage. */
66 :
67 : #include "config.h"
68 : #include "system.h"
69 : #include "coretypes.h"
70 : #include "backend.h"
71 : #include "target.h"
72 : #include "rtl.h"
73 : #include "tree.h"
74 : #include "gimple.h"
75 : #include "stringpool.h"
76 : #include "cgraph.h"
77 : #include "lto-streamer.h"
78 : #include "tree-eh.h"
79 : #include "tree-cfg.h"
80 : #include "tree-inline.h"
81 : #include "attribs.h"
82 : #include "dumpfile.h"
83 : #include "gimple-pretty-print.h"
84 : #include "alloc-pool.h"
85 : #include "symbol-summary.h"
86 : #include "tree-vrp.h"
87 : #include "sreal.h"
88 : #include "ipa-cp.h"
89 : #include "ipa-prop.h"
90 : #include "ipa-fnsummary.h"
91 : #include "symtab-thunks.h"
92 : #include "symtab-clones.h"
93 :
94 : /* Create clone of edge in the node N represented by CALL_EXPR
95 : the callgraph. */
96 :
97 : cgraph_edge *
98 7934265 : cgraph_edge::clone (cgraph_node *n, gcall *call_stmt, unsigned stmt_uid,
99 : profile_count num, profile_count den,
100 : bool update_original)
101 : {
102 7934265 : cgraph_edge *new_edge;
103 7934265 : profile_count::adjust_for_ipa_scaling (&num, &den);
104 7934265 : profile_count prof_count = count.apply_scale (num, den);
105 :
106 7934265 : if (indirect_unknown_callee)
107 : {
108 179415 : tree decl;
109 :
110 178765 : if (call_stmt && (decl = gimple_call_fndecl (call_stmt))
111 : /* When the call is speculative, we need to resolve it
112 : via cgraph_resolve_speculation and not here. */
113 188069 : && !speculative)
114 : {
115 8654 : cgraph_node *callee = cgraph_node::get (decl);
116 8654 : gcc_checking_assert (callee);
117 8654 : new_edge = n->create_edge (callee, call_stmt, prof_count, true);
118 : }
119 : else
120 : {
121 341522 : new_edge = n->create_indirect_edge (call_stmt,
122 170761 : indirect_info->ecf_flags,
123 : prof_count, true);
124 :
125 170761 : if (indirect_info->kind == CIIK_POLYMORPHIC)
126 108376 : new_edge->indirect_info
127 108376 : = (new (ggc_alloc<cgraph_polymorphic_indirect_info> ())
128 : cgraph_polymorphic_indirect_info (
129 108376 : *(const cgraph_polymorphic_indirect_info *) indirect_info));
130 62385 : else if (indirect_info->kind == CIIK_SIMPLE)
131 62271 : new_edge->indirect_info
132 62271 : = (new (ggc_alloc<cgraph_simple_indirect_info> ())
133 : cgraph_simple_indirect_info (
134 62271 : *(const cgraph_simple_indirect_info *) indirect_info));
135 : else
136 114 : new_edge->indirect_info
137 114 : = (new (ggc_alloc<cgraph_indirect_call_info> ())
138 : cgraph_indirect_call_info(
139 114 : *(const cgraph_indirect_call_info *) indirect_info));
140 : }
141 : }
142 : else
143 : {
144 7754850 : new_edge = n->create_edge (callee, call_stmt, prof_count, true);
145 7754850 : if (indirect_info)
146 : {
147 0 : new_edge->indirect_info
148 0 : = ggc_cleared_alloc<cgraph_indirect_call_info> ();
149 0 : *new_edge->indirect_info = *indirect_info;
150 : }
151 : }
152 :
153 7934265 : new_edge->inline_failed = inline_failed;
154 7934265 : new_edge->indirect_inlining_edge = indirect_inlining_edge;
155 7934265 : if (!call_stmt)
156 236886 : new_edge->lto_stmt_uid = stmt_uid;
157 7934265 : new_edge->speculative_id = speculative_id;
158 : /* Clone flags that depend on call_stmt availability manually. */
159 7934265 : new_edge->can_throw_external = can_throw_external;
160 7934265 : new_edge->call_stmt_cannot_inline_p = call_stmt_cannot_inline_p;
161 7934265 : new_edge->speculative = speculative;
162 7934265 : new_edge->callback = callback;
163 7934265 : new_edge->has_callback = has_callback;
164 7934265 : new_edge->in_polymorphic_cdtor = in_polymorphic_cdtor;
165 :
166 : /* Update IPA profile. Local profiles need no updating in original. */
167 7934265 : if (update_original)
168 7203898 : count = count.combine_with_ipa_count_within (count.ipa ()
169 7203898 : - new_edge->count.ipa (),
170 7203898 : caller->count);
171 7934265 : symtab->call_edge_duplication_hooks (this, new_edge);
172 7934265 : return new_edge;
173 : }
174 :
175 : /* Set flags of NEW_NODE and its decl. NEW_NODE is a newly created private
176 : clone or its thunk. */
177 :
178 : void
179 146416 : set_new_clone_decl_and_node_flags (cgraph_node *new_node)
180 : {
181 146416 : DECL_EXTERNAL (new_node->decl) = 0;
182 146416 : TREE_PUBLIC (new_node->decl) = 0;
183 146416 : DECL_COMDAT (new_node->decl) = 0;
184 146416 : DECL_WEAK (new_node->decl) = 0;
185 146416 : DECL_VIRTUAL_P (new_node->decl) = 0;
186 146416 : DECL_STATIC_CONSTRUCTOR (new_node->decl) = 0;
187 146416 : DECL_STATIC_DESTRUCTOR (new_node->decl) = 0;
188 146416 : DECL_SET_IS_OPERATOR_NEW (new_node->decl, 0);
189 146416 : DECL_SET_IS_OPERATOR_DELETE (new_node->decl, 0);
190 146416 : DECL_IS_REPLACEABLE_OPERATOR (new_node->decl) = 0;
191 :
192 146416 : new_node->externally_visible = 0;
193 : /* Clones of callbacks might have their address taken, and thus cannot be
194 : local. */
195 146416 : new_node->local = !new_node->address_taken;
196 146416 : new_node->lowered = true;
197 146416 : new_node->semantic_interposition = 0;
198 146416 : }
199 :
200 : /* Duplicate thunk THUNK if necessary but make it to refer to NODE.
201 : ARGS_TO_SKIP, if non-NULL, determines which parameters should be omitted.
202 : Function can return NODE if no thunk is necessary, which can happen when
203 : thunk is this_adjusting but we are removing this parameter. */
204 :
205 : static cgraph_node *
206 30 : duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node)
207 : {
208 30 : cgraph_node *new_thunk, *thunk_of;
209 30 : thunk_of = thunk->callees->callee->ultimate_alias_target ();
210 :
211 30 : if (thunk_of->thunk)
212 0 : node = duplicate_thunk_for_node (thunk_of, node);
213 :
214 30 : if (!DECL_ARGUMENTS (thunk->decl))
215 0 : thunk->get_untransformed_body ();
216 :
217 30 : thunk_info *i = thunk_info::get (thunk);
218 30 : cgraph_edge *cs;
219 30 : for (cs = node->callers; cs; cs = cs->next_caller)
220 12 : if (cs->caller->thunk)
221 : {
222 12 : thunk_info *i2 = thunk_info::get (cs->caller);
223 12 : if (*i2 == *i)
224 : return cs->caller;
225 : }
226 :
227 18 : tree new_decl;
228 18 : clone_info *info = clone_info::get (node);
229 18 : if (info && info->param_adjustments)
230 : {
231 : /* We do not need to duplicate this_adjusting thunks if we have removed
232 : this. */
233 15 : if (i->this_adjusting
234 15 : && !info->param_adjustments->first_param_intact_p ())
235 0 : return node;
236 :
237 15 : new_decl = copy_node (thunk->decl);
238 15 : ipa_param_body_adjustments body_adj (info->param_adjustments,
239 15 : new_decl);
240 15 : body_adj.modify_formal_parameters ();
241 15 : }
242 : else
243 : {
244 3 : new_decl = copy_node (thunk->decl);
245 3 : for (tree *arg = &DECL_ARGUMENTS (new_decl);
246 9 : *arg; arg = &DECL_CHAIN (*arg))
247 : {
248 6 : tree next = DECL_CHAIN (*arg);
249 6 : *arg = copy_node (*arg);
250 6 : DECL_CONTEXT (*arg) = new_decl;
251 6 : DECL_CHAIN (*arg) = next;
252 : }
253 : }
254 :
255 18 : gcc_checking_assert (!DECL_STRUCT_FUNCTION (new_decl));
256 18 : gcc_checking_assert (!DECL_INITIAL (new_decl));
257 18 : gcc_checking_assert (!DECL_RESULT (new_decl));
258 18 : gcc_checking_assert (!DECL_RTL_SET_P (new_decl));
259 :
260 18 : DECL_NAME (new_decl) = clone_function_name_numbered (thunk->decl,
261 : "artificial_thunk");
262 18 : SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
263 :
264 : /* We need to force DECL_IGNORED_P because the new thunk is created after
265 : early debug was run. */
266 18 : DECL_IGNORED_P (new_decl) = 1;
267 :
268 18 : new_thunk = cgraph_node::create (new_decl);
269 18 : set_new_clone_decl_and_node_flags (new_thunk);
270 18 : new_thunk->definition = true;
271 18 : new_thunk->can_change_signature = node->can_change_signature;
272 18 : new_thunk->thunk = thunk->thunk;
273 18 : new_thunk->unique_name = in_lto_p;
274 18 : new_thunk->former_clone_of = thunk->decl;
275 18 : if (info && info->param_adjustments)
276 15 : clone_info::get_create (new_thunk)->param_adjustments
277 15 : = info->param_adjustments;
278 18 : new_thunk->unit_id = thunk->unit_id;
279 18 : new_thunk->merged_comdat = thunk->merged_comdat;
280 18 : new_thunk->merged_extern_inline = thunk->merged_extern_inline;
281 :
282 18 : cgraph_edge *e = new_thunk->create_edge (node, NULL, new_thunk->count);
283 18 : symtab->call_edge_duplication_hooks (thunk->callees, e);
284 18 : symtab->call_cgraph_duplication_hooks (thunk, new_thunk);
285 18 : return new_thunk;
286 : }
287 :
288 : /* If E does not lead to a thunk, simply redirect it to N. Otherwise create
289 : one or more equivalent thunks for N and redirect E to the first in the
290 : chain. Note that it is then necessary to call
291 : n->expand_all_artificial_thunks once all callers are redirected. */
292 :
293 : void
294 434735 : cgraph_edge::redirect_callee_duplicating_thunks (cgraph_node *n)
295 : {
296 434735 : cgraph_node *orig_to = callee->ultimate_alias_target ();
297 434735 : if (orig_to->thunk)
298 30 : n = duplicate_thunk_for_node (orig_to, n);
299 :
300 434735 : redirect_callee (n);
301 434735 : }
302 :
303 : /* Call expand_thunk on all callers that are thunks and if analyze those nodes
304 : that were expanded. */
305 :
306 : void
307 3364622 : cgraph_node::expand_all_artificial_thunks ()
308 : {
309 3364622 : cgraph_edge *e;
310 3799691 : for (e = callers; e;)
311 435069 : if (e->caller->thunk)
312 : {
313 18 : cgraph_node *thunk = e->caller;
314 :
315 18 : e = e->next_caller;
316 18 : if (expand_thunk (thunk, false, false))
317 : {
318 0 : thunk->thunk = false;
319 0 : thunk->analyze ();
320 0 : ipa_analyze_node (thunk);
321 0 : inline_analyze_function (thunk);
322 : }
323 18 : thunk->expand_all_artificial_thunks ();
324 : }
325 : else
326 435051 : e = e->next_caller;
327 3364622 : }
328 :
329 : /* Dump information about creation of a call graph node clone to the dump file
330 : created by the -fdump-ipa-clones option. ORIGINAL is the function being
331 : cloned, CLONE is the new clone. SUFFIX is a string that helps identify the
332 : reason for cloning, often it is the suffix used by a particular IPA pass to
333 : create unique function names. SUFFIX can be NULL and in that case the
334 : dumping will not take place, which must be the case only for helper clones
335 : which will never be emitted to the output. */
336 :
337 : void
338 4942512 : dump_callgraph_transformation (const cgraph_node *original,
339 : const cgraph_node *clone,
340 : const char *suffix)
341 : {
342 4942512 : if (suffix && symtab->ipa_clones_dump_file)
343 : {
344 52 : fprintf (symtab->ipa_clones_dump_file,
345 : "Callgraph clone;%s;%d;%s;%d;%d;%s;%d;%s;%d;%d;%s\n",
346 : original->asm_name (), original->get_uid (),
347 26 : DECL_SOURCE_FILE (original->decl),
348 26 : DECL_SOURCE_LINE (original->decl),
349 26 : DECL_SOURCE_COLUMN (original->decl), clone->asm_name (),
350 26 : clone->get_uid (), DECL_SOURCE_FILE (clone->decl),
351 26 : DECL_SOURCE_LINE (clone->decl), DECL_SOURCE_COLUMN (clone->decl),
352 : suffix);
353 :
354 26 : symtab->cloned_nodes.add (original);
355 26 : symtab->cloned_nodes.add (clone);
356 : }
357 4942512 : }
358 :
359 : /* Turn profile of N to local profile. */
360 :
361 : static void
362 0 : localize_profile (cgraph_node *n)
363 : {
364 0 : n->count = n->count.guessed_local ();
365 0 : for (cgraph_edge *e = n->callees; e; e=e->next_callee)
366 : {
367 0 : e->count = e->count.guessed_local ();
368 0 : if (!e->inline_failed)
369 0 : localize_profile (e->callee);
370 : }
371 0 : for (cgraph_edge *e = n->indirect_calls; e; e=e->next_callee)
372 0 : e->count = e->count.guessed_local ();
373 0 : }
374 :
375 : /* Create node representing clone of N executed COUNT times. Decrease
376 : the execution counts from original node too.
377 : The new clone will have decl set to DECL that may or may not be the same
378 : as decl of N.
379 :
380 : When UPDATE_ORIGINAL is true, the counts are subtracted from the original
381 : function's profile to reflect the fact that part of execution is handled
382 : by node.
383 : When CALL_DUPLICATION_HOOK is true, the ipa passes are acknowledged about
384 : the new clone. Otherwise the caller is responsible for doing so later.
385 :
386 : If the new node is being inlined into another one, NEW_INLINED_TO should be
387 : the outline function the new one is (even indirectly) inlined to. All hooks
388 : will see this in node's inlined_to, when invoked. Should be NULL if the
389 : node is not inlined.
390 :
391 : SUFFIX is string that is appended to the original name, it should only be
392 : NULL if NEW_INLINED_TO is not NULL or if the clone being created is
393 : temporary and a record about it should not be added into the ipa-clones dump
394 : file.
395 :
396 : If PARAM_ADJUSTMENTS is non-NULL, the parameter manipulation information
397 : will be overwritten by the new structure. Otherwise the new node will
398 : share parameter manipulation information with the original node. */
399 :
400 : cgraph_node *
401 3364456 : cgraph_node::create_clone (tree new_decl, profile_count prof_count,
402 : bool update_original,
403 : vec<cgraph_edge *> redirect_callers,
404 : bool call_duplication_hook,
405 : cgraph_node *new_inlined_to,
406 : ipa_param_adjustments *param_adjustments,
407 : const char *suffix)
408 : {
409 3364456 : cgraph_node *new_node = symtab->create_empty ();
410 3364456 : cgraph_edge *e;
411 3364456 : unsigned i;
412 3364456 : profile_count old_count = count;
413 3364456 : bool nonzero = count.ipa ().nonzero_p ();
414 :
415 3364456 : if (new_inlined_to)
416 3193196 : dump_callgraph_transformation (this, new_inlined_to, "inlining to");
417 :
418 : /* When inlining we scale precisely to prof_count, when cloning we can
419 : preserve local profile. */
420 3193196 : if (!new_inlined_to)
421 171260 : prof_count = count.combine_with_ipa_count (prof_count);
422 3364456 : new_node->count = prof_count;
423 3364456 : new_node->has_omp_variant_constructs = this->has_omp_variant_constructs;
424 :
425 : /* Update IPA profile. Local profiles need no updating in original. */
426 3364456 : if (update_original)
427 : {
428 3171520 : if (inlined_to)
429 504368 : count = count.combine_with_ipa_count_within (count.ipa ()
430 1008736 : - prof_count.ipa (),
431 : inlined_to->count);
432 : else
433 2667152 : count = count.combine_with_ipa_count (count.ipa () - prof_count.ipa ());
434 : }
435 3364456 : new_node->decl = new_decl;
436 3364456 : new_node->order = order;
437 3364456 : new_node->register_symbol ();
438 3364456 : new_node->lto_file_data = lto_file_data;
439 3364456 : new_node->analyzed = analyzed;
440 3364456 : new_node->definition = definition;
441 3364456 : new_node->versionable = versionable;
442 3364456 : new_node->can_change_signature = can_change_signature;
443 3364456 : new_node->redefined_extern_inline = redefined_extern_inline;
444 3364456 : new_node->semantic_interposition = semantic_interposition;
445 3364456 : new_node->tm_may_enter_irr = tm_may_enter_irr;
446 3364456 : new_node->externally_visible = false;
447 3364456 : new_node->no_reorder = no_reorder;
448 3364456 : new_node->local = true;
449 3364456 : new_node->inlined_to = new_inlined_to;
450 3364456 : new_node->rtl = rtl;
451 3364456 : new_node->frequency = frequency;
452 3364456 : new_node->tp_first_run = tp_first_run;
453 3364456 : new_node->tm_clone = tm_clone;
454 3364456 : new_node->icf_merged = icf_merged;
455 3364456 : new_node->thunk = thunk;
456 3364456 : new_node->unit_id = unit_id;
457 3364456 : new_node->merged_comdat = merged_comdat;
458 3364456 : new_node->merged_extern_inline = merged_extern_inline;
459 3364456 : new_node->must_remain_in_tu_body = must_remain_in_tu_body;
460 3364456 : clone_info *info = clone_info::get (this);
461 :
462 3364456 : if (param_adjustments)
463 140376 : clone_info::get_create (new_node)->param_adjustments = param_adjustments;
464 3224080 : else if (info && info->param_adjustments)
465 345697 : clone_info::get_create (new_node)->param_adjustments
466 345697 : = info->param_adjustments;
467 3364456 : new_node->split_part = split_part;
468 :
469 3799036 : FOR_EACH_VEC_ELT (redirect_callers, i, e)
470 : {
471 : /* Redirect calls to the old version node to point to its new
472 : version. The only exception is when the edge was proved to
473 : be unreachable during the cloning procedure. */
474 434580 : if (!e->callee
475 434580 : || !fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE,
476 : BUILT_IN_UNREACHABLE_TRAP))
477 434580 : e->redirect_callee_duplicating_thunks (new_node);
478 : }
479 3364456 : new_node->expand_all_artificial_thunks ();
480 :
481 6753498 : for (e = callees;e; e=e->next_callee)
482 3389042 : e->clone (new_node, e->call_stmt, e->lto_stmt_uid, new_node->count, old_count,
483 : update_original);
484 :
485 3444704 : for (e = indirect_calls; e; e = e->next_callee)
486 80248 : e->clone (new_node, e->call_stmt, e->lto_stmt_uid,
487 : new_node->count, old_count, update_original);
488 3364456 : new_node->clone_references (this);
489 :
490 3364456 : new_node->next_sibling_clone = clones;
491 3364456 : if (clones)
492 1662863 : clones->prev_sibling_clone = new_node;
493 3364456 : clones = new_node;
494 3364456 : new_node->clone_of = this;
495 :
496 3364456 : if (call_duplication_hook)
497 3194829 : symtab->call_cgraph_duplication_hooks (this, new_node);
498 : /* With partial train run we do not want to assume that original's
499 : count is zero whenever we redurect all executed edges to clone.
500 : Simply drop profile to local one in this case. */
501 3364456 : if (update_original
502 3171520 : && opt_for_fn (decl, flag_profile_partial_training)
503 0 : && nonzero
504 0 : && count.ipa_p ()
505 3364456 : && !count.ipa ().nonzero_p ()
506 3364456 : && !inlined_to)
507 0 : localize_profile (this);
508 :
509 3364456 : if (!new_inlined_to)
510 171260 : dump_callgraph_transformation (this, new_node, suffix);
511 :
512 3364456 : return new_node;
513 : }
514 :
515 : static GTY(()) hash_map<const char *, unsigned> *clone_fn_ids;
516 :
517 : /* Return a new assembler name for a clone of decl named NAME. Apart
518 : from the string SUFFIX, the new name will end with a unique (for
519 : each NAME) unspecified number. If clone numbering is not needed
520 : then the two argument clone_function_name should be used instead.
521 : Should not be called directly except for by
522 : lto-partition.cc:privatize_symbol_name_1. */
523 :
524 : tree
525 112826 : clone_function_name_numbered (const char *name, const char *suffix)
526 : {
527 : /* Initialize the function->counter mapping the first time it's
528 : needed. */
529 112826 : if (!clone_fn_ids)
530 21157 : clone_fn_ids = hash_map<const char *, unsigned int>::create_ggc (64);
531 338478 : unsigned int &suffix_counter = clone_fn_ids->get_or_insert (
532 112826 : IDENTIFIER_POINTER (get_identifier (name)));
533 112826 : return clone_function_name (name, suffix, suffix_counter++);
534 : }
535 :
536 : /* Return a new assembler name for a clone of DECL. Apart from string
537 : SUFFIX, the new name will end with a unique (for each DECL
538 : assembler name) unspecified number. If clone numbering is not
539 : needed then the two argument clone_function_name should be used
540 : instead. */
541 :
542 : tree
543 112826 : clone_function_name_numbered (tree decl, const char *suffix)
544 : {
545 112826 : tree name = DECL_ASSEMBLER_NAME (decl);
546 112826 : return clone_function_name_numbered (IDENTIFIER_POINTER (name),
547 112826 : suffix);
548 : }
549 :
550 : /* Return a new assembler name for a clone of decl named NAME. Apart
551 : from the string SUFFIX, the new name will end with the specified
552 : NUMBER. If clone numbering is not needed then the two argument
553 : clone_function_name should be used instead. */
554 :
555 : tree
556 259553 : clone_function_name (const char *name, const char *suffix,
557 : unsigned long number)
558 : {
559 259553 : size_t len = strlen (name);
560 259553 : char *tmp_name, *prefix;
561 :
562 259553 : prefix = XALLOCAVEC (char, len + strlen (suffix) + 2);
563 259553 : memcpy (prefix, name, len);
564 259553 : strcpy (prefix + len + 1, suffix);
565 259553 : prefix[len] = symbol_table::symbol_suffix_separator ();
566 259553 : ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix, number);
567 259553 : return get_identifier (tmp_name);
568 : }
569 :
570 : /* Return a new assembler name for a clone of DECL. Apart from the
571 : string SUFFIX, the new name will end with the specified NUMBER. If
572 : clone numbering is not needed then the two argument
573 : clone_function_name should be used instead. */
574 :
575 : tree
576 146398 : clone_function_name (tree decl, const char *suffix,
577 : unsigned long number)
578 : {
579 292796 : return clone_function_name (
580 146398 : IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), suffix, number);
581 : }
582 :
583 : /* Return a new assembler name ending with the string SUFFIX for a
584 : clone of DECL. */
585 :
586 : tree
587 67004 : clone_function_name (tree decl, const char *suffix)
588 : {
589 67004 : tree identifier = DECL_ASSEMBLER_NAME (decl);
590 : /* For consistency this needs to behave the same way as
591 : ASM_FORMAT_PRIVATE_NAME does, but without the final number
592 : suffix. */
593 67004 : return clone_identifier (identifier, suffix);
594 : }
595 :
596 : /* Return true if symbol is valid in assembler name. */
597 :
598 : static bool
599 9810 : is_valid_asm_symbol (char c)
600 : {
601 9810 : if ('a' <= c && c <= 'z')
602 : return true;
603 1849 : if ('A' <= c && c <= 'Z')
604 : return true;
605 1849 : if ('0' <= c && c <= '9')
606 : return true;
607 812 : if (c == '_')
608 705 : return true;
609 : return false;
610 : }
611 :
612 : /* Return a new clone of ID ending with the string SUFFIX.
613 : If FILTER_SUFFIX is true, any illegal asm characters in the SUFFIX are
614 : replaced with _. */
615 :
616 : tree
617 68443 : clone_identifier (tree id, const char *suffix, bool filter_suffix)
618 : {
619 68443 : char *separator = XALLOCAVEC (char, 2);
620 68443 : separator[0] = symbol_table::symbol_suffix_separator ();
621 68443 : separator[1] = 0;
622 : #if defined (NO_DOT_IN_LABEL) && defined (NO_DOLLAR_IN_LABEL)
623 : const char *prefix = "__";
624 : #else
625 68443 : const char *prefix = "";
626 : #endif
627 68443 : if (!suffix)
628 161 : suffix = "";
629 :
630 68443 : if (!filter_suffix)
631 : {
632 67322 : char *result = ACONCAT (
633 : (prefix, IDENTIFIER_POINTER (id), separator, suffix, (char *) 0));
634 67322 : return get_identifier (result);
635 : }
636 : else
637 : {
638 : /* Replace any illegal chars with _. */
639 1121 : int suffix_len = strlen (suffix);
640 1121 : char *converted_suffix = XALLOCAVEC (char, suffix_len + 1);
641 10931 : for (int i = 0; i < suffix_len; i++)
642 9810 : if (!is_valid_asm_symbol (suffix[i]))
643 107 : converted_suffix[i] = '_';
644 : else
645 9703 : converted_suffix[i] = suffix[i];
646 1121 : converted_suffix[suffix_len] = '\0';
647 :
648 1121 : char *result = ACONCAT ((prefix, IDENTIFIER_POINTER (id), separator,
649 : converted_suffix, (char *) 0));
650 1121 : return get_identifier (result);
651 : }
652 : }
653 :
654 : /* Create callgraph node clone with new declaration. The actual body will be
655 : copied later at compilation stage. The name of the new clone will be
656 : constructed from the name of the original node, SUFFIX and NUM_SUFFIX.
657 :
658 : TODO: after merging in ipa-sra use function call notes instead of args_to_skip
659 : bitmap interface.
660 : */
661 : cgraph_node *
662 146398 : cgraph_node::create_virtual_clone (const vec<cgraph_edge *> &redirect_callers,
663 : vec<ipa_replace_map *, va_gc> *tree_map,
664 : ipa_param_adjustments *param_adjustments,
665 : const char * suffix, unsigned num_suffix)
666 : {
667 146398 : tree old_decl = decl;
668 146398 : cgraph_node *new_node = NULL;
669 146398 : tree new_decl;
670 146398 : size_t len, i;
671 146398 : ipa_replace_map *map;
672 146398 : char *name;
673 :
674 146398 : gcc_checking_assert (versionable);
675 : /* TODO: It would be nice if we could recognize that param_adjustments do not
676 : actually perform any changes, but at the moment let's require it simply
677 : does not exist. */
678 146398 : gcc_assert (can_change_signature || !param_adjustments);
679 :
680 : /* Make a new FUNCTION_DECL tree node */
681 144983 : if (!param_adjustments)
682 6022 : new_decl = copy_node (old_decl);
683 : else
684 140376 : new_decl = param_adjustments->adjust_decl (old_decl);
685 :
686 : /* These pointers represent function body and will be populated only when clone
687 : is materialized. */
688 146398 : gcc_assert (new_decl != old_decl);
689 146398 : DECL_STRUCT_FUNCTION (new_decl) = NULL;
690 146398 : DECL_ARGUMENTS (new_decl) = NULL;
691 146398 : DECL_INITIAL (new_decl) = NULL;
692 146398 : DECL_RESULT (new_decl) = NULL;
693 : /* We cannot do DECL_RESULT (new_decl) = NULL; here because of LTO partitioning
694 : sometimes storing only clone decl instead of original. */
695 :
696 : /* Generate a new name for the new version. */
697 146398 : len = IDENTIFIER_LENGTH (DECL_NAME (old_decl));
698 146398 : name = XALLOCAVEC (char, len + strlen (suffix) + 2);
699 146398 : memcpy (name, IDENTIFIER_POINTER (DECL_NAME (old_decl)), len);
700 146398 : strcpy (name + len + 1, suffix);
701 146398 : name[len] = '.';
702 146398 : DECL_NAME (new_decl) = get_identifier (name);
703 146398 : SET_DECL_ASSEMBLER_NAME (new_decl,
704 : clone_function_name (old_decl, suffix, num_suffix));
705 146398 : SET_DECL_RTL (new_decl, NULL);
706 :
707 146398 : new_node = create_clone (new_decl, count, false,
708 : redirect_callers, false, NULL, param_adjustments,
709 : suffix);
710 :
711 : /* Update the properties.
712 : Make clone visible only within this translation unit. Make sure
713 : that is not weak also.
714 : ??? We cannot use COMDAT linkage because there is no
715 : ABI support for this. */
716 146398 : set_new_clone_decl_and_node_flags (new_node);
717 146398 : new_node->ipcp_clone = ipcp_clone;
718 146398 : if (tree_map)
719 14157 : clone_info::get_create (new_node)->tree_map = tree_map;
720 146398 : if (!implicit_section)
721 146386 : new_node->set_section (*this);
722 :
723 : /* Clones of global symbols or symbols with unique names are unique. */
724 146398 : if ((TREE_PUBLIC (old_decl)
725 111340 : && !DECL_EXTERNAL (old_decl)
726 96077 : && !DECL_WEAK (old_decl)
727 1916 : && !DECL_COMDAT (old_decl))
728 255822 : || in_lto_p)
729 7142 : new_node->unique_name = true;
730 170894 : FOR_EACH_VEC_SAFE_ELT (tree_map, i, map)
731 : {
732 24496 : tree repl = map->new_tree;
733 24496 : if (map->force_load_ref)
734 : {
735 389 : gcc_assert (TREE_CODE (repl) == ADDR_EXPR);
736 389 : repl = get_base_address (TREE_OPERAND (repl, 0));
737 : }
738 24496 : new_node->maybe_create_reference (repl, NULL);
739 : }
740 :
741 146398 : if (ipa_transforms_to_apply.exists ())
742 127291 : new_node->ipa_transforms_to_apply
743 127291 : = ipa_transforms_to_apply.copy ();
744 :
745 146398 : symtab->call_cgraph_duplication_hooks (this, new_node);
746 :
747 146398 : return new_node;
748 : }
749 :
750 : /* callgraph node being removed from symbol table; see if its entry can be
751 : replaced by other inline clone.
752 : INFO is clone info to attach to the new root. */
753 : cgraph_node *
754 106741875 : cgraph_node::find_replacement (clone_info *info)
755 : {
756 106741875 : cgraph_node *next_inline_clone, *replacement;
757 :
758 106741875 : for (next_inline_clone = clones;
759 : next_inline_clone
760 106741875 : && next_inline_clone->decl != decl;
761 0 : next_inline_clone = next_inline_clone->next_sibling_clone)
762 : ;
763 :
764 : /* If there is inline clone of the node being removed, we need
765 : to put it into the position of removed node and reorganize all
766 : other clones to be based on it. */
767 106741875 : if (next_inline_clone)
768 : {
769 433025 : cgraph_node *n;
770 433025 : cgraph_node *new_clones;
771 :
772 433025 : replacement = next_inline_clone;
773 :
774 : /* Unlink inline clone from the list of clones of removed node. */
775 433025 : if (next_inline_clone->next_sibling_clone)
776 264854 : next_inline_clone->next_sibling_clone->prev_sibling_clone
777 264854 : = next_inline_clone->prev_sibling_clone;
778 433025 : if (next_inline_clone->prev_sibling_clone)
779 : {
780 0 : gcc_assert (clones != next_inline_clone);
781 0 : next_inline_clone->prev_sibling_clone->next_sibling_clone
782 0 : = next_inline_clone->next_sibling_clone;
783 : }
784 : else
785 : {
786 433025 : gcc_assert (clones == next_inline_clone);
787 433025 : clones = next_inline_clone->next_sibling_clone;
788 : }
789 :
790 433025 : new_clones = clones;
791 433025 : clones = NULL;
792 :
793 : /* Copy clone info. */
794 433025 : if (info)
795 68928 : *clone_info::get_create (next_inline_clone) = *info;
796 :
797 : /* Now place it into clone tree at same level at NODE. */
798 433025 : next_inline_clone->clone_of = clone_of;
799 433025 : next_inline_clone->prev_sibling_clone = NULL;
800 433025 : next_inline_clone->next_sibling_clone = NULL;
801 433025 : if (clone_of)
802 : {
803 3165 : if (clone_of->clones)
804 3165 : clone_of->clones->prev_sibling_clone = next_inline_clone;
805 3165 : next_inline_clone->next_sibling_clone = clone_of->clones;
806 3165 : clone_of->clones = next_inline_clone;
807 : }
808 :
809 : /* Merge the clone list. */
810 433025 : if (new_clones)
811 : {
812 264854 : if (!next_inline_clone->clones)
813 261530 : next_inline_clone->clones = new_clones;
814 : else
815 : {
816 : n = next_inline_clone->clones;
817 10744 : while (n->next_sibling_clone)
818 : n = n->next_sibling_clone;
819 3324 : n->next_sibling_clone = new_clones;
820 3324 : new_clones->prev_sibling_clone = n;
821 : }
822 : }
823 :
824 : /* Update clone_of pointers. */
825 433025 : n = new_clones;
826 3022642 : while (n)
827 : {
828 2589617 : n->clone_of = next_inline_clone;
829 2589617 : n = n->next_sibling_clone;
830 : }
831 :
832 : /* Update order in order to be able to find a LTO section
833 : with function body. */
834 433025 : replacement->order = order;
835 :
836 433025 : return replacement;
837 : }
838 : else
839 : return NULL;
840 : }
841 :
842 : /* Like cgraph_set_call_stmt but walk the clone tree and update all
843 : clones sharing the same function body.
844 : When WHOLE_SPECULATIVE_EDGES is true, all three components of
845 : speculative edge gets updated. Otherwise we update only direct
846 : call. */
847 :
848 : void
849 1928032 : cgraph_node::set_call_stmt_including_clones (gimple *old_stmt,
850 : gcall *new_stmt,
851 : bool update_speculative)
852 : {
853 1928032 : cgraph_node *node;
854 1928032 : cgraph_edge *master_edge = get_edge (old_stmt);
855 :
856 1928032 : if (master_edge)
857 1816993 : cgraph_edge::set_call_stmt (master_edge, new_stmt, update_speculative);
858 :
859 1928032 : node = clones;
860 1928032 : if (node)
861 1352772 : while (node != this)
862 : {
863 1090088 : cgraph_edge *edge = node->get_edge (old_stmt);
864 1090088 : if (edge)
865 : {
866 1083628 : edge = cgraph_edge::set_call_stmt (edge, new_stmt,
867 : update_speculative);
868 : /* If UPDATE_SPECULATIVE is false, it means that we are turning
869 : speculative call into a real code sequence. Update the
870 : callgraph edges. */
871 1083628 : if (edge->speculative && !update_speculative)
872 : {
873 0 : cgraph_edge *indirect = edge->speculative_call_indirect_edge ();
874 :
875 0 : for (cgraph_edge *next, *direct
876 0 : = edge->first_speculative_call_target ();
877 0 : direct;
878 0 : direct = next)
879 : {
880 0 : next = direct->next_speculative_call_target ();
881 0 : direct->speculative_call_target_ref ()->speculative = false;
882 0 : direct->speculative = false;
883 : }
884 0 : indirect->speculative = false;
885 : }
886 : }
887 1090088 : if (node->clones)
888 : node = node->clones;
889 1044267 : else if (node->next_sibling_clone)
890 : node = node->next_sibling_clone;
891 : else
892 : {
893 594658 : while (node != this && !node->next_sibling_clone)
894 308505 : node = node->clone_of;
895 286153 : if (node != this)
896 23469 : node = node->next_sibling_clone;
897 : }
898 : }
899 1928032 : }
900 :
901 : /* Like cgraph_create_edge walk the clone tree and update all clones sharing
902 : same function body. If clones already have edge for OLD_STMT; only
903 : update the edge same way as cgraph_set_call_stmt_including_clones does.
904 :
905 : TODO: COUNT and LOOP_DEPTH should be properly distributed based on relative
906 : frequencies of the clones. */
907 :
908 : void
909 0 : cgraph_node::create_edge_including_clones (cgraph_node *callee,
910 : gimple *old_stmt, gcall *stmt,
911 : profile_count count,
912 : cgraph_inline_failed_t reason)
913 : {
914 0 : cgraph_node *node;
915 :
916 0 : if (!get_edge (stmt))
917 : {
918 0 : cgraph_edge *edge = create_edge (callee, stmt, count);
919 0 : edge->inline_failed = reason;
920 : }
921 :
922 0 : node = clones;
923 0 : if (node)
924 0 : while (node != this)
925 : /* Thunk clones do not get updated while copying inline function body. */
926 0 : if (!node->thunk)
927 : {
928 0 : cgraph_edge *edge = node->get_edge (old_stmt);
929 :
930 : /* It is possible that clones already contain the edge while
931 : master didn't. Either we promoted indirect call into direct
932 : call in the clone or we are processing clones of unreachable
933 : master where edges has been removed. */
934 0 : if (edge)
935 0 : edge = cgraph_edge::set_call_stmt (edge, stmt);
936 0 : else if (! node->get_edge (stmt))
937 : {
938 0 : edge = node->create_edge (callee, stmt, count);
939 0 : edge->inline_failed = reason;
940 : }
941 :
942 0 : if (node->clones)
943 : node = node->clones;
944 0 : else if (node->next_sibling_clone)
945 : node = node->next_sibling_clone;
946 : else
947 : {
948 0 : while (node != this && !node->next_sibling_clone)
949 0 : node = node->clone_of;
950 0 : if (node != this)
951 0 : node = node->next_sibling_clone;
952 : }
953 : }
954 0 : }
955 :
956 : /* Remove the node from cgraph and all inline clones inlined into it.
957 : Skip however removal of FORBIDDEN_NODE and return true if it needs to be
958 : removed. This allows to call the function from outer loop walking clone
959 : tree. */
960 :
961 : bool
962 518 : cgraph_node::remove_symbol_and_inline_clones (cgraph_node *forbidden_node)
963 : {
964 518 : cgraph_edge *e, *next;
965 518 : bool found = false;
966 :
967 518 : if (this == forbidden_node)
968 : {
969 0 : cgraph_edge::remove (callers);
970 0 : return true;
971 : }
972 632 : for (e = callees; e; e = next)
973 : {
974 114 : next = e->next_callee;
975 114 : if (!e->inline_failed)
976 19 : found |= e->callee->remove_symbol_and_inline_clones (forbidden_node);
977 : }
978 518 : remove ();
979 518 : return found;
980 : }
981 :
982 : /* The edges representing the callers of the NEW_VERSION node were
983 : fixed by cgraph_function_versioning (), now the call_expr in their
984 : respective tree code should be updated to call the NEW_VERSION. */
985 :
986 : static void
987 58106 : update_call_expr (cgraph_node *new_version)
988 : {
989 58106 : cgraph_edge *e;
990 :
991 58106 : gcc_assert (new_version);
992 :
993 : /* Update the call expr on the edges to call the new version. */
994 58106 : for (e = new_version->callers; e; e = e->next_caller)
995 : {
996 0 : function *inner_function = DECL_STRUCT_FUNCTION (e->caller->decl);
997 0 : gimple_call_set_fndecl (e->call_stmt, new_version->decl);
998 0 : maybe_clean_eh_stmt_fn (inner_function, e->call_stmt);
999 : }
1000 58106 : }
1001 :
1002 :
1003 : /* Create a new cgraph node which is the new version of
1004 : callgraph node. REDIRECT_CALLERS holds the callers
1005 : edges which should be redirected to point to
1006 : NEW_VERSION. ALL the callees edges of the node
1007 : are cloned to the new version node. Return the new
1008 : version node.
1009 :
1010 : If non-NULL BLOCK_TO_COPY determine what basic blocks
1011 : was copied to prevent duplications of calls that are dead
1012 : in the clone. */
1013 :
1014 : cgraph_node *
1015 61304 : cgraph_node::create_version_clone (tree new_decl,
1016 : vec<cgraph_edge *> redirect_callers,
1017 : bitmap bbs_to_copy,
1018 : const char *suffix)
1019 : {
1020 61304 : cgraph_node *new_version;
1021 61304 : cgraph_edge *e;
1022 61304 : unsigned i;
1023 :
1024 61304 : new_version = cgraph_node::create (new_decl);
1025 :
1026 61304 : new_version->analyzed = analyzed;
1027 61304 : new_version->definition = definition;
1028 61304 : new_version->local = local;
1029 61304 : new_version->externally_visible = false;
1030 61304 : new_version->no_reorder = no_reorder;
1031 61304 : new_version->local = new_version->definition;
1032 61304 : new_version->inlined_to = inlined_to;
1033 61304 : new_version->rtl = rtl;
1034 61304 : new_version->count = count;
1035 61304 : new_version->unit_id = unit_id;
1036 61304 : new_version->merged_comdat = merged_comdat;
1037 61304 : new_version->merged_extern_inline = merged_extern_inline;
1038 :
1039 312618 : for (e = callees; e; e=e->next_callee)
1040 251314 : if (!bbs_to_copy
1041 251314 : || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
1042 191257 : e->clone (new_version, e->call_stmt,
1043 : e->lto_stmt_uid, count, count,
1044 : true);
1045 68987 : for (e = indirect_calls; e; e=e->next_callee)
1046 7683 : if (!bbs_to_copy
1047 7683 : || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
1048 5167 : e->clone (new_version, e->call_stmt,
1049 : e->lto_stmt_uid, count, count,
1050 : true);
1051 61304 : FOR_EACH_VEC_ELT (redirect_callers, i, e)
1052 : {
1053 : /* Redirect calls to the old version node to point to its new
1054 : version. */
1055 0 : e->redirect_callee (new_version);
1056 : }
1057 61304 : new_version->calls_comdat_local = new_version->check_calls_comdat_local_p ();
1058 :
1059 61304 : dump_callgraph_transformation (this, new_version, suffix);
1060 :
1061 61304 : return new_version;
1062 : }
1063 :
1064 : /* Perform function versioning.
1065 : Function versioning includes copying of the tree and
1066 : a callgraph update (creating a new cgraph node and updating
1067 : its callees and callers).
1068 :
1069 : REDIRECT_CALLERS varray includes the edges to be redirected
1070 : to the new version.
1071 :
1072 : TREE_MAP is a mapping of tree nodes we want to replace with
1073 : new ones (according to results of prior analysis).
1074 :
1075 : If non-NULL PARAM_ADJUSTMENTS determine how function formal parameters
1076 : should be modified in the new version and if it should return void.
1077 : If non-NULL BLOCK_TO_COPY determine what basic blocks to copy.
1078 : If non_NULL NEW_ENTRY determine new entry BB of the clone.
1079 : SUFFIX is a string that will be used to create a new name for the new
1080 : function.
1081 :
1082 : If TARGET_ATTRIBUTES is non-null, when creating a new declaration,
1083 : add the attributes to DECL_ATTRIBUTES. And call valid_attribute_p
1084 : that will promote value of the attribute DECL_FUNCTION_SPECIFIC_TARGET
1085 : of the declaration.
1086 :
1087 : If VERSION_DECL is set true, use clone_function_name_numbered for the
1088 : function clone. Otherwise, use clone_function_name.
1089 :
1090 : Return the new version's cgraph node. */
1091 :
1092 : cgraph_node *
1093 58107 : cgraph_node::create_version_clone_with_body
1094 : (vec<cgraph_edge *> redirect_callers,
1095 : vec<ipa_replace_map *, va_gc> *tree_map,
1096 : ipa_param_adjustments *param_adjustments,
1097 : bitmap bbs_to_copy, basic_block new_entry_block, const char *suffix,
1098 : tree target_attributes, bool version_decl)
1099 : {
1100 58107 : tree old_decl = decl;
1101 58107 : cgraph_node *new_version_node = NULL;
1102 58107 : tree new_decl;
1103 :
1104 58107 : if (!tree_versionable_function_p (old_decl))
1105 : return NULL;
1106 :
1107 : /* TODO: Restore an assert that we do not change signature if
1108 : can_change_signature is false. We cannot just check that
1109 : param_adjustments is NULL because unfortunately ipa-split removes return
1110 : values from such functions. */
1111 :
1112 : /* Make a new FUNCTION_DECL tree node for the new version. */
1113 58107 : if (param_adjustments)
1114 29880 : new_decl = param_adjustments->adjust_decl (old_decl);
1115 : else
1116 28227 : new_decl = copy_node (old_decl);
1117 :
1118 : /* Generate a new name for the new version. */
1119 58107 : tree fnname = (version_decl ? clone_function_name_numbered (old_decl, suffix)
1120 125 : : clone_function_name (old_decl, suffix));
1121 58107 : DECL_NAME (new_decl) = fnname;
1122 58107 : SET_DECL_ASSEMBLER_NAME (new_decl, fnname);
1123 58107 : SET_DECL_RTL (new_decl, NULL);
1124 :
1125 58107 : DECL_VIRTUAL_P (new_decl) = 0;
1126 :
1127 58107 : if (target_attributes)
1128 : {
1129 125 : DECL_ATTRIBUTES (new_decl) = target_attributes;
1130 :
1131 125 : location_t saved_loc = input_location;
1132 125 : tree v = TREE_VALUE (target_attributes);
1133 125 : input_location = DECL_SOURCE_LOCATION (new_decl);
1134 125 : bool r;
1135 125 : tree name_id = get_attribute_name (target_attributes);
1136 125 : const char *name_str = IDENTIFIER_POINTER (name_id);
1137 125 : if (strcmp (name_str, "target") == 0)
1138 125 : r = targetm.target_option.valid_attribute_p (new_decl, name_id, v, 1);
1139 0 : else if (strcmp (name_str, "target_version") == 0)
1140 0 : r = targetm.target_option.valid_version_attribute_p (new_decl, name_id,
1141 : v, 1);
1142 : else
1143 0 : gcc_unreachable();
1144 :
1145 125 : input_location = saved_loc;
1146 125 : if (!r)
1147 : return NULL;
1148 : }
1149 :
1150 : /* When the old decl was a con-/destructor make sure the clone isn't. */
1151 58106 : DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
1152 58106 : DECL_STATIC_DESTRUCTOR (new_decl) = 0;
1153 58106 : DECL_SET_IS_OPERATOR_NEW (new_decl, 0);
1154 58106 : DECL_SET_IS_OPERATOR_DELETE (new_decl, 0);
1155 58106 : DECL_IS_REPLACEABLE_OPERATOR (new_decl) = 0;
1156 :
1157 : /* Create the new version's call-graph node.
1158 : and update the edges of the new node. */
1159 58106 : new_version_node = create_version_clone (new_decl, redirect_callers,
1160 : bbs_to_copy, suffix);
1161 :
1162 58106 : if (ipa_transforms_to_apply.exists ())
1163 0 : new_version_node->ipa_transforms_to_apply
1164 0 : = ipa_transforms_to_apply.copy ();
1165 : /* Copy the OLD_VERSION_NODE function tree to the new version. */
1166 58106 : tree_function_versioning (old_decl, new_decl, tree_map, param_adjustments,
1167 : false, bbs_to_copy, new_entry_block);
1168 :
1169 : /* Update the new version's properties.
1170 : Make The new version visible only within this translation unit. Make sure
1171 : that is not weak also.
1172 : ??? We cannot use COMDAT linkage because there is no
1173 : ABI support for this. */
1174 58106 : new_version_node->make_decl_local ();
1175 58106 : DECL_VIRTUAL_P (new_version_node->decl) = 0;
1176 58106 : new_version_node->externally_visible = 0;
1177 58106 : new_version_node->local = 1;
1178 58106 : new_version_node->lowered = true;
1179 58106 : if (!implicit_section)
1180 58090 : new_version_node->set_section (*this);
1181 : /* Clones of global symbols or symbols with unique names are unique. */
1182 58106 : if ((TREE_PUBLIC (old_decl)
1183 54426 : && !DECL_EXTERNAL (old_decl)
1184 44033 : && !DECL_WEAK (old_decl)
1185 13212 : && !DECL_COMDAT (old_decl))
1186 99320 : || in_lto_p)
1187 13252 : new_version_node->unique_name = true;
1188 :
1189 : /* Update the call_expr on the edges to call the new version node. */
1190 58106 : update_call_expr (new_version_node);
1191 :
1192 58106 : symtab->call_cgraph_insertion_hooks (new_version_node);
1193 58106 : return new_version_node;
1194 : }
1195 :
1196 : /* Remove the node from the tree of virtual and inline clones and make it a
1197 : standalone node - not a clone any more. */
1198 :
1199 145833 : void cgraph_node::remove_from_clone_tree ()
1200 : {
1201 145833 : if (next_sibling_clone)
1202 953 : next_sibling_clone->prev_sibling_clone = prev_sibling_clone;
1203 145833 : if (prev_sibling_clone)
1204 1513 : prev_sibling_clone->next_sibling_clone = next_sibling_clone;
1205 : else
1206 144320 : clone_of->clones = next_sibling_clone;
1207 145833 : next_sibling_clone = NULL;
1208 145833 : prev_sibling_clone = NULL;
1209 145833 : clone_of = NULL;
1210 145833 : }
1211 :
1212 : /* Given virtual clone, turn it into actual clone. */
1213 :
1214 : void
1215 145833 : cgraph_node::materialize_clone ()
1216 : {
1217 145833 : clone_info *info = clone_info::get (this);
1218 145833 : clone_of->get_untransformed_body ();
1219 145833 : former_clone_of = clone_of->decl;
1220 145833 : if (clone_of->former_clone_of)
1221 4325 : former_clone_of = clone_of->former_clone_of;
1222 145833 : if (symtab->dump_file)
1223 : {
1224 0 : fprintf (symtab->dump_file, "cloning %s to %s\n",
1225 0 : clone_of->dump_name (),
1226 : dump_name ());
1227 0 : if (info && info->tree_map)
1228 : {
1229 0 : fprintf (symtab->dump_file, " replace map:");
1230 0 : for (unsigned int i = 0;
1231 0 : i < vec_safe_length (info->tree_map);
1232 : i++)
1233 : {
1234 0 : ipa_replace_map *replace_info;
1235 0 : replace_info = (*info->tree_map)[i];
1236 0 : fprintf (symtab->dump_file, "%s %i -> ",
1237 : i ? "," : "", replace_info->parm_num);
1238 0 : print_generic_expr (symtab->dump_file,
1239 : replace_info->new_tree);
1240 : }
1241 0 : fprintf (symtab->dump_file, "\n");
1242 : }
1243 0 : if (info && info->param_adjustments)
1244 0 : info->param_adjustments->dump (symtab->dump_file);
1245 : }
1246 145833 : clear_stmts_in_references ();
1247 : /* Copy the OLD_VERSION_NODE function tree to the new version. */
1248 145833 : tree_function_versioning (clone_of->decl, decl,
1249 : info ? info->tree_map : NULL,
1250 : info ? info->param_adjustments : NULL,
1251 : true, NULL, NULL);
1252 145833 : if (symtab->dump_file)
1253 : {
1254 0 : dump_function_to_file (clone_of->decl, symtab->dump_file,
1255 : dump_flags);
1256 0 : dump_function_to_file (decl, symtab->dump_file, dump_flags);
1257 : }
1258 :
1259 145833 : cgraph_node *this_clone_of = clone_of;
1260 : /* Function is no longer clone. */
1261 145833 : remove_from_clone_tree ();
1262 145833 : if (!this_clone_of->analyzed && !this_clone_of->clones)
1263 142208 : this_clone_of->release_body ();
1264 145833 : }
1265 :
1266 : #include "gt-cgraphclones.h"
|