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