Merge from mainline (165734:167278).
[official-gcc/graphite-test-results.git] / gcc / cp / optimize.c
blob302a1332d6676ea0b59223da202df6f7737a6122
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 "toplev.h"
30 #include "params.h"
31 #include "hashtab.h"
32 #include "target.h"
33 #include "debug.h"
34 #include "tree-inline.h"
35 #include "flags.h"
36 #include "langhooks.h"
37 #include "diagnostic-core.h"
38 #include "tree-dump.h"
39 #include "gimple.h"
40 #include "tree-iterator.h"
41 #include "cgraph.h"
43 /* Prototypes. */
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. */
52 static void
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. */
78 static void
79 clone_body (tree clone, tree fn, void *arg_map)
81 copy_body_data id;
82 tree stmts;
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));
87 id.src_fn = fn;
88 id.dst_fn = clone;
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. */
99 id.eh_lp_nr = 0;
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 unsigned ix;
111 tree decl;
113 FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (fn), ix, decl)
114 walk_tree (&DECL_INITIAL (decl), copy_tree_body_r, &id, NULL);
117 append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone));
120 /* DELETE_DTOR is a delete destructor whose body will be built.
121 COMPLETE_DTOR is the corresponding complete destructor. */
123 static void
124 build_delete_destructor_body (tree delete_dtor, tree complete_dtor)
126 tree call_dtor, call_delete;
127 tree parm = DECL_ARGUMENTS (delete_dtor);
128 tree virtual_size = cxx_sizeof (current_class_type);
130 /* Call the corresponding complete destructor. */
131 gcc_assert (complete_dtor);
132 call_dtor = build_cxx_call (complete_dtor, 1, &parm);
133 add_stmt (call_dtor);
135 add_stmt (build_stmt (0, LABEL_EXPR, cdtor_label));
137 /* Call the delete function. */
138 call_delete = build_op_delete_call (DELETE_EXPR, current_class_ptr,
139 virtual_size,
140 /*global_p=*/false,
141 /*placement=*/NULL_TREE,
142 /*alloc_fn=*/NULL_TREE);
143 add_stmt (call_delete);
145 /* Return the address of the object. */
146 if (targetm.cxx.cdtor_returns_this ())
148 tree val = DECL_ARGUMENTS (delete_dtor);
149 val = build2 (MODIFY_EXPR, TREE_TYPE (val),
150 DECL_RESULT (delete_dtor), val);
151 add_stmt (build_stmt (0, RETURN_EXPR, val));
155 /* Return name of comdat group for complete and base ctor (or dtor)
156 that have the same body. If dtor is virtual, deleting dtor goes
157 into this comdat group as well. */
159 static tree
160 cdtor_comdat_group (tree complete, tree base)
162 tree complete_name = DECL_COMDAT_GROUP (complete);
163 tree base_name = DECL_COMDAT_GROUP (base);
164 char *grp_name;
165 const char *p, *q;
166 bool diff_seen = false;
167 size_t idx;
168 if (complete_name == NULL)
169 complete_name = cxx_comdat_group (complete);
170 if (base_name == NULL)
171 base_name = cxx_comdat_group (base);
172 gcc_assert (IDENTIFIER_LENGTH (complete_name)
173 == IDENTIFIER_LENGTH (base_name));
174 grp_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name) + 1);
175 p = IDENTIFIER_POINTER (complete_name);
176 q = IDENTIFIER_POINTER (base_name);
177 for (idx = 0; idx < IDENTIFIER_LENGTH (complete_name); idx++)
178 if (p[idx] == q[idx])
179 grp_name[idx] = p[idx];
180 else
182 gcc_assert (!diff_seen
183 && idx > 0
184 && (p[idx - 1] == 'C' || p[idx - 1] == 'D')
185 && p[idx] == '1'
186 && q[idx] == '2');
187 grp_name[idx] = '5';
188 diff_seen = true;
190 grp_name[idx] = '\0';
191 gcc_assert (diff_seen);
192 return get_identifier (grp_name);
195 /* FN is a function that has a complete body. Clone the body as
196 necessary. Returns nonzero if there's no longer any need to
197 process the main body. */
199 bool
200 maybe_clone_body (tree fn)
202 tree comdat_group = NULL_TREE;
203 tree clone;
204 tree fns[3];
205 bool first = true;
206 bool in_charge_parm_used;
207 int idx;
208 bool need_alias = false;
210 /* We only clone constructors and destructors. */
211 if (!DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
212 && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
213 return 0;
215 /* Emit the DWARF1 abstract instance. */
216 (*debug_hooks->deferred_inline_function) (fn);
218 in_charge_parm_used = CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)) != NULL;
219 fns[0] = NULL_TREE;
220 fns[1] = NULL_TREE;
221 fns[2] = NULL_TREE;
223 /* Look for the complete destructor which may be used to build the
224 delete destructor. */
225 FOR_EACH_CLONE (clone, fn)
226 if (DECL_NAME (clone) == complete_dtor_identifier
227 || DECL_NAME (clone) == complete_ctor_identifier)
228 fns[1] = clone;
229 else if (DECL_NAME (clone) == base_dtor_identifier
230 || DECL_NAME (clone) == base_ctor_identifier)
231 fns[0] = clone;
232 else if (DECL_NAME (clone) == deleting_dtor_identifier)
233 fns[2] = clone;
234 else
235 gcc_unreachable ();
237 /* Remember if we can't have multiple clones for some reason. We need to
238 check this before we remap local static initializers in clone_body. */
239 if (!tree_versionable_function_p (fn))
240 need_alias = true;
242 /* We know that any clones immediately follow FN in the TYPE_METHODS
243 list. */
244 push_to_top_level ();
245 for (idx = 0; idx < 3; idx++)
247 tree parm;
248 tree clone_parm;
249 int parmno;
250 bool alias = false;
251 struct pointer_map_t *decl_map;
253 clone = fns[idx];
254 if (!clone)
255 continue;
257 /* Update CLONE's source position information to match FN's. */
258 DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (fn);
259 DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_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 (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;