re PR c++/41090 (Using static label reference in c++ class constructor produces wrong...
[gcc.git] / gcc / cp / optimize.c
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).
5
6 This file is part of GCC.
7
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)
11 any later version.
12
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.
17
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/>. */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "tree.h"
27 #include "cp-tree.h"
28 #include "rtl.h"
29 #include "insn-config.h"
30 #include "input.h"
31 #include "integrate.h"
32 #include "toplev.h"
33 #include "varray.h"
34 #include "params.h"
35 #include "hashtab.h"
36 #include "target.h"
37 #include "debug.h"
38 #include "tree-inline.h"
39 #include "flags.h"
40 #include "langhooks.h"
41 #include "diagnostic.h"
42 #include "tree-dump.h"
43 #include "gimple.h"
44 #include "tree-iterator.h"
45 #include "cgraph.h"
46
47 /* Prototypes. */
48
49 static void update_cloned_parm (tree, tree, bool);
50
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. */
55
56 static void
57 update_cloned_parm (tree parm, tree cloned_parm, bool first)
58 {
59 DECL_ABSTRACT_ORIGIN (cloned_parm) = parm;
60
61 /* We may have taken its address. */
62 TREE_ADDRESSABLE (cloned_parm) = TREE_ADDRESSABLE (parm);
63
64 /* The definition might have different constness. */
65 TREE_READONLY (cloned_parm) = TREE_READONLY (parm);
66
67 TREE_USED (cloned_parm) = !first || TREE_USED (parm);
68
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);
73
74 DECL_GIMPLE_REG_P (cloned_parm) = DECL_GIMPLE_REG_P (parm);
75 }
76
77
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. */
81
82 static void
83 clone_body (tree clone, tree fn, void *arg_map)
84 {
85 copy_body_data id;
86 tree stmts;
87
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));
91 id.src_fn = fn;
92 id.dst_fn = clone;
93 id.src_cfun = DECL_STRUCT_FUNCTION (fn);
94 id.decl_map = (struct pointer_map_t *) arg_map;
95
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;
101
102 /* We're not inside any EH region. */
103 id.eh_lp_nr = 0;
104
105 stmts = DECL_SAVED_TREE (fn);
106 walk_tree (&stmts, copy_tree_body_r, &id, NULL);
107
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)
113 {
114 tree decls = DECL_STRUCT_FUNCTION (fn)->local_decls;
115 for (; decls; decls = TREE_CHAIN (decls))
116 {
117 tree decl = TREE_VALUE (decls);
118 walk_tree (&DECL_INITIAL (decl), copy_tree_body_r, &id, NULL);
119 }
120 }
121
122 append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone));
123 }
124
125 /* DELETE_DTOR is a delete destructor whose body will be built.
126 COMPLETE_DTOR is the corresponding complete destructor. */
127
128 static void
129 build_delete_destructor_body (tree delete_dtor, tree complete_dtor)
130 {
131 tree call_dtor, call_delete;
132 tree parm = DECL_ARGUMENTS (delete_dtor);
133 tree virtual_size = cxx_sizeof (current_class_type);
134
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);
139
140 add_stmt (build_stmt (0, LABEL_EXPR, cdtor_label));
141
142 /* Call the delete function. */
143 call_delete = build_op_delete_call (DELETE_EXPR, current_class_ptr,
144 virtual_size,
145 /*global_p=*/false,
146 /*placement=*/NULL_TREE,
147 /*alloc_fn=*/NULL_TREE);
148 add_stmt (call_delete);
149
150 /* Return the address of the object. */
151 if (targetm.cxx.cdtor_returns_this ())
152 {
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));
157 }
158 }
159
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. */
163
164 static tree
165 cdtor_comdat_group (tree complete, tree base)
166 {
167 tree complete_name = DECL_COMDAT_GROUP (complete);
168 tree base_name = DECL_COMDAT_GROUP (base);
169 char *grp_name;
170 const char *p, *q;
171 bool diff_seen = false;
172 size_t idx;
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];
185 else
186 {
187 gcc_assert (!diff_seen
188 && idx > 0
189 && (p[idx - 1] == 'C' || p[idx - 1] == 'D')
190 && p[idx] == '1'
191 && q[idx] == '2');
192 grp_name[idx] = '5';
193 diff_seen = true;
194 }
195 grp_name[idx] = '\0';
196 gcc_assert (diff_seen);
197 return get_identifier (grp_name);
198 }
199
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. */
203
204 bool
205 maybe_clone_body (tree fn)
206 {
207 tree comdat_group = NULL_TREE;
208 tree clone;
209 tree fns[3];
210 bool first = true;
211 bool in_charge_parm_used;
212 int idx;
213 bool need_alias = false;
214
215 /* We only clone constructors and destructors. */
216 if (!DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
217 && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
218 return 0;
219
220 /* Emit the DWARF1 abstract instance. */
221 (*debug_hooks->deferred_inline_function) (fn);
222
223 in_charge_parm_used = CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)) != NULL;
224 fns[0] = NULL_TREE;
225 fns[1] = NULL_TREE;
226 fns[2] = NULL_TREE;
227
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)
233 fns[1] = clone;
234 else if (DECL_NAME (clone) == base_dtor_identifier
235 || DECL_NAME (clone) == base_ctor_identifier)
236 fns[0] = clone;
237 else if (DECL_NAME (clone) == deleting_dtor_identifier)
238 fns[2] = clone;
239 else
240 gcc_unreachable ();
241
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))
245 need_alias = true;
246
247 /* We know that any clones immediately follow FN in the TYPE_METHODS
248 list. */
249 push_to_top_level ();
250 for (idx = 0; idx < 3; idx++)
251 {
252 tree parm;
253 tree clone_parm;
254 int parmno;
255 bool alias = false;
256 struct pointer_map_t *decl_map;
257
258 clone = fns[idx];
259 if (!clone)
260 continue;
261
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);
267
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);
284
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);
298 for (; parm;
299 parm = TREE_CHAIN (parm), clone_parm = TREE_CHAIN (clone_parm))
300 /* Update this parameter. */
301 update_cloned_parm (parm, clone_parm, first);
302
303 /* Start processing the function. */
304 start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
305
306 /* Tell cgraph if both ctors or both dtors are known to have
307 the same body. */
308 if (!in_charge_parm_used
309 && fns[0]
310 && idx == 1
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]))
318 {
319 alias = true;
320 if (DECL_ONE_ONLY (fns[0]))
321 {
322 /* For comdat base and complete cdtors put them
323 into the same, *[CD]5* comdat group instead of
324 *[CD][12]*. */
325 comdat_group = cdtor_comdat_group (fns[1], fns[0]);
326 DECL_COMDAT_GROUP (fns[0]) = comdat_group;
327 }
328 }
329
330 /* Build the delete destructor by calling complete destructor
331 and delete function. */
332 if (idx == 2)
333 build_delete_destructor_body (clone, fns[1]);
334 else if (alias)
335 /* No need to populate body. */ ;
336 else
337 {
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)
342 {
343 if (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_set)
344 sorry (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_reason, fn);
345 else
346 sorry ("making multiple clones of %qD", fn);
347 }
348
349 /* Remap the parameters. */
350 decl_map = pointer_map_create ();
351 for (parmno = 0,
352 parm = DECL_ARGUMENTS (fn),
353 clone_parm = DECL_ARGUMENTS (clone);
354 parm;
355 ++parmno,
356 parm = TREE_CHAIN (parm))
357 {
358 /* Map the in-charge parameter to an appropriate constant. */
359 if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1)
360 {
361 tree in_charge;
362 in_charge = in_charge_arg_for_name (DECL_NAME (clone));
363 *pointer_map_insert (decl_map, parm) = in_charge;
364 }
365 else if (DECL_ARTIFICIAL (parm)
366 && DECL_NAME (parm) == vtt_parm_identifier)
367 {
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))
372 {
373 DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
374 *pointer_map_insert (decl_map, parm) = clone_parm;
375 clone_parm = TREE_CHAIN (clone_parm);
376 }
377 /* Otherwise, map the VTT parameter to `NULL'. */
378 else
379 *pointer_map_insert (decl_map, parm)
380 = fold_convert (TREE_TYPE (parm), null_pointer_node);
381 }
382 /* Map other parameters to their equivalents in the cloned
383 function. */
384 else
385 {
386 *pointer_map_insert (decl_map, parm) = clone_parm;
387 clone_parm = TREE_CHAIN (clone_parm);
388 }
389 }
390
391 if (targetm.cxx.cdtor_returns_this ())
392 {
393 parm = DECL_RESULT (fn);
394 clone_parm = DECL_RESULT (clone);
395 *pointer_map_insert (decl_map, parm) = clone_parm;
396 }
397
398 /* Clone the body. */
399 clone_body (clone, fn, decl_map);
400
401 /* Clean up. */
402 pointer_map_destroy (decl_map);
403 }
404
405 /* The clone can throw iff the original function can throw. */
406 cp_function_chain->can_throw = !TREE_NOTHROW (fn);
407
408 /* Now, expand this function into RTL, if appropriate. */
409 finish_function (0);
410 BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
411 if (alias)
412 {
413 if (expand_or_defer_fn_1 (clone))
414 emit_associated_thunks (clone);
415 }
416 else
417 expand_or_defer_fn (clone);
418 first = false;
419 }
420 pop_from_top_level ();
421
422 if (comdat_group)
423 {
424 DECL_COMDAT_GROUP (fns[1]) = comdat_group;
425 if (fns[2])
426 {
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;
437 }
438 }
439
440 /* We don't need to process the original function any further. */
441 return 1;
442 }