2012-02-15 Sandra Loosemore <sandra@codesourcery.com>
[official-gcc.git] / gcc / cp / optimize.c
blob6a06988039837a5abb1805bf406f1f25ed6bf49d
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)
11 any later version.
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/>. */
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 "input.h"
29 #include "params.h"
30 #include "hashtab.h"
31 #include "target.h"
32 #include "debug.h"
33 #include "tree-inline.h"
34 #include "flags.h"
35 #include "langhooks.h"
36 #include "diagnostic-core.h"
37 #include "tree-dump.h"
38 #include "gimple.h"
39 #include "tree-iterator.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 = (struct pointer_map_t *) 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 add_stmt (call_dtor);
134 add_stmt (build_stmt (0, LABEL_EXPR, cdtor_label));
136 /* Call the delete function. */
137 call_delete = build_op_delete_call (DELETE_EXPR, current_class_ptr,
138 virtual_size,
139 /*global_p=*/false,
140 /*placement=*/NULL_TREE,
141 /*alloc_fn=*/NULL_TREE);
142 add_stmt (call_delete);
144 /* Return the address of the object. */
145 if (targetm.cxx.cdtor_returns_this ())
147 tree val = DECL_ARGUMENTS (delete_dtor);
148 val = build2 (MODIFY_EXPR, TREE_TYPE (val),
149 DECL_RESULT (delete_dtor), val);
150 add_stmt (build_stmt (0, RETURN_EXPR, val));
154 /* Return name of comdat group for complete and base ctor (or dtor)
155 that have the same body. If dtor is virtual, deleting dtor goes
156 into this comdat group as well. */
158 static tree
159 cdtor_comdat_group (tree complete, tree base)
161 tree complete_name = DECL_COMDAT_GROUP (complete);
162 tree base_name = DECL_COMDAT_GROUP (base);
163 char *grp_name;
164 const char *p, *q;
165 bool diff_seen = false;
166 size_t idx;
167 if (complete_name == NULL)
168 complete_name = cxx_comdat_group (complete);
169 if (base_name == NULL)
170 base_name = cxx_comdat_group (base);
171 gcc_assert (IDENTIFIER_LENGTH (complete_name)
172 == IDENTIFIER_LENGTH (base_name));
173 grp_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name) + 1);
174 p = IDENTIFIER_POINTER (complete_name);
175 q = IDENTIFIER_POINTER (base_name);
176 for (idx = 0; idx < IDENTIFIER_LENGTH (complete_name); idx++)
177 if (p[idx] == q[idx])
178 grp_name[idx] = p[idx];
179 else
181 gcc_assert (!diff_seen
182 && idx > 0
183 && (p[idx - 1] == 'C' || p[idx - 1] == 'D')
184 && p[idx] == '1'
185 && q[idx] == '2');
186 grp_name[idx] = '5';
187 diff_seen = true;
189 grp_name[idx] = '\0';
190 gcc_assert (diff_seen);
191 return get_identifier (grp_name);
194 /* FN is a function that has a complete body. Clone the body as
195 necessary. Returns nonzero if there's no longer any need to
196 process the main body. */
198 bool
199 maybe_clone_body (tree fn)
201 tree comdat_group = NULL_TREE;
202 tree clone;
203 tree fns[3];
204 bool first = true;
205 bool in_charge_parm_used;
206 int idx;
207 bool need_alias = false;
209 /* We only clone constructors and destructors. */
210 if (!DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
211 && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
212 return 0;
214 /* Emit the DWARF1 abstract instance. */
215 (*debug_hooks->deferred_inline_function) (fn);
217 in_charge_parm_used = CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)) != NULL;
218 fns[0] = NULL_TREE;
219 fns[1] = NULL_TREE;
220 fns[2] = NULL_TREE;
222 /* Look for the complete destructor which may be used to build the
223 delete destructor. */
224 FOR_EACH_CLONE (clone, fn)
225 if (DECL_NAME (clone) == complete_dtor_identifier
226 || DECL_NAME (clone) == complete_ctor_identifier)
227 fns[1] = clone;
228 else if (DECL_NAME (clone) == base_dtor_identifier
229 || DECL_NAME (clone) == base_ctor_identifier)
230 fns[0] = clone;
231 else if (DECL_NAME (clone) == deleting_dtor_identifier)
232 fns[2] = clone;
233 else
234 gcc_unreachable ();
236 /* Remember if we can't have multiple clones for some reason. We need to
237 check this before we remap local static initializers in clone_body. */
238 if (!tree_versionable_function_p (fn))
239 need_alias = true;
241 /* We know that any clones immediately follow FN in the TYPE_METHODS
242 list. */
243 push_to_top_level ();
244 for (idx = 0; idx < 3; idx++)
246 tree parm;
247 tree clone_parm;
248 int parmno;
249 bool alias = false;
250 struct pointer_map_t *decl_map;
252 clone = fns[idx];
253 if (!clone)
254 continue;
256 /* Update CLONE's source position information to match FN's. */
257 DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (fn);
258 DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn);
259 DECL_DECLARED_CONSTEXPR_P (clone) = DECL_DECLARED_CONSTEXPR_P (fn);
260 DECL_COMDAT (clone) = DECL_COMDAT (fn);
261 DECL_WEAK (clone) = DECL_WEAK (fn);
263 /* We don't copy the comdat group from fn to clone because the assembler
264 name of fn was corrupted by write_mangled_name by adding *INTERNAL*
265 to it. By doing so, it also corrupted the comdat group. */
266 if (DECL_ONE_ONLY (fn))
267 DECL_COMDAT_GROUP (clone) = cxx_comdat_group (clone);
268 DECL_SECTION_NAME (clone) = DECL_SECTION_NAME (fn);
269 DECL_USE_TEMPLATE (clone) = DECL_USE_TEMPLATE (fn);
270 DECL_EXTERNAL (clone) = DECL_EXTERNAL (fn);
271 DECL_INTERFACE_KNOWN (clone) = DECL_INTERFACE_KNOWN (fn);
272 DECL_NOT_REALLY_EXTERN (clone) = DECL_NOT_REALLY_EXTERN (fn);
273 TREE_PUBLIC (clone) = TREE_PUBLIC (fn);
274 DECL_VISIBILITY (clone) = DECL_VISIBILITY (fn);
275 DECL_VISIBILITY_SPECIFIED (clone) = DECL_VISIBILITY_SPECIFIED (fn);
276 DECL_DLLIMPORT_P (clone) = DECL_DLLIMPORT_P (fn);
277 DECL_ATTRIBUTES (clone) = copy_list (DECL_ATTRIBUTES (fn));
278 DECL_DISREGARD_INLINE_LIMITS (clone) = DECL_DISREGARD_INLINE_LIMITS (fn);
280 /* Adjust the parameter names and locations. */
281 parm = DECL_ARGUMENTS (fn);
282 clone_parm = DECL_ARGUMENTS (clone);
283 /* Update the `this' parameter, which is always first. */
284 update_cloned_parm (parm, clone_parm, first);
285 parm = DECL_CHAIN (parm);
286 clone_parm = DECL_CHAIN (clone_parm);
287 if (DECL_HAS_IN_CHARGE_PARM_P (fn))
288 parm = DECL_CHAIN (parm);
289 if (DECL_HAS_VTT_PARM_P (fn))
290 parm = DECL_CHAIN (parm);
291 if (DECL_HAS_VTT_PARM_P (clone))
292 clone_parm = DECL_CHAIN (clone_parm);
293 for (; parm;
294 parm = DECL_CHAIN (parm), clone_parm = DECL_CHAIN (clone_parm))
295 /* Update this parameter. */
296 update_cloned_parm (parm, clone_parm, first);
298 /* Start processing the function. */
299 start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
301 /* Tell cgraph if both ctors or both dtors are known to have
302 the same body. */
303 if (!in_charge_parm_used
304 && fns[0]
305 && idx == 1
306 && !flag_use_repository
307 && DECL_INTERFACE_KNOWN (fns[0])
308 && (SUPPORTS_ONE_ONLY || !DECL_WEAK (fns[0]))
309 && (!DECL_ONE_ONLY (fns[0])
310 || (HAVE_COMDAT_GROUP
311 && DECL_WEAK (fns[0])))
312 && !flag_syntax_only
313 /* Set linkage flags appropriately before
314 cgraph_create_function_alias looks at them. */
315 && expand_or_defer_fn_1 (clone)
316 && cgraph_same_body_alias (cgraph_get_node (fns[0]),
317 clone, fns[0]))
319 alias = true;
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
324 *[CD][12]*. */
325 comdat_group = cdtor_comdat_group (fns[1], fns[0]);
326 DECL_COMDAT_GROUP (fns[0]) = comdat_group;
327 cgraph_add_to_same_comdat_group (cgraph_get_node (clone),
328 cgraph_get_node (fns[0]));
332 /* Build the delete destructor by calling complete destructor
333 and delete function. */
334 if (idx == 2)
336 build_delete_destructor_body (clone, fns[1]);
337 /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
338 virtual, it goes into the same comdat group as well. */
339 if (comdat_group)
340 cgraph_add_to_same_comdat_group (cgraph_get_create_node (clone),
341 cgraph_get_node (fns[0]));
343 else if (alias)
344 /* No need to populate body. */ ;
345 else
347 /* If we can't have multiple copies of FN (say, because there's a
348 static local initialized with the address of a label), we need
349 to use an alias for the complete variant. */
350 if (idx == 1 && need_alias)
352 if (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_set)
353 sorry (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_reason, fn);
354 else
355 sorry ("making multiple clones of %qD", fn);
358 /* Remap the parameters. */
359 decl_map = pointer_map_create ();
360 for (parmno = 0,
361 parm = DECL_ARGUMENTS (fn),
362 clone_parm = DECL_ARGUMENTS (clone);
363 parm;
364 ++parmno,
365 parm = DECL_CHAIN (parm))
367 /* Map the in-charge parameter to an appropriate constant. */
368 if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1)
370 tree in_charge;
371 in_charge = in_charge_arg_for_name (DECL_NAME (clone));
372 *pointer_map_insert (decl_map, parm) = in_charge;
374 else if (DECL_ARTIFICIAL (parm)
375 && DECL_NAME (parm) == vtt_parm_identifier)
377 /* For a subobject constructor or destructor, the next
378 argument is the VTT parameter. Remap the VTT_PARM
379 from the CLONE to this parameter. */
380 if (DECL_HAS_VTT_PARM_P (clone))
382 DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
383 *pointer_map_insert (decl_map, parm) = clone_parm;
384 clone_parm = DECL_CHAIN (clone_parm);
386 /* Otherwise, map the VTT parameter to `NULL'. */
387 else
388 *pointer_map_insert (decl_map, parm)
389 = fold_convert (TREE_TYPE (parm), null_pointer_node);
391 /* Map other parameters to their equivalents in the cloned
392 function. */
393 else
395 *pointer_map_insert (decl_map, parm) = clone_parm;
396 clone_parm = DECL_CHAIN (clone_parm);
400 if (targetm.cxx.cdtor_returns_this ())
402 parm = DECL_RESULT (fn);
403 clone_parm = DECL_RESULT (clone);
404 *pointer_map_insert (decl_map, parm) = clone_parm;
407 /* Clone the body. */
408 clone_body (clone, fn, decl_map);
410 /* Clean up. */
411 pointer_map_destroy (decl_map);
414 /* The clone can throw iff the original function can throw. */
415 cp_function_chain->can_throw = !TREE_NOTHROW (fn);
417 /* Now, expand this function into RTL, if appropriate. */
418 finish_function (0);
419 BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
420 if (alias)
422 if (expand_or_defer_fn_1 (clone))
423 emit_associated_thunks (clone);
425 else
426 expand_or_defer_fn (clone);
427 first = false;
429 pop_from_top_level ();
431 /* We don't need to process the original function any further. */
432 return 1;