1 /* Perform optimizations on tree structure.
2 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2008, 2009
3 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"
29 #include "insn-config.h"
31 #include "integrate.h"
38 #include "tree-inline.h"
40 #include "langhooks.h"
41 #include "diagnostic.h"
42 #include "tree-dump.h"
44 #include "tree-iterator.h"
49 static void update_cloned_parm (tree
, tree
, bool);
51 /* CLONED_PARM is a copy of CLONE, generated for a cloned constructor
52 or destructor. Update it to ensure that the source-position for
53 the cloned parameter matches that for the original, and that the
54 debugging generation code will be able to find the original PARM. */
57 update_cloned_parm (tree parm
, tree cloned_parm
, bool first
)
59 DECL_ABSTRACT_ORIGIN (cloned_parm
) = parm
;
61 /* We may have taken its address. */
62 TREE_ADDRESSABLE (cloned_parm
) = TREE_ADDRESSABLE (parm
);
64 /* The definition might have different constness. */
65 TREE_READONLY (cloned_parm
) = TREE_READONLY (parm
);
67 TREE_USED (cloned_parm
) = !first
|| TREE_USED (parm
);
69 /* The name may have changed from the declaration. */
70 DECL_NAME (cloned_parm
) = DECL_NAME (parm
);
71 DECL_SOURCE_LOCATION (cloned_parm
) = DECL_SOURCE_LOCATION (parm
);
72 TREE_TYPE (cloned_parm
) = TREE_TYPE (parm
);
74 DECL_GIMPLE_REG_P (cloned_parm
) = DECL_GIMPLE_REG_P (parm
);
78 /* FN is a function in High GIMPLE form that has a complete body and no
79 CFG. CLONE is a function whose body is to be set to a copy of FN,
80 mapping argument declarations according to the ARG_MAP splay_tree. */
83 clone_body (tree clone
, tree fn
, void *arg_map
)
88 /* Clone the body, as if we were making an inline call. But, remap
89 the parameters in the callee to the parameters of caller. */
90 memset (&id
, 0, sizeof (id
));
93 id
.src_cfun
= DECL_STRUCT_FUNCTION (fn
);
94 id
.decl_map
= (struct pointer_map_t
*) arg_map
;
96 id
.copy_decl
= copy_decl_no_change
;
97 id
.transform_call_graph_edges
= CB_CGE_DUPLICATE
;
98 id
.transform_new_cfg
= true;
99 id
.transform_return_to_modify
= false;
100 id
.transform_lang_insert_block
= NULL
;
102 /* We're not inside any EH region. */
105 stmts
= DECL_SAVED_TREE (fn
);
106 walk_tree (&stmts
, copy_tree_body_r
, &id
, NULL
);
108 /* Also remap the initializer of any static variables so that they (in
109 particular, any label addresses) correspond to the base variant rather
110 than the abstract one. */
111 if (DECL_NAME (clone
) == base_dtor_identifier
112 || DECL_NAME (clone
) == base_ctor_identifier
)
114 tree decls
= DECL_STRUCT_FUNCTION (fn
)->local_decls
;
115 for (; decls
; decls
= TREE_CHAIN (decls
))
117 tree decl
= TREE_VALUE (decls
);
118 walk_tree (&DECL_INITIAL (decl
), copy_tree_body_r
, &id
, NULL
);
122 append_to_statement_list_force (stmts
, &DECL_SAVED_TREE (clone
));
125 /* DELETE_DTOR is a delete destructor whose body will be built.
126 COMPLETE_DTOR is the corresponding complete destructor. */
129 build_delete_destructor_body (tree delete_dtor
, tree complete_dtor
)
131 tree call_dtor
, call_delete
;
132 tree parm
= DECL_ARGUMENTS (delete_dtor
);
133 tree virtual_size
= cxx_sizeof (current_class_type
);
135 /* Call the corresponding complete destructor. */
136 gcc_assert (complete_dtor
);
137 call_dtor
= build_cxx_call (complete_dtor
, 1, &parm
);
138 add_stmt (call_dtor
);
140 add_stmt (build_stmt (0, LABEL_EXPR
, cdtor_label
));
142 /* Call the delete function. */
143 call_delete
= build_op_delete_call (DELETE_EXPR
, current_class_ptr
,
146 /*placement=*/NULL_TREE
,
147 /*alloc_fn=*/NULL_TREE
);
148 add_stmt (call_delete
);
150 /* Return the address of the object. */
151 if (targetm
.cxx
.cdtor_returns_this ())
153 tree val
= DECL_ARGUMENTS (delete_dtor
);
154 val
= build2 (MODIFY_EXPR
, TREE_TYPE (val
),
155 DECL_RESULT (delete_dtor
), val
);
156 add_stmt (build_stmt (0, RETURN_EXPR
, val
));
160 /* Return name of comdat group for complete and base ctor (or dtor)
161 that have the same body. If dtor is virtual, deleting dtor goes
162 into this comdat group as well. */
165 cdtor_comdat_group (tree complete
, tree base
)
167 tree complete_name
= DECL_COMDAT_GROUP (complete
);
168 tree base_name
= DECL_COMDAT_GROUP (base
);
171 bool diff_seen
= false;
173 if (complete_name
== NULL
)
174 complete_name
= cxx_comdat_group (complete
);
175 if (base_name
== NULL
)
176 base_name
= cxx_comdat_group (base
);
177 gcc_assert (IDENTIFIER_LENGTH (complete_name
)
178 == IDENTIFIER_LENGTH (base_name
));
179 grp_name
= XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name
) + 1);
180 p
= IDENTIFIER_POINTER (complete_name
);
181 q
= IDENTIFIER_POINTER (base_name
);
182 for (idx
= 0; idx
< IDENTIFIER_LENGTH (complete_name
); idx
++)
183 if (p
[idx
] == q
[idx
])
184 grp_name
[idx
] = p
[idx
];
187 gcc_assert (!diff_seen
189 && (p
[idx
- 1] == 'C' || p
[idx
- 1] == 'D')
195 grp_name
[idx
] = '\0';
196 gcc_assert (diff_seen
);
197 return get_identifier (grp_name
);
200 /* FN is a function that has a complete body. Clone the body as
201 necessary. Returns nonzero if there's no longer any need to
202 process the main body. */
205 maybe_clone_body (tree fn
)
207 tree comdat_group
= NULL_TREE
;
211 bool in_charge_parm_used
;
213 bool need_alias
= false;
215 /* We only clone constructors and destructors. */
216 if (!DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn
)
217 && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn
))
220 /* Emit the DWARF1 abstract instance. */
221 (*debug_hooks
->deferred_inline_function
) (fn
);
223 in_charge_parm_used
= CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn
)) != NULL
;
228 /* Look for the complete destructor which may be used to build the
229 delete destructor. */
230 FOR_EACH_CLONE (clone
, fn
)
231 if (DECL_NAME (clone
) == complete_dtor_identifier
232 || DECL_NAME (clone
) == complete_ctor_identifier
)
234 else if (DECL_NAME (clone
) == base_dtor_identifier
235 || DECL_NAME (clone
) == base_ctor_identifier
)
237 else if (DECL_NAME (clone
) == deleting_dtor_identifier
)
242 /* Remember if we can't have multiple clones for some reason. We need to
243 check this before we remap local static initializers in clone_body. */
244 if (!tree_versionable_function_p (fn
))
247 /* We know that any clones immediately follow FN in the TYPE_METHODS
249 push_to_top_level ();
250 for (idx
= 0; idx
< 3; idx
++)
256 struct pointer_map_t
*decl_map
;
262 /* Update CLONE's source position information to match FN's. */
263 DECL_SOURCE_LOCATION (clone
) = DECL_SOURCE_LOCATION (fn
);
264 DECL_DECLARED_INLINE_P (clone
) = DECL_DECLARED_INLINE_P (fn
);
265 DECL_COMDAT (clone
) = DECL_COMDAT (fn
);
266 DECL_WEAK (clone
) = DECL_WEAK (fn
);
268 /* We don't copy the comdat group from fn to clone because the assembler
269 name of fn was corrupted by write_mangled_name by adding *INTERNAL*
270 to it. By doing so, it also corrupted the comdat group. */
271 if (DECL_ONE_ONLY (fn
))
272 DECL_COMDAT_GROUP (clone
) = cxx_comdat_group (clone
);
273 DECL_SECTION_NAME (clone
) = DECL_SECTION_NAME (fn
);
274 DECL_USE_TEMPLATE (clone
) = DECL_USE_TEMPLATE (fn
);
275 DECL_EXTERNAL (clone
) = DECL_EXTERNAL (fn
);
276 DECL_INTERFACE_KNOWN (clone
) = DECL_INTERFACE_KNOWN (fn
);
277 DECL_NOT_REALLY_EXTERN (clone
) = DECL_NOT_REALLY_EXTERN (fn
);
278 TREE_PUBLIC (clone
) = TREE_PUBLIC (fn
);
279 DECL_VISIBILITY (clone
) = DECL_VISIBILITY (fn
);
280 DECL_VISIBILITY_SPECIFIED (clone
) = DECL_VISIBILITY_SPECIFIED (fn
);
281 DECL_DLLIMPORT_P (clone
) = DECL_DLLIMPORT_P (fn
);
282 DECL_ATTRIBUTES (clone
) = copy_list (DECL_ATTRIBUTES (fn
));
283 DECL_DISREGARD_INLINE_LIMITS (clone
) = DECL_DISREGARD_INLINE_LIMITS (fn
);
285 /* Adjust the parameter names and locations. */
286 parm
= DECL_ARGUMENTS (fn
);
287 clone_parm
= DECL_ARGUMENTS (clone
);
288 /* Update the `this' parameter, which is always first. */
289 update_cloned_parm (parm
, clone_parm
, first
);
290 parm
= TREE_CHAIN (parm
);
291 clone_parm
= TREE_CHAIN (clone_parm
);
292 if (DECL_HAS_IN_CHARGE_PARM_P (fn
))
293 parm
= TREE_CHAIN (parm
);
294 if (DECL_HAS_VTT_PARM_P (fn
))
295 parm
= TREE_CHAIN (parm
);
296 if (DECL_HAS_VTT_PARM_P (clone
))
297 clone_parm
= TREE_CHAIN (clone_parm
);
299 parm
= TREE_CHAIN (parm
), clone_parm
= TREE_CHAIN (clone_parm
))
300 /* Update this parameter. */
301 update_cloned_parm (parm
, clone_parm
, first
);
303 /* Start processing the function. */
304 start_preparsed_function (clone
, NULL_TREE
, SF_PRE_PARSED
);
306 /* Tell cgraph if both ctors or both dtors are known to have
308 if (!in_charge_parm_used
311 && !flag_use_repository
312 && DECL_INTERFACE_KNOWN (fns
[0])
313 && (SUPPORTS_ONE_ONLY
|| !DECL_WEAK (fns
[0]))
314 && (!DECL_ONE_ONLY (fns
[0])
315 || (HAVE_COMDAT_GROUP
316 && DECL_WEAK (fns
[0])))
317 && cgraph_same_body_alias (clone
, fns
[0]))
320 if (DECL_ONE_ONLY (fns
[0]))
322 /* For comdat base and complete cdtors put them
323 into the same, *[CD]5* comdat group instead of
325 comdat_group
= cdtor_comdat_group (fns
[1], fns
[0]);
326 DECL_COMDAT_GROUP (fns
[0]) = comdat_group
;
330 /* Build the delete destructor by calling complete destructor
331 and delete function. */
333 build_delete_destructor_body (clone
, fns
[1]);
335 /* No need to populate body. */ ;
338 /* If we can't have multiple copies of FN (say, because there's a
339 static local initialized with the address of a label), we need
340 to use an alias for the complete variant. */
341 if (idx
== 1 && need_alias
)
343 if (DECL_STRUCT_FUNCTION (fn
)->cannot_be_copied_set
)
344 sorry (DECL_STRUCT_FUNCTION (fn
)->cannot_be_copied_reason
, fn
);
346 sorry ("making multiple clones of %qD", fn
);
349 /* Remap the parameters. */
350 decl_map
= pointer_map_create ();
352 parm
= DECL_ARGUMENTS (fn
),
353 clone_parm
= DECL_ARGUMENTS (clone
);
356 parm
= TREE_CHAIN (parm
))
358 /* Map the in-charge parameter to an appropriate constant. */
359 if (DECL_HAS_IN_CHARGE_PARM_P (fn
) && parmno
== 1)
362 in_charge
= in_charge_arg_for_name (DECL_NAME (clone
));
363 *pointer_map_insert (decl_map
, parm
) = in_charge
;
365 else if (DECL_ARTIFICIAL (parm
)
366 && DECL_NAME (parm
) == vtt_parm_identifier
)
368 /* For a subobject constructor or destructor, the next
369 argument is the VTT parameter. Remap the VTT_PARM
370 from the CLONE to this parameter. */
371 if (DECL_HAS_VTT_PARM_P (clone
))
373 DECL_ABSTRACT_ORIGIN (clone_parm
) = parm
;
374 *pointer_map_insert (decl_map
, parm
) = clone_parm
;
375 clone_parm
= TREE_CHAIN (clone_parm
);
377 /* Otherwise, map the VTT parameter to `NULL'. */
379 *pointer_map_insert (decl_map
, parm
)
380 = fold_convert (TREE_TYPE (parm
), null_pointer_node
);
382 /* Map other parameters to their equivalents in the cloned
386 *pointer_map_insert (decl_map
, parm
) = clone_parm
;
387 clone_parm
= TREE_CHAIN (clone_parm
);
391 if (targetm
.cxx
.cdtor_returns_this ())
393 parm
= DECL_RESULT (fn
);
394 clone_parm
= DECL_RESULT (clone
);
395 *pointer_map_insert (decl_map
, parm
) = clone_parm
;
398 /* Clone the body. */
399 clone_body (clone
, fn
, decl_map
);
402 pointer_map_destroy (decl_map
);
405 /* The clone can throw iff the original function can throw. */
406 cp_function_chain
->can_throw
= !TREE_NOTHROW (fn
);
408 /* Now, expand this function into RTL, if appropriate. */
410 BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone
)) = DECL_INITIAL (fn
);
413 if (expand_or_defer_fn_1 (clone
))
414 emit_associated_thunks (clone
);
417 expand_or_defer_fn (clone
);
420 pop_from_top_level ();
424 DECL_COMDAT_GROUP (fns
[1]) = comdat_group
;
427 struct cgraph_node
*base_dtor_node
, *deleting_dtor_node
;
428 /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
429 virtual, it goes into the same comdat group as well. */
430 DECL_COMDAT_GROUP (fns
[2]) = comdat_group
;
431 base_dtor_node
= cgraph_node (fns
[0]);
432 deleting_dtor_node
= cgraph_node (fns
[2]);
433 gcc_assert (base_dtor_node
->same_comdat_group
== NULL
);
434 gcc_assert (deleting_dtor_node
->same_comdat_group
== NULL
);
435 base_dtor_node
->same_comdat_group
= deleting_dtor_node
;
436 deleting_dtor_node
->same_comdat_group
= base_dtor_node
;
440 /* We don't need to process the original function any further. */