OSDN Git Service

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