1 /* Perform optimizations on tree structure.
2 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2008, 2009,
3 2010 Free Software Foundation, Inc.
4 Written by Mark Michell (mark@codesourcery.com).
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GCC is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
24 #include "coretypes.h"
34 #include "tree-inline.h"
36 #include "langhooks.h"
37 #include "diagnostic-core.h"
38 #include "tree-dump.h"
40 #include "tree-iterator.h"
45 static void update_cloned_parm (tree
, tree
, bool);
47 /* CLONED_PARM is a copy of CLONE, generated for a cloned constructor
48 or destructor. Update it to ensure that the source-position for
49 the cloned parameter matches that for the original, and that the
50 debugging generation code will be able to find the original PARM. */
53 update_cloned_parm (tree parm
, tree cloned_parm
, bool first
)
55 DECL_ABSTRACT_ORIGIN (cloned_parm
) = parm
;
57 /* We may have taken its address. */
58 TREE_ADDRESSABLE (cloned_parm
) = TREE_ADDRESSABLE (parm
);
60 /* The definition might have different constness. */
61 TREE_READONLY (cloned_parm
) = TREE_READONLY (parm
);
63 TREE_USED (cloned_parm
) = !first
|| TREE_USED (parm
);
65 /* The name may have changed from the declaration. */
66 DECL_NAME (cloned_parm
) = DECL_NAME (parm
);
67 DECL_SOURCE_LOCATION (cloned_parm
) = DECL_SOURCE_LOCATION (parm
);
68 TREE_TYPE (cloned_parm
) = TREE_TYPE (parm
);
70 DECL_GIMPLE_REG_P (cloned_parm
) = DECL_GIMPLE_REG_P (parm
);
74 /* FN is a function in High GIMPLE form that has a complete body and no
75 CFG. CLONE is a function whose body is to be set to a copy of FN,
76 mapping argument declarations according to the ARG_MAP splay_tree. */
79 clone_body (tree clone
, tree fn
, void *arg_map
)
84 /* Clone the body, as if we were making an inline call. But, remap
85 the parameters in the callee to the parameters of caller. */
86 memset (&id
, 0, sizeof (id
));
89 id
.src_cfun
= DECL_STRUCT_FUNCTION (fn
);
90 id
.decl_map
= (struct pointer_map_t
*) arg_map
;
92 id
.copy_decl
= copy_decl_no_change
;
93 id
.transform_call_graph_edges
= CB_CGE_DUPLICATE
;
94 id
.transform_new_cfg
= true;
95 id
.transform_return_to_modify
= false;
96 id
.transform_lang_insert_block
= NULL
;
98 /* We're not inside any EH region. */
101 stmts
= DECL_SAVED_TREE (fn
);
102 walk_tree (&stmts
, copy_tree_body_r
, &id
, NULL
);
104 /* Also remap the initializer of any static variables so that they (in
105 particular, any label addresses) correspond to the base variant rather
106 than the abstract one. */
107 if (DECL_NAME (clone
) == base_dtor_identifier
108 || DECL_NAME (clone
) == base_ctor_identifier
)
110 tree decls
= DECL_STRUCT_FUNCTION (fn
)->local_decls
;
111 for (; decls
; decls
= TREE_CHAIN (decls
))
113 tree decl
= TREE_VALUE (decls
);
114 walk_tree (&DECL_INITIAL (decl
), copy_tree_body_r
, &id
, NULL
);
118 append_to_statement_list_force (stmts
, &DECL_SAVED_TREE (clone
));
121 /* DELETE_DTOR is a delete destructor whose body will be built.
122 COMPLETE_DTOR is the corresponding complete destructor. */
125 build_delete_destructor_body (tree delete_dtor
, tree complete_dtor
)
127 tree call_dtor
, call_delete
;
128 tree parm
= DECL_ARGUMENTS (delete_dtor
);
129 tree virtual_size
= cxx_sizeof (current_class_type
);
131 /* Call the corresponding complete destructor. */
132 gcc_assert (complete_dtor
);
133 call_dtor
= build_cxx_call (complete_dtor
, 1, &parm
);
134 add_stmt (call_dtor
);
136 add_stmt (build_stmt (0, LABEL_EXPR
, cdtor_label
));
138 /* Call the delete function. */
139 call_delete
= build_op_delete_call (DELETE_EXPR
, current_class_ptr
,
142 /*placement=*/NULL_TREE
,
143 /*alloc_fn=*/NULL_TREE
);
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. */
161 cdtor_comdat_group (tree complete
, tree base
)
163 tree complete_name
= DECL_COMDAT_GROUP (complete
);
164 tree base_name
= DECL_COMDAT_GROUP (base
);
167 bool diff_seen
= false;
169 if (complete_name
== NULL
)
170 complete_name
= cxx_comdat_group (complete
);
171 if (base_name
== NULL
)
172 base_name
= cxx_comdat_group (base
);
173 gcc_assert (IDENTIFIER_LENGTH (complete_name
)
174 == IDENTIFIER_LENGTH (base_name
));
175 grp_name
= XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name
) + 1);
176 p
= IDENTIFIER_POINTER (complete_name
);
177 q
= IDENTIFIER_POINTER (base_name
);
178 for (idx
= 0; idx
< IDENTIFIER_LENGTH (complete_name
); idx
++)
179 if (p
[idx
] == q
[idx
])
180 grp_name
[idx
] = p
[idx
];
183 gcc_assert (!diff_seen
185 && (p
[idx
- 1] == 'C' || p
[idx
- 1] == 'D')
191 grp_name
[idx
] = '\0';
192 gcc_assert (diff_seen
);
193 return get_identifier (grp_name
);
196 /* FN is a function that has a complete body. Clone the body as
197 necessary. Returns nonzero if there's no longer any need to
198 process the main body. */
201 maybe_clone_body (tree fn
)
203 tree comdat_group
= NULL_TREE
;
207 bool in_charge_parm_used
;
209 bool need_alias
= false;
211 /* We only clone constructors and destructors. */
212 if (!DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn
)
213 && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn
))
216 /* Emit the DWARF1 abstract instance. */
217 (*debug_hooks
->deferred_inline_function
) (fn
);
219 in_charge_parm_used
= CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn
)) != NULL
;
224 /* Look for the complete destructor which may be used to build the
225 delete destructor. */
226 FOR_EACH_CLONE (clone
, fn
)
227 if (DECL_NAME (clone
) == complete_dtor_identifier
228 || DECL_NAME (clone
) == complete_ctor_identifier
)
230 else if (DECL_NAME (clone
) == base_dtor_identifier
231 || DECL_NAME (clone
) == base_ctor_identifier
)
233 else if (DECL_NAME (clone
) == deleting_dtor_identifier
)
238 /* Remember if we can't have multiple clones for some reason. We need to
239 check this before we remap local static initializers in clone_body. */
240 if (!tree_versionable_function_p (fn
))
243 /* We know that any clones immediately follow FN in the TYPE_METHODS
245 push_to_top_level ();
246 for (idx
= 0; idx
< 3; idx
++)
252 struct pointer_map_t
*decl_map
;
258 /* Update CLONE's source position information to match FN's. */
259 DECL_SOURCE_LOCATION (clone
) = DECL_SOURCE_LOCATION (fn
);
260 DECL_DECLARED_INLINE_P (clone
) = DECL_DECLARED_INLINE_P (fn
);
261 DECL_COMDAT (clone
) = DECL_COMDAT (fn
);
262 DECL_WEAK (clone
) = DECL_WEAK (fn
);
264 /* We don't copy the comdat group from fn to clone because the assembler
265 name of fn was corrupted by write_mangled_name by adding *INTERNAL*
266 to it. By doing so, it also corrupted the comdat group. */
267 if (DECL_ONE_ONLY (fn
))
268 DECL_COMDAT_GROUP (clone
) = cxx_comdat_group (clone
);
269 DECL_SECTION_NAME (clone
) = DECL_SECTION_NAME (fn
);
270 DECL_USE_TEMPLATE (clone
) = DECL_USE_TEMPLATE (fn
);
271 DECL_EXTERNAL (clone
) = DECL_EXTERNAL (fn
);
272 DECL_INTERFACE_KNOWN (clone
) = DECL_INTERFACE_KNOWN (fn
);
273 DECL_NOT_REALLY_EXTERN (clone
) = DECL_NOT_REALLY_EXTERN (fn
);
274 TREE_PUBLIC (clone
) = TREE_PUBLIC (fn
);
275 DECL_VISIBILITY (clone
) = DECL_VISIBILITY (fn
);
276 DECL_VISIBILITY_SPECIFIED (clone
) = DECL_VISIBILITY_SPECIFIED (fn
);
277 DECL_DLLIMPORT_P (clone
) = DECL_DLLIMPORT_P (fn
);
278 DECL_ATTRIBUTES (clone
) = copy_list (DECL_ATTRIBUTES (fn
));
279 DECL_DISREGARD_INLINE_LIMITS (clone
) = DECL_DISREGARD_INLINE_LIMITS (fn
);
281 /* Adjust the parameter names and locations. */
282 parm
= DECL_ARGUMENTS (fn
);
283 clone_parm
= DECL_ARGUMENTS (clone
);
284 /* Update the `this' parameter, which is always first. */
285 update_cloned_parm (parm
, clone_parm
, first
);
286 parm
= TREE_CHAIN (parm
);
287 clone_parm
= TREE_CHAIN (clone_parm
);
288 if (DECL_HAS_IN_CHARGE_PARM_P (fn
))
289 parm
= TREE_CHAIN (parm
);
290 if (DECL_HAS_VTT_PARM_P (fn
))
291 parm
= TREE_CHAIN (parm
);
292 if (DECL_HAS_VTT_PARM_P (clone
))
293 clone_parm
= TREE_CHAIN (clone_parm
);
295 parm
= TREE_CHAIN (parm
), clone_parm
= TREE_CHAIN (clone_parm
))
296 /* Update this parameter. */
297 update_cloned_parm (parm
, clone_parm
, first
);
299 /* Start processing the function. */
300 start_preparsed_function (clone
, NULL_TREE
, SF_PRE_PARSED
);
302 /* Tell cgraph if both ctors or both dtors are known to have
304 if (!in_charge_parm_used
307 && !flag_use_repository
308 && DECL_INTERFACE_KNOWN (fns
[0])
309 && (SUPPORTS_ONE_ONLY
|| !DECL_WEAK (fns
[0]))
310 && (!DECL_ONE_ONLY (fns
[0])
311 || (HAVE_COMDAT_GROUP
312 && DECL_WEAK (fns
[0])))
313 && cgraph_same_body_alias (clone
, fns
[0]))
316 if (DECL_ONE_ONLY (fns
[0]))
318 /* For comdat base and complete cdtors put them
319 into the same, *[CD]5* comdat group instead of
321 comdat_group
= cdtor_comdat_group (fns
[1], fns
[0]);
322 DECL_COMDAT_GROUP (fns
[0]) = comdat_group
;
326 /* Build the delete destructor by calling complete destructor
327 and delete function. */
329 build_delete_destructor_body (clone
, fns
[1]);
331 /* No need to populate body. */ ;
334 /* If we can't have multiple copies of FN (say, because there's a
335 static local initialized with the address of a label), we need
336 to use an alias for the complete variant. */
337 if (idx
== 1 && need_alias
)
339 if (DECL_STRUCT_FUNCTION (fn
)->cannot_be_copied_set
)
340 sorry (DECL_STRUCT_FUNCTION (fn
)->cannot_be_copied_reason
, fn
);
342 sorry ("making multiple clones of %qD", fn
);
345 /* Remap the parameters. */
346 decl_map
= pointer_map_create ();
348 parm
= DECL_ARGUMENTS (fn
),
349 clone_parm
= DECL_ARGUMENTS (clone
);
352 parm
= TREE_CHAIN (parm
))
354 /* Map the in-charge parameter to an appropriate constant. */
355 if (DECL_HAS_IN_CHARGE_PARM_P (fn
) && parmno
== 1)
358 in_charge
= in_charge_arg_for_name (DECL_NAME (clone
));
359 *pointer_map_insert (decl_map
, parm
) = in_charge
;
361 else if (DECL_ARTIFICIAL (parm
)
362 && DECL_NAME (parm
) == vtt_parm_identifier
)
364 /* For a subobject constructor or destructor, the next
365 argument is the VTT parameter. Remap the VTT_PARM
366 from the CLONE to this parameter. */
367 if (DECL_HAS_VTT_PARM_P (clone
))
369 DECL_ABSTRACT_ORIGIN (clone_parm
) = parm
;
370 *pointer_map_insert (decl_map
, parm
) = clone_parm
;
371 clone_parm
= TREE_CHAIN (clone_parm
);
373 /* Otherwise, map the VTT parameter to `NULL'. */
375 *pointer_map_insert (decl_map
, parm
)
376 = fold_convert (TREE_TYPE (parm
), null_pointer_node
);
378 /* Map other parameters to their equivalents in the cloned
382 *pointer_map_insert (decl_map
, parm
) = clone_parm
;
383 clone_parm
= TREE_CHAIN (clone_parm
);
387 if (targetm
.cxx
.cdtor_returns_this ())
389 parm
= DECL_RESULT (fn
);
390 clone_parm
= DECL_RESULT (clone
);
391 *pointer_map_insert (decl_map
, parm
) = clone_parm
;
394 /* Clone the body. */
395 clone_body (clone
, fn
, decl_map
);
398 pointer_map_destroy (decl_map
);
401 /* The clone can throw iff the original function can throw. */
402 cp_function_chain
->can_throw
= !TREE_NOTHROW (fn
);
404 /* Now, expand this function into RTL, if appropriate. */
406 BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone
)) = DECL_INITIAL (fn
);
409 if (expand_or_defer_fn_1 (clone
))
410 emit_associated_thunks (clone
);
413 expand_or_defer_fn (clone
);
416 pop_from_top_level ();
420 DECL_COMDAT_GROUP (fns
[1]) = comdat_group
;
423 struct cgraph_node
*base_dtor_node
, *deleting_dtor_node
;
424 /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
425 virtual, it goes into the same comdat group as well. */
426 DECL_COMDAT_GROUP (fns
[2]) = comdat_group
;
427 base_dtor_node
= cgraph_node (fns
[0]);
428 deleting_dtor_node
= cgraph_node (fns
[2]);
429 gcc_assert (base_dtor_node
->same_comdat_group
== NULL
);
430 gcc_assert (deleting_dtor_node
->same_comdat_group
== NULL
);
431 base_dtor_node
->same_comdat_group
= deleting_dtor_node
;
432 deleting_dtor_node
->same_comdat_group
= base_dtor_node
;
436 /* We don't need to process the original function any further. */