gcc/ChangeLog
[official-gcc.git] / gcc / cp / optimize.c
blob33c67c0450a96905bba4b0d8be57d671176d36f2
1 /* Perform optimizations on tree structure.
2 Copyright (C) 1998-2015 Free Software Foundation, Inc.
3 Written by Mark Michell (mark@codesourcery.com).
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 GCC is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
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/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "alias.h"
26 #include "tree.h"
27 #include "stringpool.h"
28 #include "cp-tree.h"
29 #include "params.h"
30 #include "target.h"
31 #include "debug.h"
32 #include "tree-inline.h"
33 #include "flags.h"
34 #include "langhooks.h"
35 #include "diagnostic-core.h"
36 #include "dumpfile.h"
37 #include "tree-iterator.h"
38 #include "hard-reg-set.h"
39 #include "function.h"
40 #include "cgraph.h"
42 /* Prototypes. */
44 static void update_cloned_parm (tree, tree, bool);
46 /* CLONED_PARM is a copy of CLONE, generated for a cloned constructor
47 or destructor. Update it to ensure that the source-position for
48 the cloned parameter matches that for the original, and that the
49 debugging generation code will be able to find the original PARM. */
51 static void
52 update_cloned_parm (tree parm, tree cloned_parm, bool first)
54 DECL_ABSTRACT_ORIGIN (cloned_parm) = parm;
56 /* We may have taken its address. */
57 TREE_ADDRESSABLE (cloned_parm) = TREE_ADDRESSABLE (parm);
59 /* The definition might have different constness. */
60 TREE_READONLY (cloned_parm) = TREE_READONLY (parm);
62 TREE_USED (cloned_parm) = !first || TREE_USED (parm);
64 /* The name may have changed from the declaration. */
65 DECL_NAME (cloned_parm) = DECL_NAME (parm);
66 DECL_SOURCE_LOCATION (cloned_parm) = DECL_SOURCE_LOCATION (parm);
67 TREE_TYPE (cloned_parm) = TREE_TYPE (parm);
69 DECL_GIMPLE_REG_P (cloned_parm) = DECL_GIMPLE_REG_P (parm);
73 /* FN is a function in High GIMPLE form that has a complete body and no
74 CFG. CLONE is a function whose body is to be set to a copy of FN,
75 mapping argument declarations according to the ARG_MAP splay_tree. */
77 static void
78 clone_body (tree clone, tree fn, void *arg_map)
80 copy_body_data id;
81 tree stmts;
83 /* Clone the body, as if we were making an inline call. But, remap
84 the parameters in the callee to the parameters of caller. */
85 memset (&id, 0, sizeof (id));
86 id.src_fn = fn;
87 id.dst_fn = clone;
88 id.src_cfun = DECL_STRUCT_FUNCTION (fn);
89 id.decl_map = static_cast<hash_map<tree, tree> *> (arg_map);
91 id.copy_decl = copy_decl_no_change;
92 id.transform_call_graph_edges = CB_CGE_DUPLICATE;
93 id.transform_new_cfg = true;
94 id.transform_return_to_modify = false;
95 id.transform_lang_insert_block = NULL;
97 /* We're not inside any EH region. */
98 id.eh_lp_nr = 0;
100 stmts = DECL_SAVED_TREE (fn);
101 walk_tree (&stmts, copy_tree_body_r, &id, NULL);
103 /* Also remap the initializer of any static variables so that they (in
104 particular, any label addresses) correspond to the base variant rather
105 than the abstract one. */
106 if (DECL_NAME (clone) == base_dtor_identifier
107 || DECL_NAME (clone) == base_ctor_identifier)
109 unsigned ix;
110 tree decl;
112 FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (fn), ix, decl)
113 walk_tree (&DECL_INITIAL (decl), copy_tree_body_r, &id, NULL);
116 append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone));
119 /* DELETE_DTOR is a delete destructor whose body will be built.
120 COMPLETE_DTOR is the corresponding complete destructor. */
122 static void
123 build_delete_destructor_body (tree delete_dtor, tree complete_dtor)
125 tree call_dtor, call_delete;
126 tree parm = DECL_ARGUMENTS (delete_dtor);
127 tree virtual_size = cxx_sizeof (current_class_type);
129 /* Call the corresponding complete destructor. */
130 gcc_assert (complete_dtor);
131 call_dtor = build_cxx_call (complete_dtor, 1, &parm,
132 tf_warning_or_error);
133 add_stmt (call_dtor);
135 add_stmt (build_stmt (0, LABEL_EXPR, cdtor_label));
137 /* Call the delete function. */
138 call_delete = build_op_delete_call (DELETE_EXPR, current_class_ptr,
139 virtual_size,
140 /*global_p=*/false,
141 /*placement=*/NULL_TREE,
142 /*alloc_fn=*/NULL_TREE,
143 tf_warning_or_error);
144 add_stmt (call_delete);
146 /* Return the address of the object. */
147 if (targetm.cxx.cdtor_returns_this ())
149 tree val = DECL_ARGUMENTS (delete_dtor);
150 val = build2 (MODIFY_EXPR, TREE_TYPE (val),
151 DECL_RESULT (delete_dtor), val);
152 add_stmt (build_stmt (0, RETURN_EXPR, val));
156 /* Return name of comdat group for complete and base ctor (or dtor)
157 that have the same body. If dtor is virtual, deleting dtor goes
158 into this comdat group as well. */
160 static tree
161 cdtor_comdat_group (tree complete, tree base)
163 tree complete_name = DECL_ASSEMBLER_NAME (complete);
164 tree base_name = DECL_ASSEMBLER_NAME (base);
165 char *grp_name;
166 const char *p, *q;
167 bool diff_seen = false;
168 size_t idx;
169 gcc_assert (IDENTIFIER_LENGTH (complete_name)
170 == IDENTIFIER_LENGTH (base_name));
171 grp_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name) + 1);
172 p = IDENTIFIER_POINTER (complete_name);
173 q = IDENTIFIER_POINTER (base_name);
174 for (idx = 0; idx < IDENTIFIER_LENGTH (complete_name); idx++)
175 if (p[idx] == q[idx])
176 grp_name[idx] = p[idx];
177 else
179 gcc_assert (!diff_seen
180 && idx > 0
181 && (p[idx - 1] == 'C' || p[idx - 1] == 'D')
182 && p[idx] == '1'
183 && q[idx] == '2');
184 grp_name[idx] = '5';
185 diff_seen = true;
187 grp_name[idx] = '\0';
188 gcc_assert (diff_seen);
189 return get_identifier (grp_name);
192 /* Returns true iff we can make the base and complete [cd]tor aliases of
193 the same symbol rather than separate functions. */
195 static bool
196 can_alias_cdtor (tree fn)
198 #ifndef ASM_OUTPUT_DEF
199 /* If aliases aren't supported by the assembler, fail. */
200 return false;
201 #endif
202 /* We can't use an alias if there are virtual bases. */
203 if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)))
204 return false;
205 /* ??? Why not use aliases with -frepo? */
206 if (flag_use_repository)
207 return false;
208 gcc_assert (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
209 || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn));
210 /* Don't use aliases for weak/linkonce definitions unless we can put both
211 symbols in the same COMDAT group. */
212 return (DECL_INTERFACE_KNOWN (fn)
213 && (SUPPORTS_ONE_ONLY || !DECL_WEAK (fn))
214 && (!DECL_ONE_ONLY (fn)
215 || (HAVE_COMDAT_GROUP && DECL_WEAK (fn))));
218 /* FN is a [cd]tor, fns is a pointer to an array of length 3. Fill fns
219 with pointers to the base, complete, and deleting variants. */
221 static void
222 populate_clone_array (tree fn, tree *fns)
224 tree clone;
226 fns[0] = NULL_TREE;
227 fns[1] = NULL_TREE;
228 fns[2] = NULL_TREE;
230 /* Look for the complete destructor which may be used to build the
231 delete destructor. */
232 FOR_EACH_CLONE (clone, fn)
233 if (DECL_NAME (clone) == complete_dtor_identifier
234 || DECL_NAME (clone) == complete_ctor_identifier)
235 fns[1] = clone;
236 else if (DECL_NAME (clone) == base_dtor_identifier
237 || DECL_NAME (clone) == base_ctor_identifier)
238 fns[0] = clone;
239 else if (DECL_NAME (clone) == deleting_dtor_identifier)
240 fns[2] = clone;
241 else
242 gcc_unreachable ();
245 /* FN is a constructor or destructor, and there are FUNCTION_DECLs
246 cloned from it nearby. Instead of cloning this body, leave it
247 alone and create tiny one-call bodies for the cloned
248 FUNCTION_DECLs. These clones are sibcall candidates, and their
249 resulting code will be very thunk-esque. */
251 static bool
252 maybe_thunk_body (tree fn, bool force)
254 tree bind, block, call, clone, clone_result, fn_parm, fn_parm_typelist;
255 tree last_arg, modify, *args;
256 int parmno, vtt_parmno, max_parms;
257 tree fns[3];
259 if (!force && !flag_declone_ctor_dtor)
260 return 0;
262 /* If function accepts variable arguments, give up. */
263 last_arg = tree_last (TYPE_ARG_TYPES (TREE_TYPE (fn)));
264 if (last_arg != void_list_node)
265 return 0;
267 /* If we got this far, we've decided to turn the clones into thunks. */
269 /* We're going to generate code for fn, so it is no longer "abstract."
270 Also make the unified ctor/dtor private to either the translation unit
271 (for non-vague linkage ctors) or the COMDAT group (otherwise). */
273 populate_clone_array (fn, fns);
274 DECL_ABSTRACT_P (fn) = false;
275 if (!DECL_WEAK (fn))
277 TREE_PUBLIC (fn) = false;
278 DECL_EXTERNAL (fn) = false;
279 DECL_INTERFACE_KNOWN (fn) = true;
281 else if (HAVE_COMDAT_GROUP)
283 tree comdat_group = cdtor_comdat_group (fns[1], fns[0]);
284 cgraph_node::get_create (fns[0])->set_comdat_group (comdat_group);
285 cgraph_node::get_create (fns[1])->add_to_same_comdat_group
286 (cgraph_node::get_create (fns[0]));
287 symtab_node::get (fn)->add_to_same_comdat_group
288 (symtab_node::get (fns[0]));
289 if (fns[2])
290 /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
291 virtual, it goes into the same comdat group as well. */
292 cgraph_node::get_create (fns[2])->add_to_same_comdat_group
293 (symtab_node::get (fns[0]));
294 TREE_PUBLIC (fn) = false;
295 DECL_EXTERNAL (fn) = false;
296 DECL_INTERFACE_KNOWN (fn) = true;
297 /* function_and_variable_visibility doesn't want !PUBLIC decls to
298 have these flags set. */
299 DECL_WEAK (fn) = false;
300 DECL_COMDAT (fn) = false;
303 /* Find the vtt_parm, if present. */
304 for (vtt_parmno = -1, parmno = 0, fn_parm = DECL_ARGUMENTS (fn);
305 fn_parm;
306 ++parmno, fn_parm = TREE_CHAIN (fn_parm))
308 if (DECL_ARTIFICIAL (fn_parm)
309 && DECL_NAME (fn_parm) == vtt_parm_identifier)
311 /* Compensate for removed in_charge parameter. */
312 vtt_parmno = parmno;
313 break;
317 /* Allocate an argument buffer for build_cxx_call().
318 Make sure it is large enough for any of the clones. */
319 max_parms = 0;
320 FOR_EACH_CLONE (clone, fn)
322 int length = list_length (DECL_ARGUMENTS (fn));
323 if (length > max_parms)
324 max_parms = length;
326 args = (tree *) alloca (max_parms * sizeof (tree));
328 /* We know that any clones immediately follow FN in TYPE_METHODS. */
329 FOR_EACH_CLONE (clone, fn)
331 tree clone_parm;
333 /* If we've already generated a body for this clone, avoid
334 duplicating it. (Is it possible for a clone-list to grow after we
335 first see it?) */
336 if (DECL_SAVED_TREE (clone) || TREE_ASM_WRITTEN (clone))
337 continue;
339 /* Start processing the function. */
340 start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
342 if (clone == fns[2])
344 for (clone_parm = DECL_ARGUMENTS (clone); clone_parm;
345 clone_parm = TREE_CHAIN (clone_parm))
346 DECL_ABSTRACT_ORIGIN (clone_parm) = NULL_TREE;
347 /* Build the delete destructor by calling complete destructor and
348 delete function. */
349 build_delete_destructor_body (clone, fns[1]);
351 else
353 /* Walk parameter lists together, creating parameter list for
354 call to original function. */
355 for (parmno = 0,
356 fn_parm = DECL_ARGUMENTS (fn),
357 fn_parm_typelist = TYPE_ARG_TYPES (TREE_TYPE (fn)),
358 clone_parm = DECL_ARGUMENTS (clone);
359 fn_parm;
360 ++parmno,
361 fn_parm = TREE_CHAIN (fn_parm))
363 if (parmno == vtt_parmno && ! DECL_HAS_VTT_PARM_P (clone))
365 gcc_assert (fn_parm_typelist);
366 /* Clobber argument with formal parameter type. */
367 args[parmno]
368 = convert (TREE_VALUE (fn_parm_typelist),
369 null_pointer_node);
371 else if (parmno == 1 && DECL_HAS_IN_CHARGE_PARM_P (fn))
373 tree in_charge
374 = copy_node (in_charge_arg_for_name (DECL_NAME (clone)));
375 args[parmno] = in_charge;
377 /* Map other parameters to their equivalents in the cloned
378 function. */
379 else
381 gcc_assert (clone_parm);
382 DECL_ABSTRACT_ORIGIN (clone_parm) = NULL;
383 args[parmno] = clone_parm;
384 clone_parm = TREE_CHAIN (clone_parm);
386 if (fn_parm_typelist)
387 fn_parm_typelist = TREE_CHAIN (fn_parm_typelist);
390 /* We built this list backwards; fix now. */
391 mark_used (fn);
392 call = build_cxx_call (fn, parmno, args, tf_warning_or_error);
393 /* Arguments passed to the thunk by invisible reference should
394 be transmitted to the callee unchanged. Do not create a
395 temporary and invoke the copy constructor. The thunking
396 transformation must not introduce any constructor calls. */
397 CALL_FROM_THUNK_P (call) = 1;
398 block = make_node (BLOCK);
399 if (targetm.cxx.cdtor_returns_this ())
401 clone_result = DECL_RESULT (clone);
402 modify = build2 (MODIFY_EXPR, TREE_TYPE (clone_result),
403 clone_result, call);
404 modify = build1 (RETURN_EXPR, void_type_node, modify);
405 add_stmt (modify);
407 else
409 add_stmt (call);
411 bind = c_build_bind_expr (DECL_SOURCE_LOCATION (clone),
412 block, cur_stmt_list);
413 DECL_SAVED_TREE (clone) = push_stmt_list ();
414 add_stmt (bind);
417 DECL_ABSTRACT_ORIGIN (clone) = NULL;
418 expand_or_defer_fn (finish_function (0));
420 return 1;
423 /* FN is a function that has a complete body. Clone the body as
424 necessary. Returns nonzero if there's no longer any need to
425 process the main body. */
427 bool
428 maybe_clone_body (tree fn)
430 tree comdat_group = NULL_TREE;
431 tree clone;
432 tree fns[3];
433 bool first = true;
434 int idx;
435 bool need_alias = false;
437 /* We only clone constructors and destructors. */
438 if (!DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
439 && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
440 return 0;
442 populate_clone_array (fn, fns);
444 /* Remember if we can't have multiple clones for some reason. We need to
445 check this before we remap local static initializers in clone_body. */
446 if (!tree_versionable_function_p (fn))
447 need_alias = true;
449 /* We know that any clones immediately follow FN in the TYPE_METHODS
450 list. */
451 push_to_top_level ();
452 for (idx = 0; idx < 3; idx++)
454 tree parm;
455 tree clone_parm;
457 clone = fns[idx];
458 if (!clone)
459 continue;
461 /* Update CLONE's source position information to match FN's. */
462 DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (fn);
463 DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn);
464 DECL_DECLARED_CONSTEXPR_P (clone) = DECL_DECLARED_CONSTEXPR_P (fn);
465 DECL_COMDAT (clone) = DECL_COMDAT (fn);
466 DECL_WEAK (clone) = DECL_WEAK (fn);
468 /* We don't copy the comdat group from fn to clone because the assembler
469 name of fn was corrupted by write_mangled_name by adding *INTERNAL*
470 to it. By doing so, it also corrupted the comdat group. */
471 if (DECL_ONE_ONLY (fn))
472 cgraph_node::get_create (clone)->set_comdat_group (cxx_comdat_group (clone));
473 DECL_USE_TEMPLATE (clone) = DECL_USE_TEMPLATE (fn);
474 DECL_EXTERNAL (clone) = DECL_EXTERNAL (fn);
475 DECL_INTERFACE_KNOWN (clone) = DECL_INTERFACE_KNOWN (fn);
476 DECL_NOT_REALLY_EXTERN (clone) = DECL_NOT_REALLY_EXTERN (fn);
477 TREE_PUBLIC (clone) = TREE_PUBLIC (fn);
478 DECL_VISIBILITY (clone) = DECL_VISIBILITY (fn);
479 DECL_VISIBILITY_SPECIFIED (clone) = DECL_VISIBILITY_SPECIFIED (fn);
480 DECL_DLLIMPORT_P (clone) = DECL_DLLIMPORT_P (fn);
481 DECL_ATTRIBUTES (clone) = copy_list (DECL_ATTRIBUTES (fn));
482 DECL_DISREGARD_INLINE_LIMITS (clone) = DECL_DISREGARD_INLINE_LIMITS (fn);
483 set_decl_section_name (clone, DECL_SECTION_NAME (fn));
485 /* Adjust the parameter names and locations. */
486 parm = DECL_ARGUMENTS (fn);
487 clone_parm = DECL_ARGUMENTS (clone);
488 /* Update the `this' parameter, which is always first. */
489 update_cloned_parm (parm, clone_parm, first);
490 parm = DECL_CHAIN (parm);
491 clone_parm = DECL_CHAIN (clone_parm);
492 if (DECL_HAS_IN_CHARGE_PARM_P (fn))
493 parm = DECL_CHAIN (parm);
494 if (DECL_HAS_VTT_PARM_P (fn))
495 parm = DECL_CHAIN (parm);
496 if (DECL_HAS_VTT_PARM_P (clone))
497 clone_parm = DECL_CHAIN (clone_parm);
498 for (; parm;
499 parm = DECL_CHAIN (parm), clone_parm = DECL_CHAIN (clone_parm))
500 /* Update this parameter. */
501 update_cloned_parm (parm, clone_parm, first);
504 bool can_alias = can_alias_cdtor (fn);
506 /* If we decide to turn clones into thunks, they will branch to fn.
507 Must have original function available to call. */
508 if (!can_alias && maybe_thunk_body (fn, need_alias))
510 pop_from_top_level ();
511 /* We still need to emit the original function. */
512 return 0;
515 /* Emit the DWARF1 abstract instance. */
516 (*debug_hooks->deferred_inline_function) (fn);
518 /* We know that any clones immediately follow FN in the TYPE_METHODS list. */
519 for (idx = 0; idx < 3; idx++)
521 tree parm;
522 tree clone_parm;
523 int parmno;
524 hash_map<tree, tree> *decl_map;
525 bool alias = false;
527 clone = fns[idx];
528 if (!clone)
529 continue;
531 /* Start processing the function. */
532 start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
534 /* Tell cgraph if both ctors or both dtors are known to have
535 the same body. */
536 if (can_alias
537 && fns[0]
538 && idx == 1
539 && cgraph_node::get_create (fns[0])->create_same_body_alias
540 (clone, fns[0]))
542 alias = true;
543 if (DECL_ONE_ONLY (fns[0]))
545 /* For comdat base and complete cdtors put them
546 into the same, *[CD]5* comdat group instead of
547 *[CD][12]*. */
548 comdat_group = cdtor_comdat_group (fns[1], fns[0]);
549 cgraph_node::get_create (fns[0])->set_comdat_group (comdat_group);
550 if (symtab_node::get (clone)->same_comdat_group)
551 symtab_node::get (clone)->remove_from_same_comdat_group ();
552 symtab_node::get (clone)->add_to_same_comdat_group
553 (symtab_node::get (fns[0]));
557 /* Build the delete destructor by calling complete destructor
558 and delete function. */
559 if (idx == 2)
561 build_delete_destructor_body (clone, fns[1]);
562 /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
563 virtual, it goes into the same comdat group as well. */
564 if (comdat_group)
565 cgraph_node::get_create (clone)->add_to_same_comdat_group
566 (symtab_node::get (fns[0]));
568 else if (alias)
569 /* No need to populate body. */ ;
570 else
572 /* If we can't have multiple copies of FN (say, because there's a
573 static local initialized with the address of a label), we need
574 to use an alias for the complete variant. */
575 if (idx == 1 && need_alias)
577 if (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_set)
578 sorry (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_reason, fn);
579 else
580 sorry ("making multiple clones of %qD", fn);
583 /* Remap the parameters. */
584 decl_map = new hash_map<tree, tree>;
585 for (parmno = 0,
586 parm = DECL_ARGUMENTS (fn),
587 clone_parm = DECL_ARGUMENTS (clone);
588 parm;
589 ++parmno,
590 parm = DECL_CHAIN (parm))
592 /* Map the in-charge parameter to an appropriate constant. */
593 if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1)
595 tree in_charge;
596 in_charge = in_charge_arg_for_name (DECL_NAME (clone));
597 decl_map->put (parm, in_charge);
599 else if (DECL_ARTIFICIAL (parm)
600 && DECL_NAME (parm) == vtt_parm_identifier)
602 /* For a subobject constructor or destructor, the next
603 argument is the VTT parameter. Remap the VTT_PARM
604 from the CLONE to this parameter. */
605 if (DECL_HAS_VTT_PARM_P (clone))
607 DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
608 decl_map->put (parm, clone_parm);
609 clone_parm = DECL_CHAIN (clone_parm);
611 /* Otherwise, map the VTT parameter to `NULL'. */
612 else
614 tree t
615 = fold_convert (TREE_TYPE (parm), null_pointer_node);
616 decl_map->put (parm, t);
619 /* Map other parameters to their equivalents in the cloned
620 function. */
621 else
623 decl_map->put (parm, clone_parm);
624 clone_parm = DECL_CHAIN (clone_parm);
628 if (targetm.cxx.cdtor_returns_this ())
630 parm = DECL_RESULT (fn);
631 clone_parm = DECL_RESULT (clone);
632 decl_map->put (parm, clone_parm);
635 /* Clone the body. */
636 clone_body (clone, fn, decl_map);
638 /* Clean up. */
639 delete decl_map;
642 /* The clone can throw iff the original function can throw. */
643 cp_function_chain->can_throw = !TREE_NOTHROW (fn);
645 /* Now, expand this function into RTL, if appropriate. */
646 finish_function (0);
647 BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
648 if (alias)
650 if (expand_or_defer_fn_1 (clone))
651 emit_associated_thunks (clone);
653 else
654 expand_or_defer_fn (clone);
655 first = false;
657 pop_from_top_level ();
659 /* We don't need to process the original function any further. */
660 return 1;