2011-03-15 Diego Novillo <dnovillo@google.com>
[official-gcc.git] / gcc / cp / optimize.c
blob2ce9838a74e80f593afd20c77d9b06b4a6e69383
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 && cgraph_same_body_alias (cgraph_node (fns[0]), clone, fns[0]))
314 alias = true;
315 if (DECL_ONE_ONLY (fns[0]))
317 /* For comdat base and complete cdtors put them
318 into the same, *[CD]5* comdat group instead of
319 *[CD][12]*. */
320 comdat_group = cdtor_comdat_group (fns[1], fns[0]);
321 DECL_COMDAT_GROUP (fns[0]) = comdat_group;
325 /* Build the delete destructor by calling complete destructor
326 and delete function. */
327 if (idx == 2)
328 build_delete_destructor_body (clone, fns[1]);
329 else if (alias)
330 /* No need to populate body. */ ;
331 else
333 /* If we can't have multiple copies of FN (say, because there's a
334 static local initialized with the address of a label), we need
335 to use an alias for the complete variant. */
336 if (idx == 1 && need_alias)
338 if (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_set)
339 sorry (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_reason, fn);
340 else
341 sorry ("making multiple clones of %qD", fn);
344 /* Remap the parameters. */
345 decl_map = pointer_map_create ();
346 for (parmno = 0,
347 parm = DECL_ARGUMENTS (fn),
348 clone_parm = DECL_ARGUMENTS (clone);
349 parm;
350 ++parmno,
351 parm = DECL_CHAIN (parm))
353 /* Map the in-charge parameter to an appropriate constant. */
354 if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1)
356 tree in_charge;
357 in_charge = in_charge_arg_for_name (DECL_NAME (clone));
358 *pointer_map_insert (decl_map, parm) = in_charge;
360 else if (DECL_ARTIFICIAL (parm)
361 && DECL_NAME (parm) == vtt_parm_identifier)
363 /* For a subobject constructor or destructor, the next
364 argument is the VTT parameter. Remap the VTT_PARM
365 from the CLONE to this parameter. */
366 if (DECL_HAS_VTT_PARM_P (clone))
368 DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
369 *pointer_map_insert (decl_map, parm) = clone_parm;
370 clone_parm = DECL_CHAIN (clone_parm);
372 /* Otherwise, map the VTT parameter to `NULL'. */
373 else
374 *pointer_map_insert (decl_map, parm)
375 = fold_convert (TREE_TYPE (parm), null_pointer_node);
377 /* Map other parameters to their equivalents in the cloned
378 function. */
379 else
381 *pointer_map_insert (decl_map, parm) = clone_parm;
382 clone_parm = DECL_CHAIN (clone_parm);
386 if (targetm.cxx.cdtor_returns_this ())
388 parm = DECL_RESULT (fn);
389 clone_parm = DECL_RESULT (clone);
390 *pointer_map_insert (decl_map, parm) = clone_parm;
393 /* Clone the body. */
394 clone_body (clone, fn, decl_map);
396 /* Clean up. */
397 pointer_map_destroy (decl_map);
400 /* The clone can throw iff the original function can throw. */
401 cp_function_chain->can_throw = !TREE_NOTHROW (fn);
403 /* Now, expand this function into RTL, if appropriate. */
404 finish_function (0);
405 BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
406 if (alias)
408 if (expand_or_defer_fn_1 (clone))
409 emit_associated_thunks (clone);
411 else
412 expand_or_defer_fn (clone);
413 first = false;
415 pop_from_top_level ();
417 if (comdat_group)
419 DECL_COMDAT_GROUP (fns[1]) = comdat_group;
420 if (fns[2])
422 struct cgraph_node *base_dtor_node, *deleting_dtor_node;
423 /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
424 virtual, it goes into the same comdat group as well. */
425 DECL_COMDAT_GROUP (fns[2]) = comdat_group;
426 base_dtor_node = cgraph_node (fns[0]);
427 deleting_dtor_node = cgraph_node (fns[2]);
428 gcc_assert (base_dtor_node->same_comdat_group == NULL);
429 gcc_assert (deleting_dtor_node->same_comdat_group == NULL);
430 base_dtor_node->same_comdat_group = deleting_dtor_node;
431 deleting_dtor_node->same_comdat_group = base_dtor_node;
435 /* We don't need to process the original function any further. */
436 return 1;