Branch data Line data Source code
1 : : /* Callgraph clones
2 : : Copyright (C) 2003-2024 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 : 5887372 : 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 : 5887372 : cgraph_edge *new_edge;
103 : 5887372 : profile_count::adjust_for_ipa_scaling (&num, &den);
104 : 5887372 : profile_count prof_count = count.apply_scale (num, den);
105 : :
106 : 5887372 : if (indirect_unknown_callee)
107 : : {
108 : 161261 : tree decl;
109 : :
110 : 161034 : 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 : 166523 : && !speculative)
114 : : {
115 : 5262 : cgraph_node *callee = cgraph_node::get (decl);
116 : 5262 : gcc_checking_assert (callee);
117 : 5262 : new_edge = n->create_edge (callee, call_stmt, prof_count, true);
118 : : }
119 : : else
120 : : {
121 : 311998 : new_edge = n->create_indirect_edge (call_stmt,
122 : 155999 : indirect_info->ecf_flags,
123 : : prof_count, true);
124 : 155999 : *new_edge->indirect_info = *indirect_info;
125 : : }
126 : : }
127 : : else
128 : : {
129 : 5726111 : new_edge = n->create_edge (callee, call_stmt, prof_count, true);
130 : 5726111 : if (indirect_info)
131 : : {
132 : 0 : new_edge->indirect_info
133 : 0 : = ggc_cleared_alloc<cgraph_indirect_call_info> ();
134 : 0 : *new_edge->indirect_info = *indirect_info;
135 : : }
136 : : }
137 : :
138 : 5887372 : new_edge->inline_failed = inline_failed;
139 : 5887372 : new_edge->indirect_inlining_edge = indirect_inlining_edge;
140 : 5887372 : if (!call_stmt)
141 : 228235 : new_edge->lto_stmt_uid = stmt_uid;
142 : 5887372 : new_edge->speculative_id = speculative_id;
143 : : /* Clone flags that depend on call_stmt availability manually. */
144 : 5887372 : new_edge->can_throw_external = can_throw_external;
145 : 5887372 : new_edge->call_stmt_cannot_inline_p = call_stmt_cannot_inline_p;
146 : 5887372 : new_edge->speculative = speculative;
147 : 5887372 : new_edge->in_polymorphic_cdtor = in_polymorphic_cdtor;
148 : :
149 : : /* Update IPA profile. Local profiles need no updating in original. */
150 : 5887372 : if (update_original)
151 : 5289301 : count = count.combine_with_ipa_count_within (count.ipa ()
152 : 5289301 : - new_edge->count.ipa (),
153 : 5289301 : caller->count);
154 : 5887372 : symtab->call_edge_duplication_hooks (this, new_edge);
155 : 5887372 : return new_edge;
156 : : }
157 : :
158 : : /* Set flags of NEW_NODE and its decl. NEW_NODE is a newly created private
159 : : clone or its thunk. */
160 : :
161 : : static void
162 : 111335 : set_new_clone_decl_and_node_flags (cgraph_node *new_node)
163 : : {
164 : 111335 : DECL_EXTERNAL (new_node->decl) = 0;
165 : 111335 : TREE_PUBLIC (new_node->decl) = 0;
166 : 111335 : DECL_COMDAT (new_node->decl) = 0;
167 : 111335 : DECL_WEAK (new_node->decl) = 0;
168 : 111335 : DECL_VIRTUAL_P (new_node->decl) = 0;
169 : 111335 : DECL_STATIC_CONSTRUCTOR (new_node->decl) = 0;
170 : 111335 : DECL_STATIC_DESTRUCTOR (new_node->decl) = 0;
171 : 111335 : DECL_SET_IS_OPERATOR_NEW (new_node->decl, 0);
172 : 111335 : DECL_SET_IS_OPERATOR_DELETE (new_node->decl, 0);
173 : 111335 : DECL_IS_REPLACEABLE_OPERATOR (new_node->decl) = 0;
174 : :
175 : 111335 : new_node->externally_visible = 0;
176 : 111335 : new_node->local = 1;
177 : 111335 : new_node->lowered = true;
178 : 111335 : new_node->semantic_interposition = 0;
179 : 111335 : }
180 : :
181 : : /* Duplicate thunk THUNK if necessary but make it to refer to NODE.
182 : : ARGS_TO_SKIP, if non-NULL, determines which parameters should be omitted.
183 : : Function can return NODE if no thunk is necessary, which can happen when
184 : : thunk is this_adjusting but we are removing this parameter. */
185 : :
186 : : static cgraph_node *
187 : 76 : duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node)
188 : : {
189 : 76 : cgraph_node *new_thunk, *thunk_of;
190 : 76 : thunk_of = thunk->callees->callee->ultimate_alias_target ();
191 : :
192 : 76 : if (thunk_of->thunk)
193 : 0 : node = duplicate_thunk_for_node (thunk_of, node);
194 : :
195 : 76 : if (!DECL_ARGUMENTS (thunk->decl))
196 : 1 : thunk->get_untransformed_body ();
197 : :
198 : 76 : thunk_info *i = thunk_info::get (thunk);
199 : 76 : cgraph_edge *cs;
200 : 94 : for (cs = node->callers; cs; cs = cs->next_caller)
201 : 36 : if (cs->caller->thunk)
202 : : {
203 : 18 : thunk_info *i2 = thunk_info::get (cs->caller);
204 : 18 : if (*i2 == *i)
205 : : return cs->caller;
206 : : }
207 : :
208 : 58 : tree new_decl;
209 : 58 : clone_info *info = clone_info::get (node);
210 : 58 : if (info && info->param_adjustments)
211 : : {
212 : : /* We do not need to duplicate this_adjusting thunks if we have removed
213 : : this. */
214 : 55 : if (i->this_adjusting
215 : 55 : && !info->param_adjustments->first_param_intact_p ())
216 : 27 : return node;
217 : :
218 : 28 : new_decl = copy_node (thunk->decl);
219 : 28 : ipa_param_body_adjustments body_adj (info->param_adjustments,
220 : 28 : new_decl);
221 : 28 : body_adj.modify_formal_parameters ();
222 : 28 : }
223 : : else
224 : : {
225 : 3 : new_decl = copy_node (thunk->decl);
226 : 3 : for (tree *arg = &DECL_ARGUMENTS (new_decl);
227 : 9 : *arg; arg = &DECL_CHAIN (*arg))
228 : : {
229 : 6 : tree next = DECL_CHAIN (*arg);
230 : 6 : *arg = copy_node (*arg);
231 : 6 : DECL_CONTEXT (*arg) = new_decl;
232 : 6 : DECL_CHAIN (*arg) = next;
233 : : }
234 : : }
235 : :
236 : 31 : gcc_checking_assert (!DECL_STRUCT_FUNCTION (new_decl));
237 : 31 : gcc_checking_assert (!DECL_INITIAL (new_decl));
238 : 31 : gcc_checking_assert (!DECL_RESULT (new_decl));
239 : 31 : gcc_checking_assert (!DECL_RTL_SET_P (new_decl));
240 : :
241 : 31 : DECL_NAME (new_decl) = clone_function_name_numbered (thunk->decl,
242 : : "artificial_thunk");
243 : 31 : SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
244 : :
245 : : /* We need to force DECL_IGNORED_P because the new thunk is created after
246 : : early debug was run. */
247 : 31 : DECL_IGNORED_P (new_decl) = 1;
248 : :
249 : 31 : new_thunk = cgraph_node::create (new_decl);
250 : 31 : set_new_clone_decl_and_node_flags (new_thunk);
251 : 31 : new_thunk->definition = true;
252 : 31 : new_thunk->can_change_signature = node->can_change_signature;
253 : 31 : new_thunk->thunk = thunk->thunk;
254 : 31 : new_thunk->unique_name = in_lto_p;
255 : 31 : new_thunk->former_clone_of = thunk->decl;
256 : 31 : if (info && info->param_adjustments)
257 : 28 : clone_info::get_create (new_thunk)->param_adjustments
258 : 28 : = info->param_adjustments;
259 : 31 : new_thunk->unit_id = thunk->unit_id;
260 : 31 : new_thunk->merged_comdat = thunk->merged_comdat;
261 : 31 : new_thunk->merged_extern_inline = thunk->merged_extern_inline;
262 : :
263 : 31 : cgraph_edge *e = new_thunk->create_edge (node, NULL, new_thunk->count);
264 : 31 : symtab->call_edge_duplication_hooks (thunk->callees, e);
265 : 31 : symtab->call_cgraph_duplication_hooks (thunk, new_thunk);
266 : 31 : return new_thunk;
267 : : }
268 : :
269 : : /* If E does not lead to a thunk, simply redirect it to N. Otherwise create
270 : : one or more equivalent thunks for N and redirect E to the first in the
271 : : chain. Note that it is then necessary to call
272 : : n->expand_all_artificial_thunks once all callers are redirected. */
273 : :
274 : : void
275 : 274829 : cgraph_edge::redirect_callee_duplicating_thunks (cgraph_node *n)
276 : : {
277 : 274829 : cgraph_node *orig_to = callee->ultimate_alias_target ();
278 : 274829 : if (orig_to->thunk)
279 : 76 : n = duplicate_thunk_for_node (orig_to, n);
280 : :
281 : 274829 : redirect_callee (n);
282 : 274829 : }
283 : :
284 : : /* Call expand_thunk on all callers that are thunks and if analyze those nodes
285 : : that were expanded. */
286 : :
287 : : void
288 : 2620876 : cgraph_node::expand_all_artificial_thunks ()
289 : : {
290 : 2620876 : cgraph_edge *e;
291 : 2895930 : for (e = callers; e;)
292 : 275054 : if (e->caller->thunk)
293 : : {
294 : 34 : cgraph_node *thunk = e->caller;
295 : :
296 : 34 : e = e->next_caller;
297 : 34 : if (expand_thunk (thunk, false, false))
298 : : {
299 : 0 : thunk->thunk = false;
300 : 0 : thunk->analyze ();
301 : 0 : ipa_analyze_node (thunk);
302 : 0 : inline_analyze_function (thunk);
303 : : }
304 : 34 : thunk->expand_all_artificial_thunks ();
305 : : }
306 : : else
307 : 275020 : e = e->next_caller;
308 : 2620876 : }
309 : :
310 : : void
311 : 3939452 : dump_callgraph_transformation (const cgraph_node *original,
312 : : const cgraph_node *clone,
313 : : const char *suffix)
314 : : {
315 : 3939452 : if (symtab->ipa_clones_dump_file)
316 : : {
317 : 0 : fprintf (symtab->ipa_clones_dump_file,
318 : : "Callgraph clone;%s;%d;%s;%d;%d;%s;%d;%s;%d;%d;%s\n",
319 : 0 : original->asm_name (), original->order,
320 : 0 : DECL_SOURCE_FILE (original->decl),
321 : 0 : DECL_SOURCE_LINE (original->decl),
322 : 0 : DECL_SOURCE_COLUMN (original->decl), clone->asm_name (),
323 : 0 : clone->order, DECL_SOURCE_FILE (clone->decl),
324 : 0 : DECL_SOURCE_LINE (clone->decl), DECL_SOURCE_COLUMN (clone->decl),
325 : : suffix);
326 : :
327 : 0 : symtab->cloned_nodes.add (original);
328 : 0 : symtab->cloned_nodes.add (clone);
329 : : }
330 : 3939452 : }
331 : :
332 : : /* Turn profile of N to local profile. */
333 : :
334 : : static void
335 : 0 : localize_profile (cgraph_node *n)
336 : : {
337 : 0 : n->count = n->count.guessed_local ();
338 : 0 : for (cgraph_edge *e = n->callees; e; e=e->next_callee)
339 : : {
340 : 0 : e->count = e->count.guessed_local ();
341 : 0 : if (!e->inline_failed)
342 : 0 : localize_profile (e->callee);
343 : : }
344 : 0 : for (cgraph_edge *e = n->indirect_calls; e; e=e->next_callee)
345 : 0 : e->count = e->count.guessed_local ();
346 : 0 : }
347 : :
348 : : /* Create node representing clone of N executed COUNT times. Decrease
349 : : the execution counts from original node too.
350 : : The new clone will have decl set to DECL that may or may not be the same
351 : : as decl of N.
352 : :
353 : : When UPDATE_ORIGINAL is true, the counts are subtracted from the original
354 : : function's profile to reflect the fact that part of execution is handled
355 : : by node.
356 : : When CALL_DUPLICATION_HOOK is true, the ipa passes are acknowledged about
357 : : the new clone. Otherwise the caller is responsible for doing so later.
358 : :
359 : : If the new node is being inlined into another one, NEW_INLINED_TO should be
360 : : the outline function the new one is (even indirectly) inlined to. All hooks
361 : : will see this in node's inlined_to, when invoked. Can be NULL if the
362 : : node is not inlined.
363 : :
364 : : If PARAM_ADJUSTMENTS is non-NULL, the parameter manipulation information
365 : : will be overwritten by the new structure. Otherwise the new node will
366 : : share parameter manipulation information with the original node. */
367 : :
368 : : cgraph_node *
369 : 2620717 : cgraph_node::create_clone (tree new_decl, profile_count prof_count,
370 : : bool update_original,
371 : : vec<cgraph_edge *> redirect_callers,
372 : : bool call_duplication_hook,
373 : : cgraph_node *new_inlined_to,
374 : : ipa_param_adjustments *param_adjustments,
375 : : const char *suffix)
376 : : {
377 : 2620717 : cgraph_node *new_node = symtab->create_empty ();
378 : 2620717 : cgraph_edge *e;
379 : 2620717 : unsigned i;
380 : 2620717 : profile_count old_count = count;
381 : 2620717 : bool nonzero = count.ipa ().nonzero_p ();
382 : :
383 : 2620717 : if (new_inlined_to)
384 : 2485487 : dump_callgraph_transformation (this, new_inlined_to, "inlining to");
385 : :
386 : : /* When inlining we scale precisely to prof_count, when cloning we can
387 : : preserve local profile. */
388 : 2485487 : if (!new_inlined_to)
389 : 135230 : prof_count = count.combine_with_ipa_count (prof_count);
390 : 2620717 : new_node->count = prof_count;
391 : 2620717 : new_node->calls_declare_variant_alt = this->calls_declare_variant_alt;
392 : :
393 : : /* Update IPA profile. Local profiles need no updating in original. */
394 : 2620717 : if (update_original)
395 : : {
396 : 2468714 : if (inlined_to)
397 : 345331 : count = count.combine_with_ipa_count_within (count.ipa ()
398 : 690662 : - prof_count.ipa (),
399 : : inlined_to->count);
400 : : else
401 : 2123383 : count = count.combine_with_ipa_count (count.ipa () - prof_count.ipa ());
402 : : }
403 : 2620717 : new_node->decl = new_decl;
404 : 2620717 : new_node->order = order;
405 : 2620717 : new_node->register_symbol ();
406 : 2620717 : new_node->lto_file_data = lto_file_data;
407 : 2620717 : new_node->analyzed = analyzed;
408 : 2620717 : new_node->definition = definition;
409 : 2620717 : new_node->versionable = versionable;
410 : 2620717 : new_node->can_change_signature = can_change_signature;
411 : 2620717 : new_node->redefined_extern_inline = redefined_extern_inline;
412 : 2620717 : new_node->semantic_interposition = semantic_interposition;
413 : 2620717 : new_node->tm_may_enter_irr = tm_may_enter_irr;
414 : 2620717 : new_node->externally_visible = false;
415 : 2620717 : new_node->no_reorder = no_reorder;
416 : 2620717 : new_node->local = true;
417 : 2620717 : new_node->inlined_to = new_inlined_to;
418 : 2620717 : new_node->rtl = rtl;
419 : 2620717 : new_node->frequency = frequency;
420 : 2620717 : new_node->tp_first_run = tp_first_run;
421 : 2620717 : new_node->tm_clone = tm_clone;
422 : 2620717 : new_node->icf_merged = icf_merged;
423 : 2620717 : new_node->thunk = thunk;
424 : 2620717 : new_node->unit_id = unit_id;
425 : 2620717 : new_node->merged_comdat = merged_comdat;
426 : 2620717 : new_node->merged_extern_inline = merged_extern_inline;
427 : 2620717 : clone_info *info = clone_info::get (this);
428 : :
429 : 2620717 : if (param_adjustments)
430 : 106156 : clone_info::get_create (new_node)->param_adjustments = param_adjustments;
431 : 2514561 : else if (info && info->param_adjustments)
432 : 202930 : clone_info::get_create (new_node)->param_adjustments
433 : 202930 : = info->param_adjustments;
434 : 2620717 : new_node->split_part = split_part;
435 : :
436 : 2895334 : FOR_EACH_VEC_ELT (redirect_callers, i, e)
437 : : {
438 : : /* Redirect calls to the old version node to point to its new
439 : : version. The only exception is when the edge was proved to
440 : : be unreachable during the cloning procedure. */
441 : 274617 : if (!e->callee
442 : 274617 : || !fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE,
443 : : BUILT_IN_UNREACHABLE_TRAP))
444 : 274617 : e->redirect_callee_duplicating_thunks (new_node);
445 : : }
446 : 2620717 : new_node->expand_all_artificial_thunks ();
447 : :
448 : 5091703 : for (e = callees;e; e=e->next_callee)
449 : 2470986 : e->clone (new_node, e->call_stmt, e->lto_stmt_uid, new_node->count, old_count,
450 : : update_original);
451 : :
452 : 2692151 : for (e = indirect_calls; e; e = e->next_callee)
453 : 71434 : e->clone (new_node, e->call_stmt, e->lto_stmt_uid,
454 : : new_node->count, old_count, update_original);
455 : 2620717 : new_node->clone_references (this);
456 : :
457 : 2620717 : new_node->next_sibling_clone = clones;
458 : 2620717 : if (clones)
459 : 1254649 : clones->prev_sibling_clone = new_node;
460 : 2620717 : clones = new_node;
461 : 2620717 : new_node->clone_of = this;
462 : :
463 : 2620717 : if (call_duplication_hook)
464 : 2486946 : symtab->call_cgraph_duplication_hooks (this, new_node);
465 : : /* With partial train run we do not want to assume that original's
466 : : count is zero whenever we redurect all executed edges to clone.
467 : : Simply drop profile to local one in this case. */
468 : 2620717 : if (update_original
469 : 2468714 : && opt_for_fn (decl, flag_profile_partial_training)
470 : 0 : && nonzero
471 : 0 : && count.ipa_p ()
472 : 2620717 : && !count.ipa ().nonzero_p ()
473 : 2620717 : && !inlined_to)
474 : 0 : localize_profile (this);
475 : :
476 : 2620717 : if (!new_inlined_to)
477 : 135230 : dump_callgraph_transformation (this, new_node, suffix);
478 : :
479 : 2620717 : return new_node;
480 : : }
481 : :
482 : : static GTY(()) hash_map<const char *, unsigned> *clone_fn_ids;
483 : :
484 : : /* Return a new assembler name for a clone of decl named NAME. Apart
485 : : from the string SUFFIX, the new name will end with a unique (for
486 : : each NAME) unspecified number. If clone numbering is not needed
487 : : then the two argument clone_function_name should be used instead.
488 : : Should not be called directly except for by
489 : : lto-partition.cc:privatize_symbol_name_1. */
490 : :
491 : : tree
492 : 99303 : clone_function_name_numbered (const char *name, const char *suffix)
493 : : {
494 : : /* Initialize the function->counter mapping the first time it's
495 : : needed. */
496 : 99303 : if (!clone_fn_ids)
497 : 19232 : clone_fn_ids = hash_map<const char *, unsigned int>::create_ggc (64);
498 : 297909 : unsigned int &suffix_counter = clone_fn_ids->get_or_insert (
499 : 99303 : IDENTIFIER_POINTER (get_identifier (name)));
500 : 99303 : return clone_function_name (name, suffix, suffix_counter++);
501 : : }
502 : :
503 : : /* Return a new assembler name for a clone of DECL. Apart from string
504 : : SUFFIX, the new name will end with a unique (for each DECL
505 : : assembler name) unspecified number. If clone numbering is not
506 : : needed then the two argument clone_function_name should be used
507 : : instead. */
508 : :
509 : : tree
510 : 99303 : clone_function_name_numbered (tree decl, const char *suffix)
511 : : {
512 : 99303 : tree name = DECL_ASSEMBLER_NAME (decl);
513 : 99303 : return clone_function_name_numbered (IDENTIFIER_POINTER (name),
514 : 99303 : suffix);
515 : : }
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 the specified
519 : : NUMBER. If clone numbering is not needed then the two argument
520 : : clone_function_name should be used instead. */
521 : :
522 : : tree
523 : 210941 : clone_function_name (const char *name, const char *suffix,
524 : : unsigned long number)
525 : : {
526 : 210941 : size_t len = strlen (name);
527 : 210941 : char *tmp_name, *prefix;
528 : :
529 : 210941 : prefix = XALLOCAVEC (char, len + strlen (suffix) + 2);
530 : 210941 : memcpy (prefix, name, len);
531 : 210941 : strcpy (prefix + len + 1, suffix);
532 : 210941 : prefix[len] = symbol_table::symbol_suffix_separator ();
533 : 210941 : ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix, number);
534 : 210941 : return get_identifier (tmp_name);
535 : : }
536 : :
537 : : /* Return a new assembler name for a clone of DECL. Apart from the
538 : : string SUFFIX, the new name will end with the specified NUMBER. If
539 : : clone numbering is not needed then the two argument
540 : : clone_function_name should be used instead. */
541 : :
542 : : tree
543 : 111304 : clone_function_name (tree decl, const char *suffix,
544 : : unsigned long number)
545 : : {
546 : 222608 : return clone_function_name (
547 : 111304 : IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), suffix, number);
548 : : }
549 : :
550 : : /* Return a new assembler name ending with the string SUFFIX for a
551 : : clone of DECL. */
552 : :
553 : : tree
554 : 61609 : clone_function_name (tree decl, const char *suffix)
555 : : {
556 : 61609 : tree identifier = DECL_ASSEMBLER_NAME (decl);
557 : : /* For consistency this needs to behave the same way as
558 : : ASM_FORMAT_PRIVATE_NAME does, but without the final number
559 : : suffix. */
560 : 61609 : char *separator = XALLOCAVEC (char, 2);
561 : 61609 : separator[0] = symbol_table::symbol_suffix_separator ();
562 : 61609 : separator[1] = 0;
563 : : #if defined (NO_DOT_IN_LABEL) && defined (NO_DOLLAR_IN_LABEL)
564 : : const char *prefix = "__";
565 : : #else
566 : 61609 : const char *prefix = "";
567 : : #endif
568 : 61609 : char *result = ACONCAT ((prefix,
569 : : IDENTIFIER_POINTER (identifier),
570 : : separator,
571 : : suffix,
572 : : (char*)0));
573 : 61609 : return get_identifier (result);
574 : : }
575 : :
576 : :
577 : : /* Create callgraph node clone with new declaration. The actual body will be
578 : : copied later at compilation stage. The name of the new clone will be
579 : : constructed from the name of the original node, SUFFIX and NUM_SUFFIX.
580 : :
581 : : TODO: after merging in ipa-sra use function call notes instead of args_to_skip
582 : : bitmap interface.
583 : : */
584 : : cgraph_node *
585 : 111304 : cgraph_node::create_virtual_clone (const vec<cgraph_edge *> &redirect_callers,
586 : : vec<ipa_replace_map *, va_gc> *tree_map,
587 : : ipa_param_adjustments *param_adjustments,
588 : : const char * suffix, unsigned num_suffix)
589 : : {
590 : 111304 : tree old_decl = decl;
591 : 111304 : cgraph_node *new_node = NULL;
592 : 111304 : tree new_decl;
593 : 111304 : size_t len, i;
594 : 111304 : ipa_replace_map *map;
595 : 111304 : char *name;
596 : :
597 : 111304 : gcc_checking_assert (versionable);
598 : : /* TODO: It would be nice if we could recognize that param_adjustments do not
599 : : actually perform any changes, but at the moment let's require it simply
600 : : does not exist. */
601 : 111304 : gcc_assert (can_change_signature || !param_adjustments);
602 : :
603 : : /* Make a new FUNCTION_DECL tree node */
604 : 110166 : if (!param_adjustments)
605 : 5148 : new_decl = copy_node (old_decl);
606 : : else
607 : 106156 : new_decl = param_adjustments->adjust_decl (old_decl);
608 : :
609 : : /* These pointers represent function body and will be populated only when clone
610 : : is materialized. */
611 : 111304 : gcc_assert (new_decl != old_decl);
612 : 111304 : DECL_STRUCT_FUNCTION (new_decl) = NULL;
613 : 111304 : DECL_ARGUMENTS (new_decl) = NULL;
614 : 111304 : DECL_INITIAL (new_decl) = NULL;
615 : 111304 : DECL_RESULT (new_decl) = NULL;
616 : : /* We cannot do DECL_RESULT (new_decl) = NULL; here because of LTO partitioning
617 : : sometimes storing only clone decl instead of original. */
618 : :
619 : : /* Generate a new name for the new version. */
620 : 111304 : len = IDENTIFIER_LENGTH (DECL_NAME (old_decl));
621 : 111304 : name = XALLOCAVEC (char, len + strlen (suffix) + 2);
622 : 111304 : memcpy (name, IDENTIFIER_POINTER (DECL_NAME (old_decl)), len);
623 : 111304 : strcpy (name + len + 1, suffix);
624 : 111304 : name[len] = '.';
625 : 111304 : DECL_NAME (new_decl) = get_identifier (name);
626 : 111304 : SET_DECL_ASSEMBLER_NAME (new_decl,
627 : : clone_function_name (old_decl, suffix, num_suffix));
628 : 111304 : SET_DECL_RTL (new_decl, NULL);
629 : :
630 : 111304 : new_node = create_clone (new_decl, count, false,
631 : : redirect_callers, false, NULL, param_adjustments,
632 : : suffix);
633 : :
634 : : /* Update the properties.
635 : : Make clone visible only within this translation unit. Make sure
636 : : that is not weak also.
637 : : ??? We cannot use COMDAT linkage because there is no
638 : : ABI support for this. */
639 : 111304 : set_new_clone_decl_and_node_flags (new_node);
640 : 111304 : new_node->ipcp_clone = ipcp_clone;
641 : 111304 : if (tree_map)
642 : 10927 : clone_info::get_create (new_node)->tree_map = tree_map;
643 : 111304 : if (!implicit_section)
644 : 111272 : new_node->set_section (*this);
645 : :
646 : : /* Clones of global symbols or symbols with unique names are unique. */
647 : 111304 : if ((TREE_PUBLIC (old_decl)
648 : 81732 : && !DECL_EXTERNAL (old_decl)
649 : 74728 : && !DECL_WEAK (old_decl)
650 : 2173 : && !DECL_COMDAT (old_decl))
651 : 190863 : || in_lto_p)
652 : 5857 : new_node->unique_name = true;
653 : 129320 : FOR_EACH_VEC_SAFE_ELT (tree_map, i, map)
654 : : {
655 : 18016 : tree repl = map->new_tree;
656 : 18016 : if (map->force_load_ref)
657 : : {
658 : 300 : gcc_assert (TREE_CODE (repl) == ADDR_EXPR);
659 : 300 : repl = get_base_address (TREE_OPERAND (repl, 0));
660 : : }
661 : 18016 : new_node->maybe_create_reference (repl, NULL);
662 : : }
663 : :
664 : 111304 : if (ipa_transforms_to_apply.exists ())
665 : 93932 : new_node->ipa_transforms_to_apply
666 : 93932 : = ipa_transforms_to_apply.copy ();
667 : :
668 : 111304 : symtab->call_cgraph_duplication_hooks (this, new_node);
669 : :
670 : 111304 : return new_node;
671 : : }
672 : :
673 : : /* callgraph node being removed from symbol table; see if its entry can be
674 : : replaced by other inline clone.
675 : : INFO is clone info to attach to the new root. */
676 : : cgraph_node *
677 : 88811343 : cgraph_node::find_replacement (clone_info *info)
678 : : {
679 : 88811343 : cgraph_node *next_inline_clone, *replacement;
680 : :
681 : 88811343 : for (next_inline_clone = clones;
682 : : next_inline_clone
683 : 88811343 : && next_inline_clone->decl != decl;
684 : 0 : next_inline_clone = next_inline_clone->next_sibling_clone)
685 : : ;
686 : :
687 : : /* If there is inline clone of the node being removed, we need
688 : : to put it into the position of removed node and reorganize all
689 : : other clones to be based on it. */
690 : 88811343 : if (next_inline_clone)
691 : : {
692 : 348049 : cgraph_node *n;
693 : 348049 : cgraph_node *new_clones;
694 : :
695 : 348049 : replacement = next_inline_clone;
696 : :
697 : : /* Unlink inline clone from the list of clones of removed node. */
698 : 348049 : if (next_inline_clone->next_sibling_clone)
699 : 212371 : next_inline_clone->next_sibling_clone->prev_sibling_clone
700 : 212371 : = next_inline_clone->prev_sibling_clone;
701 : 348049 : if (next_inline_clone->prev_sibling_clone)
702 : : {
703 : 0 : gcc_assert (clones != next_inline_clone);
704 : 0 : next_inline_clone->prev_sibling_clone->next_sibling_clone
705 : 0 : = next_inline_clone->next_sibling_clone;
706 : : }
707 : : else
708 : : {
709 : 348049 : gcc_assert (clones == next_inline_clone);
710 : 348049 : clones = next_inline_clone->next_sibling_clone;
711 : : }
712 : :
713 : 348049 : new_clones = clones;
714 : 348049 : clones = NULL;
715 : :
716 : : /* Copy clone info. */
717 : 348049 : if (info)
718 : 51552 : *clone_info::get_create (next_inline_clone) = *info;
719 : :
720 : : /* Now place it into clone tree at same level at NODE. */
721 : 348049 : next_inline_clone->clone_of = clone_of;
722 : 348049 : next_inline_clone->prev_sibling_clone = NULL;
723 : 348049 : next_inline_clone->next_sibling_clone = NULL;
724 : 348049 : if (clone_of)
725 : : {
726 : 2305 : if (clone_of->clones)
727 : 2305 : clone_of->clones->prev_sibling_clone = next_inline_clone;
728 : 2305 : next_inline_clone->next_sibling_clone = clone_of->clones;
729 : 2305 : clone_of->clones = next_inline_clone;
730 : : }
731 : :
732 : : /* Merge the clone list. */
733 : 348049 : if (new_clones)
734 : : {
735 : 212371 : if (!next_inline_clone->clones)
736 : 210216 : next_inline_clone->clones = new_clones;
737 : : else
738 : : {
739 : : n = next_inline_clone->clones;
740 : 11155 : while (n->next_sibling_clone)
741 : : n = n->next_sibling_clone;
742 : 2155 : n->next_sibling_clone = new_clones;
743 : 2155 : new_clones->prev_sibling_clone = n;
744 : : }
745 : : }
746 : :
747 : : /* Update clone_of pointers. */
748 : : n = new_clones;
749 : 2539236 : while (n)
750 : : {
751 : 2191187 : n->clone_of = next_inline_clone;
752 : 2191187 : n = n->next_sibling_clone;
753 : : }
754 : :
755 : : /* Update order in order to be able to find a LTO section
756 : : with function body. */
757 : 348049 : replacement->order = order;
758 : :
759 : 348049 : return replacement;
760 : : }
761 : : else
762 : : return NULL;
763 : : }
764 : :
765 : : /* Like cgraph_set_call_stmt but walk the clone tree and update all
766 : : clones sharing the same function body.
767 : : When WHOLE_SPECULATIVE_EDGES is true, all three components of
768 : : speculative edge gets updated. Otherwise we update only direct
769 : : call. */
770 : :
771 : : void
772 : 1386290 : cgraph_node::set_call_stmt_including_clones (gimple *old_stmt,
773 : : gcall *new_stmt,
774 : : bool update_speculative)
775 : : {
776 : 1386290 : cgraph_node *node;
777 : 1386290 : cgraph_edge *master_edge = get_edge (old_stmt);
778 : :
779 : 1386290 : if (master_edge)
780 : 1286725 : cgraph_edge::set_call_stmt (master_edge, new_stmt, update_speculative);
781 : :
782 : 1386290 : node = clones;
783 : 1386290 : if (node)
784 : 976139 : while (node != this)
785 : : {
786 : 765138 : cgraph_edge *edge = node->get_edge (old_stmt);
787 : 765138 : if (edge)
788 : : {
789 : 763173 : edge = cgraph_edge::set_call_stmt (edge, new_stmt,
790 : : update_speculative);
791 : : /* If UPDATE_SPECULATIVE is false, it means that we are turning
792 : : speculative call into a real code sequence. Update the
793 : : callgraph edges. */
794 : 763173 : if (edge->speculative && !update_speculative)
795 : : {
796 : 0 : cgraph_edge *indirect = edge->speculative_call_indirect_edge ();
797 : :
798 : 0 : for (cgraph_edge *next, *direct
799 : 0 : = edge->first_speculative_call_target ();
800 : 0 : direct;
801 : 0 : direct = next)
802 : : {
803 : 0 : next = direct->next_speculative_call_target ();
804 : 0 : direct->speculative_call_target_ref ()->speculative = false;
805 : 0 : direct->speculative = false;
806 : : }
807 : 0 : indirect->speculative = false;
808 : : }
809 : : }
810 : 765138 : if (node->clones)
811 : : node = node->clones;
812 : 741850 : else if (node->next_sibling_clone)
813 : : node = node->next_sibling_clone;
814 : : else
815 : : {
816 : 457392 : while (node != this && !node->next_sibling_clone)
817 : 234289 : node = node->clone_of;
818 : 223103 : if (node != this)
819 : 12102 : node = node->next_sibling_clone;
820 : : }
821 : : }
822 : 1386290 : }
823 : :
824 : : /* Like cgraph_create_edge walk the clone tree and update all clones sharing
825 : : same function body. If clones already have edge for OLD_STMT; only
826 : : update the edge same way as cgraph_set_call_stmt_including_clones does.
827 : :
828 : : TODO: COUNT and LOOP_DEPTH should be properly distributed based on relative
829 : : frequencies of the clones. */
830 : :
831 : : void
832 : 0 : cgraph_node::create_edge_including_clones (cgraph_node *callee,
833 : : gimple *old_stmt, gcall *stmt,
834 : : profile_count count,
835 : : cgraph_inline_failed_t reason)
836 : : {
837 : 0 : cgraph_node *node;
838 : :
839 : 0 : if (!get_edge (stmt))
840 : : {
841 : 0 : cgraph_edge *edge = create_edge (callee, stmt, count);
842 : 0 : edge->inline_failed = reason;
843 : : }
844 : :
845 : 0 : node = clones;
846 : 0 : if (node)
847 : 0 : while (node != this)
848 : : /* Thunk clones do not get updated while copying inline function body. */
849 : 0 : if (!node->thunk)
850 : : {
851 : 0 : cgraph_edge *edge = node->get_edge (old_stmt);
852 : :
853 : : /* It is possible that clones already contain the edge while
854 : : master didn't. Either we promoted indirect call into direct
855 : : call in the clone or we are processing clones of unreachable
856 : : master where edges has been removed. */
857 : 0 : if (edge)
858 : 0 : edge = cgraph_edge::set_call_stmt (edge, stmt);
859 : 0 : else if (! node->get_edge (stmt))
860 : : {
861 : 0 : edge = node->create_edge (callee, stmt, count);
862 : 0 : edge->inline_failed = reason;
863 : : }
864 : :
865 : 0 : if (node->clones)
866 : : node = node->clones;
867 : 0 : else if (node->next_sibling_clone)
868 : : node = node->next_sibling_clone;
869 : : else
870 : : {
871 : 0 : while (node != this && !node->next_sibling_clone)
872 : 0 : node = node->clone_of;
873 : 0 : if (node != this)
874 : 0 : node = node->next_sibling_clone;
875 : : }
876 : : }
877 : 0 : }
878 : :
879 : : /* Remove the node from cgraph and all inline clones inlined into it.
880 : : Skip however removal of FORBIDDEN_NODE and return true if it needs to be
881 : : removed. This allows to call the function from outer loop walking clone
882 : : tree. */
883 : :
884 : : bool
885 : 28 : cgraph_node::remove_symbol_and_inline_clones (cgraph_node *forbidden_node)
886 : : {
887 : 28 : cgraph_edge *e, *next;
888 : 28 : bool found = false;
889 : :
890 : 28 : if (this == forbidden_node)
891 : : {
892 : 0 : cgraph_edge::remove (callers);
893 : 0 : return true;
894 : : }
895 : 38 : for (e = callees; e; e = next)
896 : : {
897 : 10 : next = e->next_callee;
898 : 10 : if (!e->inline_failed)
899 : 0 : found |= e->callee->remove_symbol_and_inline_clones (forbidden_node);
900 : : }
901 : 28 : remove ();
902 : 28 : return found;
903 : : }
904 : :
905 : : /* The edges representing the callers of the NEW_VERSION node were
906 : : fixed by cgraph_function_versioning (), now the call_expr in their
907 : : respective tree code should be updated to call the NEW_VERSION. */
908 : :
909 : : static void
910 : 47896 : update_call_expr (cgraph_node *new_version)
911 : : {
912 : 47896 : cgraph_edge *e;
913 : :
914 : 47896 : gcc_assert (new_version);
915 : :
916 : : /* Update the call expr on the edges to call the new version. */
917 : 47896 : for (e = new_version->callers; e; e = e->next_caller)
918 : : {
919 : 0 : function *inner_function = DECL_STRUCT_FUNCTION (e->caller->decl);
920 : 0 : gimple_call_set_fndecl (e->call_stmt, new_version->decl);
921 : 0 : maybe_clean_eh_stmt_fn (inner_function, e->call_stmt);
922 : : }
923 : 47896 : }
924 : :
925 : :
926 : : /* Create a new cgraph node which is the new version of
927 : : callgraph node. REDIRECT_CALLERS holds the callers
928 : : edges which should be redirected to point to
929 : : NEW_VERSION. ALL the callees edges of the node
930 : : are cloned to the new version node. Return the new
931 : : version node.
932 : :
933 : : If non-NULL BLOCK_TO_COPY determine what basic blocks
934 : : was copied to prevent duplications of calls that are dead
935 : : in the clone. */
936 : :
937 : : cgraph_node *
938 : 50982 : cgraph_node::create_version_clone (tree new_decl,
939 : : vec<cgraph_edge *> redirect_callers,
940 : : bitmap bbs_to_copy,
941 : : const char *suffix)
942 : : {
943 : 50982 : cgraph_node *new_version;
944 : 50982 : cgraph_edge *e;
945 : 50982 : unsigned i;
946 : :
947 : 50982 : new_version = cgraph_node::create (new_decl);
948 : :
949 : 50982 : new_version->analyzed = analyzed;
950 : 50982 : new_version->definition = definition;
951 : 50982 : new_version->local = local;
952 : 50982 : new_version->externally_visible = false;
953 : 50982 : new_version->no_reorder = no_reorder;
954 : 50982 : new_version->local = new_version->definition;
955 : 50982 : new_version->inlined_to = inlined_to;
956 : 50982 : new_version->rtl = rtl;
957 : 50982 : new_version->count = count;
958 : 50982 : new_version->unit_id = unit_id;
959 : 50982 : new_version->merged_comdat = merged_comdat;
960 : 50982 : new_version->merged_extern_inline = merged_extern_inline;
961 : :
962 : 276146 : for (e = callees; e; e=e->next_callee)
963 : 225164 : if (!bbs_to_copy
964 : 225164 : || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
965 : 175964 : e->clone (new_version, e->call_stmt,
966 : : e->lto_stmt_uid, count, count,
967 : : true);
968 : 58281 : for (e = indirect_calls; e; e=e->next_callee)
969 : 7299 : if (!bbs_to_copy
970 : 7299 : || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
971 : 4892 : e->clone (new_version, e->call_stmt,
972 : : e->lto_stmt_uid, count, count,
973 : : true);
974 : 50982 : FOR_EACH_VEC_ELT (redirect_callers, i, e)
975 : : {
976 : : /* Redirect calls to the old version node to point to its new
977 : : version. */
978 : 0 : e->redirect_callee (new_version);
979 : : }
980 : :
981 : 50982 : dump_callgraph_transformation (this, new_version, suffix);
982 : :
983 : 50982 : return new_version;
984 : : }
985 : :
986 : : /* Perform function versioning.
987 : : Function versioning includes copying of the tree and
988 : : a callgraph update (creating a new cgraph node and updating
989 : : its callees and callers).
990 : :
991 : : REDIRECT_CALLERS varray includes the edges to be redirected
992 : : to the new version.
993 : :
994 : : TREE_MAP is a mapping of tree nodes we want to replace with
995 : : new ones (according to results of prior analysis).
996 : :
997 : : If non-NULL ARGS_TO_SKIP determine function parameters to remove
998 : : from new version.
999 : : If SKIP_RETURN is true, the new version will return void.
1000 : : If non-NULL BLOCK_TO_COPY determine what basic blocks to copy.
1001 : : If non_NULL NEW_ENTRY determine new entry BB of the clone.
1002 : :
1003 : : If TARGET_ATTRIBUTES is non-null, when creating a new declaration,
1004 : : add the attributes to DECL_ATTRIBUTES. And call valid_attribute_p
1005 : : that will promote value of the attribute DECL_FUNCTION_SPECIFIC_TARGET
1006 : : of the declaration.
1007 : :
1008 : : If VERSION_DECL is set true, use clone_function_name_numbered for the
1009 : : function clone. Otherwise, use clone_function_name.
1010 : :
1011 : : Return the new version's cgraph node. */
1012 : :
1013 : : cgraph_node *
1014 : 47897 : cgraph_node::create_version_clone_with_body
1015 : : (vec<cgraph_edge *> redirect_callers,
1016 : : vec<ipa_replace_map *, va_gc> *tree_map,
1017 : : ipa_param_adjustments *param_adjustments,
1018 : : bitmap bbs_to_copy, basic_block new_entry_block, const char *suffix,
1019 : : tree target_attributes, bool version_decl)
1020 : : {
1021 : 47897 : tree old_decl = decl;
1022 : 47897 : cgraph_node *new_version_node = NULL;
1023 : 47897 : tree new_decl;
1024 : :
1025 : 47897 : if (!tree_versionable_function_p (old_decl))
1026 : : return NULL;
1027 : :
1028 : : /* TODO: Restore an assert that we do not change signature if
1029 : : can_change_signature is false. We cannot just check that
1030 : : param_adjustments is NULL because unfortunately ipa-split removes return
1031 : : values from such functions. */
1032 : :
1033 : : /* Make a new FUNCTION_DECL tree node for the new version. */
1034 : 47897 : if (param_adjustments)
1035 : 24110 : new_decl = param_adjustments->adjust_decl (old_decl);
1036 : : else
1037 : 23787 : new_decl = copy_node (old_decl);
1038 : :
1039 : : /* Generate a new name for the new version. */
1040 : 47897 : tree fnname = (version_decl ? clone_function_name_numbered (old_decl, suffix)
1041 : 98 : : clone_function_name (old_decl, suffix));
1042 : 47897 : DECL_NAME (new_decl) = fnname;
1043 : 47897 : SET_DECL_ASSEMBLER_NAME (new_decl, fnname);
1044 : 47897 : SET_DECL_RTL (new_decl, NULL);
1045 : :
1046 : 47897 : DECL_VIRTUAL_P (new_decl) = 0;
1047 : :
1048 : 47897 : if (target_attributes)
1049 : : {
1050 : 98 : DECL_ATTRIBUTES (new_decl) = target_attributes;
1051 : :
1052 : 98 : location_t saved_loc = input_location;
1053 : 98 : tree v = TREE_VALUE (target_attributes);
1054 : 98 : input_location = DECL_SOURCE_LOCATION (new_decl);
1055 : 98 : bool r;
1056 : 98 : tree name_id = get_attribute_name (target_attributes);
1057 : 98 : const char *name_str = IDENTIFIER_POINTER (name_id);
1058 : 98 : if (strcmp (name_str, "target") == 0)
1059 : 98 : r = targetm.target_option.valid_attribute_p (new_decl, name_id, v, 1);
1060 : 0 : else if (strcmp (name_str, "target_version") == 0)
1061 : 0 : r = targetm.target_option.valid_version_attribute_p (new_decl, name_id,
1062 : : v, 1);
1063 : : else
1064 : 0 : gcc_unreachable();
1065 : :
1066 : 98 : input_location = saved_loc;
1067 : 98 : if (!r)
1068 : : return NULL;
1069 : : }
1070 : :
1071 : : /* When the old decl was a con-/destructor make sure the clone isn't. */
1072 : 47896 : DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
1073 : 47896 : DECL_STATIC_DESTRUCTOR (new_decl) = 0;
1074 : 47896 : DECL_SET_IS_OPERATOR_NEW (new_decl, 0);
1075 : 47896 : DECL_SET_IS_OPERATOR_DELETE (new_decl, 0);
1076 : 47896 : DECL_IS_REPLACEABLE_OPERATOR (new_decl) = 0;
1077 : :
1078 : : /* Create the new version's call-graph node.
1079 : : and update the edges of the new node. */
1080 : 47896 : new_version_node = create_version_clone (new_decl, redirect_callers,
1081 : : bbs_to_copy, suffix);
1082 : :
1083 : 47896 : if (ipa_transforms_to_apply.exists ())
1084 : 0 : new_version_node->ipa_transforms_to_apply
1085 : 0 : = ipa_transforms_to_apply.copy ();
1086 : : /* Copy the OLD_VERSION_NODE function tree to the new version. */
1087 : 47896 : tree_function_versioning (old_decl, new_decl, tree_map, param_adjustments,
1088 : : false, bbs_to_copy, new_entry_block);
1089 : :
1090 : : /* Update the new version's properties.
1091 : : Make The new version visible only within this translation unit. Make sure
1092 : : that is not weak also.
1093 : : ??? We cannot use COMDAT linkage because there is no
1094 : : ABI support for this. */
1095 : 47896 : new_version_node->make_decl_local ();
1096 : 47896 : DECL_VIRTUAL_P (new_version_node->decl) = 0;
1097 : 47896 : new_version_node->externally_visible = 0;
1098 : 47896 : new_version_node->local = 1;
1099 : 47896 : new_version_node->lowered = true;
1100 : 47896 : if (!implicit_section)
1101 : 47880 : new_version_node->set_section (*this);
1102 : : /* Clones of global symbols or symbols with unique names are unique. */
1103 : 47896 : if ((TREE_PUBLIC (old_decl)
1104 : 44582 : && !DECL_EXTERNAL (old_decl)
1105 : 37288 : && !DECL_WEAK (old_decl)
1106 : 12531 : && !DECL_COMDAT (old_decl))
1107 : 79947 : || in_lto_p)
1108 : 12571 : new_version_node->unique_name = true;
1109 : :
1110 : : /* Update the call_expr on the edges to call the new version node. */
1111 : 47896 : update_call_expr (new_version_node);
1112 : :
1113 : 47896 : symtab->call_cgraph_insertion_hooks (new_version_node);
1114 : 47896 : return new_version_node;
1115 : : }
1116 : :
1117 : : /* Remove the node from the tree of virtual and inline clones and make it a
1118 : : standalone node - not a clone any more. */
1119 : :
1120 : 110351 : void cgraph_node::remove_from_clone_tree ()
1121 : : {
1122 : 110351 : if (next_sibling_clone)
1123 : 309 : next_sibling_clone->prev_sibling_clone = prev_sibling_clone;
1124 : 110351 : if (prev_sibling_clone)
1125 : 501 : prev_sibling_clone->next_sibling_clone = next_sibling_clone;
1126 : : else
1127 : 109850 : clone_of->clones = next_sibling_clone;
1128 : 110351 : next_sibling_clone = NULL;
1129 : 110351 : prev_sibling_clone = NULL;
1130 : 110351 : clone_of = NULL;
1131 : 110351 : }
1132 : :
1133 : : /* Given virtual clone, turn it into actual clone. */
1134 : :
1135 : : void
1136 : 110351 : cgraph_node::materialize_clone ()
1137 : : {
1138 : 110351 : clone_info *info = clone_info::get (this);
1139 : 110351 : clone_of->get_untransformed_body ();
1140 : 110351 : former_clone_of = clone_of->decl;
1141 : 110351 : if (clone_of->former_clone_of)
1142 : 3304 : former_clone_of = clone_of->former_clone_of;
1143 : 110351 : if (symtab->dump_file)
1144 : : {
1145 : 0 : fprintf (symtab->dump_file, "cloning %s to %s\n",
1146 : 0 : clone_of->dump_name (),
1147 : : dump_name ());
1148 : 0 : if (info && info->tree_map)
1149 : : {
1150 : 0 : fprintf (symtab->dump_file, " replace map:");
1151 : 0 : for (unsigned int i = 0;
1152 : 0 : i < vec_safe_length (info->tree_map);
1153 : : i++)
1154 : : {
1155 : 0 : ipa_replace_map *replace_info;
1156 : 0 : replace_info = (*info->tree_map)[i];
1157 : 0 : fprintf (symtab->dump_file, "%s %i -> ",
1158 : : i ? "," : "", replace_info->parm_num);
1159 : 0 : print_generic_expr (symtab->dump_file,
1160 : : replace_info->new_tree);
1161 : : }
1162 : 0 : fprintf (symtab->dump_file, "\n");
1163 : : }
1164 : 0 : if (info && info->param_adjustments)
1165 : 0 : info->param_adjustments->dump (symtab->dump_file);
1166 : : }
1167 : 110351 : clear_stmts_in_references ();
1168 : : /* Copy the OLD_VERSION_NODE function tree to the new version. */
1169 : 110351 : tree_function_versioning (clone_of->decl, decl,
1170 : : info ? info->tree_map : NULL,
1171 : : info ? info->param_adjustments : NULL,
1172 : : true, NULL, NULL);
1173 : 110351 : if (symtab->dump_file)
1174 : : {
1175 : 0 : dump_function_to_file (clone_of->decl, symtab->dump_file,
1176 : : dump_flags);
1177 : 0 : dump_function_to_file (decl, symtab->dump_file, dump_flags);
1178 : : }
1179 : :
1180 : 110351 : cgraph_node *this_clone_of = clone_of;
1181 : : /* Function is no longer clone. */
1182 : 110351 : remove_from_clone_tree ();
1183 : 110351 : if (!this_clone_of->analyzed && !this_clone_of->clones)
1184 : 107573 : this_clone_of->release_body ();
1185 : 110351 : }
1186 : :
1187 : : #include "gt-cgraphclones.h"
|