OSDN Git Service

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