OSDN Git Service

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