OSDN Git Service

PR c++/44443
[pf3gnuchains/gcc-fork.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    2010 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 "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"
42
43 /* Prototypes.  */
44
45 static void update_cloned_parm (tree, tree, bool);
46
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.  */
51
52 static void
53 update_cloned_parm (tree parm, tree cloned_parm, bool first)
54 {
55   DECL_ABSTRACT_ORIGIN (cloned_parm) = parm;
56
57   /* We may have taken its address.  */
58   TREE_ADDRESSABLE (cloned_parm) = TREE_ADDRESSABLE (parm);
59
60   /* The definition might have different constness.  */
61   TREE_READONLY (cloned_parm) = TREE_READONLY (parm);
62
63   TREE_USED (cloned_parm) = !first || TREE_USED (parm);
64
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);
69
70   DECL_GIMPLE_REG_P (cloned_parm) = DECL_GIMPLE_REG_P (parm);
71 }
72
73
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.  */
77
78 static void
79 clone_body (tree clone, tree fn, void *arg_map)
80 {
81   copy_body_data id;
82   tree stmts;
83
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;
91
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;
97
98   /* We're not inside any EH region.  */
99   id.eh_lp_nr = 0;
100
101   stmts = DECL_SAVED_TREE (fn);
102   walk_tree (&stmts, copy_tree_body_r, &id, NULL);
103
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)
109     {
110       tree decls = DECL_STRUCT_FUNCTION (fn)->local_decls;
111       for (; decls; decls = TREE_CHAIN (decls))
112         {
113           tree decl = TREE_VALUE (decls);
114           walk_tree (&DECL_INITIAL (decl), copy_tree_body_r, &id, NULL);
115         }
116     }
117
118   append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone));
119 }
120
121 /* DELETE_DTOR is a delete destructor whose body will be built.
122    COMPLETE_DTOR is the corresponding complete destructor.  */
123
124 static void
125 build_delete_destructor_body (tree delete_dtor, tree complete_dtor)
126 {
127   tree call_dtor, call_delete;
128   tree parm = DECL_ARGUMENTS (delete_dtor);
129   tree virtual_size = cxx_sizeof (current_class_type);
130
131   /* Call the corresponding complete destructor.  */
132   gcc_assert (complete_dtor);
133   call_dtor = build_cxx_call (complete_dtor, 1, &parm);
134   add_stmt (call_dtor);
135
136   add_stmt (build_stmt (0, LABEL_EXPR, cdtor_label));
137
138   /* Call the delete function.  */
139   call_delete = build_op_delete_call (DELETE_EXPR, current_class_ptr,
140                                       virtual_size,
141                                       /*global_p=*/false,
142                                       /*placement=*/NULL_TREE,
143                                       /*alloc_fn=*/NULL_TREE);
144   add_stmt (call_delete);
145
146   /* Return the address of the object.  */
147   if (targetm.cxx.cdtor_returns_this ())
148     {
149       tree val = DECL_ARGUMENTS (delete_dtor);
150       val = build2 (MODIFY_EXPR, TREE_TYPE (val),
151                     DECL_RESULT (delete_dtor), val);
152       add_stmt (build_stmt (0, RETURN_EXPR, val));
153     }
154 }
155
156 /* Return name of comdat group for complete and base ctor (or dtor)
157    that have the same body.  If dtor is virtual, deleting dtor goes
158    into this comdat group as well.  */
159
160 static tree
161 cdtor_comdat_group (tree complete, tree base)
162 {
163   tree complete_name = DECL_COMDAT_GROUP (complete);
164   tree base_name = DECL_COMDAT_GROUP (base);
165   char *grp_name;
166   const char *p, *q;
167   bool diff_seen = false;
168   size_t idx;
169   if (complete_name == NULL)
170     complete_name = cxx_comdat_group (complete);
171   if (base_name == NULL)
172     base_name = cxx_comdat_group (base);
173   gcc_assert (IDENTIFIER_LENGTH (complete_name)
174               == IDENTIFIER_LENGTH (base_name));
175   grp_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name) + 1);
176   p = IDENTIFIER_POINTER (complete_name);
177   q = IDENTIFIER_POINTER (base_name);
178   for (idx = 0; idx < IDENTIFIER_LENGTH (complete_name); idx++)
179     if (p[idx] == q[idx])
180       grp_name[idx] = p[idx];
181     else
182       {
183         gcc_assert (!diff_seen
184                     && idx > 0
185                     && (p[idx - 1] == 'C' || p[idx - 1] == 'D')
186                     && p[idx] == '1'
187                     && q[idx] == '2');
188         grp_name[idx] = '5';
189         diff_seen = true;
190       }
191   grp_name[idx] = '\0';
192   gcc_assert (diff_seen);
193   return get_identifier (grp_name);
194 }
195
196 /* FN is a function that has a complete body.  Clone the body as
197    necessary.  Returns nonzero if there's no longer any need to
198    process the main body.  */
199
200 bool
201 maybe_clone_body (tree fn)
202 {
203   tree comdat_group = NULL_TREE;
204   tree clone;
205   tree fns[3];
206   bool first = true;
207   bool in_charge_parm_used;
208   int idx;
209   bool need_alias = false;
210
211   /* We only clone constructors and destructors.  */
212   if (!DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
213       && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
214     return 0;
215
216   /* Emit the DWARF1 abstract instance.  */
217   (*debug_hooks->deferred_inline_function) (fn);
218
219   in_charge_parm_used = CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)) != NULL;
220   fns[0] = NULL_TREE;
221   fns[1] = NULL_TREE;
222   fns[2] = NULL_TREE;
223
224   /* Look for the complete destructor which may be used to build the
225      delete destructor.  */
226   FOR_EACH_CLONE (clone, fn)
227     if (DECL_NAME (clone) == complete_dtor_identifier
228         || DECL_NAME (clone) == complete_ctor_identifier)
229       fns[1] = clone;
230     else if (DECL_NAME (clone) == base_dtor_identifier
231              || DECL_NAME (clone) == base_ctor_identifier)
232       fns[0] = clone;
233     else if (DECL_NAME (clone) == deleting_dtor_identifier)
234       fns[2] = clone;
235     else
236       gcc_unreachable ();
237
238   /* Remember if we can't have multiple clones for some reason.  We need to
239      check this before we remap local static initializers in clone_body.  */
240   if (!tree_versionable_function_p (fn))
241     need_alias = true;
242
243   /* We know that any clones immediately follow FN in the TYPE_METHODS
244      list.  */
245   push_to_top_level ();
246   for (idx = 0; idx < 3; idx++)
247     {
248       tree parm;
249       tree clone_parm;
250       int parmno;
251       bool alias = false;
252       struct pointer_map_t *decl_map;
253
254       clone = fns[idx];
255       if (!clone)
256         continue;      
257
258       /* Update CLONE's source position information to match FN's.  */
259       DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (fn);
260       DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn);
261       DECL_COMDAT (clone) = DECL_COMDAT (fn);
262       DECL_WEAK (clone) = DECL_WEAK (fn);
263
264       /* We don't copy the comdat group from fn to clone because the assembler
265          name of fn was corrupted by write_mangled_name by adding *INTERNAL*
266          to it. By doing so, it also corrupted the comdat group. */
267       if (DECL_ONE_ONLY (fn))
268         DECL_COMDAT_GROUP (clone) = cxx_comdat_group (clone);
269       DECL_SECTION_NAME (clone) = DECL_SECTION_NAME (fn);
270       DECL_USE_TEMPLATE (clone) = DECL_USE_TEMPLATE (fn);
271       DECL_EXTERNAL (clone) = DECL_EXTERNAL (fn);
272       DECL_INTERFACE_KNOWN (clone) = DECL_INTERFACE_KNOWN (fn);
273       DECL_NOT_REALLY_EXTERN (clone) = DECL_NOT_REALLY_EXTERN (fn);
274       TREE_PUBLIC (clone) = TREE_PUBLIC (fn);
275       DECL_VISIBILITY (clone) = DECL_VISIBILITY (fn);
276       DECL_VISIBILITY_SPECIFIED (clone) = DECL_VISIBILITY_SPECIFIED (fn);
277       DECL_DLLIMPORT_P (clone) = DECL_DLLIMPORT_P (fn);
278       DECL_ATTRIBUTES (clone) = copy_list (DECL_ATTRIBUTES (fn));
279       DECL_DISREGARD_INLINE_LIMITS (clone) = DECL_DISREGARD_INLINE_LIMITS (fn);
280
281       /* Adjust the parameter names and locations.  */
282       parm = DECL_ARGUMENTS (fn);
283       clone_parm = DECL_ARGUMENTS (clone);
284       /* Update the `this' parameter, which is always first.  */
285       update_cloned_parm (parm, clone_parm, first);
286       parm = TREE_CHAIN (parm);
287       clone_parm = TREE_CHAIN (clone_parm);
288       if (DECL_HAS_IN_CHARGE_PARM_P (fn))
289         parm = TREE_CHAIN (parm);
290       if (DECL_HAS_VTT_PARM_P (fn))
291         parm = TREE_CHAIN (parm);
292       if (DECL_HAS_VTT_PARM_P (clone))
293         clone_parm = TREE_CHAIN (clone_parm);
294       for (; parm;
295            parm = TREE_CHAIN (parm), clone_parm = TREE_CHAIN (clone_parm))
296         /* Update this parameter.  */
297         update_cloned_parm (parm, clone_parm, first);
298
299       /* Start processing the function.  */
300       start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
301
302       /* Tell cgraph if both ctors or both dtors are known to have
303          the same body.  */
304       if (!in_charge_parm_used
305           && fns[0]
306           && idx == 1
307           && !flag_use_repository
308           && DECL_INTERFACE_KNOWN (fns[0])
309           && (SUPPORTS_ONE_ONLY || !DECL_WEAK (fns[0]))
310           && (!DECL_ONE_ONLY (fns[0])
311               || (HAVE_COMDAT_GROUP
312                   && DECL_WEAK (fns[0])))
313           && cgraph_same_body_alias (clone, fns[0]))
314         {
315           alias = true;
316           if (DECL_ONE_ONLY (fns[0]))
317             {
318               /* For comdat base and complete cdtors put them
319                  into the same, *[CD]5* comdat group instead of
320                  *[CD][12]*.  */
321               comdat_group = cdtor_comdat_group (fns[1], fns[0]);
322               DECL_COMDAT_GROUP (fns[0]) = comdat_group;
323             }
324         }
325
326       /* Build the delete destructor by calling complete destructor
327          and delete function.  */
328       if (idx == 2)
329         build_delete_destructor_body (clone, fns[1]);
330       else if (alias)
331         /* No need to populate body.  */ ;
332       else
333         {
334           /* If we can't have multiple copies of FN (say, because there's a
335              static local initialized with the address of a label), we need
336              to use an alias for the complete variant.  */
337           if (idx == 1 && need_alias)
338             {
339               if (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_set)
340                 sorry (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_reason, fn);
341               else
342                 sorry ("making multiple clones of %qD", fn);
343             }
344
345           /* Remap the parameters.  */
346           decl_map = pointer_map_create ();
347           for (parmno = 0,
348                 parm = DECL_ARGUMENTS (fn),
349                 clone_parm = DECL_ARGUMENTS (clone);
350               parm;
351               ++parmno,
352                 parm = TREE_CHAIN (parm))
353             {
354               /* Map the in-charge parameter to an appropriate constant.  */
355               if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1)
356                 {
357                   tree in_charge;
358                   in_charge = in_charge_arg_for_name (DECL_NAME (clone));
359                   *pointer_map_insert (decl_map, parm) = in_charge;
360                 }
361               else if (DECL_ARTIFICIAL (parm)
362                        && DECL_NAME (parm) == vtt_parm_identifier)
363                 {
364                   /* For a subobject constructor or destructor, the next
365                      argument is the VTT parameter.  Remap the VTT_PARM
366                      from the CLONE to this parameter.  */
367                   if (DECL_HAS_VTT_PARM_P (clone))
368                     {
369                       DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
370                       *pointer_map_insert (decl_map, parm) = clone_parm;
371                       clone_parm = TREE_CHAIN (clone_parm);
372                     }
373                   /* Otherwise, map the VTT parameter to `NULL'.  */
374                   else
375                     *pointer_map_insert (decl_map, parm)
376                        = fold_convert (TREE_TYPE (parm), null_pointer_node);
377                 }
378               /* Map other parameters to their equivalents in the cloned
379                  function.  */
380               else
381                 {
382                   *pointer_map_insert (decl_map, parm) = clone_parm;
383                   clone_parm = TREE_CHAIN (clone_parm);
384                 }
385             }
386
387           if (targetm.cxx.cdtor_returns_this ())
388             {
389               parm = DECL_RESULT (fn);
390               clone_parm = DECL_RESULT (clone);
391               *pointer_map_insert (decl_map, parm) = clone_parm;
392             }
393
394           /* Clone the body.  */
395           clone_body (clone, fn, decl_map);
396
397           /* Clean up.  */
398           pointer_map_destroy (decl_map);
399         }
400
401       /* The clone can throw iff the original function can throw.  */
402       cp_function_chain->can_throw = !TREE_NOTHROW (fn);
403
404       /* Now, expand this function into RTL, if appropriate.  */
405       finish_function (0);
406       BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
407       if (alias)
408         {
409           if (expand_or_defer_fn_1 (clone))
410             emit_associated_thunks (clone);
411         }
412       else
413         expand_or_defer_fn (clone);
414       first = false;
415     }
416   pop_from_top_level ();
417
418   if (comdat_group)
419     {
420       DECL_COMDAT_GROUP (fns[1]) = comdat_group;
421       if (fns[2])
422         {
423           struct cgraph_node *base_dtor_node, *deleting_dtor_node;
424           /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
425              virtual, it goes into the same comdat group as well.  */
426           DECL_COMDAT_GROUP (fns[2]) = comdat_group;
427           base_dtor_node = cgraph_node (fns[0]);
428           deleting_dtor_node = cgraph_node (fns[2]);
429           gcc_assert (base_dtor_node->same_comdat_group == NULL);
430           gcc_assert (deleting_dtor_node->same_comdat_group == NULL);
431           base_dtor_node->same_comdat_group = deleting_dtor_node;
432           deleting_dtor_node->same_comdat_group = base_dtor_node;
433         }
434     }
435
436   /* We don't need to process the original function any further.  */
437   return 1;
438 }