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 : 6564915 : 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 : 6564915 : cgraph_edge *new_edge;
103 : 6564915 : profile_count::adjust_for_ipa_scaling (&num, &den);
104 : 6564915 : profile_count prof_count = count.apply_scale (num, den);
105 : :
106 : 6564915 : if (indirect_unknown_callee)
107 : : {
108 : 178671 : tree decl;
109 : :
110 : 178403 : 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 : 183795 : && !speculative)
114 : : {
115 : 5124 : cgraph_node *callee = cgraph_node::get (decl);
116 : 5124 : gcc_checking_assert (callee);
117 : 5124 : new_edge = n->create_edge (callee, call_stmt, prof_count, true);
118 : : }
119 : : else
120 : : {
121 : 347094 : new_edge = n->create_indirect_edge (call_stmt,
122 : 173547 : indirect_info->ecf_flags,
123 : : prof_count, true);
124 : 173547 : *new_edge->indirect_info = *indirect_info;
125 : : }
126 : : }
127 : : else
128 : : {
129 : 6386244 : new_edge = n->create_edge (callee, call_stmt, prof_count, true);
130 : 6386244 : 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 : 6564915 : new_edge->inline_failed = inline_failed;
139 : 6564915 : new_edge->indirect_inlining_edge = indirect_inlining_edge;
140 : 6564915 : if (!call_stmt)
141 : 232539 : new_edge->lto_stmt_uid = stmt_uid;
142 : 6564915 : new_edge->speculative_id = speculative_id;
143 : : /* Clone flags that depend on call_stmt availability manually. */
144 : 6564915 : new_edge->can_throw_external = can_throw_external;
145 : 6564915 : new_edge->call_stmt_cannot_inline_p = call_stmt_cannot_inline_p;
146 : 6564915 : new_edge->speculative = speculative;
147 : 6564915 : new_edge->in_polymorphic_cdtor = in_polymorphic_cdtor;
148 : :
149 : : /* Update IPA profile. Local profiles need no updating in original. */
150 : 6564915 : if (update_original)
151 : 5946289 : count = count.combine_with_ipa_count_within (count.ipa ()
152 : 5946289 : - new_edge->count.ipa (),
153 : 5946289 : caller->count);
154 : 6564915 : symtab->call_edge_duplication_hooks (this, new_edge);
155 : 6564915 : 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 : : void
162 : 126336 : set_new_clone_decl_and_node_flags (cgraph_node *new_node)
163 : : {
164 : 126336 : DECL_EXTERNAL (new_node->decl) = 0;
165 : 126336 : TREE_PUBLIC (new_node->decl) = 0;
166 : 126336 : DECL_COMDAT (new_node->decl) = 0;
167 : 126336 : DECL_WEAK (new_node->decl) = 0;
168 : 126336 : DECL_VIRTUAL_P (new_node->decl) = 0;
169 : 126336 : DECL_STATIC_CONSTRUCTOR (new_node->decl) = 0;
170 : 126336 : DECL_STATIC_DESTRUCTOR (new_node->decl) = 0;
171 : 126336 : DECL_SET_IS_OPERATOR_NEW (new_node->decl, 0);
172 : 126336 : DECL_SET_IS_OPERATOR_DELETE (new_node->decl, 0);
173 : 126336 : DECL_IS_REPLACEABLE_OPERATOR (new_node->decl) = 0;
174 : :
175 : 126336 : new_node->externally_visible = 0;
176 : 126336 : new_node->local = 1;
177 : 126336 : new_node->lowered = true;
178 : 126336 : new_node->semantic_interposition = 0;
179 : 126336 : }
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 : 309441 : cgraph_edge::redirect_callee_duplicating_thunks (cgraph_node *n)
276 : : {
277 : 309441 : cgraph_node *orig_to = callee->ultimate_alias_target ();
278 : 309441 : if (orig_to->thunk)
279 : 76 : n = duplicate_thunk_for_node (orig_to, n);
280 : :
281 : 309441 : redirect_callee (n);
282 : 309441 : }
283 : :
284 : : /* Call expand_thunk on all callers that are thunks and if analyze those nodes
285 : : that were expanded. */
286 : :
287 : : void
288 : 3058503 : cgraph_node::expand_all_artificial_thunks ()
289 : : {
290 : 3058503 : cgraph_edge *e;
291 : 3368244 : for (e = callers; e;)
292 : 309741 : 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 : 309707 : e = e->next_caller;
308 : 3058503 : }
309 : :
310 : : /* Dump information about creation of a call graph node clone to the dump file
311 : : created by the -fdump-ipa-clones option. ORIGINAL is the function being
312 : : cloned, CLONE is the new clone. SUFFIX is a string that helps identify the
313 : : reason for cloning, often it is the suffix used by a particular IPA pass to
314 : : create unique function names. SUFFIX can be NULL and in that case the
315 : : dumping will not take place, which must be the case only for helper clones
316 : : which will never be emitted to the output. */
317 : :
318 : : void
319 : 4559306 : dump_callgraph_transformation (const cgraph_node *original,
320 : : const cgraph_node *clone,
321 : : const char *suffix)
322 : : {
323 : 4559306 : if (suffix && symtab->ipa_clones_dump_file)
324 : : {
325 : 126 : fprintf (symtab->ipa_clones_dump_file,
326 : : "Callgraph clone;%s;%d;%s;%d;%d;%s;%d;%s;%d;%d;%s\n",
327 : : original->asm_name (), original->get_uid (),
328 : 63 : DECL_SOURCE_FILE (original->decl),
329 : 63 : DECL_SOURCE_LINE (original->decl),
330 : 63 : DECL_SOURCE_COLUMN (original->decl), clone->asm_name (),
331 : 63 : clone->get_uid (), DECL_SOURCE_FILE (clone->decl),
332 : 63 : DECL_SOURCE_LINE (clone->decl), DECL_SOURCE_COLUMN (clone->decl),
333 : : suffix);
334 : :
335 : 63 : symtab->cloned_nodes.add (original);
336 : 63 : symtab->cloned_nodes.add (clone);
337 : : }
338 : 4559306 : }
339 : :
340 : : /* Turn profile of N to local profile. */
341 : :
342 : : static void
343 : 0 : localize_profile (cgraph_node *n)
344 : : {
345 : 0 : n->count = n->count.guessed_local ();
346 : 0 : for (cgraph_edge *e = n->callees; e; e=e->next_callee)
347 : : {
348 : 0 : e->count = e->count.guessed_local ();
349 : 0 : if (!e->inline_failed)
350 : 0 : localize_profile (e->callee);
351 : : }
352 : 0 : for (cgraph_edge *e = n->indirect_calls; e; e=e->next_callee)
353 : 0 : e->count = e->count.guessed_local ();
354 : 0 : }
355 : :
356 : : /* Create node representing clone of N executed COUNT times. Decrease
357 : : the execution counts from original node too.
358 : : The new clone will have decl set to DECL that may or may not be the same
359 : : as decl of N.
360 : :
361 : : When UPDATE_ORIGINAL is true, the counts are subtracted from the original
362 : : function's profile to reflect the fact that part of execution is handled
363 : : by node.
364 : : When CALL_DUPLICATION_HOOK is true, the ipa passes are acknowledged about
365 : : the new clone. Otherwise the caller is responsible for doing so later.
366 : :
367 : : If the new node is being inlined into another one, NEW_INLINED_TO should be
368 : : the outline function the new one is (even indirectly) inlined to. All hooks
369 : : will see this in node's inlined_to, when invoked. Should be NULL if the
370 : : node is not inlined.
371 : :
372 : : SUFFIX is string that is appended to the original name, it should only be
373 : : NULL if NEW_INLINED_TO is not NULL or if the clone being created is
374 : : temporary and a record about it should not be added into the ipa-clones dump
375 : : file.
376 : :
377 : : If PARAM_ADJUSTMENTS is non-NULL, the parameter manipulation information
378 : : will be overwritten by the new structure. Otherwise the new node will
379 : : share parameter manipulation information with the original node. */
380 : :
381 : : cgraph_node *
382 : 3058266 : cgraph_node::create_clone (tree new_decl, profile_count prof_count,
383 : : bool update_original,
384 : : vec<cgraph_edge *> redirect_callers,
385 : : bool call_duplication_hook,
386 : : cgraph_node *new_inlined_to,
387 : : ipa_param_adjustments *param_adjustments,
388 : : const char *suffix)
389 : : {
390 : 3058266 : cgraph_node *new_node = symtab->create_empty ();
391 : 3058266 : cgraph_edge *e;
392 : 3058266 : unsigned i;
393 : 3058266 : profile_count old_count = count;
394 : 3058266 : bool nonzero = count.ipa ().nonzero_p ();
395 : :
396 : 3058266 : if (new_inlined_to)
397 : 2902161 : dump_callgraph_transformation (this, new_inlined_to, "inlining to");
398 : :
399 : : /* When inlining we scale precisely to prof_count, when cloning we can
400 : : preserve local profile. */
401 : 2902161 : if (!new_inlined_to)
402 : 156105 : prof_count = count.combine_with_ipa_count (prof_count);
403 : 3058266 : new_node->count = prof_count;
404 : 3058266 : new_node->has_omp_variant_constructs = this->has_omp_variant_constructs;
405 : :
406 : : /* Update IPA profile. Local profiles need no updating in original. */
407 : 3058266 : if (update_original)
408 : : {
409 : 2884777 : if (inlined_to)
410 : 420686 : count = count.combine_with_ipa_count_within (count.ipa ()
411 : 841372 : - prof_count.ipa (),
412 : : inlined_to->count);
413 : : else
414 : 2464091 : count = count.combine_with_ipa_count (count.ipa () - prof_count.ipa ());
415 : : }
416 : 3058266 : new_node->decl = new_decl;
417 : 3058266 : new_node->order = order;
418 : 3058266 : new_node->register_symbol ();
419 : 3058266 : new_node->lto_file_data = lto_file_data;
420 : 3058266 : new_node->analyzed = analyzed;
421 : 3058266 : new_node->definition = definition;
422 : 3058266 : new_node->versionable = versionable;
423 : 3058266 : new_node->can_change_signature = can_change_signature;
424 : 3058266 : new_node->redefined_extern_inline = redefined_extern_inline;
425 : 3058266 : new_node->semantic_interposition = semantic_interposition;
426 : 3058266 : new_node->tm_may_enter_irr = tm_may_enter_irr;
427 : 3058266 : new_node->externally_visible = false;
428 : 3058266 : new_node->no_reorder = no_reorder;
429 : 3058266 : new_node->local = true;
430 : 3058266 : new_node->inlined_to = new_inlined_to;
431 : 3058266 : new_node->rtl = rtl;
432 : 3058266 : new_node->frequency = frequency;
433 : 3058266 : new_node->tp_first_run = tp_first_run;
434 : 3058266 : new_node->tm_clone = tm_clone;
435 : 3058266 : new_node->icf_merged = icf_merged;
436 : 3058266 : new_node->thunk = thunk;
437 : 3058266 : new_node->unit_id = unit_id;
438 : 3058266 : new_node->merged_comdat = merged_comdat;
439 : 3058266 : new_node->merged_extern_inline = merged_extern_inline;
440 : 3058266 : clone_info *info = clone_info::get (this);
441 : :
442 : 3058266 : if (param_adjustments)
443 : 120356 : clone_info::get_create (new_node)->param_adjustments = param_adjustments;
444 : 2937910 : else if (info && info->param_adjustments)
445 : 240362 : clone_info::get_create (new_node)->param_adjustments
446 : 240362 : = info->param_adjustments;
447 : 3058266 : new_node->split_part = split_part;
448 : :
449 : 3367417 : FOR_EACH_VEC_ELT (redirect_callers, i, e)
450 : : {
451 : : /* Redirect calls to the old version node to point to its new
452 : : version. The only exception is when the edge was proved to
453 : : be unreachable during the cloning procedure. */
454 : 309151 : if (!e->callee
455 : 309151 : || !fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE,
456 : : BUILT_IN_UNREACHABLE_TRAP))
457 : 309151 : e->redirect_callee_duplicating_thunks (new_node);
458 : : }
459 : 3058266 : new_node->expand_all_artificial_thunks ();
460 : :
461 : 5819290 : for (e = callees;e; e=e->next_callee)
462 : 2761024 : e->clone (new_node, e->call_stmt, e->lto_stmt_uid, new_node->count, old_count,
463 : : update_original);
464 : :
465 : 3137952 : for (e = indirect_calls; e; e = e->next_callee)
466 : 79686 : e->clone (new_node, e->call_stmt, e->lto_stmt_uid,
467 : : new_node->count, old_count, update_original);
468 : 3058266 : new_node->clone_references (this);
469 : :
470 : 3058266 : new_node->next_sibling_clone = clones;
471 : 3058266 : if (clones)
472 : 1458238 : clones->prev_sibling_clone = new_node;
473 : 3058266 : clones = new_node;
474 : 3058266 : new_node->clone_of = this;
475 : :
476 : 3058266 : if (call_duplication_hook)
477 : 2903706 : symtab->call_cgraph_duplication_hooks (this, new_node);
478 : : /* With partial train run we do not want to assume that original's
479 : : count is zero whenever we redurect all executed edges to clone.
480 : : Simply drop profile to local one in this case. */
481 : 3058266 : if (update_original
482 : 2884777 : && opt_for_fn (decl, flag_profile_partial_training)
483 : 0 : && nonzero
484 : 0 : && count.ipa_p ()
485 : 3058266 : && !count.ipa ().nonzero_p ()
486 : 3058266 : && !inlined_to)
487 : 0 : localize_profile (this);
488 : :
489 : 3058266 : if (!new_inlined_to)
490 : 156105 : dump_callgraph_transformation (this, new_node, suffix);
491 : :
492 : 3058266 : return new_node;
493 : : }
494 : :
495 : : static GTY(()) hash_map<const char *, unsigned> *clone_fn_ids;
496 : :
497 : : /* Return a new assembler name for a clone of decl named NAME. Apart
498 : : from the string SUFFIX, the new name will end with a unique (for
499 : : each NAME) unspecified number. If clone numbering is not needed
500 : : then the two argument clone_function_name should be used instead.
501 : : Should not be called directly except for by
502 : : lto-partition.cc:privatize_symbol_name_1. */
503 : :
504 : : tree
505 : 106355 : clone_function_name_numbered (const char *name, const char *suffix)
506 : : {
507 : : /* Initialize the function->counter mapping the first time it's
508 : : needed. */
509 : 106355 : if (!clone_fn_ids)
510 : 19936 : clone_fn_ids = hash_map<const char *, unsigned int>::create_ggc (64);
511 : 319065 : unsigned int &suffix_counter = clone_fn_ids->get_or_insert (
512 : 106355 : IDENTIFIER_POINTER (get_identifier (name)));
513 : 106355 : return clone_function_name (name, suffix, suffix_counter++);
514 : : }
515 : :
516 : : /* Return a new assembler name for a clone of DECL. Apart from string
517 : : SUFFIX, the new name will end with a unique (for each DECL
518 : : assembler name) unspecified number. If clone numbering is not
519 : : needed then the two argument clone_function_name should be used
520 : : instead. */
521 : :
522 : : tree
523 : 106355 : clone_function_name_numbered (tree decl, const char *suffix)
524 : : {
525 : 106355 : tree name = DECL_ASSEMBLER_NAME (decl);
526 : 106355 : return clone_function_name_numbered (IDENTIFIER_POINTER (name),
527 : 106355 : suffix);
528 : : }
529 : :
530 : : /* Return a new assembler name for a clone of decl named NAME. Apart
531 : : from the string SUFFIX, the new name will end with the specified
532 : : NUMBER. If clone numbering is not needed then the two argument
533 : : clone_function_name should be used instead. */
534 : :
535 : : tree
536 : 232992 : clone_function_name (const char *name, const char *suffix,
537 : : unsigned long number)
538 : : {
539 : 232992 : size_t len = strlen (name);
540 : 232992 : char *tmp_name, *prefix;
541 : :
542 : 232992 : prefix = XALLOCAVEC (char, len + strlen (suffix) + 2);
543 : 232992 : memcpy (prefix, name, len);
544 : 232992 : strcpy (prefix + len + 1, suffix);
545 : 232992 : prefix[len] = symbol_table::symbol_suffix_separator ();
546 : 232992 : ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix, number);
547 : 232992 : return get_identifier (tmp_name);
548 : : }
549 : :
550 : : /* Return a new assembler name for a clone of DECL. Apart from the
551 : : string SUFFIX, the new name will end with the specified NUMBER. If
552 : : clone numbering is not needed then the two argument
553 : : clone_function_name should be used instead. */
554 : :
555 : : tree
556 : 126305 : clone_function_name (tree decl, const char *suffix,
557 : : unsigned long number)
558 : : {
559 : 252610 : return clone_function_name (
560 : 126305 : IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), suffix, number);
561 : : }
562 : :
563 : : /* Return a new assembler name ending with the string SUFFIX for a
564 : : clone of DECL. */
565 : :
566 : : tree
567 : 63257 : clone_function_name (tree decl, const char *suffix)
568 : : {
569 : 63257 : tree identifier = DECL_ASSEMBLER_NAME (decl);
570 : : /* For consistency this needs to behave the same way as
571 : : ASM_FORMAT_PRIVATE_NAME does, but without the final number
572 : : suffix. */
573 : 63257 : char *separator = XALLOCAVEC (char, 2);
574 : 63257 : separator[0] = symbol_table::symbol_suffix_separator ();
575 : 63257 : separator[1] = 0;
576 : : #if defined (NO_DOT_IN_LABEL) && defined (NO_DOLLAR_IN_LABEL)
577 : : const char *prefix = "__";
578 : : #else
579 : 63257 : const char *prefix = "";
580 : : #endif
581 : 63257 : char *result = ACONCAT ((prefix,
582 : : IDENTIFIER_POINTER (identifier),
583 : : separator,
584 : : suffix,
585 : : (char*)0));
586 : 63257 : return get_identifier (result);
587 : : }
588 : :
589 : :
590 : : /* Create callgraph node clone with new declaration. The actual body will be
591 : : copied later at compilation stage. The name of the new clone will be
592 : : constructed from the name of the original node, SUFFIX and NUM_SUFFIX.
593 : :
594 : : TODO: after merging in ipa-sra use function call notes instead of args_to_skip
595 : : bitmap interface.
596 : : */
597 : : cgraph_node *
598 : 126305 : cgraph_node::create_virtual_clone (const vec<cgraph_edge *> &redirect_callers,
599 : : vec<ipa_replace_map *, va_gc> *tree_map,
600 : : ipa_param_adjustments *param_adjustments,
601 : : const char * suffix, unsigned num_suffix)
602 : : {
603 : 126305 : tree old_decl = decl;
604 : 126305 : cgraph_node *new_node = NULL;
605 : 126305 : tree new_decl;
606 : 126305 : size_t len, i;
607 : 126305 : ipa_replace_map *map;
608 : 126305 : char *name;
609 : :
610 : 126305 : gcc_checking_assert (versionable);
611 : : /* TODO: It would be nice if we could recognize that param_adjustments do not
612 : : actually perform any changes, but at the moment let's require it simply
613 : : does not exist. */
614 : 126305 : gcc_assert (can_change_signature || !param_adjustments);
615 : :
616 : : /* Make a new FUNCTION_DECL tree node */
617 : 124871 : if (!param_adjustments)
618 : 5949 : new_decl = copy_node (old_decl);
619 : : else
620 : 120356 : new_decl = param_adjustments->adjust_decl (old_decl);
621 : :
622 : : /* These pointers represent function body and will be populated only when clone
623 : : is materialized. */
624 : 126305 : gcc_assert (new_decl != old_decl);
625 : 126305 : DECL_STRUCT_FUNCTION (new_decl) = NULL;
626 : 126305 : DECL_ARGUMENTS (new_decl) = NULL;
627 : 126305 : DECL_INITIAL (new_decl) = NULL;
628 : 126305 : DECL_RESULT (new_decl) = NULL;
629 : : /* We cannot do DECL_RESULT (new_decl) = NULL; here because of LTO partitioning
630 : : sometimes storing only clone decl instead of original. */
631 : :
632 : : /* Generate a new name for the new version. */
633 : 126305 : len = IDENTIFIER_LENGTH (DECL_NAME (old_decl));
634 : 126305 : name = XALLOCAVEC (char, len + strlen (suffix) + 2);
635 : 126305 : memcpy (name, IDENTIFIER_POINTER (DECL_NAME (old_decl)), len);
636 : 126305 : strcpy (name + len + 1, suffix);
637 : 126305 : name[len] = '.';
638 : 126305 : DECL_NAME (new_decl) = get_identifier (name);
639 : 126305 : SET_DECL_ASSEMBLER_NAME (new_decl,
640 : : clone_function_name (old_decl, suffix, num_suffix));
641 : 126305 : SET_DECL_RTL (new_decl, NULL);
642 : :
643 : 126305 : new_node = create_clone (new_decl, count, false,
644 : : redirect_callers, false, NULL, param_adjustments,
645 : : suffix);
646 : :
647 : : /* Update the properties.
648 : : Make clone visible only within this translation unit. Make sure
649 : : that is not weak also.
650 : : ??? We cannot use COMDAT linkage because there is no
651 : : ABI support for this. */
652 : 126305 : set_new_clone_decl_and_node_flags (new_node);
653 : 126305 : new_node->ipcp_clone = ipcp_clone;
654 : 126305 : if (tree_map)
655 : 12856 : clone_info::get_create (new_node)->tree_map = tree_map;
656 : 126305 : if (!implicit_section)
657 : 126273 : new_node->set_section (*this);
658 : :
659 : : /* Clones of global symbols or symbols with unique names are unique. */
660 : 126305 : if ((TREE_PUBLIC (old_decl)
661 : 92132 : && !DECL_EXTERNAL (old_decl)
662 : 84993 : && !DECL_WEAK (old_decl)
663 : 3060 : && !DECL_COMDAT (old_decl))
664 : 215377 : || in_lto_p)
665 : 6809 : new_node->unique_name = true;
666 : 147640 : FOR_EACH_VEC_SAFE_ELT (tree_map, i, map)
667 : : {
668 : 21335 : tree repl = map->new_tree;
669 : 21335 : if (map->force_load_ref)
670 : : {
671 : 364 : gcc_assert (TREE_CODE (repl) == ADDR_EXPR);
672 : 364 : repl = get_base_address (TREE_OPERAND (repl, 0));
673 : : }
674 : 21335 : new_node->maybe_create_reference (repl, NULL);
675 : : }
676 : :
677 : 126305 : if (ipa_transforms_to_apply.exists ())
678 : 106388 : new_node->ipa_transforms_to_apply
679 : 106388 : = ipa_transforms_to_apply.copy ();
680 : :
681 : 126305 : symtab->call_cgraph_duplication_hooks (this, new_node);
682 : :
683 : 126305 : return new_node;
684 : : }
685 : :
686 : : /* callgraph node being removed from symbol table; see if its entry can be
687 : : replaced by other inline clone.
688 : : INFO is clone info to attach to the new root. */
689 : : cgraph_node *
690 : 90497716 : cgraph_node::find_replacement (clone_info *info)
691 : : {
692 : 90497716 : cgraph_node *next_inline_clone, *replacement;
693 : :
694 : 90497716 : for (next_inline_clone = clones;
695 : : next_inline_clone
696 : 90497716 : && next_inline_clone->decl != decl;
697 : 0 : next_inline_clone = next_inline_clone->next_sibling_clone)
698 : : ;
699 : :
700 : : /* If there is inline clone of the node being removed, we need
701 : : to put it into the position of removed node and reorganize all
702 : : other clones to be based on it. */
703 : 90497716 : if (next_inline_clone)
704 : : {
705 : 400872 : cgraph_node *n;
706 : 400872 : cgraph_node *new_clones;
707 : :
708 : 400872 : replacement = next_inline_clone;
709 : :
710 : : /* Unlink inline clone from the list of clones of removed node. */
711 : 400872 : if (next_inline_clone->next_sibling_clone)
712 : 245656 : next_inline_clone->next_sibling_clone->prev_sibling_clone
713 : 245656 : = next_inline_clone->prev_sibling_clone;
714 : 400872 : if (next_inline_clone->prev_sibling_clone)
715 : : {
716 : 0 : gcc_assert (clones != next_inline_clone);
717 : 0 : next_inline_clone->prev_sibling_clone->next_sibling_clone
718 : 0 : = next_inline_clone->next_sibling_clone;
719 : : }
720 : : else
721 : : {
722 : 400872 : gcc_assert (clones == next_inline_clone);
723 : 400872 : clones = next_inline_clone->next_sibling_clone;
724 : : }
725 : :
726 : 400872 : new_clones = clones;
727 : 400872 : clones = NULL;
728 : :
729 : : /* Copy clone info. */
730 : 400872 : if (info)
731 : 61282 : *clone_info::get_create (next_inline_clone) = *info;
732 : :
733 : : /* Now place it into clone tree at same level at NODE. */
734 : 400872 : next_inline_clone->clone_of = clone_of;
735 : 400872 : next_inline_clone->prev_sibling_clone = NULL;
736 : 400872 : next_inline_clone->next_sibling_clone = NULL;
737 : 400872 : if (clone_of)
738 : : {
739 : 2241 : if (clone_of->clones)
740 : 2241 : clone_of->clones->prev_sibling_clone = next_inline_clone;
741 : 2241 : next_inline_clone->next_sibling_clone = clone_of->clones;
742 : 2241 : clone_of->clones = next_inline_clone;
743 : : }
744 : :
745 : : /* Merge the clone list. */
746 : 400872 : if (new_clones)
747 : : {
748 : 245656 : if (!next_inline_clone->clones)
749 : 242844 : next_inline_clone->clones = new_clones;
750 : : else
751 : : {
752 : : n = next_inline_clone->clones;
753 : 13225 : while (n->next_sibling_clone)
754 : : n = n->next_sibling_clone;
755 : 2812 : n->next_sibling_clone = new_clones;
756 : 2812 : new_clones->prev_sibling_clone = n;
757 : : }
758 : : }
759 : :
760 : : /* Update clone_of pointers. */
761 : : n = new_clones;
762 : 2825185 : while (n)
763 : : {
764 : 2424313 : n->clone_of = next_inline_clone;
765 : 2424313 : n = n->next_sibling_clone;
766 : : }
767 : :
768 : : /* Update order in order to be able to find a LTO section
769 : : with function body. */
770 : 400872 : replacement->order = order;
771 : :
772 : 400872 : return replacement;
773 : : }
774 : : else
775 : : return NULL;
776 : : }
777 : :
778 : : /* Like cgraph_set_call_stmt but walk the clone tree and update all
779 : : clones sharing the same function body.
780 : : When WHOLE_SPECULATIVE_EDGES is true, all three components of
781 : : speculative edge gets updated. Otherwise we update only direct
782 : : call. */
783 : :
784 : : void
785 : 1526158 : cgraph_node::set_call_stmt_including_clones (gimple *old_stmt,
786 : : gcall *new_stmt,
787 : : bool update_speculative)
788 : : {
789 : 1526158 : cgraph_node *node;
790 : 1526158 : cgraph_edge *master_edge = get_edge (old_stmt);
791 : :
792 : 1526158 : if (master_edge)
793 : 1422045 : cgraph_edge::set_call_stmt (master_edge, new_stmt, update_speculative);
794 : :
795 : 1526158 : node = clones;
796 : 1526158 : if (node)
797 : 1105427 : while (node != this)
798 : : {
799 : 874679 : cgraph_edge *edge = node->get_edge (old_stmt);
800 : 874679 : if (edge)
801 : : {
802 : 872210 : edge = cgraph_edge::set_call_stmt (edge, new_stmt,
803 : : update_speculative);
804 : : /* If UPDATE_SPECULATIVE is false, it means that we are turning
805 : : speculative call into a real code sequence. Update the
806 : : callgraph edges. */
807 : 872210 : if (edge->speculative && !update_speculative)
808 : : {
809 : 0 : cgraph_edge *indirect = edge->speculative_call_indirect_edge ();
810 : :
811 : 0 : for (cgraph_edge *next, *direct
812 : 0 : = edge->first_speculative_call_target ();
813 : 0 : direct;
814 : 0 : direct = next)
815 : : {
816 : 0 : next = direct->next_speculative_call_target ();
817 : 0 : direct->speculative_call_target_ref ()->speculative = false;
818 : 0 : direct->speculative = false;
819 : : }
820 : 0 : indirect->speculative = false;
821 : : }
822 : : }
823 : 874679 : if (node->clones)
824 : : node = node->clones;
825 : 844056 : else if (node->next_sibling_clone)
826 : : node = node->next_sibling_clone;
827 : : else
828 : : {
829 : 508372 : while (node != this && !node->next_sibling_clone)
830 : 261371 : node = node->clone_of;
831 : 247001 : if (node != this)
832 : 16253 : node = node->next_sibling_clone;
833 : : }
834 : : }
835 : 1526158 : }
836 : :
837 : : /* Like cgraph_create_edge walk the clone tree and update all clones sharing
838 : : same function body. If clones already have edge for OLD_STMT; only
839 : : update the edge same way as cgraph_set_call_stmt_including_clones does.
840 : :
841 : : TODO: COUNT and LOOP_DEPTH should be properly distributed based on relative
842 : : frequencies of the clones. */
843 : :
844 : : void
845 : 0 : cgraph_node::create_edge_including_clones (cgraph_node *callee,
846 : : gimple *old_stmt, gcall *stmt,
847 : : profile_count count,
848 : : cgraph_inline_failed_t reason)
849 : : {
850 : 0 : cgraph_node *node;
851 : :
852 : 0 : if (!get_edge (stmt))
853 : : {
854 : 0 : cgraph_edge *edge = create_edge (callee, stmt, count);
855 : 0 : edge->inline_failed = reason;
856 : : }
857 : :
858 : 0 : node = clones;
859 : 0 : if (node)
860 : 0 : while (node != this)
861 : : /* Thunk clones do not get updated while copying inline function body. */
862 : 0 : if (!node->thunk)
863 : : {
864 : 0 : cgraph_edge *edge = node->get_edge (old_stmt);
865 : :
866 : : /* It is possible that clones already contain the edge while
867 : : master didn't. Either we promoted indirect call into direct
868 : : call in the clone or we are processing clones of unreachable
869 : : master where edges has been removed. */
870 : 0 : if (edge)
871 : 0 : edge = cgraph_edge::set_call_stmt (edge, stmt);
872 : 0 : else if (! node->get_edge (stmt))
873 : : {
874 : 0 : edge = node->create_edge (callee, stmt, count);
875 : 0 : edge->inline_failed = reason;
876 : : }
877 : :
878 : 0 : if (node->clones)
879 : : node = node->clones;
880 : 0 : else if (node->next_sibling_clone)
881 : : node = node->next_sibling_clone;
882 : : else
883 : : {
884 : 0 : while (node != this && !node->next_sibling_clone)
885 : 0 : node = node->clone_of;
886 : 0 : if (node != this)
887 : 0 : node = node->next_sibling_clone;
888 : : }
889 : : }
890 : 0 : }
891 : :
892 : : /* Remove the node from cgraph and all inline clones inlined into it.
893 : : Skip however removal of FORBIDDEN_NODE and return true if it needs to be
894 : : removed. This allows to call the function from outer loop walking clone
895 : : tree. */
896 : :
897 : : bool
898 : 31 : cgraph_node::remove_symbol_and_inline_clones (cgraph_node *forbidden_node)
899 : : {
900 : 31 : cgraph_edge *e, *next;
901 : 31 : bool found = false;
902 : :
903 : 31 : if (this == forbidden_node)
904 : : {
905 : 0 : cgraph_edge::remove (callers);
906 : 0 : return true;
907 : : }
908 : 41 : for (e = callees; e; e = next)
909 : : {
910 : 10 : next = e->next_callee;
911 : 10 : if (!e->inline_failed)
912 : 0 : found |= e->callee->remove_symbol_and_inline_clones (forbidden_node);
913 : : }
914 : 31 : remove ();
915 : 31 : return found;
916 : : }
917 : :
918 : : /* The edges representing the callers of the NEW_VERSION node were
919 : : fixed by cgraph_function_versioning (), now the call_expr in their
920 : : respective tree code should be updated to call the NEW_VERSION. */
921 : :
922 : : static void
923 : 53029 : update_call_expr (cgraph_node *new_version)
924 : : {
925 : 53029 : cgraph_edge *e;
926 : :
927 : 53029 : gcc_assert (new_version);
928 : :
929 : : /* Update the call expr on the edges to call the new version. */
930 : 53029 : for (e = new_version->callers; e; e = e->next_caller)
931 : : {
932 : 0 : function *inner_function = DECL_STRUCT_FUNCTION (e->caller->decl);
933 : 0 : gimple_call_set_fndecl (e->call_stmt, new_version->decl);
934 : 0 : maybe_clean_eh_stmt_fn (inner_function, e->call_stmt);
935 : : }
936 : 53029 : }
937 : :
938 : :
939 : : /* Create a new cgraph node which is the new version of
940 : : callgraph node. REDIRECT_CALLERS holds the callers
941 : : edges which should be redirected to point to
942 : : NEW_VERSION. ALL the callees edges of the node
943 : : are cloned to the new version node. Return the new
944 : : version node.
945 : :
946 : : If non-NULL BLOCK_TO_COPY determine what basic blocks
947 : : was copied to prevent duplications of calls that are dead
948 : : in the clone. */
949 : :
950 : : cgraph_node *
951 : 56054 : cgraph_node::create_version_clone (tree new_decl,
952 : : vec<cgraph_edge *> redirect_callers,
953 : : bitmap bbs_to_copy,
954 : : const char *suffix)
955 : : {
956 : 56054 : cgraph_node *new_version;
957 : 56054 : cgraph_edge *e;
958 : 56054 : unsigned i;
959 : :
960 : 56054 : new_version = cgraph_node::create (new_decl);
961 : :
962 : 56054 : new_version->analyzed = analyzed;
963 : 56054 : new_version->definition = definition;
964 : 56054 : new_version->local = local;
965 : 56054 : new_version->externally_visible = false;
966 : 56054 : new_version->no_reorder = no_reorder;
967 : 56054 : new_version->local = new_version->definition;
968 : 56054 : new_version->inlined_to = inlined_to;
969 : 56054 : new_version->rtl = rtl;
970 : 56054 : new_version->count = count;
971 : 56054 : new_version->unit_id = unit_id;
972 : 56054 : new_version->merged_comdat = merged_comdat;
973 : 56054 : new_version->merged_extern_inline = merged_extern_inline;
974 : :
975 : 294093 : for (e = callees; e; e=e->next_callee)
976 : 238039 : if (!bbs_to_copy
977 : 238039 : || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
978 : 183122 : e->clone (new_version, e->call_stmt,
979 : : e->lto_stmt_uid, count, count,
980 : : true);
981 : 63437 : for (e = indirect_calls; e; e=e->next_callee)
982 : 7383 : if (!bbs_to_copy
983 : 7383 : || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
984 : 5005 : e->clone (new_version, e->call_stmt,
985 : : e->lto_stmt_uid, count, count,
986 : : true);
987 : 56054 : FOR_EACH_VEC_ELT (redirect_callers, i, e)
988 : : {
989 : : /* Redirect calls to the old version node to point to its new
990 : : version. */
991 : 0 : e->redirect_callee (new_version);
992 : : }
993 : :
994 : 56054 : dump_callgraph_transformation (this, new_version, suffix);
995 : :
996 : 56054 : return new_version;
997 : : }
998 : :
999 : : /* Perform function versioning.
1000 : : Function versioning includes copying of the tree and
1001 : : a callgraph update (creating a new cgraph node and updating
1002 : : its callees and callers).
1003 : :
1004 : : REDIRECT_CALLERS varray includes the edges to be redirected
1005 : : to the new version.
1006 : :
1007 : : TREE_MAP is a mapping of tree nodes we want to replace with
1008 : : new ones (according to results of prior analysis).
1009 : :
1010 : : If non-NULL PARAM_ADJUSTMENTS determine how function formal parameters
1011 : : should be modified in the new version and if it should return void.
1012 : : If non-NULL BLOCK_TO_COPY determine what basic blocks to copy.
1013 : : If non_NULL NEW_ENTRY determine new entry BB of the clone.
1014 : : SUFFIX is a string that will be used to create a new name for the new
1015 : : function.
1016 : :
1017 : : If TARGET_ATTRIBUTES is non-null, when creating a new declaration,
1018 : : add the attributes to DECL_ATTRIBUTES. And call valid_attribute_p
1019 : : that will promote value of the attribute DECL_FUNCTION_SPECIFIC_TARGET
1020 : : of the declaration.
1021 : :
1022 : : If VERSION_DECL is set true, use clone_function_name_numbered for the
1023 : : function clone. Otherwise, use clone_function_name.
1024 : :
1025 : : Return the new version's cgraph node. */
1026 : :
1027 : : cgraph_node *
1028 : 53030 : cgraph_node::create_version_clone_with_body
1029 : : (vec<cgraph_edge *> redirect_callers,
1030 : : vec<ipa_replace_map *, va_gc> *tree_map,
1031 : : ipa_param_adjustments *param_adjustments,
1032 : : bitmap bbs_to_copy, basic_block new_entry_block, const char *suffix,
1033 : : tree target_attributes, bool version_decl)
1034 : : {
1035 : 53030 : tree old_decl = decl;
1036 : 53030 : cgraph_node *new_version_node = NULL;
1037 : 53030 : tree new_decl;
1038 : :
1039 : 53030 : if (!tree_versionable_function_p (old_decl))
1040 : : return NULL;
1041 : :
1042 : : /* TODO: Restore an assert that we do not change signature if
1043 : : can_change_signature is false. We cannot just check that
1044 : : param_adjustments is NULL because unfortunately ipa-split removes return
1045 : : values from such functions. */
1046 : :
1047 : : /* Make a new FUNCTION_DECL tree node for the new version. */
1048 : 53030 : if (param_adjustments)
1049 : 26931 : new_decl = param_adjustments->adjust_decl (old_decl);
1050 : : else
1051 : 26099 : new_decl = copy_node (old_decl);
1052 : :
1053 : : /* Generate a new name for the new version. */
1054 : 53030 : tree fnname = (version_decl ? clone_function_name_numbered (old_decl, suffix)
1055 : 124 : : clone_function_name (old_decl, suffix));
1056 : 53030 : DECL_NAME (new_decl) = fnname;
1057 : 53030 : SET_DECL_ASSEMBLER_NAME (new_decl, fnname);
1058 : 53030 : SET_DECL_RTL (new_decl, NULL);
1059 : :
1060 : 53030 : DECL_VIRTUAL_P (new_decl) = 0;
1061 : :
1062 : 53030 : if (target_attributes)
1063 : : {
1064 : 124 : DECL_ATTRIBUTES (new_decl) = target_attributes;
1065 : :
1066 : 124 : location_t saved_loc = input_location;
1067 : 124 : tree v = TREE_VALUE (target_attributes);
1068 : 124 : input_location = DECL_SOURCE_LOCATION (new_decl);
1069 : 124 : bool r;
1070 : 124 : tree name_id = get_attribute_name (target_attributes);
1071 : 124 : const char *name_str = IDENTIFIER_POINTER (name_id);
1072 : 124 : if (strcmp (name_str, "target") == 0)
1073 : 124 : r = targetm.target_option.valid_attribute_p (new_decl, name_id, v, 1);
1074 : 0 : else if (strcmp (name_str, "target_version") == 0)
1075 : 0 : r = targetm.target_option.valid_version_attribute_p (new_decl, name_id,
1076 : : v, 1);
1077 : : else
1078 : 0 : gcc_unreachable();
1079 : :
1080 : 124 : input_location = saved_loc;
1081 : 124 : if (!r)
1082 : : return NULL;
1083 : : }
1084 : :
1085 : : /* When the old decl was a con-/destructor make sure the clone isn't. */
1086 : 53029 : DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
1087 : 53029 : DECL_STATIC_DESTRUCTOR (new_decl) = 0;
1088 : 53029 : DECL_SET_IS_OPERATOR_NEW (new_decl, 0);
1089 : 53029 : DECL_SET_IS_OPERATOR_DELETE (new_decl, 0);
1090 : 53029 : DECL_IS_REPLACEABLE_OPERATOR (new_decl) = 0;
1091 : :
1092 : : /* Create the new version's call-graph node.
1093 : : and update the edges of the new node. */
1094 : 53029 : new_version_node = create_version_clone (new_decl, redirect_callers,
1095 : : bbs_to_copy, suffix);
1096 : :
1097 : 53029 : if (ipa_transforms_to_apply.exists ())
1098 : 0 : new_version_node->ipa_transforms_to_apply
1099 : 0 : = ipa_transforms_to_apply.copy ();
1100 : : /* Copy the OLD_VERSION_NODE function tree to the new version. */
1101 : 53029 : tree_function_versioning (old_decl, new_decl, tree_map, param_adjustments,
1102 : : false, bbs_to_copy, new_entry_block);
1103 : :
1104 : : /* Update the new version's properties.
1105 : : Make The new version visible only within this translation unit. Make sure
1106 : : that is not weak also.
1107 : : ??? We cannot use COMDAT linkage because there is no
1108 : : ABI support for this. */
1109 : 53029 : new_version_node->make_decl_local ();
1110 : 53029 : DECL_VIRTUAL_P (new_version_node->decl) = 0;
1111 : 53029 : new_version_node->externally_visible = 0;
1112 : 53029 : new_version_node->local = 1;
1113 : 53029 : new_version_node->lowered = true;
1114 : 53029 : if (!implicit_section)
1115 : 53013 : new_version_node->set_section (*this);
1116 : : /* Clones of global symbols or symbols with unique names are unique. */
1117 : 53029 : if ((TREE_PUBLIC (old_decl)
1118 : 49684 : && !DECL_EXTERNAL (old_decl)
1119 : 42402 : && !DECL_WEAK (old_decl)
1120 : 12699 : && !DECL_COMDAT (old_decl))
1121 : 90014 : || in_lto_p)
1122 : 12739 : new_version_node->unique_name = true;
1123 : :
1124 : : /* Update the call_expr on the edges to call the new version node. */
1125 : 53029 : update_call_expr (new_version_node);
1126 : :
1127 : 53029 : symtab->call_cgraph_insertion_hooks (new_version_node);
1128 : 53029 : return new_version_node;
1129 : : }
1130 : :
1131 : : /* Remove the node from the tree of virtual and inline clones and make it a
1132 : : standalone node - not a clone any more. */
1133 : :
1134 : 125557 : void cgraph_node::remove_from_clone_tree ()
1135 : : {
1136 : 125557 : if (next_sibling_clone)
1137 : 613 : next_sibling_clone->prev_sibling_clone = prev_sibling_clone;
1138 : 125557 : if (prev_sibling_clone)
1139 : 933 : prev_sibling_clone->next_sibling_clone = next_sibling_clone;
1140 : : else
1141 : 124624 : clone_of->clones = next_sibling_clone;
1142 : 125557 : next_sibling_clone = NULL;
1143 : 125557 : prev_sibling_clone = NULL;
1144 : 125557 : clone_of = NULL;
1145 : 125557 : }
1146 : :
1147 : : /* Given virtual clone, turn it into actual clone. */
1148 : :
1149 : : void
1150 : 125557 : cgraph_node::materialize_clone ()
1151 : : {
1152 : 125557 : clone_info *info = clone_info::get (this);
1153 : 125557 : clone_of->get_untransformed_body ();
1154 : 125557 : former_clone_of = clone_of->decl;
1155 : 125557 : if (clone_of->former_clone_of)
1156 : 4360 : former_clone_of = clone_of->former_clone_of;
1157 : 125557 : if (symtab->dump_file)
1158 : : {
1159 : 0 : fprintf (symtab->dump_file, "cloning %s to %s\n",
1160 : 0 : clone_of->dump_name (),
1161 : : dump_name ());
1162 : 0 : if (info && info->tree_map)
1163 : : {
1164 : 0 : fprintf (symtab->dump_file, " replace map:");
1165 : 0 : for (unsigned int i = 0;
1166 : 0 : i < vec_safe_length (info->tree_map);
1167 : : i++)
1168 : : {
1169 : 0 : ipa_replace_map *replace_info;
1170 : 0 : replace_info = (*info->tree_map)[i];
1171 : 0 : fprintf (symtab->dump_file, "%s %i -> ",
1172 : : i ? "," : "", replace_info->parm_num);
1173 : 0 : print_generic_expr (symtab->dump_file,
1174 : : replace_info->new_tree);
1175 : : }
1176 : 0 : fprintf (symtab->dump_file, "\n");
1177 : : }
1178 : 0 : if (info && info->param_adjustments)
1179 : 0 : info->param_adjustments->dump (symtab->dump_file);
1180 : : }
1181 : 125557 : clear_stmts_in_references ();
1182 : : /* Copy the OLD_VERSION_NODE function tree to the new version. */
1183 : 125557 : tree_function_versioning (clone_of->decl, decl,
1184 : : info ? info->tree_map : NULL,
1185 : : info ? info->param_adjustments : NULL,
1186 : : true, NULL, NULL);
1187 : 125557 : if (symtab->dump_file)
1188 : : {
1189 : 0 : dump_function_to_file (clone_of->decl, symtab->dump_file,
1190 : : dump_flags);
1191 : 0 : dump_function_to_file (decl, symtab->dump_file, dump_flags);
1192 : : }
1193 : :
1194 : 125557 : cgraph_node *this_clone_of = clone_of;
1195 : : /* Function is no longer clone. */
1196 : 125557 : remove_from_clone_tree ();
1197 : 125557 : if (!this_clone_of->analyzed && !this_clone_of->clones)
1198 : 121262 : this_clone_of->release_body ();
1199 : 125557 : }
1200 : :
1201 : : #include "gt-cgraphclones.h"
|