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