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